]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #15421 : catharsis/rust/doc-ffi-minor-fixes, r=alexcrichton
authorbors <bors@rust-lang.org>
Tue, 15 Jul 2014 14:26:11 +0000 (14:26 +0000)
committerbors <bors@rust-lang.org>
Tue, 15 Jul 2014 14:26:11 +0000 (14:26 +0000)
Signed-off-by: Anton Lofgren <alofgren@op5.com>
610 files changed:
.gitattributes
.gitignore
RELEASES.txt
configure
man/rustc.1
man/rustdoc.1
mk/crates.mk
mk/dist.mk
mk/install.mk
mk/llvm.mk
mk/main.mk
mk/target.mk
mk/tests.mk
src/compiletest/compiletest.rs
src/compiletest/errors.rs
src/compiletest/procsrv.rs
src/compiletest/runtest.rs
src/compiletest/util.rs
src/doc/favicon.inc
src/doc/guide-tasks.md
src/doc/guide.md
src/doc/po/ja/complement-cheatsheet.md.po
src/doc/po/ja/complement-lang-faq.md.po
src/doc/po/ja/complement-project-faq.md.po
src/doc/po/ja/complement-usage-faq.md.po
src/doc/po/ja/guide-conditions.md.po
src/doc/po/ja/guide-container.md.po
src/doc/po/ja/guide-ffi.md.po
src/doc/po/ja/guide-lifetimes.md.po
src/doc/po/ja/guide-macros.md.po
src/doc/po/ja/guide-pointers.md.po
src/doc/po/ja/guide-runtime.md.po
src/doc/po/ja/guide-tasks.md.po
src/doc/po/ja/guide-testing.md.po
src/doc/po/ja/index.md.po
src/doc/po/ja/rust.md.po
src/doc/po/ja/rustdoc.md.po
src/doc/po/ja/tutorial.md.po
src/doc/rust.css
src/doc/rust.md
src/doc/tutorial.md
src/etc/install.sh
src/etc/kate/rust.xml
src/etc/regex-unicode-tables.py [deleted file]
src/etc/unicode.py
src/etc/vim/ftplugin/rust.vim
src/etc/vim/syntax/rust.vim
src/etc/zsh/_rust
src/liballoc/boxed.rs [new file with mode: 0644]
src/liballoc/lib.rs
src/liballoc/owned.rs [deleted file]
src/libarena/lib.rs
src/libcollections/bitv.rs
src/libcollections/btree.rs
src/libcollections/dlist.rs
src/libcollections/hash/mod.rs
src/libcollections/hash/sip.rs
src/libcollections/lib.rs
src/libcollections/smallintmap.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/treemap.rs
src/libcollections/trie.rs
src/libcollections/unicode.rs [deleted file]
src/libcollections/vec.rs
src/libcore/any.rs
src/libcore/atomics.rs
src/libcore/cell.rs
src/libcore/char.rs
src/libcore/cmp.rs
src/libcore/fmt/float.rs
src/libcore/intrinsics.rs
src/libcore/iter.rs
src/libcore/lib.rs
src/libcore/num/f32.rs
src/libcore/num/f64.rs
src/libcore/num/mod.rs
src/libcore/ops.rs
src/libcore/prelude.rs
src/libcore/ptr.rs
src/libcore/result.rs
src/libcore/slice.rs
src/libcore/str.rs
src/libcore/unicode.rs [deleted file]
src/libcoretest/char.rs
src/libcoretest/iter.rs
src/libdebug/fmt.rs
src/libdebug/lib.rs
src/libdebug/repr.rs
src/libflate/lib.rs
src/libfmt_macros/lib.rs
src/libfourcc/lib.rs
src/libgetopts/lib.rs
src/libglob/lib.rs
src/libgraphviz/lib.rs
src/libgreen/lib.rs
src/libgreen/stack.rs
src/libhexfloat/lib.rs
src/liblibc/lib.rs
src/liblog/lib.rs
src/libnative/io/file_win32.rs
src/libnative/io/pipe_unix.rs
src/libnative/io/pipe_win32.rs
src/libnative/io/process.rs
src/libnative/io/util.rs
src/libnative/lib.rs
src/libnum/bigint.rs
src/libnum/complex.rs
src/libnum/lib.rs
src/libnum/rational.rs
src/librand/lib.rs
src/libregex/lib.rs
src/libregex/parse.rs [new file with mode: 0644]
src/libregex/parse/mod.rs [deleted file]
src/libregex/parse/unicode.rs [deleted file]
src/libregex/test/tests.rs
src/libregex/vm.rs
src/libregex_macros/lib.rs
src/librlibc/lib.rs
src/librustc/back/abi.rs [deleted file]
src/librustc/back/archive.rs [deleted file]
src/librustc/back/arm.rs [deleted file]
src/librustc/back/link.rs
src/librustc/back/lto.rs
src/librustc/back/mips.rs [deleted file]
src/librustc/back/mipsel.rs [deleted file]
src/librustc/back/rpath.rs [deleted file]
src/librustc/back/svh.rs [deleted file]
src/librustc/back/target_strs.rs [deleted file]
src/librustc/back/x86.rs [deleted file]
src/librustc/back/x86_64.rs [deleted file]
src/librustc/diagnostics.rs [new file with mode: 0644]
src/librustc/driver/config.rs
src/librustc/driver/driver.rs
src/librustc/driver/mod.rs
src/librustc/driver/session.rs
src/librustc/front/config.rs
src/librustc/front/feature_gate.rs
src/librustc/front/std_inject.rs
src/librustc/front/test.rs
src/librustc/lib.rs
src/librustc/lib/llvm.rs [deleted file]
src/librustc/lib/llvmdeps.rs [new file with mode: 0644]
src/librustc/lint/builtin.rs
src/librustc/lint/context.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/borrowck/check_loans.rs
src/librustc/middle/borrowck/gather_loans/move_error.rs
src/librustc/middle/borrowck/graphviz.rs [new file with mode: 0644]
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/borrowck/move_data.rs
src/librustc/middle/cfg/graphviz.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_match.rs
src/librustc/middle/check_static.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/dead.rs
src/librustc/middle/effect.rs
src/librustc/middle/graph.rs
src/librustc/middle/kind.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/privacy.rs
src/librustc/middle/reachable.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/save/mod.rs
src/librustc/middle/save/recorder.rs
src/librustc/middle/stability.rs
src/librustc/middle/subst.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/asm.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/basic_block.rs
src/librustc/middle/trans/build.rs
src/librustc/middle/trans/builder.rs
src/librustc/middle/trans/cabi.rs
src/librustc/middle/trans/cabi_arm.rs
src/librustc/middle/trans/cabi_mips.rs
src/librustc/middle/trans/cabi_x86.rs
src/librustc/middle/trans/cabi_x86_64.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/cleanup.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/datum.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/inline.rs
src/librustc/middle/trans/intrinsic.rs
src/librustc/middle/trans/llrepr.rs
src/librustc/middle/trans/machine.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/type_.rs
src/librustc/middle/trans/type_of.rs
src/librustc/middle/trans/value.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/_match.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/check/regionmanip.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/check/writeback.rs
src/librustc/middle/typeck/coherence.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/error_reporting.rs
src/librustc/middle/typeck/infer/glb.rs
src/librustc/middle/typeck/infer/lattice.rs
src/librustc/middle/typeck/infer/lub.rs
src/librustc/middle/typeck/infer/mod.rs
src/librustc/middle/typeck/infer/resolve.rs
src/librustc/middle/typeck/infer/sub.rs
src/librustc/middle/typeck/infer/test.rs
src/librustc/middle/typeck/mod.rs
src/librustc/middle/typeck/variance.rs
src/librustc/plugin/load.rs
src/librustc/plugin/mod.rs
src/librustc/plugin/registry.rs
src/librustc/util/fs.rs [deleted file]
src/librustc/util/ppaux.rs
src/librustc/util/sha2.rs [deleted file]
src/librustc_back/abi.rs [new file with mode: 0644]
src/librustc_back/archive.rs [new file with mode: 0644]
src/librustc_back/arm.rs [new file with mode: 0644]
src/librustc_back/fs.rs [new file with mode: 0644]
src/librustc_back/lib.rs [new file with mode: 0644]
src/librustc_back/mips.rs [new file with mode: 0644]
src/librustc_back/mipsel.rs [new file with mode: 0644]
src/librustc_back/rpath.rs [new file with mode: 0644]
src/librustc_back/sha2.rs [new file with mode: 0644]
src/librustc_back/svh.rs [new file with mode: 0644]
src/librustc_back/target_strs.rs [new file with mode: 0644]
src/librustc_back/x86.rs [new file with mode: 0644]
src/librustc_back/x86_64.rs [new file with mode: 0644]
src/librustc_llvm/archive_ro.rs [new file with mode: 0644]
src/librustc_llvm/lib.rs [new file with mode: 0644]
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/html/format.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/layout.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/FiraSans-LICENSE.txt [new file with mode: 0644]
src/librustdoc/html/static/Heuristica-Bold.woff [deleted file]
src/librustdoc/html/static/Heuristica-LICENSE.txt [new file with mode: 0644]
src/librustdoc/html/static/Heuristica-Regular.woff [deleted file]
src/librustdoc/html/static/SourceCodePro-LICENSE.txt [new file with mode: 0644]
src/librustdoc/html/static/SourceCodePro-Regular.woff [new file with mode: 0644]
src/librustdoc/html/static/SourceCodePro-Semibold.woff [new file with mode: 0644]
src/librustdoc/html/static/SourceSerifPro-Bold.woff [new file with mode: 0644]
src/librustdoc/html/static/SourceSerifPro-LICENSE.txt [new file with mode: 0644]
src/librustdoc/html/static/SourceSerifPro-Regular.woff [new file with mode: 0644]
src/librustdoc/html/static/main.css
src/librustdoc/lib.rs
src/librustdoc/stability_summary.rs [new file with mode: 0644]
src/librustdoc/test.rs
src/librustrt/args.rs
src/librustrt/at_exit_imp.rs
src/librustrt/c_str.rs
src/librustrt/lib.rs
src/librustrt/local.rs
src/librustrt/local_data.rs
src/librustrt/local_ptr.rs
src/librustrt/rtio.rs
src/librustrt/stack.rs
src/librustrt/task.rs
src/librustrt/thread.rs
src/librustrt/unwind.rs
src/librustuv/file.rs
src/librustuv/lib.rs
src/librustuv/net.rs
src/librustuv/process.rs
src/librustuv/uvll.rs
src/libsemver/lib.rs
src/libserialize/json.rs
src/libserialize/lib.rs
src/libserialize/serialize.rs
src/libstd/ascii.rs
src/libstd/collections/hashmap.rs
src/libstd/collections/lru_cache.rs
src/libstd/dynamic_lib.rs
src/libstd/failure.rs
src/libstd/from_str.rs
src/libstd/hash.rs
src/libstd/io/extensions.rs
src/libstd/io/fs.rs
src/libstd/io/mem.rs
src/libstd/io/mod.rs
src/libstd/io/net/ip.rs
src/libstd/io/net/tcp.rs
src/libstd/io/net/udp.rs
src/libstd/io/net/unix.rs
src/libstd/io/pipe.rs
src/libstd/io/process.rs
src/libstd/io/signal.rs
src/libstd/io/stdio.rs
src/libstd/io/timer.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/int_macros.rs
src/libstd/num/strconv.rs
src/libstd/num/uint_macros.rs
src/libstd/os.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/prelude.rs
src/libstd/rt/backtrace.rs
src/libstd/task.rs
src/libstd/to_str.rs
src/libsync/atomics.rs
src/libsync/comm/mod.rs
src/libsync/comm/oneshot.rs
src/libsync/comm/select.rs
src/libsync/comm/shared.rs
src/libsync/comm/stream.rs
src/libsync/comm/sync.rs
src/libsync/deque.rs
src/libsync/lib.rs
src/libsync/mpsc_queue.rs
src/libsync/mutex.rs
src/libsync/spsc_queue.rs
src/libsyntax/abi.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map.rs [deleted file]
src/libsyntax/ast_map/blocks.rs [new file with mode: 0644]
src/libsyntax/ast_map/mod.rs [new file with mode: 0644]
src/libsyntax/ast_util.rs
src/libsyntax/attr.rs
src/libsyntax/codemap.rs
src/libsyntax/diagnostic.rs
src/libsyntax/diagnostics/macros.rs [new file with mode: 0644]
src/libsyntax/diagnostics/plugin.rs [new file with mode: 0644]
src/libsyntax/diagnostics/registry.rs [new file with mode: 0644]
src/libsyntax/ext/asm.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/clone.rs
src/libsyntax/ext/deriving/cmp/eq.rs
src/libsyntax/ext/deriving/cmp/ord.rs
src/libsyntax/ext/deriving/cmp/totaleq.rs
src/libsyntax/ext/deriving/cmp/totalord.rs
src/libsyntax/ext/deriving/decodable.rs
src/libsyntax/ext/deriving/default.rs
src/libsyntax/ext/deriving/encodable.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/generic/ty.rs
src/libsyntax/ext/deriving/hash.rs
src/libsyntax/ext/deriving/primitive.rs
src/libsyntax/ext/deriving/rand.rs
src/libsyntax/ext/deriving/show.rs
src/libsyntax/ext/deriving/zero.rs
src/libsyntax/ext/env.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/format.rs
src/libsyntax/ext/log_syntax.rs
src/libsyntax/ext/mtwt.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/classify.rs
src/libsyntax/parse/common.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax/util/interner.rs
src/libsyntax/util/parser_testing.rs
src/libsyntax/visit.rs
src/libterm/lib.rs
src/libterm/terminfo/parser/compiled.rs
src/libtest/lib.rs
src/libtest/stats.rs
src/libtime/lib.rs
src/libunicode/decompose.rs [new file with mode: 0644]
src/libunicode/lib.rs [new file with mode: 0644]
src/libunicode/tables.rs [new file with mode: 0644]
src/libunicode/u_char.rs [new file with mode: 0644]
src/libunicode/u_str.rs [new file with mode: 0644]
src/liburl/lib.rs
src/libuuid/lib.rs
src/snapshots.txt
src/test/auxiliary/crateresolve1-1.rs
src/test/auxiliary/crateresolve1-2.rs
src/test/auxiliary/crateresolve1-3.rs
src/test/auxiliary/crateresolve2-1.rs [deleted file]
src/test/auxiliary/crateresolve2-2.rs [deleted file]
src/test/auxiliary/crateresolve2-3.rs [deleted file]
src/test/auxiliary/extern-crosscrate-source.rs
src/test/auxiliary/issue-11908-1.rs [deleted file]
src/test/auxiliary/issue-11908-2.rs [deleted file]
src/test/auxiliary/issue2378a.rs [deleted file]
src/test/auxiliary/issue2378b.rs [deleted file]
src/test/auxiliary/rlib_crate_test.rs [new file with mode: 0644]
src/test/auxiliary/xcrate_struct_aliases.rs [new file with mode: 0644]
src/test/bench/core-set.rs
src/test/bench/core-uint-to-str.rs
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-k-nucleotide-pipes.rs
src/test/bench/shootout-pfib.rs
src/test/bench/shootout-regex-dna.rs
src/test/compile-fail-fulldeps/macro-crate-rlib.rs [new file with mode: 0644]
src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs
src/test/compile-fail/bad-crate-id.rs
src/test/compile-fail/bad-crate-id2.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-forbid-static-unsafe-interior.rs
src/test/compile-fail/borrowck-overloaded-index.rs [new file with mode: 0644]
src/test/compile-fail/check-static-values-constraints.rs
src/test/compile-fail/crateresolve2.rs [deleted file]
src/test/compile-fail/crateresolve5.rs [deleted file]
src/test/compile-fail/dup-struct-enum-struct-variant.rs
src/test/compile-fail/enum-and-module-in-same-scope.rs [new file with mode: 0644]
src/test/compile-fail/issue-11692.rs
src/test/compile-fail/issue-11908-1.rs [deleted file]
src/test/compile-fail/issue-11908-2.rs [deleted file]
src/test/compile-fail/issue-12187-1.rs [new file with mode: 0644]
src/test/compile-fail/issue-12187-2.rs [new file with mode: 0644]
src/test/compile-fail/issue-14541.rs
src/test/compile-fail/issue-2063.rs
src/test/compile-fail/issue-3099-a.rs
src/test/compile-fail/issue-3099-b.rs
src/test/compile-fail/issue-3973.rs
src/test/compile-fail/lex-bad-char-literals.rs [new file with mode: 0644]
src/test/compile-fail/lex-bad-fp-base-1.rs [deleted file]
src/test/compile-fail/lex-bad-fp-base-2.rs [deleted file]
src/test/compile-fail/lex-bad-fp-base-3.rs [deleted file]
src/test/compile-fail/lex-bad-fp-base-4.rs [deleted file]
src/test/compile-fail/lex-bad-fp-base-5.rs [deleted file]
src/test/compile-fail/lex-bad-fp-base-6.rs [deleted file]
src/test/compile-fail/lex-bad-fp-base-7.rs [deleted file]
src/test/compile-fail/lex-bad-fp-base-8.rs [deleted file]
src/test/compile-fail/lex-bad-fp-base-9.rs [deleted file]
src/test/compile-fail/lex-bad-fp-lit.rs [deleted file]
src/test/compile-fail/lex-bad-numeric-literals.rs [new file with mode: 0644]
src/test/compile-fail/lex-bad-token.rs [new file with mode: 0644]
src/test/compile-fail/lex-hex-float-lit.rs [deleted file]
src/test/compile-fail/lex-illegal-num-char-escape.rs [deleted file]
src/test/compile-fail/lex-int-lit-too-large-2.rs [deleted file]
src/test/compile-fail/lex-int-lit-too-large.rs [deleted file]
src/test/compile-fail/lex-no-valid-digits-2.rs [deleted file]
src/test/compile-fail/lex-no-valid-digits.rs [deleted file]
src/test/compile-fail/lex-unknown-char-escape.rs [deleted file]
src/test/compile-fail/lex-unknown-start-tok.rs [deleted file]
src/test/compile-fail/lex-unknown-str-escape.rs [deleted file]
src/test/compile-fail/lex-unterminated-char-const.rs [deleted file]
src/test/compile-fail/lint-non-camel-case-types.rs
src/test/compile-fail/lint-type-overflow.rs
src/test/compile-fail/lint-uppercase-variables.rs
src/test/compile-fail/liveness-issue-2163.rs
src/test/compile-fail/moves-based-on-type-block-bad.rs
src/test/compile-fail/multitrait.rs
src/test/compile-fail/new-box-syntax-bad.rs
src/test/compile-fail/no-implicit-prelude-nested.rs
src/test/compile-fail/no-implicit-prelude.rs
src/test/compile-fail/no-oct-float-literal.rs [deleted file]
src/test/compile-fail/non-exhaustive-pattern-witness.rs
src/test/compile-fail/rustc-diagnostics-1.rs [new file with mode: 0644]
src/test/compile-fail/rustc-diagnostics-2.rs [new file with mode: 0644]
src/test/compile-fail/rustc-diagnostics-3.rs [new file with mode: 0644]
src/test/compile-fail/typeck-cast-pointer-to-float.rs [new file with mode: 0644]
src/test/compile-fail/uninhabited-enum-cast.rs
src/test/compile-fail/unsized-bare-typaram.rs
src/test/compile-fail/unsized-enum.rs
src/test/compile-fail/unsized-struct.rs
src/test/compile-fail/unsized3.rs
src/test/compile-fail/unsized4.rs
src/test/compile-fail/unsized5.rs
src/test/compile-fail/unsized6.rs
src/test/compile-fail/unused-result.rs
src/test/compile-fail/use-after-move-implicity-coerced-object.rs
src/test/compile-fail/use-meta.rc [deleted file]
src/test/debuginfo/cross-crate-type-uniquing.rs
src/test/run-make/bootstrap-from-c-with-green/Makefile
src/test/run-make/bootstrap-from-c-with-green/lib.rs
src/test/run-make/bootstrap-from-c-with-native/Makefile
src/test/run-make/c-link-to-rust-dylib/Makefile
src/test/run-make/c-link-to-rust-staticlib/Makefile
src/test/run-make/crate-data-smoke/Makefile
src/test/run-make/crate-data-smoke/crate.rs
src/test/run-make/crate-data-smoke/lib.rs
src/test/run-make/crate-data-smoke/rlib.rs
src/test/run-make/crate-name-priority/Makefile [new file with mode: 0644]
src/test/run-make/crate-name-priority/foo.rs [new file with mode: 0644]
src/test/run-make/crate-name-priority/foo1.rs [new file with mode: 0644]
src/test/run-make/dep-info/lib.rs
src/test/run-make/extern-flag-disambiguates/Makefile [new file with mode: 0644]
src/test/run-make/extern-flag-disambiguates/a.rs [new file with mode: 0644]
src/test/run-make/extern-flag-disambiguates/b.rs [new file with mode: 0644]
src/test/run-make/extern-flag-disambiguates/c.rs [new file with mode: 0644]
src/test/run-make/extern-flag-disambiguates/d.rs [new file with mode: 0644]
src/test/run-make/extern-flag-fun/Makefile [new file with mode: 0644]
src/test/run-make/extern-flag-fun/bar.rs [new file with mode: 0644]
src/test/run-make/extern-flag-fun/foo.rs [new file with mode: 0644]
src/test/run-make/graphviz-flowgraph/f06.dot-expected.dot
src/test/run-make/issue-11908/Makefile [new file with mode: 0644]
src/test/run-make/issue-11908/bar.rs [new file with mode: 0644]
src/test/run-make/issue-11908/foo.rs [new file with mode: 0644]
src/test/run-make/lto-smoke-c/Makefile
src/test/run-make/lto-syntax-extension/lib.rs
src/test/run-make/manual-crate-name/Makefile [new file with mode: 0644]
src/test/run-make/manual-crate-name/bar.rs [new file with mode: 0644]
src/test/run-make/metadata-flag-frobs-symbols/Makefile [new file with mode: 0644]
src/test/run-make/metadata-flag-frobs-symbols/bar.rs [new file with mode: 0644]
src/test/run-make/metadata-flag-frobs-symbols/foo.rs [new file with mode: 0644]
src/test/run-make/multiple-versions/Makefile [new file with mode: 0644]
src/test/run-make/multiple-versions/bar.rs [new file with mode: 0644]
src/test/run-make/multiple-versions/foo.rs [new file with mode: 0644]
src/test/run-make/output-type-permutations/foo.rs
src/test/run-make/rustdoc-smoke/foo.rs
src/test/run-make/weird-output-filenames/Makefile
src/test/run-pass/assignability-trait.rs
src/test/run-pass/backtrace.rs
src/test/run-pass/bitv-perf-test.rs
src/test/run-pass/bool.rs
src/test/run-pass/borrowck-mut-uniq.rs
src/test/run-pass/byte-literals.rs
src/test/run-pass/capturing-logging.rs
src/test/run-pass/class-cast-to-trait-cross-crate-2.rs
src/test/run-pass/class-separate-impl.rs
src/test/run-pass/crate-name-attr-used.rs [new file with mode: 0644]
src/test/run-pass/crateresolve1.rs [deleted file]
src/test/run-pass/crateresolve2.rs [deleted file]
src/test/run-pass/crateresolve3.rs [deleted file]
src/test/run-pass/crateresolve4.rs [deleted file]
src/test/run-pass/crateresolve5.rs [deleted file]
src/test/run-pass/crateresolve8.rs [deleted file]
src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs [new file with mode: 0644]
src/test/run-pass/deriving-show-2.rs
src/test/run-pass/enum-null-pointer-opt.rs [new file with mode: 0644]
src/test/run-pass/exponential-notation.rs
src/test/run-pass/extern-crosscrate.rs
src/test/run-pass/fixed_length_vec_glue.rs
src/test/run-pass/issue-11736.rs
src/test/run-pass/issue-15149.rs [new file with mode: 0644]
src/test/run-pass/issue-15487.rs [new file with mode: 0644]
src/test/run-pass/issue-2904.rs
src/test/run-pass/issue-3037.rs
src/test/run-pass/issue-3559.rs
src/test/run-pass/issue-3563-3.rs
src/test/run-pass/issue-3702.rs
src/test/run-pass/issue-4241.rs
src/test/run-pass/issue-5280.rs
src/test/run-pass/issue-5917.rs
src/test/run-pass/issue-7911.rs
src/test/run-pass/issue-8578.rs
src/test/run-pass/issue2378c.rs [deleted file]
src/test/run-pass/macro-method-issue-4621.rs [new file with mode: 0644]
src/test/run-pass/match-pattern-bindings.rs [new file with mode: 0644]
src/test/run-pass/monad.rs
src/test/run-pass/move-out-of-field.rs
src/test/run-pass/new-box-syntax.rs
src/test/run-pass/new-impl-syntax.rs
src/test/run-pass/operator-overloading.rs
src/test/run-pass/order-drop-with-match.rs [new file with mode: 0644]
src/test/run-pass/overload-index-operator.rs
src/test/run-pass/overloaded-deref-count.rs
src/test/run-pass/overloaded-index.rs [new file with mode: 0644]
src/test/run-pass/process-spawn-with-unicode-params.rs
src/test/run-pass/send_str_treemap.rs
src/test/run-pass/static-impl.rs
src/test/run-pass/string-escapes.rs [new file with mode: 0644]
src/test/run-pass/struct-aliases-xcrate.rs [new file with mode: 0644]
src/test/run-pass/struct-aliases.rs [new file with mode: 0644]
src/test/run-pass/task-stderr.rs
src/test/run-pass/tcp-connect-timeouts.rs
src/test/run-pass/tcp-stress.rs
src/test/run-pass/test-ignore-cfg.rs
src/test/run-pass/trait-cast.rs
src/test/run-pass/trait-generic.rs
src/test/run-pass/trait-to-str.rs
src/test/run-pass/trans-tag-static-padding.rs
src/test/run-pass/typeck_type_placeholder_1.rs
src/test/run-pass/unit-like-struct-drop-run.rs
src/test/run-pass/unsized.rs
src/test/run-pass/unsized2.rs
src/test/run-pass/use.rs
src/test/run-pass/vec-to_str.rs

index c15f7aba7c9c11b85f8abd659ee60f9421bf6d1d..d80daa346ef0c9249d9d4cfcfa0c9fef0c4274e6 100644 (file)
@@ -8,3 +8,4 @@ src/etc/pkg/rust-logo.ico binary
 src/etc/pkg/rust-logo.png binary
 src/rt/msvc/* -whitespace
 src/rt/valgrind/* -whitespace
+*.woff binary
index 896480ba2570828758d8f594a036afe0c4cf0526..bc34fc2dcdfbb5cc771b32dae4351fbb7d59857d 100644 (file)
@@ -86,5 +86,5 @@ src/etc/dl
 .settings/
 /build
 i686-pc-mingw32/
-src/librustc/lib/llvmdeps.rs
+src/librustc_llvm/llvmdeps.rs
 *.pot
index 457328b2c90ca32ab54991f0ff1c21516a6e697c..ba87e575056377ecae8c1ab4fa536379ff5380fb 100644 (file)
@@ -306,7 +306,7 @@ Version 0.9 (January 2014)
       * A new facility for enabling experimental features (feature gating) has
         been added, using the crate-level `#[feature(foo)]` attribute.
       * Managed boxes (@) are now behind a feature gate
-        (`#[feature(managed_boxes)]`) in preperation for future removal. Use the
+        (`#[feature(managed_boxes)]`) in preparation for future removal. Use the
         standard library's `Gc` or `Rc` types instead.
       * `@mut` has been removed. Use `std::cell::{Cell, RefCell}` instead.
       * Jumping back to the top of a loop is now done with `continue` instead of
@@ -398,7 +398,7 @@ Version 0.9 (January 2014)
       * std: `fmt::Default` can be implemented for any type to provide default
         formatting to the `format!` macro, as in `format!("{}", myfoo)`.
       * std: The `rand` API continues to be tweaked.
-      * std: The `rust_begin_unwind` function, useful for insterting breakpoints
+      * std: The `rust_begin_unwind` function, useful for inserting breakpoints
         on failure in gdb, is now named `rust_fail`.
       * std: The `each_key` and `each_value` methods on `HashMap` have been
         replaced by the `keys` and `values` iterators.
@@ -429,7 +429,7 @@ Version 0.9 (January 2014)
         extensible interfaces and is now implemented by two different crates:
         libnative, for native threading and I/O; and libgreen, for green threading
         and I/O. This paves the way for using the standard library in more limited
-        embeded environments.
+        embedded environments.
       * std: The `comm` module has been rewritten to be much faster, have a
         simpler, more consistent API, and to work for both native and green
         threading.
index 59aa6ece6b2f1c230fa028f2ff722afc1b7758f5..135bdcd3782f06d54435328ab53e2e4f7f56bd86 100755 (executable)
--- a/configure
+++ b/configure
@@ -418,7 +418,7 @@ opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
 opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
 opt inject-std-version 1 "inject the current compiler version of libstd into programs"
 opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
-opt rpath 1 "build rpaths into rustc itself"
+opt rpath 0 "build rpaths into rustc itself"
 opt nightly 0 "build nightly packages"
 opt verify-install 1 "verify installed binaries work"
 opt jemalloc 1 "build liballoc with jemalloc"
index df65cf7bb37ffdd41d4179763c0f7557adbb12a7..f49faf2ec6e3a8d68fa76631158f4a06fb0bd7a0 100644 (file)
@@ -1,4 +1,4 @@
-.TH RUSTC "1" "March 2014" "rustc 0.11.0" "User Commands"
+.TH RUSTC "1" "March 2014" "rustc 0.12.0-pre" "User Commands"
 .SH NAME
 rustc \- The Rust compiler
 .SH SYNOPSIS
@@ -11,6 +11,9 @@ This program is a compiler for the Rust language, available at
 
 .SH OPTIONS
 
+.TP
+\fB\-\-crate-name NAME\fR
+Specify the name of the crate being built
 .TP
 \fB\-\-crate-type=[bin|lib|dylib|rlib|staticlib]\fR
 Configure the flavor of rust crate that is generated (default `bin`)
@@ -60,8 +63,9 @@ Parse only; do not compile, assemble, or link
 \fB\-\-pretty\fR [TYPE]
 Pretty-print the input instead of compiling; valid types are: normal
 (un-annotated source), expanded (crates expanded), typed (crates
-expanded, with type annotations), or identified (fully parenthesized,
-AST nodes and blocks with IDs)
+expanded, with type annotations), identified (fully parenthesized,
+AST nodes and blocks with IDs), or flowgraph=<nodeid> (graphviz
+formatted flowgraph for node)
 .TP
 \fB\-\-dep-info\fR [FILENAME]
 Output dependency info to <filename> after compiling, in o format suitable
@@ -138,8 +142,8 @@ A space-separated list of arguments to pass through to LLVM.
 If specified, the compiler will save more files (.bc, .o, .no-opt.bc) generated
 throughout compilation in the output directory.
 .TP
-\fBno-rpath\fR
-If specified, then the rpath value for dynamic libraries will not be set in
+\fBrpath\fR
+If specified, then the rpath value for dynamic libraries will be set in
 either dynamic library or executable outputs.
 .TP
 \fBno-prepopulate-passes\fR
index 03414ca163ec2a01e09e4d83e5942fe4ccf32b51..12e776b98618e988405e28c49bae5c58ad3958f5 100644 (file)
@@ -1,4 +1,4 @@
-.TH RUSTDOC "1" "March 2014" "rustdoc 0.11.0" "User Commands"
+.TH RUSTDOC "1" "March 2014" "rustdoc 0.12.0-pre" "User Commands"
 .SH NAME
 rustdoc \- generate documentation from Rust source code
 .SH SYNOPSIS
index 6c309f7c90a66a8ab21abffde1da720a085f0039..c95576f6252aa3feca7b16ef2c458ec7de17f04e 100644 (file)
 
 TARGET_CRATES := libc std green rustuv native flate arena glob term semver \
                  uuid serialize sync getopts collections num test time rand \
-                 url log regex graphviz core rlibc alloc debug rustrt
-HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros
+                 url log regex graphviz core rlibc alloc debug rustrt \
+                 unicode
+HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros \
+              rustc_llvm rustc_back
 CRATES := $(TARGET_CRATES) $(HOST_CRATES)
 TOOLS := compiletest rustdoc rustc
 
 DEPS_core :=
 DEPS_rlibc :=
+DEPS_unicode := core
 DEPS_alloc := core libc native:jemalloc
 DEPS_debug := std
 DEPS_rustrt := alloc core libc collections native:rustrt_native
-DEPS_std := core libc rand alloc collections rustrt sync \
+DEPS_std := core libc rand alloc collections rustrt sync unicode \
        native:rust_builtin native:backtrace
 DEPS_graphviz := std
 DEPS_green := std native:context_switch
 DEPS_rustuv := std native:uv native:uv_support
 DEPS_native := std
 DEPS_syntax := std term serialize log fmt_macros debug
-DEPS_rustc := syntax native:rustllvm flate arena serialize getopts \
-              time log graphviz debug
+DEPS_rustc := syntax flate arena serialize getopts \
+              time log graphviz debug rustc_llvm rustc_back
+DEPS_rustc_llvm := native:rustllvm libc std
+DEPS_rustc_back := std syntax rustc_llvm flate log libc
 DEPS_rustdoc := rustc native:hoedown serialize getopts \
                 test time debug
 DEPS_flate := std native:miniz
@@ -82,7 +87,7 @@ DEPS_semver := std
 DEPS_uuid := std serialize
 DEPS_sync := core alloc rustrt collections
 DEPS_getopts := std
-DEPS_collections := core alloc
+DEPS_collections := core alloc unicode
 DEPS_fourcc := rustc syntax std
 DEPS_hexfloat := rustc syntax std
 DEPS_num := std
@@ -108,6 +113,7 @@ ONLY_RLIB_rlibc := 1
 ONLY_RLIB_alloc := 1
 ONLY_RLIB_rand := 1
 ONLY_RLIB_collections := 1
+ONLY_RLIB_unicode := 1
 
 ################################################################################
 # You should not need to edit below this line
index 76ebfe9b49fd64929ce5b07b49b2faba38ece8e9..c73d66a999ec7750df61f2913cf0c602d834a815 100644 (file)
@@ -259,7 +259,6 @@ distcheck-tar-bins: dist-tar-bins
        $(Q)cd tmp/distcheck && tar -xzf ../../dist/$(PKG_NAME)-$(CFG_BUILD).tar.gz
        $(Q)mkdir -p tmp/distcheck/tarbininstall
        $(Q)sh tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix=tmp/distcheck/tarbininstall
-       $(Q)tmp/distcheck/tarbininstall/bin/rustc --version
        $(Q)sh tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix=tmp/distcheck/tarbininstall --uninstall
        $(Q)rm -Rf tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)
        $(Q)rm -Rf tmp/distcheck/tarbininstall
index 206046faeb6ef34e52c9715e4c9ed2d42bd380ef..b9baf6e02e1024b009583de9342511b5932f2432 100644 (file)
@@ -14,16 +14,18 @@ else
 MAYBE_DISABLE_VERIFY=
 endif
 
-install: dist-install-dir-$(CFG_BUILD)-with-target-libs
-       $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)"
+install: dist-install-dir-$(CFG_BUILD)-with-target-libs | tmp/empty_dir
+       $(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)"
 # Remove tmp files while we can because they may have been created under sudo
        $(Q)rm -R tmp/dist
 
-uninstall: dist-install-dir-$(CFG_BUILD)-with-target-libs
-       $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)"
+uninstall: dist-install-dir-$(CFG_BUILD)-with-target-libs | tmp/empty_dir
+       $(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)"
 # Remove tmp files while we can because they may have been created under sudo
        $(Q)rm -R tmp/dist
 
+tmp/empty_dir:
+       mkdir -p $@
 
 ######################################################################
 # Android remote installation
index 789ce2dabc25edc056bee81f2e7fb926e04071a1..177e4de310324dd6f2d3c1e35f0e50d5b80d8119 100644 (file)
@@ -57,7 +57,7 @@ $(foreach host,$(CFG_HOST), \
 $(foreach host,$(CFG_HOST), \
  $(eval LLVM_CONFIGS := $(LLVM_CONFIGS) $(LLVM_CONFIG_$(host))))
 
-$(S)src/librustc/lib/llvmdeps.rs: \
+$(S)src/librustc_llvm/llvmdeps.rs: \
                    $(LLVM_CONFIGS) \
                    $(S)src/etc/mklldeps.py \
                    $(MKFILE_DEPS)
index c4be89033a648933ab411ad7196184b582e074f5..8f54b2735a575d03ef455bff94b913e4285f342b 100644 (file)
 ######################################################################
 
 # The version number
-CFG_RELEASE_NUM=0.11.0
-CFG_RELEASE_LABEL=
+CFG_RELEASE_NUM=0.12.0
+CFG_RELEASE_LABEL=-pre
+
+CFG_FILENAME_EXTRA=4e7c5e5c
 
 ifndef CFG_ENABLE_NIGHTLY
 # This is the normal version string
@@ -120,8 +122,8 @@ endif
 ifdef TRACE
   CFG_RUSTC_FLAGS += -Z trace
 endif
-ifdef CFG_DISABLE_RPATH
-CFG_RUSTC_FLAGS += -C no-rpath
+ifdef CFG_ENABLE_RPATH
+CFG_RUSTC_FLAGS += -C rpath
 endif
 
 # The executables crated during this compilation process have no need to include
index 0f63ef9a430d0424323b0f69c8b55f9a664d8e90..7da11a21a7cb7fe4927f397d75390870c32d766c 100644 (file)
@@ -85,7 +85,9 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4):                                    \
                -L "$$(LLVM_LIBDIR_$(2))" \
                -L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
                $$(RUSTFLAGS_$(4)) \
-               --out-dir $$(@D) $$<
+               --out-dir $$(@D) \
+               -C extra-filename=-$$(CFG_FILENAME_EXTRA) \
+               $$<
        @touch $$@
        $$(call LIST_ALL_OLD_GLOB_MATCHES,\
            $$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
@@ -132,7 +134,7 @@ SNAPSHOT_RUSTC_POST_CLEANUP=$(HBIN0_H_$(CFG_BUILD))/rustc$(X_$(CFG_BUILD))
 
 define TARGET_HOST_RULES
 
-$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc: $(S)src/librustc/lib/llvmdeps.rs
+$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc_llvm: $(S)src/librustc_llvm/llvmdeps.rs
 
 $$(TBIN$(1)_T_$(2)_H_$(3))/:
        mkdir -p $$@
index 44bedde99ccffdba2a1571000adc371b601da523..d2e4388521ecd7730a30f169d2795994ebe219a2 100644 (file)
 
 # The names of crates that must be tested
 
-# libcore tests are in a separate crate
+# libcore/libunicode tests are in a separate crate
 DEPS_coretest :=
 $(eval $(call RUST_CRATE,coretest))
 
-TEST_TARGET_CRATES = $(filter-out core,$(TARGET_CRATES)) coretest
+TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) coretest
 TEST_DOC_CRATES = $(DOC_CRATES)
 TEST_HOST_CRATES = $(HOST_CRATES)
 TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
@@ -171,7 +171,7 @@ endif
 # Main test targets
 ######################################################################
 
-check: cleantmptestlogs cleantestlibs tidy check-notidy
+check: cleantmptestlogs cleantestlibs check-notidy tidy
 
 check-notidy: cleantmptestlogs cleantestlibs all check-stage2
        $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
index 9eac38e4cd5b7cb77e70cc03e65fde68c64c45db..4de66d8746fbea72f45206832e1ef93c56a2ba9e 100644 (file)
@@ -187,7 +187,7 @@ pub fn log_config(config: &Config) {
                     opt_str(&config.filter
                                    .as_ref()
                                    .map(|re| {
-                                       re.to_str().into_string()
+                                       re.to_string().into_string()
                                    }))));
     logv(c, format!("runtool: {}", opt_str(&config.runtool)));
     logv(c, format!("host-rustcflags: {}",
index 8e79f58c60881d21399b2c98f0ab750f98222a73..7681792bdf53d1e1af5f92fe111e710f398410d6 100644 (file)
@@ -31,7 +31,7 @@ pub fn load_errors(re: &Regex, testfile: &Path) -> Vec<ExpectedError> {
 fn parse_expected(line_num: uint, line: &str, re: &Regex) -> Option<ExpectedError> {
     re.captures(line).and_then(|caps| {
         let adjusts = caps.name("adjusts").len();
-        let kind = caps.name("kind").to_ascii().to_lower().into_str();
+        let kind = caps.name("kind").to_ascii().to_lower().into_string();
         let msg = caps.name("msg").trim().to_string();
 
         debug!("line={} kind={} msg={}", line_num, kind, msg);
index 797477d29202d57d00c5eb0033059fbceef68c16..1ee6f2b500c138fbceec3c74baa53be31cef3e52 100644 (file)
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::os;
 use std::str;
 use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
 use std::dynamic_lib::DynamicLibrary;
 
-fn target_env(lib_path: &str, aux_path: Option<&str>) -> Vec<(String, String)> {
+fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
     // Need to be sure to put both the lib_path and the aux path in the dylib
     // search path for the child.
     let mut path = DynamicLibrary::search_path();
@@ -23,19 +22,11 @@ fn target_env(lib_path: &str, aux_path: Option<&str>) -> Vec<(String, String)> {
     }
     path.insert(0, Path::new(lib_path));
 
-    // Remove the previous dylib search path var
-    let var = DynamicLibrary::envvar();
-    let mut env: Vec<(String,String)> = os::env();
-    match env.iter().position(|&(ref k, _)| k.as_slice() == var) {
-        Some(i) => { env.remove(i); }
-        None => {}
-    }
-
     // Add the new dylib search path var
+    let var = DynamicLibrary::envvar();
     let newpath = DynamicLibrary::create_path(path.as_slice());
     let newpath = str::from_utf8(newpath.as_slice()).unwrap().to_string();
-    env.push((var.to_string(), newpath));
-    return env;
+    cmd.env(var.to_string(), newpath);
 }
 
 pub struct Result {pub status: ProcessExit, pub out: String, pub err: String}
@@ -47,8 +38,14 @@ pub fn run(lib_path: &str,
            env: Vec<(String, String)> ,
            input: Option<String>) -> Option<Result> {
 
-    let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
-    match Command::new(prog).args(args).env(env.as_slice()).spawn() {
+    let mut cmd = Command::new(prog);
+    cmd.args(args);
+    add_target_env(&mut cmd, lib_path, aux_path);
+    for (key, val) in env.move_iter() {
+        cmd.env(key, val);
+    }
+
+    match cmd.spawn() {
         Ok(mut process) => {
             for input in input.iter() {
                 process.stdin.get_mut_ref().write(input.as_bytes()).unwrap();
@@ -73,8 +70,14 @@ pub fn run_background(lib_path: &str,
            env: Vec<(String, String)> ,
            input: Option<String>) -> Option<Process> {
 
-    let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
-    match Command::new(prog).args(args).env(env.as_slice()).spawn() {
+    let mut cmd = Command::new(prog);
+    cmd.args(args);
+    add_target_env(&mut cmd, lib_path, aux_path);
+    for (key, val) in env.move_iter() {
+        cmd.env(key, val);
+    }
+
+    match cmd.spawn() {
         Ok(mut process) => {
             for input in input.iter() {
                 process.stdin.get_mut_ref().write(input.as_bytes()).unwrap();
index 7c8e7e85e4607a97edee73af6fff8f4959d6c26d..f28604908e0b3fb938b99aca02e7bd630b698d28 100644 (file)
@@ -574,7 +574,7 @@ fn run_lldb(config: &Config, test_executable: &Path, debugger_script: &Path) ->
         cmd.arg("./src/etc/lldb_batchmode.py")
            .arg(test_executable)
            .arg(debugger_script)
-           .env([("PYTHONPATH", config.lldb_python_dir.clone().unwrap().as_slice())]);
+           .env_set_all([("PYTHONPATH", config.lldb_python_dir.clone().unwrap().as_slice())]);
 
         let (status, out, err) = match cmd.spawn() {
             Ok(process) => {
index c6e02606f74e750fa4eababd3d61c6a05f7941dc..369e6b0af645c82505bf6e08e7ed0df5b6f852b6 100644 (file)
@@ -41,7 +41,7 @@ pub fn make_new_path(path: &str) -> String {
       Some(curr) => {
         format!("{}{}{}", path, path_div(), curr)
       }
-      None => path.to_str()
+      None => path.to_string()
     }
 }
 
index 5de7957cdab285fbf7b21ee35663a27fd0b555bf..51609a660d397194a95586abeaa70b8a54dcda7b 100644 (file)
@@ -1,3 +1 @@
 <link rel="shortcut icon" href="http://www.rust-lang.org/favicon.ico">
-<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400'
-        rel='stylesheet' type='text/css'>
index 9021b761954d05dfd8212e52972c41132dc8d58c..6ef273e7a1a59099021bfdb11f3de3816f1ac9c3 100644 (file)
@@ -465,7 +465,7 @@ fn stringifier(channel: &DuplexStream<String, uint>) {
     let mut value: uint;
     loop {
         value = channel.recv();
-        channel.send(value.to_str());
+        channel.send(value.to_string());
         if value == 0 { break; }
     }
 }
@@ -478,7 +478,7 @@ send strings (the first type parameter) and receive `uint` messages
 (the second type parameter). The body itself simply loops, reading
 from the channel and then sending its response back.  The actual
 response itself is simply the stringified version of the received value,
-`uint::to_str(value)`.
+`uint::to_string(value)`.
 
 Here is the code for the parent task:
 
@@ -492,7 +492,7 @@ use std::comm::duplex;
 #     let mut value: uint;
 #     loop {
 #         value = channel.recv();
-#         channel.send(value.to_str());
+#         channel.send(value.to_string());
 #         if value == 0u { break; }
 #     }
 # }
index dc9608563e176c08190d8ccd865c2037539837f6..1f3aae90aa153604c796f2e89927b2455a41f28c 100644 (file)
@@ -90,8 +90,7 @@ $ rustc --version
 You should see some output that looks something like this:
 
 ```{ignore}
-rustc 0.11.0-pre (443a1cd 2014-06-08 14:56:52 -0700)
-host: x86_64-unknown-linux-gnu
+rustc 0.12.0-pre (443a1cd 2014-06-08 14:56:52 -0700)
 ```
 
 If you did, Rust has been installed successfully! Congrats!
@@ -274,16 +273,11 @@ is still a work in progress. However, it is already good enough to use for many
 Rust projects, and so it is assumed that Rust projects will use Cargo from the
 beginning.
 
-Programmers love car analogies, so I've got a good one for you to think about
-the relationship between `cargo` and `rustc`: `rustc` is like a car, and
-`cargo` is like a robotic driver. You can drive your car yourself, of course,
-but isn't it just easier to let a computer drive it for you?
-
-Anyway, Cargo manages three things: building your code, downloading the
-dependencies your code needs, and building the dependencies your code needs.
-At first, your program doesn't have any dependencies, so we'll only be using
-the first part of its functionality. Eventually, we'll add more. Since we
-started off by using Cargo, it'll be easy to add later.
+Cargo manages three things: building your code, downloading the dependencies
+your code needs, and building the dependencies your code needs.  At first, your
+program doesn't have any dependencies, so we'll only be using the first part of
+its functionality. Eventually, we'll add more. Since we started off by using
+Cargo, it'll be easy to add later.
 
 Let's convert Hello World to Cargo. The first thing we need to do to begin using Cargo
 is to install Cargo. To do this, we need to build it from source. There are no binaries
@@ -737,10 +731,10 @@ let x = (let y = 5i); // found `let` in ident position
 The compiler is telling us here that it was expecting to see the beginning of
 an expression, and a `let` can only begin a statement, not an expression.
 
-However, re-assigning to a mutable binding is an expression:
+However, assigning to a variable binding is an expression:
 
 ```{rust}
-let mut x = 0i;
+let x;
 let y = x = 5i;
 ```
 
@@ -895,13 +889,14 @@ fn add_one(x: int) -> int {
 We would get an error:
 
 ```{ignore,notrust}
-note: consider removing this semicolon:
-     x + 1;
-          ^
 error: not all control paths return a value
 fn add_one(x: int) -> int {
      x + 1;
 }
+
+note: consider removing this semicolon:
+     x + 1;
+          ^
 ```
 
 Remember our earlier discussions about semicolons and `()`? Our function claims
@@ -940,31 +935,679 @@ fn foo(x: int) -> int {
 There are some additional ways to define functions, but they involve features
 that we haven't learned about yet, so let's just leave it at that for now.
 
+
 ## Comments
 
-return
+Now that we have some functions, it's a good idea to learn about comments.
+Comments are notes that you leave to other programmers to help explain things
+about your code. The compiler mostly ignores them.
+
+Rust has two kinds of comments that you should care about: **line comment**s
+and **doc comment**s.
+
+```{rust}
+// Line comments are anything after '//' and extend to the end of the line.
+
+let x = 5i; // this is also a line comment.
+
+// If you have a long explanation for something, you can put line comments next
+// to each other. Put a space between the // and your comment so that it's
+// more readable.
+```
+
+The other kind of comment is a doc comment. Doc comments use `///` instead of
+`//`, and support Markdown notation inside:
+
+```{rust}
+/// `hello` is a function that prints a greeting that is personalized based on
+/// the name given.
+///
+/// # Arguments
+///
+/// * `name` - The name of the person you'd like to greet.
+///
+/// # Example
+///
+/// ```rust
+/// let name = "Steve";
+/// hello(name); // prints "Hello, Steve!"
+/// ```
+fn hello(name: &str) {
+    println!("Hello, {}!", name);
+}
+```
 
-comments
+When writing doc comments, adding sections for any arguments, return values,
+and providing some examples of usage is very, very helpful.
+
+You can use the `rustdoc` tool to generate HTML documentation from these doc
+comments. We will talk more about `rustdoc` when we get to modules, as
+generally, you want to export documentation for a full module.
 
 ## Compound Data Types
 
-Tuples
+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 are called **tuple**s.
+Tuples are an ordered list of a fixed size. Like this:
+
+```rust
+let x = (1i, "hello");
+```
+
+The parenthesis and commas form this two-length tuple. Here's the same code, but
+with the type annotated:
+
+```rust
+let x: (int, &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 `int` and a `&str` in this tuple.
+You haven't seen `&str` 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) = (1i, 2i, 3i);
+
+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.
+
+The last thing to say about tuples is that they are only equivalent if
+the arity, types, and values are all identical.
+
+```rust
+let x = (1i, 2i, 3i);
+let y = (2i, 3i, 4i);
+
+if x == y {
+    println!("yes");
+} else {
+    println!("no");
+}
+```
+
+This will print `no`, as the values aren't equal.
+
+One other use of tuples is to return multiple values from a function:
+
+```rust
+fn next_two(x: int) -> (int, int) { (x + 1i, x + 2i) }
+
+fn main() {
+    let (x, y) = next_two(5i);
+    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 two. 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: int,
+    y: int,
+}
+
+fn main() {
+    let origin = Point { x: 0i, y:  0i };
+
+    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, like other bindings in Rust. However, you
+can use `mut` to make them mutable:
+
+```rust
+struct Point {
+    x: int,
+    y: int,
+}
+
+fn main() {
+    let mut point = Point { x: 0i, y:  0i };
+
+    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:
+
+
+```
+struct Color(int, int, int);
+struct Point(int, int, int);
+```
+
+These two will not be equal, even if they have the same values:
+
+```{rust,ignore}
+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: int,
+    blue: int,
+    green: int,
+}
+
+struct Point {
+    x: int,
+    y: int,
+    z: int,
+}
+```
+
+Now, we have actual names, rather than positions. Good names are important,
+and with a struct, we have actual names.
 
-Structs
+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 a 'newtype,' because it lets
+you create a new type that's a synonym for another one:
 
-Enums
+```
+struct Inches(int);
+struct Centimeters(int);
+
+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`.
+
+### Enums
+
+Finally, Rust has a "sum type", an **enum**. Enums are an incredibly useful
+feature of Rust, and are used throughout the standard library. Enums look
+like this:
+
+```
+enum Ordering {
+    Less,
+    Equal,
+    Greater,
+}
+```
+
+This is an enum that is provided by the Rust standard library. An `Ordering`
+can only be _one_ of `Less`, `Equal`, or `Greater` at any given time. Here's
+an example:
+
+```rust
+let x = 5i;
+let y = 10i;
+
+let ordering = x.cmp(&y);
+
+if ordering == Less {
+    println!("less");
+} else if ordering == Greater {
+    println!("greater");
+} else if ordering == Equal {
+    println!("equal");
+}
+```
+
+`cmp` is a function that compares two things, and returns an `Ordering`. The
+call looks a little bit strange: rather than `cmp(x, y)`, we say `x.cmp(&y)`.
+We haven't covered methods and references yet, so it should look a little bit
+foreign. Right now, just pretend it says `cmp(x, y)`, and we'll get to those
+details soon.
+
+The `ordering` variable has the type `Ordering`, and so contains one of the
+three values. We can then do a bunch of `if`/`else` comparisons to check
+which one it is.
+
+However, repeated `if`/`else` comparisons get quite tedious. Rust has a feature
+that not only makes them nicer to read, but also makes sure that you never
+miss a case. Before we get to that, though, let's talk about another kind of
+enum: one with values.
+
+This enum has two variants, one of which has a value.:
+
+```
+enum OptionalInt {
+    Value(int),
+    Missing
+}
+
+fn main() {
+    let x = Value(5);
+    let y = Missing;
+
+    match x {
+        Value(n) => println!("x is {:d}", n),
+        Missing  => println!("x is missing!"),
+    }
+
+    match y {
+        Value(n) => println!("y is {:d}", n),
+        Missing  => println!("y is missing!"),
+    }
+}
+```
+
+This enum represents an `int` that we may or may not have. In the `Missing`
+case, we have no value, but in the `Value` case, we do. This enum is specific
+to `int`s, though. We can make it usable by any type, but we haven't quite
+gotten there yet!
+
+You can have any number of values in an enum:
+
+```
+enum OptionalColor {
+    Color(int, int, int),
+    Missing
+}
+```
+
+Enums with values are quite useful, but as I mentioned, they're even more
+useful when they're generic across types. But before we get to generics, let's
+talk about how to fix this big `if`/`else` statements we've been writing. We'll
+do that with `match`.
 
 ## Match
 
+Often, a simple `if`/`else` isn't enough, because you have more than two
+possible options. And `else` conditions can get incredibly complicated. So
+what's the solution?
+
+Rust has a keyword, `match`, that allows you to replace complicated `if`/`else`
+groupings with something more powerful. Check it out:
+
+```rust
+let x = 5i;
+
+match x {
+    1 => println!("one"),
+    2 => println!("two"),
+    3 => println!("three"),
+    4 => println!("four"),
+    5 => println!("five"),
+    _ => println!("something else"),
+}
+```
+
+`match` takes an expression, and then branches based on its value. Each 'arm' of
+the branch is of the form `val => expression`. When the value matches, that arm's
+expression will be evaluated. It's called `match` because of the term 'pattern
+matching,' which `match` is an implementation of.
+
+So what's the big advantage here? Well, there are a few. First of all, `match`
+does 'exhaustiveness checking.' Do you see that last arm, the one with the
+underscore (`_`)? If we remove that arm, Rust will give us an error:
+
+```{ignore,notrust}
+error: non-exhaustive patterns: `_` not covered
+```
+
+In other words, Rust is trying to tell us we forgot a value. Because `x` is an
+integer, Rust knows that it can have a number of different values. For example,
+`6i`. But without the `_`, there is no arm that could match, and so Rust refuses
+to compile. `_` is sort of like a catch-all arm. If none of the other arms match,
+the arm with `_` will. And since we have this catch-all arm, we now have an arm
+for every possible value of `x`, and so our program will now compile.
+
+`match` statements also destructure enums, as well. Remember this code from the
+section on enums?
+
+```{rust}
+let x = 5i;
+let y = 10i;
+
+let ordering = x.cmp(&y);
+
+if ordering == Less {
+    println!("less");
+} else if ordering == Greater {
+    println!("greater");
+} else if ordering == Equal {
+    println!("equal");
+}
+```
+
+We can re-write this as a `match`:
+
+```{rust}
+let x = 5i;
+let y = 10i;
+
+match x.cmp(&y) {
+    Less    => println!("less"),
+    Greater => println!("greater"),
+    Equal   => println!("equal"),
+}
+```
+
+This version has way less noise, and it also checks exhaustively to make sure
+that we have covered all possible variants of `Ordering`. With our `if`/`else`
+version, if we had forgotten the `Greater` case, for example, our program would
+have happily compiled. If we forget in the `match`, it will not. Rust helps us
+make sure to cover all of our bases.
+
+`match` is also an expression, which means we can use it on the right hand side
+of a `let` binding. We could also implement the previous line like this:
+
+```
+let x = 5i;
+let y = 10i;
+
+let result = match x.cmp(&y) {
+    Less    => "less",
+    Greater => "greater",
+    Equal   => "equal",
+};
+
+println!("{}", result);
+```
+
+In this case, it doesn't make a lot of sense, as we are just making a temporary
+string where we don't need to, but sometimes, it's a nice pattern.
+
 ## Looping
 
-for
+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 `for` loop:
+
+```{ignore,c}
+for (x = 0; x < 10; x++) {
+    printf( "%d\n", x );
+}
+```
+
+It looks like this:
+
+```{rust}
+for x in range(0i, 10i) {
+    println!("{:d}", x);
+}
+```
+
+In slightly more abstract terms,
+
+```{ignore,notrust}
+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, the `range` function is a function, provided by Rust, 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. There's an old joke that goes, "There are two hard problems in
+computer science: naming things, cache invalidation, and off-by-one errors."
+The joke, of course, being that the setup says "two hard problems" but then
+lists three things. This happens quite a bit with "C style" `for` loops.
+
+We'll talk more about `for` when we cover **vector**s, 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 = 5u;
+let mut done = false;
+
+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 {
+```
+
+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 = 5u;
+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 skip 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 = 5u;
+
+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:
+
+```
+for x in range(0i, 10i) {
+    if x % 2 == 0 { continue; }
+
+    println!("{:d}", x);
+}
+```
 
-while
+Both `continue` and `break` are valid in both kinds of loops.
+
+We have now learned all of the most basic Rust concepts. We're ready to start
+building our guessing game, but we need to know how to do one last thing first:
+get input from the keyboard. You can't have a guessing game without the ability
+to guess!
+
+## Standard Input
+
+Getting input from the keyboard is pretty easy, but uses some things
+we haven't seen before. Here's a simple program that reads some input,
+and then prints it back out:
+
+```{rust,ignore}
+fn main() {
+    println!("Type something!");
+
+    let input = std::io::stdin().read_line().ok().expect("Failed to read line");
+
+    println!("{}", input);
+}
+```
+
+Let's go over these chunks, one by one:
+
+```{rust}
+std::io::stdin();
+```
+
+This calls a function, `stdin()`, that lives inside the `std::io` module. As
+you can imagine, everything in `std` is provided by Rust, the 'standard
+library.' We'll talk more about the module system later.
+
+Since writing the fully qualified name all the time is annoying, we can use
+the `use` statement to import it in:
+
+```{rust}
+use std::io::stdin;
+
+stdin();
+```
+
+However, it's considered better practice to not import individual functions, but
+to import the module, and only use one level of qualification:
+
+```{rust}
+use std::io;
+
+io::stdin();
+```
+
+Let's update our example to use this style:
+
+```{rust,ignore}
+use std::io;
+
+fn main() {
+    println!("Type something!");
+
+    let input = io::stdin().read_line().ok().expect("Failed to read line");
+
+    println!("{}", input);
+}
+```
+
+Next up:
+
+```{rust,ignore}
+.read_line()
+```
+
+The `read_line()` method can be called on the result of `stdin()` to return
+a full line of input. Nice and easy.
+
+```{rust,ignore}
+.ok().expect("Failed to read line");
+```
+
+Here's the thing: reading a line from standard input could fail. For example,
+if this program isn't running in a terminal, but is running as part of a cron
+job, or some other context where there's no standard input. So Rust expects us
+to handle this case. Given that we plan on always running this program in a
+terminal, we use the `ok()` method to tell Rust that we're expecting everything
+to be just peachy, and the `expect()` method on that result to give an error
+message if our expectation goes wrong.
+
+We will cover the exact details of how all of this works later in the Guide.
+For now, this is all you need.
+
+With long lines like this, Rust gives you some flexibility with the whitespace.
+We _could_ write the example like this:
+
+```{rust,ignore}
+use std::io;
+
+fn main() {
+    println!("Type something!");
+
+    let input = io::stdin()
+                  .read_line()
+                  .ok()
+                  .expect("Failed to read line");
+
+    println!("{}", input);
+}
+```
 
-loop
+Sometimes, this makes things more readable. Sometimes, less. Use your judgement
+here.
 
-break/continue
+That's all you need to get basic input from the standard input! It's not too
+complicated, but there are a number of small parts.
 
 ## Guessing Game: complete
 
index 3b7bb2e740d46a58ca7c0689acd859c7da0991ef..b8eab539c6119a64d13597f218b39af77110fa18 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
@@ -23,7 +23,7 @@ msgstr ""
 #| "[tarball]: http://static.rust-lang.org/dist/rust-nightly.tar.gz [win-exe]: "
 #| "http://static.rust-lang.org/dist/rust-nightly-install.exe"
 msgid ""
-"Use [`ToStr`](http://static.rust-lang.org/doc/master/std/to_str/trait.ToStr."
+"Use [`ToString`](http://static.rust-lang.org/doc/master/std/to_str/trait.ToString."
 "html)."
 msgstr ""
 "[tarball]: http://static.rust-lang.org/dist/rust-nightly.tar.gz\n"
@@ -34,7 +34,7 @@ msgstr ""
 #, fuzzy
 #| msgid ""
 #| "~~~~ let x: f64 = 4.0; let y: uint = x as uint; assert!(y == 4u); ~~~~"
-msgid "~~~ let x: int = 42; let y: String = x.to_str(); ~~~"
+msgid "~~~ let x: int = 42; let y: String = x.to_string(); ~~~"
 msgstr ""
 "~~~~\n"
 "let x: f64 = 4.0;\n"
index f28abcf1d524fcc7e2a512dd291c348413b082fa..6668975473d38a660f829b635ad272624f239d50 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index 0361c67b9dc360e21251d3ed6cbeb7deafe8d8e4..3e10a3bc956d051bc2617e75b2429878caf1f57c 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index 819e12ccd13a7ae47cc06c30c7b1600e44a48d36..c068b630ca7e44daf4d91de5a5d88e3d24971757 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-02-03 08:13+0900\n"
 "Last-Translator: Automatically generated\n"
index 69f5ea1c733566c7a9dc0a244540fe50be0512aa..089ad6d60a9cbb367cd865f28db7a7717d5ccafc 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index d20ad9568730411c3deeca270e7cacd371f8c010..399443b6e21d11c96a89eff3fb5d0d3847d46e17 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index fe7d1d911efdd43b2f491f62164e1e8add479b5e..08089f30d2458ae0b1f211c0e0053a6d05d21295 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index 44984c4a25fb7ea12cbb9830c844eab3d6a4c308..b5c0761324d2597ea57cf017447c3d791cfdbfaa 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index 39d71dafd8c9fa2f01536b3fa422174205cee6a8..bf35bcd4ca68c311fe8a0e8c4deca79dc3b58e2b 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index f1005caedd5c117af2ff08ca8238d3781efbf5f9..0c0ca5e73a1ddddb2e967da8e15de33f2c09c780 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index 216a854db2a26c04273fe3fa2bcb86daaed71249..1cfdfad28367d38125def87ceeb8e70635353614 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-02-03 08:13+0900\n"
 "Last-Translator: Automatically generated\n"
index 480d1351e56432b409692ba76e2bc9ec700573ee..bb5252cb7375cd7e1675dd34038425de1eed995a 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index 55a9e00f54d27aa17b81765b25726097dc6806e0..9025ae1505467037eb0247c30e556904f11778b0 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index 6a2e512da26548b7d9575e1d63114de5500f8546..4e226cbfe37e2e05651386c07867c1d0800387bf 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-14 21:02+0900\n"
 "Last-Translator: Automatically generated\n"
index f0aef7accb6e1a0484f68cca36cf05bb4d3475b1..a28a62d01c2674d561ac69661fb19b6240dd0dc0 100644 (file)
@@ -1656,7 +1656,7 @@ msgstr ""
 #| msgid "~~~~ {.ignore} // main.rs extern crate world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
 msgid ""
 "impl Printable for int {\n"
-"  fn to_string(&self) -> String { self.to_str() }\n"
+"  fn to_string(&self) -> String { self.to_string() }\n"
 "}\n"
 msgstr ""
 "~~~~ {.ignore}\n"
index eaf954333152e32dd7fbea12aa18eebc485c4a44..e2bc4716d7064904f5cb0625261662e11d103d84 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
 "POT-Creation-Date: 2014-02-03 08:13+0900\n"
 "PO-Revision-Date: 2014-01-13 12:01+0900\n"
 "Last-Translator: Automatically generated\n"
index 68c32ae9704a36bc74a66ffe7f8447a4549dfe8d..597cf5b7ac509cfde4b42385ee3d07557b68d0ab 100644 (file)
@@ -4410,9 +4410,9 @@ msgstr ""
 
 #. type: Plain text
 #: src/doc/tutorial.md:2528
-msgid "#[deriving(Rand, ToStr)] enum ABC { A, B, C } ~~~"
+msgid "#[deriving(Rand, ToString)] enum ABC { A, B, C } ~~~"
 msgstr ""
-"#[deriving(Rand, ToStr)]\n"
+"#[deriving(Rand, ToString)]\n"
 "enum ABC { A, B, C }\n"
 "~~~"
 
@@ -4422,15 +4422,15 @@ msgstr ""
 #| msgid ""
 #| "The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
 #| "`Encodable` `Decodable`, `Clone`, `DeepClone`, `Hash`, `Rand`, "
-#| "`Zero`, and `ToStr`."
+#| "`Zero`, and `ToString`."
 msgid ""
 "The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
 "`Encodable` `Decodable`, `Clone`, `DeepClone`, `Hash`, `Rand`, "
-"`Default`, `Zero`, and `ToStr`."
+"`Default`, `Zero`, and `ToString`."
 msgstr ""
 "実装を自動的に導出可能なトレイトは、 `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
 "`Encodable` `Decodable`, `Clone`, `DeepClone`, `Hash`, `Rand`, `Zero`, "
-"および `ToStr` です。."
+"および `ToString` です。."
 
 #. type: Plain text
 #: src/doc/tutorial.md:2534
index 3dd770fd976b2829f312912a53cc255f5224a1bc..668acc9a3893b1db6c215fe675caf04f486c1f83 100644 (file)
     src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
 }
 @font-face {
-    font-family: 'Heuristica';
+    font-family: 'Source Serif Pro';
     font-style: normal;
     font-weight: 400;
-    src: local('Heuristica Regular'), url("Heuristica-Regular.woff") format('woff');
+    src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
 }
 @font-face {
-    font-family: 'Heuristica';
+    font-family: 'Source Serif Pro';
     font-style: italic;
     font-weight: 400;
-    src: local('Heuristica Italic'), url("Heuristica-Italic.woff") format('woff');
+    src: url("Heuristica-Italic.woff") format('woff');
 }
 @font-face {
-    font-family: 'Heuristica';
+    font-family: 'Source Serif Pro';
     font-style: normal;
     font-weight: 700;
-    src: local('Heuristica Bold'), url("Heuristica-Bold.woff") format('woff');
+    src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
+}
+@font-face {
+    font-family: 'Source Code Pro';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff');
 }
 
 *:not(body) {
@@ -52,7 +58,7 @@
 body {
     margin: 0 auto;
     padding: 0 15px;
-    font-family: "Heuristica", "Helvetica Neue", Helvetica, Arial, sans-serif;
+    font-family: "Source Serif Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
     font-size: 18px;
     color: #333;
     line-height: 1.428571429;
index e149920ab352d9fe9362f64e5208164115387fd3..9d5a6fa42a830239fb21695527511b85fc6abe1f 100644 (file)
@@ -3671,15 +3671,15 @@ An example of an object type:
 
 ~~~~
 trait Printable {
-  fn to_string(&self) -> String;
+  fn stringify(&self) -> String;
 }
 
 impl Printable for int {
-  fn to_string(&self) -> String { self.to_str() }
+  fn stringify(&self) -> String { self.to_string() }
 }
 
 fn print(a: Box<Printable>) {
-   println!("{}", a.to_string());
+   println!("{}", a.stringify());
 }
 
 fn main() {
@@ -3889,12 +3889,11 @@ by the prefix operator `box`. When the standard library is in use, the type of a
 An example of an owned box type and value:
 
 ~~~~
-
 let x: Box<int> = box 10;
 ~~~~
 
-Owned box values exist in 1:1 correspondence with their heap allocation
-copying an owned box value makes a shallow copy of the pointer
+Owned box values exist in 1:1 correspondence with their heap allocation,
+copying an owned box value makes a shallow copy of the pointer.
 Rust will consider a shallow copy of an owned box to move ownership of the value. After a value has been moved, the source location cannot be used unless it is reinitialized.
 
 ~~~~
index 2a788d7e7934c495d1d6ca218209faa3181c062c..10f67876e508fc34137c20bbce97cf67fa9a17d3 100644 (file)
@@ -979,7 +979,7 @@ let mut b = Foo { x: 5, y: box 10 };
 b.x = 10;
 ~~~~
 
-If an object doesn't contain any non-Send types, it consists of a single
+If an object doesn't contain any non-`Send` types, it consists of a single
 ownership tree and is itself given the `Send` trait which allows it to be sent
 between tasks. Custom destructors can only be implemented directly on types
 that are `Send`, but non-`Send` types can still *contain* types with custom
@@ -3038,7 +3038,7 @@ fn main() {
 ~~~{.ignore}
 // `b/mod.rs`
 pub mod c;
-pub fn foo() { println!("Foo!"; }
+pub fn foo() { println!("Foo!"); }
 ~~~
 
 ~~~{.ignore}
index 2ed7a9dd6c28ab246cf857376ec3d33571f6631d..c949743ea75949f4bd84b4e1b6812b391ec7f5d9 100644 (file)
@@ -285,6 +285,19 @@ then
     CFG_LIBDIR_RELATIVE=bin
 fi
 
+if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ]
+then
+    CFG_LD_PATH_VAR=PATH
+    CFG_OLD_LD_PATH_VAR=$PATH
+elif [ "$CFG_OSTYPE" = "Darwin" ]
+then
+    CFG_LD_PATH_VAR=DYLD_LIBRARY_PATH
+    CFG_OLD_LD_PATH_VAR=$DYLD_LIBRARY_PATH
+else
+    CFG_LD_PATH_VAR=LD_LIBRARY_PATH
+    CFG_OLD_LD_PATH_VAR=$LD_LIBRARY_PATH
+fi
+
 flag uninstall "only uninstall from the installation prefix"
 opt verify 1 "verify that the installed binaries run correctly"
 valopt prefix "/usr/local" "set installation prefix"
@@ -312,11 +325,13 @@ then
     if [ -z "${CFG_UNINSTALL}" ]
     then
         msg "verifying platform can run binaries"
+        export $CFG_LD_PATH_VAR="${CFG_SRC_DIR}/lib":$CFG_OLD_LD_PATH_VAR
         "${CFG_SRC_DIR}/bin/rustc" --version > /dev/null
         if [ $? -ne 0 ]
         then
             err "can't execute rustc binary on this platform"
         fi
+        export $CFG_LD_PATH_VAR=$CFG_OLD_LD_PATH_VAR
     fi
 fi
 
@@ -451,22 +466,45 @@ while read p; do
 # The manifest lists all files to install
 done < "${CFG_SRC_DIR}/${CFG_LIBDIR_RELATIVE}/rustlib/manifest.in"
 
+# Run ldconfig to make dynamic libraries available to the linker
+if [ "$CFG_OSTYPE" = "Linux" ]
+    then
+    ldconfig
+    if [ $? -ne 0 ]
+    then
+        warn "failed to run ldconfig."
+        warn "this may happen when not installing as root and may be fine"
+    fi
+fi
+
 # Sanity check: can we run the installed binaries?
+#
+# As with the verification above, make sure the right LD_LIBRARY_PATH-equivalent
+# is in place. Try first without this variable, and if that fails try again with
+# the variable. If the second time tries, print a hopefully helpful message to
+# add something to the appropriate environment variable.
 if [ -z "${CFG_DISABLE_VERIFY}" ]
 then
     msg "verifying installed binaries are executable"
-    "${CFG_PREFIX}/bin/rustc" --version > /dev/null
+    "${CFG_PREFIX}/bin/rustc" --version 2> /dev/null 1> /dev/null
     if [ $? -ne 0 ]
     then
-        ERR="can't execute installed rustc binary. "
-        ERR="${ERR}installation may be broken. "
-        ERR="${ERR}if this is expected then rerun install.sh with \`--disable-verify\` "
-        ERR="${ERR}or \`make install\` with \`--disable-verify-install\`"
-        err "${ERR}"
+        export $CFG_LD_PATH_VAR="${CFG_PREFIX}/lib":$CFG_OLD_LD_PATH_VAR
+        "${CFG_PREFIX}/bin/rustc" --version > /dev/null
+        if [ $? -ne 0 ]
+        then
+            ERR="can't execute installed rustc binary. "
+            ERR="${ERR}installation may be broken. "
+            ERR="${ERR}if this is expected then rerun install.sh with \`--disable-verify\` "
+            ERR="${ERR}or \`make install\` with \`--disable-verify-install\`"
+            err "${ERR}"
+        else
+            echo
+            echo "    Note: please ensure '${CFG_PREFIX}/lib' is added to ${CFG_LD_PATH_VAR}"
+        fi
     fi
 fi
 
-
 echo
 echo "    Rust is ready to roll."
 echo
index deb713ac1ae01bcc7f057d27d48c5e33a4965762..f2f54d9d307037a545b0f8ed5180c438759e4168 100644 (file)
@@ -7,7 +7,7 @@
        <!ENTITY rustIdent "[a-zA-Z_][a-zA-Z_0-9]*">
        <!ENTITY rustIntSuf "([iu](8|16|32|64)?)?">
 ]>
-<language name="Rust" version="0.11.0" kateversion="2.4" section="Sources" extensions="*.rs" mimetype="text/x-rust" priority="15">
+<language name="Rust" version="0.12.0-pre" kateversion="2.4" section="Sources" extensions="*.rs" mimetype="text/x-rust" priority="15">
 <highlighting>
        <list name="fn">
                <item> fn </item>
diff --git a/src/etc/regex-unicode-tables.py b/src/etc/regex-unicode-tables.py
deleted file mode 100755 (executable)
index 5dc4047..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-#!/usr/bin/env python2
-
-# 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.
-
-from __future__ import absolute_import, division, print_function
-import argparse
-from collections import defaultdict
-import csv
-import datetime
-import urllib2
-
-BASE_URL = 'http://www.unicode.org/Public/6.3.0/ucd/'
-DATA = 'UnicodeData.txt'
-SCRIPTS = 'Scripts.txt'
-
-# Mapping taken from Table 12 from:
-# http://www.unicode.org/reports/tr44/#General_Category_Values
-expanded_categories = {
-    'Lu': ['LC', 'L'], 'Ll': ['LC', 'L'], 'Lt': ['LC', 'L'],
-    'Lm': ['L'], 'Lo': ['L'],
-    'Mn': ['M'], 'Mc': ['M'], 'Me': ['M'],
-    'Nd': ['N'], 'Nl': ['N'], 'No': ['No'],
-    'Pc': ['P'], 'Pd': ['P'], 'Ps': ['P'], 'Pe': ['P'],
-    'Pi': ['P'], 'Pf': ['P'], 'Po': ['P'],
-    'Sm': ['S'], 'Sc': ['S'], 'Sk': ['S'], 'So': ['S'],
-    'Zs': ['Z'], 'Zl': ['Z'], 'Zp': ['Z'],
-    'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'],
-}
-
-
-def as_4byte_uni(n):
-    s = hex(n)[2:]
-    return '\\U%s%s' % ('0' * (8 - len(s)), s)
-
-
-def expand_cat(c):
-    return expanded_categories.get(c, []) + [c]
-
-
-def is_valid_unicode(n):
-    return 0 <= n <= 0xD7FF or 0xE000 <= n <= 0x10FFFF
-
-
-def read_cats(f):
-    assigned = defaultdict(list)
-    for row in csv.reader(f, delimiter=';'):
-        (hex, cats) = (int(row[0], 16), expand_cat(row[2]))
-        if not is_valid_unicode(hex):
-            continue
-        for cat in cats:
-            assigned[cat].append(hex)
-    return assigned
-
-
-def read_scripts(f):
-    assigned = defaultdict(list)
-    for line in f:
-        line = line.strip()
-        if not line or line.startswith('#'):
-            continue
-        hexes, name = map(str.strip, line.split(';'))[:2]
-        name = name[:name.index('#')].strip()
-        if '..' not in hexes:
-            hex = int(hexes, 16)
-            if is_valid_unicode(hex):
-                assigned[name].append(hex)
-        else:
-            hex1, hex2 = map(lambda s: int(s, 16), hexes.split('..'))
-            for hex in xrange(hex1, hex2 + 1):
-                if is_valid_unicode(hex):
-                    assigned[name].append(hex)
-    return assigned
-
-
-def group(letters):
-    letters = sorted(set(letters))
-    grouped = []
-    cur_start = letters.pop(0)
-    cur_end = cur_start
-    for letter in letters:
-        assert letter > cur_end, \
-            'cur_end: %s, letter: %s' % (hex(cur_end), hex(letter))
-
-        if letter == cur_end + 1:
-            cur_end = letter
-        else:
-            grouped.append((cur_start, cur_end))
-            cur_start, cur_end = letter, letter
-    grouped.append((cur_start, cur_end))
-    return grouped
-
-
-def ranges_to_rust(rs):
-    rs = ("('%s', '%s')" % (as_4byte_uni(s), as_4byte_uni(e)) for s, e in rs)
-    return ',\n    '.join(rs)
-
-
-def groups_to_rust(groups):
-    rust_groups = []
-    for group_name in sorted(groups):
-        rust_groups.append('("%s", &[\n    %s\n    ]),'
-                           % (group_name, ranges_to_rust(groups[group_name])))
-    return '\n'.join(rust_groups)
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(
-        description='Generate Unicode character class tables.')
-    aa = parser.add_argument
-    aa('--local', action='store_true',
-       help='When set, Scripts.txt and UnicodeData.txt will be read from '
-            'the CWD.')
-    aa('--base-url', type=str, default=BASE_URL,
-       help='The base URL to use for downloading Unicode data files.')
-    args = parser.parse_args()
-
-    if args.local:
-        cats = read_cats(open(DATA))
-        scripts = read_scripts(open(SCRIPTS))
-    else:
-        cats = read_cats(urllib2.urlopen(args.base_url + '/' + DATA))
-        scripts = read_scripts(urllib2.urlopen(args.base_url + '/' + SCRIPTS))
-
-    # Get Rust code for all Unicode general categories and scripts.
-    combined = dict(cats, **scripts)
-    unigroups = groups_to_rust({k: group(letters)
-                                for k, letters in combined.items()})
-
-    # Now get Perl character classes that are Unicode friendly.
-    perld = range(ord('0'), ord('9') + 1)
-    dgroups = ranges_to_rust(group(perld + cats['Nd'][:]))
-
-    perls = map(ord, ['\t', '\n', '\x0C', '\r', ' '])
-    sgroups = ranges_to_rust(group(perls + cats['Z'][:]))
-
-    low, up = (range(ord('a'), ord('z') + 1), range(ord('A'), ord('Z') + 1))
-    perlw = [ord('_')] + perld + low + up
-    wgroups = ranges_to_rust(group(perlw + cats['L'][:]))
-
-    tpl = '''// 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.
-
-// DO NOT EDIT. Automatically generated by 'src/etc/regexp-unicode-tables'
-// on {date}.
-
-use parse::{{Class, NamedClasses}};
-
-pub static UNICODE_CLASSES: NamedClasses = &[
-
-{groups}
-
-];
-
-pub static PERLD: Class = &[
-    {dgroups}
-];
-
-pub static PERLS: Class = &[
-    {sgroups}
-];
-
-pub static PERLW: Class = &[
-    {wgroups}
-];
-'''
-    now = datetime.datetime.now()
-    print(tpl.format(date=str(now), groups=unigroups,
-                     dgroups=dgroups, sgroups=sgroups, wgroups=wgroups))
index 586890ebe4c9a118fc4a8e30b462955928ff48f6..a87c755397d94d4ad64b816e406342f909cdeb31 100755 (executable)
 # option. This file may not be copied, modified, or distributed
 # except according to those terms.
 
-# This digests UnicodeData.txt and DerivedCoreProperties.txt and emits rust
-# code covering the core properties. Since this is a pretty rare event we
-# just store this out-of-line and check the unicode.rs file into git.
+# This script uses the following Unicode tables:
+# - DerivedCoreProperties.txt
+# - EastAsianWidth.txt
+# - PropList.txt
+# - Scripts.txt
+# - UnicodeData.txt
 #
-# The emitted code is "the minimum we think is necessary for libstd", that
-# is, to support basic operations of the compiler and "most nontrivial rust
-# programs". It is not meant to be a complete implementation of unicode.
-# For that we recommend you use a proper binding to libicu.
+# Since this should not require frequent updates, we just store this
+# out-of-line and check the unicode.rs file into git.
 
 import fileinput, re, os, sys, operator
 
+preamble = '''// Copyright 2012-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.
+
+// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
+
+#![allow(missing_doc, non_uppercase_statics, non_snake_case_functions)]
+'''
+
+# Mapping taken from Table 12 from:
+# http://www.unicode.org/reports/tr44/#General_Category_Values
+expanded_categories = {
+    'Lu': ['LC', 'L'], 'Ll': ['LC', 'L'], 'Lt': ['LC', 'L'],
+    'Lm': ['L'], 'Lo': ['L'],
+    'Mn': ['M'], 'Mc': ['M'], 'Me': ['M'],
+    'Nd': ['N'], 'Nl': ['N'], 'No': ['No'],
+    'Pc': ['P'], 'Pd': ['P'], 'Ps': ['P'], 'Pe': ['P'],
+    'Pi': ['P'], 'Pf': ['P'], 'Po': ['P'],
+    'Sm': ['S'], 'Sc': ['S'], 'Sk': ['S'], 'So': ['S'],
+    'Zs': ['Z'], 'Zl': ['Z'], 'Zp': ['Z'],
+    'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'],
+}
 
 def fetch(f):
     if not os.path.exists(f):
@@ -31,21 +60,17 @@ def fetch(f):
         sys.stderr.write("cannot load %s" % f)
         exit(1)
 
+def is_valid_unicode(n):
+    return 0 <= n <= 0xD7FF or 0xE000 <= n <= 0x10FFFF
 
 def load_unicode_data(f):
     fetch(f)
     gencats = {}
     upperlower = {}
     lowerupper = {}
-    combines = []
+    combines = {}
     canon_decomp = {}
     compat_decomp = {}
-    curr_cat = ""
-    curr_combine = ""
-    c_lo = 0
-    c_hi = 0
-    com_lo = 0
-    com_hi = 0
 
     for line in fileinput.input(f):
         fields = line.split(";")
@@ -58,6 +83,9 @@ def load_unicode_data(f):
         code_org = code
         code     = int(code, 16)
 
+        if not is_valid_unicode(code):
+            continue
+
         # generate char to char direct common and simple conversions
         # uppercase to lowercase
         if gencat == "Lu" and lowcase != "" and code_org != lowcase:
@@ -67,6 +95,7 @@ def load_unicode_data(f):
         if gencat == "Ll" and upcase != "" and code_org != upcase:
             lowerupper[code] = int(upcase, 16)
 
+        # store decomposition, if given
         if decomp != "":
             if decomp.startswith('<'):
                 seq = []
@@ -79,37 +108,75 @@ def load_unicode_data(f):
                     seq.append(int(i, 16))
                 canon_decomp[code] = seq
 
-        if curr_cat == "":
-            curr_cat = gencat
-            c_lo = code
-            c_hi = code
+        # place letter in categories as appropriate
+        for cat in [gencat] + expanded_categories.get(gencat, []):
+            if cat not in gencats:
+                gencats[cat] = []
+            gencats[cat].append(code)
 
-        if curr_cat == gencat:
-            c_hi = code
-        else:
-            if curr_cat not in gencats:
-                gencats[curr_cat] = []
+        # record combining class, if any
+        if combine != "0":
+            if combine not in combines:
+                combines[combine] = []
+            combines[combine].append(code)
 
-            gencats[curr_cat].append((c_lo, c_hi))
-            curr_cat = gencat
-            c_lo = code
-            c_hi = code
+    gencats = group_cats(gencats)
+    combines = to_combines(group_cats(combines))
 
-        if curr_combine == "":
-            curr_combine = combine
-            com_lo = code
-            com_hi = code
+    return (canon_decomp, compat_decomp, gencats, combines, lowerupper, upperlower)
 
-        if curr_combine == combine:
-            com_hi = code
+def group_cats(cats):
+    cats_out = {}
+    for cat in cats:
+        cats_out[cat] = group_cat(cats[cat])
+    return cats_out
+
+def group_cat(cat):
+    cat_out = []
+    letters = sorted(set(cat))
+    cur_start = letters.pop(0)
+    cur_end = cur_start
+    for letter in letters:
+        assert letter > cur_end, \
+            "cur_end: %s, letter: %s" % (hex(cur_end), hex(letter))
+        if letter == cur_end + 1:
+            cur_end = letter
         else:
-            if curr_combine != "0":
-                combines.append((com_lo, com_hi, curr_combine))
-            curr_combine = combine
-            com_lo = code
-            com_hi = code
+            cat_out.append((cur_start, cur_end))
+            cur_start = cur_end = letter
+    cat_out.append((cur_start, cur_end))
+    return cat_out
+
+def ungroup_cat(cat):
+    cat_out = []
+    for (lo, hi) in cat:
+        while lo <= hi:
+            cat_out.append(lo)
+            lo += 1
+    return cat_out
+
+def to_combines(combs):
+    combs_out = []
+    for comb in combs:
+        for (lo, hi) in combs[comb]:
+            combs_out.append((lo, hi, comb))
+    combs_out.sort(key=lambda comb: comb[0])
+    return combs_out
 
-    return (canon_decomp, compat_decomp, gencats, combines, lowerupper, upperlower)
+def format_table_content(f, content, indent):
+    line = " "*indent
+    first = True
+    for chunk in content.split(","):
+        if len(line) + len(chunk) < 98:
+            if first:
+                line += chunk
+            else:
+                line += ", " + chunk
+            first = False
+        else:
+            f.write(line + ",\n")
+            line = " "*indent + chunk
+    f.write(line)
 
 def load_properties(f, interestingprops):
     fetch(f)
@@ -134,7 +201,7 @@ def load_properties(f, interestingprops):
                 prop = m.group(3)
             else:
                 continue
-        if prop not in interestingprops:
+        if interestingprops and prop not in interestingprops:
             continue
         d_lo = int(d_lo, 16)
         d_hi = int(d_hi, 16)
@@ -143,6 +210,43 @@ def load_properties(f, interestingprops):
         props[prop].append((d_lo, d_hi))
     return props
 
+# load all widths of want_widths, except those in except_cats
+def load_east_asian_width(want_widths, except_cats):
+    f = "EastAsianWidth.txt"
+    fetch(f)
+    widths = {}
+    re1 = re.compile("^([0-9A-F]+);(\w+) +# (\w+)")
+    re2 = re.compile("^([0-9A-F]+)\.\.([0-9A-F]+);(\w+) +# (\w+)")
+
+    for line in fileinput.input(f):
+        width = None
+        d_lo = 0
+        d_hi = 0
+        cat = None
+        m = re1.match(line)
+        if m:
+            d_lo = m.group(1)
+            d_hi = m.group(1)
+            width = m.group(2)
+            cat = m.group(3)
+        else:
+            m = re2.match(line)
+            if m:
+                d_lo = m.group(1)
+                d_hi = m.group(2)
+                width = m.group(3)
+                cat = m.group(4)
+            else:
+                continue
+        if cat in except_cats or width not in want_widths:
+            continue
+        d_lo = int(d_lo, 16)
+        d_hi = int(d_hi, 16)
+        if width not in widths:
+            widths[width] = []
+        widths[width].append((d_lo, d_hi))
+    return widths
+
 def escape_char(c):
     if c <= 0xff:
         return "'\\x%2.2x'" % c
@@ -150,59 +254,72 @@ def escape_char(c):
         return "'\\u%4.4x'" % c
     return "'\\U%8.8x'" % c
 
-def ch_prefix(ix):
-    if ix == 0:
-        return "        "
-    if ix % 2 == 0:
-        return ",\n        "
-    else:
-        return ", "
-
 def emit_bsearch_range_table(f):
     f.write("""
 fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
-    use cmp::{Equal, Less, Greater};
-    use slice::ImmutableVector;
-    use option::None;
+    use core::cmp::{Equal, Less, Greater};
+    use core::slice::ImmutableVector;
+    use core::option::None;
     r.bsearch(|&(lo,hi)| {
         if lo <= c && c <= hi { Equal }
         else if hi < c { Less }
         else { Greater }
     }) != None
 }\n
-""");
+""")
+
+def emit_table(f, name, t_data, t_type = "&'static [(char, char)]", is_pub=True,
+        pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1]))):
+    pub_string = ""
+    if is_pub:
+        pub_string = "pub "
+    f.write("    %sstatic %s: %s = &[\n" % (pub_string, name, t_type))
+    data = ""
+    first = True
+    for dat in t_data:
+        if not first:
+            data += ","
+        first = False
+        data += pfun(dat)
+    format_table_content(f, data, 8)
+    f.write("\n    ];\n\n")
 
-def emit_property_module(f, mod, tbl):
+def emit_property_module(f, mod, tbl, emit_fn):
     f.write("pub mod %s {\n" % mod)
     keys = tbl.keys()
     keys.sort()
-
     for cat in keys:
-        if cat not in ["Nd", "Nl", "No", "Cc",
-            "XID_Start", "XID_Continue", "Alphabetic",
-            "Lowercase", "Uppercase", "White_Space"]:
-            continue
-        f.write("    static %s_table : &'static [(char,char)] = &[\n" % cat)
-        ix = 0
-        for pair in tbl[cat]:
-            f.write(ch_prefix(ix))
-            f.write("(%s, %s)" % (escape_char(pair[0]), escape_char(pair[1])))
-            ix += 1
-        f.write("\n    ];\n\n")
-
-        f.write("    pub fn %s(c: char) -> bool {\n" % cat)
-        f.write("        super::bsearch_range_table(c, %s_table)\n" % cat)
-        f.write("    }\n\n")
+        emit_table(f, "%s_table" % cat, tbl[cat])
+        if cat in emit_fn:
+            f.write("    pub fn %s(c: char) -> bool {\n" % cat)
+            f.write("        super::bsearch_range_table(c, %s_table)\n" % cat)
+            f.write("    }\n\n")
     f.write("}\n\n")
 
+def emit_regex_module(f, cats, w_data):
+    f.write("pub mod regex {\n")
+    regex_class = "&'static [(char, char)]"
+    class_table = "&'static [(&'static str, %s)]" % regex_class
+
+    emit_table(f, "UNICODE_CLASSES", cats, class_table,
+        pfun=lambda x: "(\"%s\",super::%s::%s_table)" % (x[0], x[1], x[0]))
+
+    f.write("    pub static PERLD: %s = super::general_category::Nd_table;\n\n"
+            % regex_class)
+    f.write("    pub static PERLS: %s = super::property::White_Space_table;\n\n"
+            % regex_class)
+
+    emit_table(f, "PERLW", w_data, regex_class)
+
+    f.write("}\n\n")
 
 def emit_conversions_module(f, lowerupper, upperlower):
     f.write("pub mod conversions {")
     f.write("""
-    use cmp::{Equal, Less, Greater};
-    use slice::ImmutableVector;
-    use tuple::Tuple2;
-    use option::{Option, Some, None};
+    use core::cmp::{Equal, Less, Greater};
+    use core::slice::ImmutableVector;
+    use core::tuple::Tuple2;
+    use core::option::{Option, Some, None};
 
     pub fn to_lower(c: char) -> char {
         match bsearch_case_table(c, LuLl_table) {
@@ -226,189 +343,88 @@ def emit_conversions_module(f, lowerupper, upperlower):
         })
     }
 
-""");
-    emit_caseconversion_table(f, "LuLl", upperlower)
-    emit_caseconversion_table(f, "LlLu", lowerupper)
-    f.write("}\n")
-
-def emit_caseconversion_table(f, name, table):
-    f.write("    static %s_table : &'static [(char, char)] = &[\n" % name)
-    sorted_table = sorted(table.iteritems(), key=operator.itemgetter(0))
-    ix = 0
-    for key, value in sorted_table:
-        f.write(ch_prefix(ix))
-        f.write("(%s, %s)" % (escape_char(key), escape_char(value)))
-        ix += 1
-    f.write("\n    ];\n\n")
-
-def format_table_content(f, content, indent):
-    line = " "*indent
-    first = True
-    for chunk in content.split(","):
-        if len(line) + len(chunk) < 98:
-            if first:
-                line += chunk
-            else:
-                line += ", " + chunk
-            first = False
-        else:
-            f.write(line + ",\n")
-            line = " "*indent + chunk
-    f.write(line)
-
-def emit_core_norm_module(f, canon, compat):
-    canon_keys = canon.keys()
-    canon_keys.sort()
+""")
+    emit_table(f, "LuLl_table",
+        sorted(upperlower.iteritems(), key=operator.itemgetter(0)), is_pub=False)
+    emit_table(f, "LlLu_table",
+        sorted(lowerupper.iteritems(), key=operator.itemgetter(0)), is_pub=False)
+    f.write("}\n\n")
 
-    compat_keys = compat.keys()
-    compat_keys.sort()
-    f.write("pub mod normalization {\n");
-    f.write("    use option::Option;\n");
-    f.write("    use option::{Some, None};\n");
-    f.write("    use slice::ImmutableVector;\n");
+def emit_charwidth_module(f, width_table):
+    f.write("pub mod charwidth {\n")
+    f.write("    use core::option::{Option, Some, None};\n")
+    f.write("    use core::slice::ImmutableVector;\n")
     f.write("""
-    fn bsearch_table(c: char, r: &'static [(char, &'static [char])]) -> Option<&'static [char]> {
-        use cmp::{Equal, Less, Greater};
-        match r.bsearch(|&(val, _)| {
-            if c == val { Equal }
-            else if val < c { Less }
+    fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
+        use core::cmp::{Equal, Less, Greater};
+        match r.bsearch(|&(lo, hi, _, _)| {
+            if lo <= c && c <= hi { Equal }
+            else if hi < c { Less }
             else { Greater }
         }) {
             Some(idx) => {
-                let (_, result) = r[idx];
-                Some(result)
+                let (_, _, r_ncjk, r_cjk) = r[idx];
+                if is_cjk { r_cjk } else { r_ncjk }
             }
-            None => None
+            None => 1
         }
-    }\n\n
+    }
 """)
 
-    f.write("    // Canonical decompositions\n")
-    f.write("    static canonical_table : &'static [(char, &'static [char])] = &[\n")
-    data = ""
-    first = True
-    for char in canon_keys:
-        if not first:
-            data += ","
-        first = False
-        data += "(%s,&[" % escape_char(char)
-        first2 = True
-        for d in canon[char]:
-            if not first2:
-                data += ","
-            first2 = False
-            data += escape_char(d)
-        data += "])"
-    format_table_content(f, data, 8)
-    f.write("\n    ];\n\n")
-
-    f.write("    // Compatibility decompositions\n")
-    f.write("    static compatibility_table : &'static [(char, &'static [char])] = &[\n")
-    data = ""
-    first = True
-    for char in compat_keys:
-        if not first:
-            data += ","
-        first = False
-        data += "(%s,&[" % escape_char(char)
-        first2 = True
-        for d in compat[char]:
-            if not first2:
-                data += ","
-            first2 = False
-            data += escape_char(d)
-        data += "])"
-    format_table_content(f, data, 8)
-    f.write("\n    ];\n\n")
-
     f.write("""
-    pub fn decompose_canonical(c: char, i: |char|) { d(c, i, false); }
-
-    pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
-
-    fn d(c: char, i: |char|, k: bool) {
-        use iter::Iterator;
-
-        // 7-bit ASCII never decomposes
-        if c <= '\\x7f' { i(c); return; }
-
-        // Perform decomposition for Hangul
-        if (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) {
-            decompose_hangul(c, i);
-            return;
+    pub fn width(c: char, is_cjk: bool) -> Option<uint> {
+        match c as uint {
+            _c @ 0 => Some(0),          // null is zero width
+            cu if cu < 0x20 => None,    // control sequences have no width
+            cu if cu < 0x7F => Some(1), // ASCII
+            cu if cu < 0xA0 => None,    // more control sequences
+            _ => Some(bsearch_range_value_table(c, is_cjk, charwidth_table) as uint)
         }
+    }
 
-        // First check the canonical decompositions
-        match bsearch_table(c, canonical_table) {
-            Some(canon) => {
-                for x in canon.iter() {
-                    d(*x, |b| i(b), k);
-                }
-                return;
-            }
-            None => ()
-        }
+""")
 
-        // Bottom out if we're not doing compat.
-        if !k { i(c); return; }
+    f.write("    // character width table. Based on Markus Kuhn's free wcwidth() implementation,\n")
+    f.write("    //     http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c\n")
+    emit_table(f, "charwidth_table", width_table, "&'static [(char, char, u8, u8)]", is_pub=False,
+            pfun=lambda x: "(%s,%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2], x[3]))
+    f.write("}\n")
 
-        // Then check the compatibility decompositions
-        match bsearch_table(c, compatibility_table) {
-            Some(compat) => {
-                for x in compat.iter() {
-                    d(*x, |b| i(b), k);
-                }
-                return;
-            }
-            None => ()
-        }
+def emit_norm_module(f, canon, compat, combine):
+    canon_keys = canon.keys()
+    canon_keys.sort()
 
-        // Finally bottom out.
-        i(c);
-    }
+    compat_keys = compat.keys()
+    compat_keys.sort()
 
-    // Constants from Unicode 6.2.0 Section 3.12 Conjoining Jamo Behavior
-    static S_BASE: u32 = 0xAC00;
-    static L_BASE: u32 = 0x1100;
-    static V_BASE: u32 = 0x1161;
-    static T_BASE: u32 = 0x11A7;
-    static L_COUNT: u32 = 19;
-    static V_COUNT: u32 = 21;
-    static T_COUNT: u32 = 28;
-    static N_COUNT: u32 = (V_COUNT * T_COUNT);
-    static S_COUNT: u32 = (L_COUNT * N_COUNT);
-
-    // Decompose a precomposed Hangul syllable
-    fn decompose_hangul(s: char, f: |char|) {
-        use cast::transmute;
-
-        let si = s as u32 - S_BASE;
-
-        let li = si / N_COUNT;
-        unsafe {
-            f(transmute(L_BASE + li));
-
-            let vi = (si % N_COUNT) / T_COUNT;
-            f(transmute(V_BASE + vi));
-
-            let ti = si % T_COUNT;
-            if ti > 0 {
-                f(transmute(T_BASE + ti));
-            }
-        }
-    }
-}
+    f.write("pub mod normalization {\n")
+
+    def mkdata_fun(table):
+        def f(char):
+            data = "(%s,&[" % escape_char(char)
+            first = True
+            for d in table[char]:
+                if not first:
+                    data += ","
+                first = False
+                data += escape_char(d)
+            data += "])"
+            return data
+        return f
 
-""")
+    f.write("    // Canonical decompositions\n")
+    emit_table(f, "canonical_table", canon_keys, "&'static [(char, &'static [char])]",
+        pfun=mkdata_fun(canon))
 
-def emit_std_norm_module(f, combine):
-    f.write("pub mod normalization {\n");
-    f.write("    use option::{Some, None};\n");
-    f.write("    use slice::ImmutableVector;\n");
+    f.write("    // Compatibility decompositions\n")
+    emit_table(f, "compatibility_table", compat_keys, "&'static [(char, &'static [char])]",
+        pfun=mkdata_fun(compat))
 
     f.write("""
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
-        use cmp::{Equal, Less, Greater};
+        use core::option::{Some, None};
+        use core::cmp::{Equal, Less, Greater};
+        use core::slice::ImmutableVector;
         match r.bsearch(|&(lo, hi, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
@@ -420,72 +436,122 @@ def emit_std_norm_module(f, combine):
             }
             None => 0
         }
-    }\n\n
+    }\n
 """)
 
-    f.write("    static combining_class_table : &'static [(char, char, u8)] = &[\n")
-    ix = 0
-    for pair in combine:
-        f.write(ch_prefix(ix))
-        f.write("(%s, %s, %s)" % (escape_char(pair[0]), escape_char(pair[1]), pair[2]))
-        ix += 1
-    f.write("\n    ];\n\n")
+    emit_table(f, "combining_class_table", combine, "&'static [(char, char, u8)]", is_pub=False,
+            pfun=lambda x: "(%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2]))
 
     f.write("    pub fn canonical_combining_class(c: char) -> u8 {\n"
         + "        bsearch_range_value_table(c, combining_class_table)\n"
         + "    }\n")
-    f.write("}\n")
-
-
-preamble = '''// Copyright 2012-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.
 
-// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
-
-#![allow(missing_doc, non_uppercase_statics)]
+    f.write("""
+}
 
-'''
+""")
 
-(canon_decomp, compat_decomp, gencats,
- combines, lowerupper, upperlower) = load_unicode_data("UnicodeData.txt")
+def remove_from_wtable(wtable, val):
+    wtable_out = []
+    while wtable:
+        if wtable[0][1] < val:
+            wtable_out.append(wtable.pop(0))
+        elif wtable[0][0] > val:
+            break
+        else:
+            (wt_lo, wt_hi, width, width_cjk) = wtable.pop(0)
+            if wt_lo == wt_hi == val:
+                continue
+            elif wt_lo == val:
+                wtable_out.append((wt_lo+1, wt_hi, width, width_cjk))
+            elif wt_hi == val:
+                wtable_out.append((wt_lo, wt_hi-1, width, width_cjk))
+            else:
+                wtable_out.append((wt_lo, val-1, width, width_cjk))
+                wtable_out.append((val+1, wt_hi, width, width_cjk))
+    if wtable:
+        wtable_out.extend(wtable)
+    return wtable_out
+
+def optimize_width_table(wtable):
+    wtable_out = []
+    w_this = wtable.pop(0)
+    while wtable:
+        if w_this[1] == wtable[0][0] - 1 and w_this[2:3] == wtable[0][2:3]:
+            w_tmp = wtable.pop(0)
+            w_this = (w_this[0], w_tmp[1], w_tmp[2], w_tmp[3])
+        else:
+            wtable_out.append(w_this)
+            w_this = wtable.pop(0)
+    wtable_out.append(w_this)
+    return wtable_out
 
-def gen_core_unicode():
-    r = "core_unicode.rs"
+if __name__ == "__main__":
+    r = "unicode.rs"
     if os.path.exists(r):
-        os.remove(r);
+        os.remove(r)
     with open(r, "w") as rf:
-        # Preamble
+        # write the file's preamble
         rf.write(preamble)
 
-        emit_bsearch_range_table(rf);
-        emit_property_module(rf, "general_category", gencats)
-
-        emit_core_norm_module(rf, canon_decomp, compat_decomp)
+        # download and parse all the data
+        (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"]
+        derived = load_properties("DerivedCoreProperties.txt", want_derived + other_derived)
+        scripts = load_properties("Scripts.txt", [])
+        props = load_properties("PropList.txt",
+                ["White_Space", "Join_Control", "Noncharacter_Code_Point"])
+
+        # bsearch_range_table is used in all the property modules below
+        emit_bsearch_range_table(rf)
+
+        # all of these categories will also be available as \p{} in libregex
+        allcats = []
+        for (name, cat, pfuns) in ("general_category", gencats, ["N", "Cc"]), \
+                                  ("derived_property", derived, want_derived), \
+                                  ("script", scripts, []), \
+                                  ("property", props, ["White_Space"]):
+            emit_property_module(rf, name, cat, pfuns)
+            allcats.extend(map(lambda x: (x, name), cat))
+        allcats.sort(key=lambda c: c[0])
+
+        # the \w regex corresponds to Alphabetic + Mark + Decimal_Number +
+        # Connector_Punctuation + Join-Control according to UTS#18
+        # http://www.unicode.org/reports/tr18/#Compatibility_Properties
+        perl_words = []
+        for cat in derived["Alphabetic"], gencats["M"], gencats["Nd"], \
+                   gencats["Pc"], props["Join_Control"]:
+            perl_words.extend(ungroup_cat(cat))
+        perl_words = group_cat(perl_words)
+
+        # emit lookup tables for \p{}, along with \d, \w, and \s for libregex
+        emit_regex_module(rf, allcats, perl_words)
+
+        # normalizations and conversions module
+        emit_norm_module(rf, canon_decomp, compat_decomp, combines)
+        emit_conversions_module(rf, lowerupper, upperlower)
 
-        derived = load_properties("DerivedCoreProperties.txt",
-                ["XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase"])
+        # character width module
+        width_table = []
+        for zwcat in ["Me", "Mn", "Cf"]:
+            width_table.extend(map(lambda (lo, hi): (lo, hi, 0, 0), gencats[zwcat]))
+        width_table.append((4448, 4607, 0, 0))
 
-        emit_property_module(rf, "derived_property", derived)
+        # get widths, except those that are explicitly marked zero-width above
+        ea_widths = load_east_asian_width(["W", "F", "A"], ["Me", "Mn", "Cf"])
+        # these are doublewidth
+        for dwcat in ["W", "F"]:
+            width_table.extend(map(lambda (lo, hi): (lo, hi, 2, 2), ea_widths[dwcat]))
+        width_table.extend(map(lambda (lo, hi): (lo, hi, 1, 2), ea_widths["A"]))
 
-        props = load_properties("PropList.txt", ["White_Space"])
-        emit_property_module(rf, "property", props)
-        emit_conversions_module(rf, lowerupper, upperlower)
+        width_table.sort(key=lambda w: w[0])
 
-def gen_std_unicode():
-    r = "std_unicode.rs"
-    if os.path.exists(r):
-        os.remove(r);
-    with open(r, "w") as rf:
-        # Preamble
-        rf.write(preamble)
-        emit_std_norm_module(rf, combines)
+        # soft hyphen is not zero width in preformatted text; it's used to indicate
+        # a hyphen inserted to facilitate a linebreak.
+        width_table = remove_from_wtable(width_table, 173)
 
-gen_core_unicode()
-gen_std_unicode()
+        # optimize the width table by collapsing adjacent entities when possible
+        width_table = optimize_width_table(width_table)
+        emit_charwidth_module(rf, width_table)
index 65f9f4105ad8fda5c8d58657f5832072102e47d5..16ed43415c3ef5a7231011a19081a49870e3d6e5 100644 (file)
@@ -31,6 +31,12 @@ setlocal formatoptions-=t formatoptions+=croqnl
 " j was only added in 7.3.541, so stop complaints about its nonexistence
 silent! setlocal formatoptions+=j
 
+" smartindent will be overridden by indentexpr if filetype indent is on, but
+" otherwise it's better than nothing.
+setlocal smartindent nocindent
+
+setlocal tabstop=4 shiftwidth=4 expandtab
+
 " This includeexpr isn't perfect, but it's a good start
 setlocal includeexpr=substitute(v:fname,'::','/','g')
 
index a15bd3ca60ff1c7e484b10e1997a1fb525a8bd09..86df9cba4cdf5317b8a148f97dbde8b912a2607e 100644 (file)
@@ -65,7 +65,7 @@ syn keyword   rustTrait       Copy Send Sized Share
 syn keyword   rustTrait       Add Sub Mul Div Rem Neg Not
 syn keyword   rustTrait       BitAnd BitOr BitXor
 syn keyword   rustTrait       Drop Deref DerefMut
-syn keyword   rustTrait       Shl Shr Index
+syn keyword   rustTrait       Shl Shr Index IndexMut
 syn keyword   rustEnum        Option
 syn keyword   rustEnumVariant Some None
 syn keyword   rustEnum        Result
@@ -100,7 +100,7 @@ syn keyword rustTrait RawPtr
 syn keyword rustTrait Buffer Writer Reader Seek
 syn keyword rustTrait Str StrVector StrSlice OwnedStr
 syn keyword rustTrait IntoMaybeOwned StrAllocating
-syn keyword rustTrait ToStr IntoStr
+syn keyword rustTrait ToString IntoStr
 syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
 syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
 syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
index 9c821117205422427ae9f68f7321a706833fff17..b423191d54ad74c6fa7762e683fe3567fcdace0a 100644 (file)
@@ -9,10 +9,12 @@ _rustc_opts_switches=(
     -c'[Compile and assemble, but do not link]'
     --cfg'[Configure the compilation environment]'
     --crate-id'[Output the crate id and exit]'
-    --crate-file-name'[Output the file(s) that would be written if compilation continued and exit]'
-    --crate-name'[Output the crate name and exit]'
-    --dep-info'[Output dependency info to <filename> after compiling]'
+    --crate-file-name'[deprecated in favor of --print-file-name]'
+    --crate-name'[Specify the name of the crate being built]'
     --crate-type'[Specify the type of crate to crate]'
+    --debuginfo'[Emit DWARF debug info to the objects created: 0 = no debug info, 1 = line-tables only (for stacktraces and breakpoints), 2 = full debug info with variable and type information (same as -g)]'
+    --dep-info'[Output dependency info to <filename> after compiling]'
+    -g'[Equivalent to --debuginfo=2]'
     {-h,--help}'[Display this message]'
     -L'[Add a directory to the library search path]'
     --linker'[Program to use for linking instead of the default.]'
@@ -29,6 +31,8 @@ _rustc_opts_switches=(
     --parse-only'[Parse only; do not compile, assemble, or link]'
     --passes'[Comma or space separated list of pass names to use]'
     --pretty'[Pretty-print the input instead of compiling]'
+    --print-crate-name'[Output the crate name and exit]'
+    --print-file-name'[Output the file(s) that would be written if compilation continued and exit]'
     --save-temps'[Write intermediate files (.bc, .opt.bc, .o) in addition to normal output]'
     --sysroot'[Override the system root]'
     --test'[Build a test harness]'
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
new file mode 100644 (file)
index 0000000..56506d7
--- /dev/null
@@ -0,0 +1,180 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A unique pointer type
+
+use core::any::{Any, AnyRefExt};
+use core::clone::Clone;
+use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
+use core::default::Default;
+use core::fmt;
+use core::intrinsics;
+use core::mem;
+use core::option::Option;
+use core::raw::TraitObject;
+use core::result::{Ok, Err, Result};
+
+/// A value that represents the global exchange heap. This is the default
+/// place that the `box` keyword allocates into when no place is supplied.
+///
+/// The following two examples are equivalent:
+///
+///     use std::boxed::HEAP;
+///
+///     # struct Bar;
+///     # impl Bar { fn new(_a: int) { } }
+///     let foo = box(HEAP) Bar::new(2);
+///     let foo = box Bar::new(2);
+#[lang = "exchange_heap"]
+#[experimental = "may be renamed; uncertain about custom allocator design"]
+pub static HEAP: () = ();
+
+/// A type that represents a uniquely-owned value.
+#[lang = "owned_box"]
+#[unstable = "custom allocators will add an additional type parameter (with default)"]
+pub struct Box<T>(*mut T);
+
+impl<T: Default> Default for Box<T> {
+    fn default() -> Box<T> { box Default::default() }
+}
+
+#[unstable]
+impl<T: Clone> Clone for Box<T> {
+    /// Return a copy of the owned box.
+    #[inline]
+    fn clone(&self) -> Box<T> { box {(**self).clone()} }
+
+    /// Perform copy-assignment from `source` by reusing the existing allocation.
+    #[inline]
+    fn clone_from(&mut self, source: &Box<T>) {
+        (**self).clone_from(&(**source));
+    }
+}
+
+impl<T:PartialEq> PartialEq for Box<T> {
+    #[inline]
+    fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) }
+    #[inline]
+    fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
+}
+impl<T:PartialOrd> PartialOrd for Box<T> {
+    #[inline]
+    fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
+        (**self).partial_cmp(*other)
+    }
+    #[inline]
+    fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
+    #[inline]
+    fn le(&self, other: &Box<T>) -> bool { *(*self) <= *(*other) }
+    #[inline]
+    fn ge(&self, other: &Box<T>) -> bool { *(*self) >= *(*other) }
+    #[inline]
+    fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
+}
+impl<T: Ord> Ord for Box<T> {
+    #[inline]
+    fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
+}
+impl<T: Eq> Eq for Box<T> {}
+
+/// Extension methods for an owning `Any` trait object
+#[unstable = "post-DST, the signature of `downcast` will change to take `Box<Self>`"]
+pub trait BoxAny {
+    /// Returns the boxed value if it is of type `T`, or
+    /// `Err(Self)` if it isn't.
+    fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
+
+    /// Deprecated; this method has been renamed to `downcast`.
+    #[deprecated = "use downcast instead"]
+    fn move<T: 'static>(self) -> Result<Box<T>, Self> {
+        self.downcast::<T>()
+    }
+}
+
+impl BoxAny for Box<Any> {
+    #[inline]
+    fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
+        if self.is::<T>() {
+            unsafe {
+                // Get the raw representation of the trait object
+                let to: TraitObject =
+                    *mem::transmute::<&Box<Any>, &TraitObject>(&self);
+
+                // Prevent destructor on self being run
+                intrinsics::forget(self);
+
+                // Extract the data pointer
+                Ok(mem::transmute(to.data))
+            }
+        } else {
+            Err(self)
+        }
+    }
+}
+
+impl<T: fmt::Show> fmt::Show for Box<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        (**self).fmt(f)
+    }
+}
+
+impl fmt::Show for Box<Any> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Box<Any>")
+    }
+}
+
+#[cfg(test)]
+mod test {
+    #[test]
+    fn test_owned_clone() {
+        let a = box 5i;
+        let b: Box<int> = a.clone();
+        assert!(a == b);
+    }
+
+    #[test]
+    fn any_move() {
+        let a = box 8u as Box<Any>;
+        let b = box Test as Box<Any>;
+
+        match a.downcast::<uint>() {
+            Ok(a) => { assert!(a == box 8u); }
+            Err(..) => fail!()
+        }
+        match b.downcast::<Test>() {
+            Ok(a) => { assert!(a == box Test); }
+            Err(..) => fail!()
+        }
+
+        let a = box 8u as Box<Any>;
+        let b = box Test as Box<Any>;
+
+        assert!(a.downcast::<Box<Test>>().is_err());
+        assert!(b.downcast::<Box<uint>>().is_err());
+    }
+
+    #[test]
+    fn test_show() {
+        let a = box 8u as Box<Any>;
+        let b = box Test as Box<Any>;
+        let a_str = a.to_str();
+        let b_str = b.to_str();
+        assert_eq!(a_str.as_slice(), "Box<Any>");
+        assert_eq!(b_str.as_slice(), "Box<Any>");
+
+        let a = &8u as &Any;
+        let b = &Test as &Any;
+        let s = format!("{}", a);
+        assert_eq!(s.as_slice(), "&Any");
+        let s = format!("{}", b);
+        assert_eq!(s.as_slice(), "&Any");
+    }
+}
index 26b8ccaf573718523428bd8f82c76b61be87c3e4..6ae91f3897104bddcbf7ae9e17c64c520c5e58cd 100644 (file)
 //!
 //! Currently, there are four major definitions in this library.
 //!
-//! ## Owned pointers
+//! ## Boxed values
 //!
-//! The [`Box`](owned/index.html) type is the core owned pointer type in rust.
+//! The [`Box`](boxed/index.html) type is the core owned pointer type in rust.
 //! There can only be one owner of a `Box`, and the owner can decide to mutate
-//! the contents.
+//! the contents, which live on the heap.
 //!
 //! This type can be sent among tasks efficiently as the size of a `Box` value
 //! is just a pointer. Tree-like data structures are often built on owned
@@ -60,7 +60,7 @@
 //! by libc malloc/free.  The `libc_heap` module is defined to be wired up to
 //! the system malloc/free.
 
-#![crate_id = "alloc#0.11.0"]
+#![crate_name = "alloc"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #[cfg(test)] #[phase(plugin, link)] extern crate std;
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 
+// The deprecated name of the boxed module
+
+#[deprecated = "use boxed instead"]
+#[cfg(not(test))]
+pub use owned = boxed;
+
 // Heaps provided for low-level allocation strategies
 
 pub mod heap;
@@ -91,7 +97,7 @@
 // Primitive types using the heaps above
 
 #[cfg(not(test))]
-pub mod owned;
+pub mod boxed;
 pub mod arc;
 pub mod rc;
 
diff --git a/src/liballoc/owned.rs b/src/liballoc/owned.rs
deleted file mode 100644 (file)
index addec39..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A unique pointer type
-
-use core::any::{Any, AnyRefExt};
-use core::clone::Clone;
-use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
-use core::default::Default;
-use core::fmt;
-use core::intrinsics;
-use core::kinds::Send;
-use core::mem;
-use core::option::Option;
-use core::raw::TraitObject;
-use core::result::{Ok, Err, Result};
-
-/// A value that represents the global exchange heap. This is the default
-/// place that the `box` keyword allocates into when no place is supplied.
-///
-/// The following two examples are equivalent:
-///
-///     use std::owned::HEAP;
-///
-///     # struct Bar;
-///     # impl Bar { fn new(_a: int) { } }
-///     let foo = box(HEAP) Bar::new(2);
-///     let foo = box Bar::new(2);
-#[lang="exchange_heap"]
-pub static HEAP: () = ();
-
-/// A type that represents a uniquely-owned value.
-#[lang="owned_box"]
-pub struct Box<T>(*mut T);
-
-impl<T: Default> Default for Box<T> {
-    fn default() -> Box<T> { box Default::default() }
-}
-
-#[unstable]
-impl<T: Clone> Clone for Box<T> {
-    /// Return a copy of the owned box.
-    #[inline]
-    fn clone(&self) -> Box<T> { box {(**self).clone()} }
-
-    /// Perform copy-assignment from `source` by reusing the existing allocation.
-    #[inline]
-    fn clone_from(&mut self, source: &Box<T>) {
-        (**self).clone_from(&(**source));
-    }
-}
-
-// box pointers
-impl<T:PartialEq> PartialEq for Box<T> {
-    #[inline]
-    fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) }
-    #[inline]
-    fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
-}
-impl<T:PartialOrd> PartialOrd for Box<T> {
-    #[inline]
-    fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
-        (**self).partial_cmp(*other)
-    }
-    #[inline]
-    fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
-    #[inline]
-    fn le(&self, other: &Box<T>) -> bool { *(*self) <= *(*other) }
-    #[inline]
-    fn ge(&self, other: &Box<T>) -> bool { *(*self) >= *(*other) }
-    #[inline]
-    fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
-}
-impl<T: Ord> Ord for Box<T> {
-    #[inline]
-    fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
-}
-impl<T: Eq> Eq for Box<T> {}
-
-/// Extension methods for an owning `Any` trait object
-pub trait AnyOwnExt {
-    /// Returns the boxed value if it is of type `T`, or
-    /// `Err(Self)` if it isn't.
-    fn move<T: 'static>(self) -> Result<Box<T>, Self>;
-}
-
-impl AnyOwnExt for Box<Any> {
-    #[inline]
-    fn move<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
-        if self.is::<T>() {
-            unsafe {
-                // Get the raw representation of the trait object
-                let to: TraitObject =
-                    *mem::transmute::<&Box<Any>, &TraitObject>(&self);
-
-                // Prevent destructor on self being run
-                intrinsics::forget(self);
-
-                // Extract the data pointer
-                Ok(mem::transmute(to.data))
-            }
-        } else {
-            Err(self)
-        }
-    }
-}
-
-/// Extension methods for an owning `Any+Send` trait object
-pub trait AnySendOwnExt {
-    /// Returns the boxed value if it is of type `T`, or
-    /// `Err(Self)` if it isn't.
-    fn move_send<T: 'static>(self) -> Result<Box<T>, Self>;
-}
-
-impl AnySendOwnExt for Box<Any+Send> {
-    #[inline]
-    fn move_send<T: 'static>(self) -> Result<Box<T>, Box<Any+Send>> {
-        if self.is::<T>() {
-            unsafe {
-                // Get the raw representation of the trait object
-                let to: TraitObject =
-                    *mem::transmute::<&Box<Any+Send>, &TraitObject>(&self);
-
-                // Prevent destructor on self being run
-                intrinsics::forget(self);
-
-                // Extract the data pointer
-                Ok(mem::transmute(to.data))
-            }
-        } else {
-            Err(self)
-        }
-    }
-}
-
-impl<T: fmt::Show> fmt::Show for Box<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        (**self).fmt(f)
-    }
-}
-
-impl fmt::Show for Box<Any> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.pad("Box<Any>")
-    }
-}
-
-#[cfg(test)]
-mod test {
-    #[test]
-    fn test_owned_clone() {
-        let a = box 5i;
-        let b: Box<int> = a.clone();
-        assert!(a == b);
-    }
-
-    #[test]
-    fn any_move() {
-        let a = box 8u as Box<Any>;
-        let b = box Test as Box<Any>;
-
-        match a.move::<uint>() {
-            Ok(a) => { assert!(a == box 8u); }
-            Err(..) => fail!()
-        }
-        match b.move::<Test>() {
-            Ok(a) => { assert!(a == box Test); }
-            Err(..) => fail!()
-        }
-
-        let a = box 8u as Box<Any>;
-        let b = box Test as Box<Any>;
-
-        assert!(a.move::<Box<Test>>().is_err());
-        assert!(b.move::<Box<uint>>().is_err());
-    }
-
-    #[test]
-    fn test_show() {
-        let a = box 8u as Box<Any>;
-        let b = box Test as Box<Any>;
-        let a_str = a.to_str();
-        let b_str = b.to_str();
-        assert_eq!(a_str.as_slice(), "Box<Any>");
-        assert_eq!(b_str.as_slice(), "Box<Any>");
-
-        let a = &8u as &Any;
-        let b = &Test as &Any;
-        let s = format!("{}", a);
-        assert_eq!(s.as_slice(), "&Any");
-        let s = format!("{}", b);
-        assert_eq!(s.as_slice(), "&Any");
-    }
-}
index 917de94470b35e0bf3ceb4f189e464fb747d2310..e672c555b804df163b6d259d4a29ce09590c0f2d 100644 (file)
 //! arena but can only hold objects of a single type, and Arena, which is a
 //! more complex, slower Arena which can hold objects of any type.
 
-#![crate_id = "arena#0.11.0"]
+#![crate_name = "arena"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 
 #![feature(unsafe_destructor)]
 #![allow(missing_doc)]
index 234393ce56183b8dfbf330e4bb370a04c4e96d3e..226da13f9e228b5c33c80a71481738ec67855a0f 100644 (file)
@@ -15,8 +15,8 @@
 use core::cmp;
 use core::default::Default;
 use core::fmt;
-use core::iter::{Enumerate, Repeat, Map, Zip};
-use core::ops;
+use core::iter::Take;
+use core::ops::Index;
 use core::slice;
 use core::uint;
 use std::hash;
 use {Collection, Mutable, Set, MutableSet};
 use vec::Vec;
 
+
+static TRUE: bool = true;
+static FALSE: bool = false;
+
 #[deriving(Clone)]
 struct SmallBitv {
     /// only the lowest nbits of this value are used. the rest is undefined.
     bits: uint
 }
 
-/// a mask that has a 1 for each defined bit in a small_bitv, assuming n bits
-#[inline]
-fn small_mask(nbits: uint) -> uint {
-    (1 << nbits) - 1
-}
-
-impl SmallBitv {
-    fn new(bits: uint) -> SmallBitv {
-        SmallBitv {bits: bits}
-    }
-
-    #[inline]
-    fn bits_op(&mut self,
-                   right_bits: uint,
-                   nbits: uint,
-                   f: |uint, uint| -> uint)
-                   -> bool {
-        let mask = small_mask(nbits);
-        let old_b: uint = self.bits;
-        let new_b = f(old_b, right_bits);
-        self.bits = new_b;
-        mask & old_b != mask & new_b
-    }
-
-    #[inline]
-    fn union(&mut self, s: &SmallBitv, nbits: uint) -> bool {
-        self.bits_op(s.bits, nbits, |u1, u2| u1 | u2)
-    }
-
-    #[inline]
-    fn intersect(&mut self, s: &SmallBitv, nbits: uint) -> bool {
-        self.bits_op(s.bits, nbits, |u1, u2| u1 & u2)
-    }
-
-    #[inline]
-    fn become(&mut self, s: &SmallBitv, nbits: uint) -> bool {
-        self.bits_op(s.bits, nbits, |_u1, u2| u2)
-    }
-
-    #[inline]
-    fn difference(&mut self, s: &SmallBitv, nbits: uint) -> bool {
-        self.bits_op(s.bits, nbits, |u1, u2| u1 & !u2)
-    }
-
-    #[inline]
-    fn get(&self, i: uint) -> bool {
-        (self.bits & (1 << i)) != 0
-    }
-
-    #[inline]
-    fn set(&mut self, i: uint, x: bool) {
-        if x {
-            self.bits |= 1<<i;
-        }
-        else {
-            self.bits &= !(1<<i);
-        }
-    }
-
-    #[inline]
-    fn equals(&self, b: &SmallBitv, nbits: uint) -> bool {
-        let mask = small_mask(nbits);
-        mask & self.bits == mask & b.bits
-    }
-
-    #[inline]
-    fn clear(&mut self) { self.bits = 0; }
-
-    #[inline]
-    fn set_all(&mut self) { self.bits = !0; }
-
-    #[inline]
-    fn all(&self, nbits: uint) -> bool {
-        small_mask(nbits) & !self.bits == 0
-    }
-
-    #[inline]
-    fn none(&self, nbits: uint) -> bool {
-        small_mask(nbits) & self.bits == 0
-    }
-
-    #[inline]
-    fn negate(&mut self) { self.bits = !self.bits; }
-}
-
 #[deriving(Clone)]
 struct BigBitv {
     storage: Vec<uint>
 }
 
-/**
- * A mask that has a 1 for each defined bit in the n'th element of a `BigBitv`,
- * assuming n bits.
- */
-#[inline]
-fn big_mask(nbits: uint, elem: uint) -> uint {
-    let rmd = nbits % uint::BITS;
-    let nelems = nbits/uint::BITS + if rmd == 0 {0} else {1};
-
-    if elem < nelems - 1 || rmd == 0 {
-        !0
-    } else {
-        (1 << rmd) - 1
-    }
-}
-
-impl BigBitv {
-    fn new(storage: Vec<uint>) -> BigBitv {
-        BigBitv {storage: storage}
-    }
-
-    #[inline]
-    fn process(&mut self,
-                   b: &BigBitv,
-                   nbits: uint,
-                   op: |uint, uint| -> uint)
-                   -> bool {
-        let len = b.storage.len();
-        assert_eq!(self.storage.len(), len);
-        let mut changed = false;
-        for (i, (a, b)) in self.storage.mut_iter()
-                               .zip(b.storage.iter())
-                               .enumerate() {
-            let mask = big_mask(nbits, i);
-            let w0 = *a & mask;
-            let w1 = *b & mask;
-            let w = op(w0, w1) & mask;
-            if w0 != w {
-                changed = true;
-                *a = w;
-            }
-        }
-        changed
-    }
-
-    #[inline]
-    fn each_storage(&mut self, op: |v: &mut uint| -> bool) -> bool {
-        self.storage.mut_iter().advance(|elt| op(elt))
-    }
-
-    #[inline]
-    fn negate(&mut self) {
-        self.each_storage(|w| { *w = !*w; true });
-    }
-
-    #[inline]
-    fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
-        self.process(b, nbits, |w1, w2| w1 | w2)
-    }
-
-    #[inline]
-    fn intersect(&mut self, b: &BigBitv, nbits: uint) -> bool {
-        self.process(b, nbits, |w1, w2| w1 & w2)
-    }
-
-    #[inline]
-    fn become(&mut self, b: &BigBitv, nbits: uint) -> bool {
-        self.process(b, nbits, |_, w| w)
-    }
-
-    #[inline]
-    fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool {
-        self.process(b, nbits, |w1, w2| w1 & !w2)
-    }
-
-    #[inline]
-    fn get(&self, i: uint) -> bool {
-        let w = i / uint::BITS;
-        let b = i % uint::BITS;
-        let x = 1 & self.storage.get(w) >> b;
-        x == 1
-    }
-
-    #[inline]
-    fn set(&mut self, i: uint, x: bool) {
-        let w = i / uint::BITS;
-        let b = i % uint::BITS;
-        let flag = 1 << b;
-        *self.storage.get_mut(w) = if x { *self.storage.get(w) | flag }
-                          else { *self.storage.get(w) & !flag };
-    }
-
-    #[inline]
-    fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
-        for (i, elt) in b.storage.iter().enumerate() {
-            let mask = big_mask(nbits, i);
-            if mask & *self.storage.get(i) != mask & *elt {
-                return false;
-            }
-        }
-        true
-    }
-}
-
 #[deriving(Clone)]
 enum BitvVariant { Big(BigBitv), Small(SmallBitv) }
 
-enum Op {Union, Intersect, Assign, Difference}
-
 /// The bitvector type
 ///
 /// # Example
@@ -236,91 +49,125 @@ enum Op {Union, Intersect, Assign, Difference}
 /// ```rust
 /// use collections::bitv::Bitv;
 ///
-/// let mut bv = Bitv::new(10, false);
+/// let mut bv = Bitv::with_capacity(10, false);
 ///
 /// // insert all primes less than 10
 /// bv.set(2, true);
 /// bv.set(3, true);
 /// bv.set(5, true);
 /// bv.set(7, true);
-/// println!("{}", bv.to_str());
+/// println!("{}", bv.to_string());
 /// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
 ///
 /// // flip all values in bitvector, producing non-primes less than 10
 /// bv.negate();
-/// println!("{}", bv.to_str());
+/// println!("{}", bv.to_string());
 /// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
 ///
 /// // reset bitvector to empty
 /// bv.clear();
-/// println!("{}", bv.to_str());
+/// println!("{}", bv.to_string());
 /// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
 /// ```
-#[deriving(Clone)]
 pub struct Bitv {
-    /// Internal representation of the bit vector (small or large)
-    rep: BitvVariant,
+    /// Internal representation of the bit vector
+    storage: Vec<uint>,
     /// The number of valid bits in the internal representation
     nbits: uint
 }
 
-fn die() -> ! {
-    fail!("Tried to do operation on bit vectors with different sizes");
+impl Index<uint,bool> for Bitv {
+    #[inline]
+    fn index<'a>(&'a self, i: &uint) -> &'a bool {
+        if self.get(*i) {
+            &TRUE
+        } else {
+            &FALSE
+        }
+    }
 }
 
-impl Bitv {
+struct MaskWords<'a> {
+    iter: slice::Items<'a, uint>,
+    next_word: Option<&'a uint>,
+    last_word_mask: uint,
+    offset: uint
+}
+
+impl<'a> Iterator<(uint, uint)> for MaskWords<'a> {
+    /// Returns (offset, word)
     #[inline]
-    fn do_op(&mut self, op: Op, other: &Bitv) -> bool {
-        if self.nbits != other.nbits {
-            die();
-        }
-        match self.rep {
-          Small(ref mut s) => match other.rep {
-            Small(ref s1) => match op {
-              Union      => s.union(s1,      self.nbits),
-              Intersect  => s.intersect(s1,  self.nbits),
-              Assign     => s.become(s1,     self.nbits),
-              Difference => s.difference(s1, self.nbits)
+    fn next<'a>(&'a mut self) -> Option<(uint, uint)> {
+        let ret = self.next_word;
+        match ret {
+            Some(&w) => {
+                self.next_word = self.iter.next();
+                self.offset += 1;
+                // The last word may need to be masked
+                if self.next_word.is_none() {
+                    Some((self.offset - 1, w & self.last_word_mask))
+                } else {
+                    Some((self.offset - 1, w))
+                }
             },
-            Big(_) => die()
-          },
-          Big(ref mut s) => match other.rep {
-            Small(_) => die(),
-            Big(ref s1) => match op {
-              Union      => s.union(s1,      self.nbits),
-              Intersect  => s.intersect(s1,  self.nbits),
-              Assign     => s.become(s1,     self.nbits),
-              Difference => s.difference(s1, self.nbits)
-            }
-          }
+            None => None
         }
     }
 }
 
 impl Bitv {
-    /// Creates an empty Bitv that holds `nbits` elements, setting each element
+    #[inline]
+    fn process(&mut self, other: &Bitv, op: |uint, uint| -> uint) -> bool {
+        let len = other.storage.len();
+        assert_eq!(self.storage.len(), len);
+        let mut changed = false;
+        // Notice: `a` is *not* masked here, which is fine as long as
+        // `op` is a bitwise operation, since any bits that should've
+        // been masked were fine to change anyway. `b` is masked to
+        // make sure its unmasked bits do not cause damage.
+        for (a, (_, b)) in self.storage.mut_iter()
+                           .zip(other.mask_words(0)) {
+            let w = op(*a, b);
+            if *a != w {
+                changed = true;
+                *a = w;
+            }
+        }
+        changed
+    }
+
+    #[inline]
+    fn mask_words<'a>(&'a self, mut start: uint) -> MaskWords<'a> {
+        if start > self.storage.len() {
+            start = self.storage.len();
+        }
+        let mut iter = self.storage.slice_from(start).iter();
+        MaskWords {
+          next_word: iter.next(),
+          iter: iter,
+          last_word_mask: {
+              let rem = self.nbits % uint::BITS;
+              if rem > 0 {
+                  (1 << rem) - 1
+              } else { !0 }
+          },
+          offset: start
+        }
+    }
+
+    /// Creates an empty Bitv
+    pub fn new() -> Bitv {
+        Bitv { storage: Vec::new(), nbits: 0 }
+    }
+
+    /// Creates a Bitv that holds `nbits` elements, setting each element
     /// to `init`.
-    pub fn new(nbits: uint, init: bool) -> Bitv {
-        let rep = if nbits < uint::BITS {
-            Small(SmallBitv::new(if init {(1<<nbits)-1} else {0}))
-        } else if nbits == uint::BITS {
-            Small(SmallBitv::new(if init {!0} else {0}))
-        } else {
-            let exact = nbits % uint::BITS == 0;
-            let nelems = nbits/uint::BITS + if exact {0} else {1};
-            let s =
-                if init {
-                    if exact {
-                        Vec::from_elem(nelems, !0u)
-                    } else {
-                        let mut v = Vec::from_elem(nelems-1, !0u);
-                        v.push((1<<nbits % uint::BITS)-1);
-                        v
-                    }
-                } else { Vec::from_elem(nelems, 0u)};
-            Big(BigBitv::new(s))
-        };
-        Bitv {rep: rep, nbits: nbits}
+    pub fn with_capacity(nbits: uint, init: bool) -> Bitv {
+        Bitv {
+            storage: Vec::from_elem((nbits + uint::BITS - 1) / uint::BITS,
+                                    if init { !0u } else { 0u }),
+            nbits: nbits
+        }
     }
 
     /**
@@ -330,7 +177,9 @@ pub fn new(nbits: uint, init: bool) -> Bitv {
      * the same length. Returns `true` if `self` changed.
     */
     #[inline]
-    pub fn union(&mut self, v1: &Bitv) -> bool { self.do_op(Union, v1) }
+    pub fn union(&mut self, other: &Bitv) -> bool {
+        self.process(other, |w1, w2| w1 | w2)
+    }
 
     /**
      * Calculates the intersection of two bitvectors
@@ -339,27 +188,18 @@ pub fn union(&mut self, v1: &Bitv) -> bool { self.do_op(Union, v1) }
      * must be the same length. Returns `true` if `self` changed.
     */
     #[inline]
-    pub fn intersect(&mut self, v1: &Bitv) -> bool {
-        self.do_op(Intersect, v1)
+    pub fn intersect(&mut self, other: &Bitv) -> bool {
+        self.process(other, |w1, w2| w1 & w2)
     }
 
-    /**
-     * Assigns the value of `v1` to `self`
-     *
-     * Both bitvectors must be the same length. Returns `true` if `self` was
-     * changed
-     */
-    #[inline]
-    pub fn assign(&mut self, v: &Bitv) -> bool { self.do_op(Assign, v) }
-
     /// Retrieve the value at index `i`
     #[inline]
     pub fn get(&self, i: uint) -> bool {
-        assert!((i < self.nbits));
-        match self.rep {
-            Big(ref b)   => b.get(i),
-            Small(ref s) => s.get(i)
-        }
+        assert!(i < self.nbits);
+        let w = i / uint::BITS;
+        let b = i % uint::BITS;
+        let x = self.storage.get(w) & (1 << b);
+        x != 0
     }
 
     /**
@@ -369,42 +209,24 @@ pub fn get(&self, i: uint) -> bool {
      */
     #[inline]
     pub fn set(&mut self, i: uint, x: bool) {
-      assert!((i < self.nbits));
-      match self.rep {
-        Big(ref mut b)   => b.set(i, x),
-        Small(ref mut s) => s.set(i, x)
-      }
-    }
-
-    /// Set all bits to 0
-    #[inline]
-    pub fn clear(&mut self) {
-        match self.rep {
-            Small(ref mut b) => b.clear(),
-            Big(ref mut s) => {
-                s.each_storage(|w| { *w = 0u; true });
-            }
-        }
+        assert!(i < self.nbits);
+        let w = i / uint::BITS;
+        let b = i % uint::BITS;
+        let flag = 1 << b;
+        *self.storage.get_mut(w) = if x { *self.storage.get(w) | flag }
+                          else { *self.storage.get(w) & !flag };
     }
 
     /// Set all bits to 1
     #[inline]
     pub fn set_all(&mut self) {
-        match self.rep {
-            Small(ref mut b) => b.set_all(),
-            Big(ref mut s) => {
-                s.each_storage(|w| { *w = !0u; true });
-            }
-        }
+        for w in self.storage.mut_iter() { *w = !0u; }
     }
 
     /// Flip all bits
     #[inline]
     pub fn negate(&mut self) {
-        match self.rep {
-            Small(ref mut s) => s.negate(),
-            Big(ref mut b) => b.negate(),
-        }
+        for w in self.storage.mut_iter() { *w = !*w; }
     }
 
     /**
@@ -417,17 +239,19 @@ pub fn negate(&mut self) {
      * Returns `true` if `v0` was changed.
      */
     #[inline]
-    pub fn difference(&mut self, v: &Bitv) -> bool {
-        self.do_op(Difference, v)
+    pub fn difference(&mut self, other: &Bitv) -> bool {
+        self.process(other, |w1, w2| w1 & !w2)
     }
 
     /// Returns `true` if all bits are 1
     #[inline]
     pub fn all(&self) -> bool {
-      match self.rep {
-        Small(ref b) => b.all(self.nbits),
-        _ => self.iter().all(|x| x)
-      }
+        let mut last_word = !0u;
+        // Check that every word but the last is all-ones...
+        self.mask_words(0).all(|(_, elem)|
+            { let tmp = last_word; last_word = elem; tmp == !0u }) &&
+        // ...and that the last word is ones as far as it needs to be
+        (last_word == ((1 << self.nbits % uint::BITS) - 1) || last_word == !0u)
     }
 
     /// Returns an iterator over the elements of the vector in order.
@@ -436,7 +260,7 @@ pub fn all(&self) -> bool {
     ///
     /// ```rust
     /// use collections::bitv::Bitv;
-    /// let mut bv = Bitv::new(10, false);
+    /// let mut bv = Bitv::with_capacity(10, false);
     /// bv.set(1, true);
     /// bv.set(2, true);
     /// bv.set(3, true);
@@ -452,10 +276,7 @@ pub fn iter<'a>(&'a self) -> Bits<'a> {
 
     /// Returns `true` if all bits are 0
     pub fn none(&self) -> bool {
-      match self.rep {
-        Small(ref b) => b.none(self.nbits),
-        _ => self.iter().all(|x| !x)
-      }
+        self.mask_words(0).all(|(_, w)| w == 0)
     }
 
     #[inline]
@@ -464,15 +285,6 @@ pub fn any(&self) -> bool {
         !self.none()
     }
 
-    /**
-     * Converts `self` to a vector of `uint` with the same length.
-     *
-     * Each `uint` in the resulting vector has either value `0u` or `1u`.
-     */
-    pub fn to_vec(&self) -> Vec<uint> {
-        Vec::from_fn(self.nbits, |i| if self.get(i) { 1 } else { 0 })
-    }
-
     /**
      * Organise the bits into bytes, such that the first bit in the
      * `Bitv` becomes the high-order bit of the first byte. If the
@@ -485,7 +297,7 @@ fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
             if offset >= bitv.nbits {
                 0
             } else {
-                bitv[offset] as u8 << (7 - bit)
+                bitv.get(offset) as u8 << (7 - bit)
             }
         }
 
@@ -507,7 +319,7 @@ fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
      * Transform `self` into a `Vec<bool>` by turning each bit into a `bool`.
      */
     pub fn to_bools(&self) -> Vec<bool> {
-        Vec::from_fn(self.nbits, |i| self[i])
+        Vec::from_fn(self.nbits, |i| self.get(i))
     }
 
     /**
@@ -525,10 +337,131 @@ pub fn eq_vec(&self, v: &[bool]) -> bool {
         true
     }
 
-    pub fn ones(&self, f: |uint| -> bool) -> bool {
-        range(0u, self.nbits).advance(|i| !self.get(i) || f(i))
+    /// Shorten a Bitv, dropping excess elements.
+    ///
+    /// If `len` is greater than the vector's current length, this has no
+    /// effect.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use collections::bitv::Bitv;
+    /// let mut bvec: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+    /// let expected: Bitv = vec![false, true].iter().map(|n| *n).collect();
+    /// bvec.truncate(2);
+    /// assert_eq!(bvec, expected);
+    /// ```
+    pub fn truncate(&mut self, len: uint) {
+        if len < self.len() {
+            self.nbits = len;
+            let word_len = (len + uint::BITS - 1) / uint::BITS;
+            self.storage.truncate(word_len);
+            if len % uint::BITS > 0 {
+                let mask = (1 << len % uint::BITS) - 1;
+                *self.storage.get_mut(word_len - 1) &= mask;
+            }
+        }
+    }
+
+    /// Grows the vector to be able to store `size` bits without resizing
+    pub fn reserve(&mut self, size: uint) {
+        let old_size = self.storage.len();
+        let size = (size + uint::BITS - 1) / uint::BITS;
+        if old_size < size {
+            self.storage.grow(size - old_size, &0);
+        }
+    }
+
+    /// Returns the capacity in bits for this bit vector. Inserting any
+    /// element less than this amount will not trigger a resizing.
+    #[inline]
+    pub fn capacity(&self) -> uint {
+        self.storage.len() * uint::BITS
     }
 
+    /// Grows the `Bitv` in-place.
+    ///
+    /// Adds `n` copies of `value` to the `Bitv`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use collections::bitv::Bitv;
+    /// let mut bvec: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+    /// bvec.grow(2, true);
+    /// assert_eq!(bvec, vec![false, true, true, false, true, true].iter().map(|n| *n).collect());
+    /// ```
+    pub fn grow(&mut self, n: uint, value: bool) {
+        let new_nbits = self.nbits + n;
+        let new_nwords = (new_nbits + uint::BITS - 1) / uint::BITS;
+        let full_value = if value { !0 } else { 0 };
+        // Correct the old tail word
+        let old_last_word = (self.nbits + uint::BITS - 1) / uint::BITS - 1;
+        if self.nbits % uint::BITS > 0 {
+            let overhang = self.nbits % uint::BITS; // # of already-used bits
+            let mask = !((1 << overhang) - 1);  // e.g. 5 unused bits => 111110....0
+            if value {
+                *self.storage.get_mut(old_last_word) |= mask;
+            } else {
+                *self.storage.get_mut(old_last_word) &= !mask;
+            }
+        }
+        // Fill in words after the old tail word
+        let stop_idx = cmp::min(self.storage.len(), new_nwords);
+        for idx in range(old_last_word + 1, stop_idx) {
+            *self.storage.get_mut(idx) = full_value;
+        }
+        // Allocate new words, if needed
+        if new_nwords > self.storage.len() {
+          let to_add = new_nwords - self.storage.len();
+          self.storage.grow(to_add, &full_value);
+        }
+        // Adjust internal bit count
+        self.nbits = new_nbits;
+    }
+
+    /// Shorten a `Bitv` by one, returning the removed element
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use collections::bitv::Bitv;
+    /// let mut bvec: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+    /// let expected: Bitv = vec![false, true, true].iter().map(|n| *n).collect();
+    /// let popped = bvec.pop();
+    /// assert_eq!(popped, false);
+    /// assert_eq!(bvec, expected);
+    /// ```
+    pub fn pop(&mut self) -> bool {
+        let ret = self.get(self.nbits - 1);
+        // If we are unusing a whole word, make sure it is zeroed out
+        if self.nbits % uint::BITS == 1 {
+            *self.storage.get_mut(self.nbits / uint::BITS) = 0;
+        }
+        self.nbits -= 1;
+        ret
+    }
+
+    /// Pushes a `bool` onto the `Bitv`
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use collections::bitv::Bitv;
+    /// let prototype: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+    /// let mut bvec: Bitv = vec![false, true].iter().map(|n| *n).collect();
+    /// bvec.push(true);
+    /// bvec.push(false);
+    /// assert_eq!(prototype, bvec);
+    /// ```
+    pub fn push(&mut self, elem: bool) {
+        let insert_pos = self.nbits;
+        self.nbits += 1;
+        if self.storage.len() * uint::BITS < self.nbits {
+            self.storage.push(0);
+        }
+        self.set(insert_pos, elem);
+    }
 }
 
 /**
@@ -544,28 +477,66 @@ pub fn from_bytes(bytes: &[u8]) -> Bitv {
     })
 }
 
-/**
- * Transform a `[bool]` into a `Bitv` by converting each `bool` into a bit.
- */
-pub fn from_bools(bools: &[bool]) -> Bitv {
-    from_fn(bools.len(), |i| bools[i])
-}
-
 /**
  * Create a `Bitv` of the specified length where the value at each
  * index is `f(index)`.
  */
 pub fn from_fn(len: uint, f: |index: uint| -> bool) -> Bitv {
-    let mut bitv = Bitv::new(len, false);
+    let mut bitv = Bitv::with_capacity(len, false);
     for i in range(0u, len) {
         bitv.set(i, f(i));
     }
     bitv
 }
 
-impl ops::Index<uint,bool> for Bitv {
-    fn index(&self, i: &uint) -> bool {
-        self.get(*i)
+impl Default for Bitv {
+    #[inline]
+    fn default() -> Bitv { Bitv::new() }
+}
+
+impl Collection for Bitv {
+    #[inline]
+    fn len(&self) -> uint { self.nbits }
+}
+
+impl Mutable for Bitv {
+    #[inline]
+    fn clear(&mut self) {
+        for w in self.storage.mut_iter() { *w = 0u; }
+    }
+}
+
+impl FromIterator<bool> for Bitv {
+    fn from_iter<I:Iterator<bool>>(iterator: I) -> Bitv {
+        let mut ret = Bitv::new();
+        ret.extend(iterator);
+        ret
+    }
+}
+
+impl Extendable<bool> for Bitv {
+    #[inline]
+    fn extend<I: Iterator<bool>>(&mut self, mut iterator: I) {
+        let (min, _) = iterator.size_hint();
+        let nbits = self.nbits;
+        self.reserve(nbits + min);
+        for element in iterator {
+            self.push(element)
+        }
+    }
+}
+
+impl Clone for Bitv {
+    #[inline]
+    fn clone(&self) -> Bitv {
+        Bitv { storage: self.storage.clone(), nbits: self.nbits }
+    }
+
+    #[inline]
+    fn clone_from(&mut self, source: &Bitv) {
+        self.nbits = source.nbits;
+        self.storage.reserve(source.storage.len());
+        for (i, w) in self.storage.mut_iter().enumerate() { *w = *source.storage.get(i); }
     }
 }
 
@@ -581,13 +552,8 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 impl<S: hash::Writer> hash::Hash<S> for Bitv {
     fn hash(&self, state: &mut S) {
         self.nbits.hash(state);
-        match self.rep {
-            Small(ref s) => (s.bits & small_mask(self.nbits)).hash(state),
-            Big(ref b) => {
-                for (i, ele) in b.storage.iter().enumerate() {
-                    (ele & big_mask(self.nbits, i)).hash(state);
-                }
-            }
+        for (_, elem) in self.mask_words(0) {
+            elem.hash(state);
         }
     }
 }
@@ -595,37 +561,15 @@ fn hash(&self, state: &mut S) {
 impl cmp::PartialEq for Bitv {
     #[inline]
     fn eq(&self, other: &Bitv) -> bool {
-        if self.nbits != other.nbits { return false; }
-        match self.rep {
-            Small(ref b) => match other.rep {
-                Small(ref b1) => b.equals(b1, self.nbits),
-                _ => false
-            },
-            Big(ref s) => match other.rep {
-                Big(ref s1) => s.equals(s1, self.nbits),
-                Small(_) => return false
-            }
+        if self.nbits != other.nbits {
+            return false;
         }
+        self.mask_words(0).zip(other.mask_words(0)).all(|((_, w1), (_, w2))| w1 == w2)
     }
 }
 
 impl cmp::Eq for Bitv {}
 
-#[inline]
-fn iterate_bits(base: uint, bits: uint, f: |uint| -> bool) -> bool {
-    if bits == 0 {
-        return true;
-    }
-    for i in range(0u, uint::BITS) {
-        if bits & (1 << i) != 0 {
-            if !f(base + i) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
 /// An iterator for `Bitv`.
 pub struct Bits<'a> {
     bitv: &'a Bitv,
@@ -687,15 +631,8 @@ fn idx(&mut self, index: uint) -> Option<bool> {
 /// It should also be noted that the amount of storage necessary for holding a
 /// set of objects is proportional to the maximum of the objects when viewed
 /// as a `uint`.
-#[deriving(Clone)]
-pub struct BitvSet {
-    size: uint,
-
-    // In theory this is a `Bitv` instead of always a `BigBitv`, but knowing that
-    // there's an array of storage makes our lives a whole lot easier when
-    // performing union/intersection/etc operations
-    bitv: BigBitv
-}
+#[deriving(Clone, PartialEq, Eq)]
+pub struct BitvSet(Bitv);
 
 impl Default for BitvSet {
     #[inline]
@@ -704,143 +641,168 @@ fn default() -> BitvSet { BitvSet::new() }
 
 impl BitvSet {
     /// Creates a new bit vector set with initially no contents
+    #[inline]
     pub fn new() -> BitvSet {
-        BitvSet{ size: 0, bitv: BigBitv::new(vec!(0)) }
+        BitvSet(Bitv::new())
+    }
+
+    /// Creates a new bit vector set with initially no contents, able to
+    /// hold `nbits` elements without resizing
+    #[inline]
+    pub fn with_capacity(nbits: uint) -> BitvSet {
+        BitvSet(Bitv::with_capacity(nbits, false))
     }
 
     /// Creates a new bit vector set from the given bit vector
+    #[inline]
     pub fn from_bitv(bitv: Bitv) -> BitvSet {
-        let mut size = 0;
-        bitv.ones(|_| {
-            size += 1;
-            true
-        });
-        let Bitv{rep, ..} = bitv;
-        match rep {
-            Big(b) => BitvSet{ size: size, bitv: b },
-            Small(SmallBitv{bits}) =>
-                BitvSet{ size: size, bitv: BigBitv{ storage: vec!(bits) } },
-        }
+        BitvSet(bitv)
     }
 
     /// Returns the capacity in bits for this bit vector. Inserting any
     /// element less than this amount will not trigger a resizing.
-    pub fn capacity(&self) -> uint { self.bitv.storage.len() * uint::BITS }
+    #[inline]
+    pub fn capacity(&self) -> uint {
+        let &BitvSet(ref bitv) = self;
+        bitv.capacity()
+    }
+
+    /// Grows the underlying vector to be able to store `size` bits
+    pub fn reserve(&mut self, size: uint) {
+        let &BitvSet(ref mut bitv) = self;
+        bitv.reserve(size)
+    }
 
     /// Consumes this set to return the underlying bit vector
+    #[inline]
     pub fn unwrap(self) -> Bitv {
-        let cap = self.capacity();
-        let BitvSet{bitv, ..} = self;
-        return Bitv{ nbits:cap, rep: Big(bitv) };
+        let BitvSet(bitv) = self;
+        bitv
+    }
+
+    /// Returns a reference to the underlying bit vector
+    #[inline]
+    pub fn get_ref<'a>(&'a self) -> &'a Bitv {
+        let &BitvSet(ref bitv) = self;
+        bitv
+    }
+
+    /// Returns a mutable reference to the underlying bit vector
+    #[inline]
+    pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut Bitv {
+        let &BitvSet(ref mut bitv) = self;
+        bitv
     }
 
     #[inline]
     fn other_op(&mut self, other: &BitvSet, f: |uint, uint| -> uint) {
-        fn nbits(mut w: uint) -> uint {
-            let mut bits = 0;
-            for _ in range(0u, uint::BITS) {
-                if w == 0 {
-                    break;
-                }
-                bits += w & 1;
-                w >>= 1;
-            }
-            return bits;
-        }
-        if self.capacity() < other.capacity() {
-            self.bitv.storage.grow(other.capacity() / uint::BITS, &0);
-        }
-        for (i, &w) in other.bitv.storage.iter().enumerate() {
-            let old = *self.bitv.storage.get(i);
+        // Unwrap Bitvs
+        let &BitvSet(ref mut self_bitv) = self;
+        let &BitvSet(ref other_bitv) = other;
+        // Expand the vector if necessary
+        self_bitv.reserve(other_bitv.capacity());
+        // Apply values
+        for (i, w) in other_bitv.mask_words(0) {
+            let old = *self_bitv.storage.get(i);
             let new = f(old, w);
-            *self.bitv.storage.get_mut(i) = new;
-            self.size += nbits(new) - nbits(old);
+            *self_bitv.storage.get_mut(i) = new;
         }
     }
 
+    #[inline]
+    /// Truncate the underlying vector to the least length required
+    pub fn shrink_to_fit(&mut self) {
+        let &BitvSet(ref mut bitv) = self;
+        // Obtain original length
+        let old_len = bitv.storage.len();
+        // Obtain coarse trailing zero length
+        let n = bitv.storage.iter().rev().take_while(|&&n| n == 0).count();
+        // Truncate
+        let trunc_len = cmp::max(old_len - n, 1);
+        bitv.storage.truncate(trunc_len);
+        bitv.nbits = trunc_len * uint::BITS;
+    }
+
     /// Union in-place with the specified other bit vector
+    #[inline]
     pub fn union_with(&mut self, other: &BitvSet) {
         self.other_op(other, |w1, w2| w1 | w2);
     }
 
     /// Intersect in-place with the specified other bit vector
+    #[inline]
     pub fn intersect_with(&mut self, other: &BitvSet) {
         self.other_op(other, |w1, w2| w1 & w2);
     }
 
     /// Difference in-place with the specified other bit vector
+    #[inline]
     pub fn difference_with(&mut self, other: &BitvSet) {
         self.other_op(other, |w1, w2| w1 & !w2);
     }
 
     /// Symmetric difference in-place with the specified other bit vector
+    #[inline]
     pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
         self.other_op(other, |w1, w2| w1 ^ w2);
     }
 
+    /// Iterator over each uint stored in the BitvSet
+    #[inline]
     pub fn iter<'a>(&'a self) -> BitPositions<'a> {
         BitPositions {set: self, next_idx: 0}
     }
 
-    pub fn difference(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
-        for (i, w1, w2) in self.commons(other) {
-            if !iterate_bits(i, w1 & !w2, |b| f(&b)) {
-                return false
-            }
-        };
-        /* everything we have that they don't also shows up */
-        self.outliers(other).advance(|(mine, i, w)|
-            !mine || iterate_bits(i, w, |b| f(&b))
-        )
-    }
-
-    pub fn symmetric_difference(&self, other: &BitvSet, f: |&uint| -> bool)
-                                -> bool {
-        for (i, w1, w2) in self.commons(other) {
-            if !iterate_bits(i, w1 ^ w2, |b| f(&b)) {
-                return false
-            }
-        };
-        self.outliers(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
-    }
-
-    pub fn intersection(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
-        self.commons(other).advance(|(i, w1, w2)| iterate_bits(i, w1 & w2, |b| f(&b)))
+    /// Iterator over each uint stored in the `self` setminus `other`
+    #[inline]
+    pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+        TwoBitPositions {
+            set: self,
+            other: other,
+            merge: |w1, w2| w1 & !w2,
+            current_word: 0,
+            next_idx: 0
+        }
     }
 
-    pub fn union(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
-        for (i, w1, w2) in self.commons(other) {
-            if !iterate_bits(i, w1 | w2, |b| f(&b)) {
-                return false
-            }
-        };
-        self.outliers(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
+    /// Iterator over each uint stored in the symmetric difference of `self` and `other`
+    #[inline]
+    pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+        TwoBitPositions {
+            set: self,
+            other: other,
+            merge: |w1, w2| w1 ^ w2,
+            current_word: 0,
+            next_idx: 0
+        }
     }
-}
 
-impl cmp::PartialEq for BitvSet {
-    fn eq(&self, other: &BitvSet) -> bool {
-        if self.size != other.size {
-            return false;
-        }
-        for (_, w1, w2) in self.commons(other) {
-            if w1 != w2 {
-                return false;
-            }
-        }
-        for (_, _, w) in self.outliers(other) {
-            if w != 0 {
-                return false;
-            }
+    /// Iterator over each uint stored in `self` intersect `other`
+    #[inline]
+    pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> {
+        let min = cmp::min(self.capacity(), other.capacity());
+        TwoBitPositions {
+            set: self,
+            other: other,
+            merge: |w1, w2| w1 & w2,
+            current_word: 0,
+            next_idx: 0
+        }.take(min)
+    }
+
+    /// Iterator over each uint stored in `self` union `other`
+    #[inline]
+    pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+        TwoBitPositions {
+            set: self,
+            other: other,
+            merge: |w1, w2| w1 | w2,
+            current_word: 0,
+            next_idx: 0
         }
-        return true;
     }
-
-    fn ne(&self, other: &BitvSet) -> bool { !self.eq(other) }
 }
 
-impl cmp::Eq for BitvSet {}
-
 impl fmt::Show for BitvSet {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(fmt, "{{"));
@@ -866,44 +828,45 @@ fn hash(&self, state: &mut S) {
 
 impl Collection for BitvSet {
     #[inline]
-    fn len(&self) -> uint { self.size }
+    fn len(&self) -> uint  {
+        let &BitvSet(ref bitv) = self;
+        bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones())
+    }
 }
 
 impl Mutable for BitvSet {
+    #[inline]
     fn clear(&mut self) {
-        self.bitv.each_storage(|w| { *w = 0; true });
-        self.size = 0;
+        let &BitvSet(ref mut bitv) = self;
+        bitv.clear();
     }
 }
 
 impl Set<uint> for BitvSet {
+    #[inline]
     fn contains(&self, value: &uint) -> bool {
-        *value < self.bitv.storage.len() * uint::BITS && self.bitv.get(*value)
+        let &BitvSet(ref bitv) = self;
+        *value < bitv.nbits && bitv.get(*value)
     }
 
+    #[inline]
     fn is_disjoint(&self, other: &BitvSet) -> bool {
-        self.intersection(other, |_| false)
+        self.intersection(other).count() > 0
     }
 
+    #[inline]
     fn is_subset(&self, other: &BitvSet) -> bool {
-        for (_, w1, w2) in self.commons(other) {
-            if w1 & w2 != w1 {
-                return false;
-            }
-        }
-        /* If anything is not ours, then everything is not ours so we're
-           definitely a subset in that case. Otherwise if there's any stray
-           ones that 'other' doesn't have, we're not a subset. */
-        for (mine, _, w) in self.outliers(other) {
-            if !mine {
-                return true;
-            } else if w != 0 {
-                return false;
-            }
-        }
-        return true;
+        let &BitvSet(ref self_bitv) = self;
+        let &BitvSet(ref other_bitv) = other;
+
+        // Check that `self` intersect `other` is self
+        self_bitv.mask_words(0).zip(other_bitv.mask_words(0))
+                               .all(|((_, w1), (_, w2))| w1 & w2 == w1) &&
+        // Check that `self` setminus `other` is empty
+        self_bitv.mask_words(other_bitv.storage.len()).all(|(_, w)| w == 0)
     }
 
+    #[inline]
     fn is_superset(&self, other: &BitvSet) -> bool {
         other.is_subset(self)
     }
@@ -914,14 +877,21 @@ fn insert(&mut self, value: uint) -> bool {
         if self.contains(&value) {
             return false;
         }
-        let nbits = self.capacity();
-        if value >= nbits {
-            let newsize = cmp::max(value, nbits * 2) / uint::BITS + 1;
-            assert!(newsize > self.bitv.storage.len());
-            self.bitv.storage.grow(newsize, &0);
+        if value >= self.capacity() {
+            let new_cap = cmp::max(value + 1, self.capacity() * 2);
+            self.reserve(new_cap);
+        }
+        let &BitvSet(ref mut bitv) = self;
+        if value >= bitv.nbits {
+            // If we are increasing nbits, make sure we mask out any previously-unconsidered bits
+            let old_rem = bitv.nbits % uint::BITS;
+            if old_rem != 0 {
+                let old_last_word = (bitv.nbits + uint::BITS - 1) / uint::BITS - 1;
+                *bitv.storage.get_mut(old_last_word) &= (1 << old_rem) - 1;
+            }
+            bitv.nbits = value + 1;
         }
-        self.size += 1;
-        self.bitv.set(value, true);
+        bitv.set(value, true);
         return true;
     }
 
@@ -929,66 +899,26 @@ fn remove(&mut self, value: &uint) -> bool {
         if !self.contains(value) {
             return false;
         }
-        self.size -= 1;
-        self.bitv.set(*value, false);
-
-        // Attempt to truncate our storage
-        let mut i = self.bitv.storage.len();
-        while i > 1 && *self.bitv.storage.get(i - 1) == 0 {
-            i -= 1;
-        }
-        self.bitv.storage.truncate(i);
-
+        let &BitvSet(ref mut bitv) = self;
+        bitv.set(*value, false);
         return true;
     }
 }
 
-impl BitvSet {
-    /// Visits each of the words that the two bit vectors (`self` and `other`)
-    /// both have in common. The three yielded arguments are (bit location,
-    /// w1, w2) where the bit location is the number of bits offset so far,
-    /// and w1/w2 are the words coming from the two vectors self, other.
-    fn commons<'a>(&'a self, other: &'a BitvSet)
-        -> Map<'static, ((uint, &'a uint), &'a Vec<uint>), (uint, uint, uint),
-               Zip<Enumerate<slice::Items<'a, uint>>, Repeat<&'a Vec<uint>>>> {
-        let min = cmp::min(self.bitv.storage.len(), other.bitv.storage.len());
-        self.bitv.storage.slice(0, min).iter().enumerate()
-            .zip(Repeat::new(&other.bitv.storage))
-            .map(|((i, &w), o_store)| (i * uint::BITS, w, *o_store.get(i)))
-    }
-
-    /// Visits each word in `self` or `other` that extends beyond the other. This
-    /// will only iterate through one of the vectors, and it only iterates
-    /// over the portion that doesn't overlap with the other one.
-    ///
-    /// The yielded arguments are a `bool`, the bit offset, and a word. The `bool`
-    /// is true if the word comes from `self`, and `false` if it comes from
-    /// `other`.
-    fn outliers<'a>(&'a self, other: &'a BitvSet)
-        -> Map<'static, ((uint, &'a uint), uint), (bool, uint, uint),
-               Zip<Enumerate<slice::Items<'a, uint>>, Repeat<uint>>> {
-        let slen = self.bitv.storage.len();
-        let olen = other.bitv.storage.len();
-
-        if olen < slen {
-            self.bitv.storage.slice_from(olen).iter().enumerate()
-                .zip(Repeat::new(olen))
-                .map(|((i, &w), min)| (true, (i + min) * uint::BITS, w))
-        } else {
-            other.bitv.storage.slice_from(slen).iter().enumerate()
-                .zip(Repeat::new(slen))
-                .map(|((i, &w), min)| (false, (i + min) * uint::BITS, w))
-        }
-    }
+pub struct BitPositions<'a> {
+    set: &'a BitvSet,
+    next_idx: uint
 }
 
-pub struct BitPositions<'a> {
+pub struct TwoBitPositions<'a> {
     set: &'a BitvSet,
+    other: &'a BitvSet,
+    merge: |uint, uint|: 'a -> uint,
+    current_word: uint,
     next_idx: uint
 }
 
 impl<'a> Iterator<uint> for BitPositions<'a> {
-    #[inline]
     fn next(&mut self) -> Option<uint> {
         while self.next_idx < self.set.capacity() {
             let idx = self.next_idx;
@@ -1002,11 +932,47 @@ fn next(&mut self) -> Option<uint> {
         return None;
     }
 
+    #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
         (0, Some(self.set.capacity() - self.next_idx))
     }
 }
 
+impl<'a> Iterator<uint> for TwoBitPositions<'a> {
+    fn next(&mut self) -> Option<uint> {
+        while self.next_idx < self.set.capacity() ||
+              self.next_idx < self.other.capacity() {
+            let bit_idx = self.next_idx % uint::BITS;
+            if bit_idx == 0 {
+                let &BitvSet(ref s_bitv) = self.set;
+                let &BitvSet(ref o_bitv) = self.other;
+                // Merging the two words is a bit of an awkward dance since
+                // one Bitv might be longer than the other
+                let word_idx = self.next_idx / uint::BITS;
+                let w1 = if word_idx < s_bitv.storage.len() {
+                             *s_bitv.storage.get(word_idx)
+                         } else { 0 };
+                let w2 = if word_idx < o_bitv.storage.len() {
+                             *o_bitv.storage.get(word_idx)
+                         } else { 0 };
+                self.current_word = (self.merge)(w1, w2);
+            }
+
+            self.next_idx += 1;
+            if self.current_word & (1 << bit_idx) != 0 {
+                return Some(self.next_idx - 1);
+            }
+        }
+        return None;
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let cap = cmp::max(self.set.capacity(), self.other.capacity());
+        (0, Some(cap - self.next_idx))
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use std::prelude::*;
@@ -1016,8 +982,7 @@ mod tests {
     use test::Bencher;
 
     use {Set, Mutable, MutableSet};
-    use bitv::{Bitv, SmallBitv, BigBitv, BitvSet, from_bools, from_fn,
-               from_bytes};
+    use bitv::{Bitv, BitvSet, from_fn, from_bytes};
     use bitv;
     use vec::Vec;
 
@@ -1025,34 +990,34 @@ mod tests {
 
     #[test]
     fn test_to_str() {
-        let zerolen = Bitv::new(0u, false);
-        assert_eq!(zerolen.to_str().as_slice(), "");
+        let zerolen = Bitv::new();
+        assert_eq!(zerolen.to_string().as_slice(), "");
 
-        let eightbits = Bitv::new(8u, false);
-        assert_eq!(eightbits.to_str().as_slice(), "00000000")
+        let eightbits = Bitv::with_capacity(8u, false);
+        assert_eq!(eightbits.to_string().as_slice(), "00000000")
     }
 
     #[test]
     fn test_0_elements() {
-        let act = Bitv::new(0u, false);
+        let act = Bitv::new();
         let exp = Vec::from_elem(0u, false);
         assert!(act.eq_vec(exp.as_slice()));
     }
 
     #[test]
     fn test_1_element() {
-        let mut act = Bitv::new(1u, false);
+        let mut act = Bitv::with_capacity(1u, false);
         assert!(act.eq_vec([false]));
-        act = Bitv::new(1u, true);
+        act = Bitv::with_capacity(1u, true);
         assert!(act.eq_vec([true]));
     }
 
     #[test]
     fn test_2_elements() {
-        let mut b = bitv::Bitv::new(2, false);
+        let mut b = bitv::Bitv::with_capacity(2, false);
         b.set(0, true);
         b.set(1, false);
-        assert_eq!(b.to_str().as_slice(), "10");
+        assert_eq!(b.to_string().as_slice(), "10");
     }
 
     #[test]
@@ -1060,16 +1025,16 @@ fn test_10_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::new(10u, false);
+        act = Bitv::with_capacity(10u, false);
         assert!((act.eq_vec(
                     [false, false, false, false, false, false, false, false, false, false])));
         // all 1
 
-        act = Bitv::new(10u, true);
+        act = Bitv::with_capacity(10u, true);
         assert!((act.eq_vec([true, true, true, true, true, true, true, true, true, true])));
         // mixed
 
-        act = Bitv::new(10u, false);
+        act = Bitv::with_capacity(10u, false);
         act.set(0u, true);
         act.set(1u, true);
         act.set(2u, true);
@@ -1078,7 +1043,7 @@ fn test_10_elements() {
         assert!((act.eq_vec([true, true, true, true, true, false, false, false, false, false])));
         // mixed
 
-        act = Bitv::new(10u, false);
+        act = Bitv::with_capacity(10u, false);
         act.set(5u, true);
         act.set(6u, true);
         act.set(7u, true);
@@ -1087,7 +1052,7 @@ fn test_10_elements() {
         assert!((act.eq_vec([false, false, false, false, false, true, true, true, true, true])));
         // mixed
 
-        act = Bitv::new(10u, false);
+        act = Bitv::with_capacity(10u, false);
         act.set(0u, true);
         act.set(3u, true);
         act.set(6u, true);
@@ -1100,21 +1065,21 @@ fn test_31_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         assert!(act.eq_vec(
                 [false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false]));
         // all 1
 
-        act = Bitv::new(31u, true);
+        act = Bitv::with_capacity(31u, true);
         assert!(act.eq_vec(
                 [true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true]));
         // mixed
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         act.set(0u, true);
         act.set(1u, true);
         act.set(2u, true);
@@ -1129,7 +1094,7 @@ fn test_31_elements() {
                 false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         act.set(16u, true);
         act.set(17u, true);
         act.set(18u, true);
@@ -1144,7 +1109,7 @@ fn test_31_elements() {
                 false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         act.set(24u, true);
         act.set(25u, true);
         act.set(26u, true);
@@ -1158,7 +1123,7 @@ fn test_31_elements() {
                 false, true, true, true, true, true, true, true]));
         // mixed
 
-        act = Bitv::new(31u, false);
+        act = Bitv::with_capacity(31u, false);
         act.set(3u, true);
         act.set(17u, true);
         act.set(30u, true);
@@ -1173,21 +1138,21 @@ fn test_32_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         assert!(act.eq_vec(
                 [false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false]));
         // all 1
 
-        act = Bitv::new(32u, true);
+        act = Bitv::with_capacity(32u, true);
         assert!(act.eq_vec(
                 [true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true]));
         // mixed
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         act.set(0u, true);
         act.set(1u, true);
         act.set(2u, true);
@@ -1202,7 +1167,7 @@ fn test_32_elements() {
                 false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         act.set(16u, true);
         act.set(17u, true);
         act.set(18u, true);
@@ -1217,7 +1182,7 @@ fn test_32_elements() {
                 false, false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         act.set(24u, true);
         act.set(25u, true);
         act.set(26u, true);
@@ -1232,7 +1197,7 @@ fn test_32_elements() {
                 false, true, true, true, true, true, true, true, true]));
         // mixed
 
-        act = Bitv::new(32u, false);
+        act = Bitv::with_capacity(32u, false);
         act.set(3u, true);
         act.set(17u, true);
         act.set(30u, true);
@@ -1248,21 +1213,21 @@ fn test_33_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         assert!(act.eq_vec(
                 [false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false, false, false, false,
                 false, false, false, false, false, false, false, false, false, false]));
         // all 1
 
-        act = Bitv::new(33u, true);
+        act = Bitv::with_capacity(33u, true);
         assert!(act.eq_vec(
                 [true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true, true, true, true, true, true, true, true, true, true,
                 true, true, true, true, true, true]));
         // mixed
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         act.set(0u, true);
         act.set(1u, true);
         act.set(2u, true);
@@ -1277,7 +1242,7 @@ fn test_33_elements() {
                 false, false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         act.set(16u, true);
         act.set(17u, true);
         act.set(18u, true);
@@ -1292,7 +1257,7 @@ fn test_33_elements() {
                 false, false, false, false, false, false, false, false, false]));
         // mixed
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         act.set(24u, true);
         act.set(25u, true);
         act.set(26u, true);
@@ -1307,7 +1272,7 @@ fn test_33_elements() {
                 false, true, true, true, true, true, true, true, true, false]));
         // mixed
 
-        act = Bitv::new(33u, false);
+        act = Bitv::with_capacity(33u, false);
         act.set(3u, true);
         act.set(17u, true);
         act.set(30u, true);
@@ -1321,24 +1286,24 @@ fn test_33_elements() {
 
     #[test]
     fn test_equal_differing_sizes() {
-        let v0 = Bitv::new(10u, false);
-        let v1 = Bitv::new(11u, false);
+        let v0 = Bitv::with_capacity(10u, false);
+        let v1 = Bitv::with_capacity(11u, false);
         assert!(v0 != v1);
     }
 
     #[test]
     fn test_equal_greatly_differing_sizes() {
-        let v0 = Bitv::new(10u, false);
-        let v1 = Bitv::new(110u, false);
+        let v0 = Bitv::with_capacity(10u, false);
+        let v1 = Bitv::with_capacity(110u, false);
         assert!(v0 != v1);
     }
 
     #[test]
     fn test_equal_sneaky_small() {
-        let mut a = bitv::Bitv::new(1, false);
+        let mut a = bitv::Bitv::with_capacity(1, false);
         a.set(0, true);
 
-        let mut b = bitv::Bitv::new(1, true);
+        let mut b = bitv::Bitv::with_capacity(1, true);
         b.set(0, true);
 
         assert_eq!(a, b);
@@ -1346,12 +1311,12 @@ fn test_equal_sneaky_small() {
 
     #[test]
     fn test_equal_sneaky_big() {
-        let mut a = bitv::Bitv::new(100, false);
+        let mut a = bitv::Bitv::with_capacity(100, false);
         for i in range(0u, 100) {
             a.set(i, true);
         }
 
-        let mut b = bitv::Bitv::new(100, true);
+        let mut b = bitv::Bitv::with_capacity(100, true);
         for i in range(0u, 100) {
             b.set(i, true);
         }
@@ -1363,16 +1328,16 @@ fn test_equal_sneaky_big() {
     fn test_from_bytes() {
         let bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
         let str = format!("{}{}{}", "10110110", "00000000", "11111111");
-        assert_eq!(bitv.to_str().as_slice(), str.as_slice());
+        assert_eq!(bitv.to_string().as_slice(), str.as_slice());
     }
 
     #[test]
     fn test_to_bytes() {
-        let mut bv = Bitv::new(3, true);
+        let mut bv = Bitv::with_capacity(3, true);
         bv.set(1, false);
         assert_eq!(bv.to_bytes(), vec!(0b10100000));
 
-        let mut bv = Bitv::new(9, false);
+        let mut bv = Bitv::with_capacity(9, false);
         bv.set(2, true);
         bv.set(8, true);
         assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
@@ -1380,20 +1345,21 @@ fn test_to_bytes() {
 
     #[test]
     fn test_from_bools() {
-        assert!(from_bools([true, false, true, true]).to_str().as_slice() ==
-                "1011");
+        let bools = vec![true, false, true, true];
+        let bitv: Bitv = bools.iter().map(|n| *n).collect();
+        assert_eq!(bitv.to_string().as_slice(), "1011");
     }
 
     #[test]
     fn test_to_bools() {
         let bools = vec!(false, false, true, false, false, true, true, false);
-        assert_eq!(from_bytes([0b00100110]).to_bools(), bools);
+        assert_eq!(from_bytes([0b00100110]).iter().collect::<Vec<bool>>(), bools);
     }
 
     #[test]
     fn test_bitv_iterator() {
         let bools = [true, false, true, true];
-        let bitv = from_bools(bools);
+        let bitv: Bitv = bools.iter().map(|n| *n).collect();
 
         for (act, &ex) in bitv.iter().zip(bools.iter()) {
             assert_eq!(ex, act);
@@ -1403,7 +1369,7 @@ fn test_bitv_iterator() {
     #[test]
     fn test_bitv_set_iterator() {
         let bools = [true, false, true, true];
-        let bitv = BitvSet::from_bitv(from_bools(bools));
+        let bitv = BitvSet::from_bitv(bools.iter().map(|n| *n).collect());
 
         let idxs: Vec<uint> = bitv.iter().collect();
         assert_eq!(idxs, vec!(0, 2, 3));
@@ -1415,7 +1381,7 @@ fn test_bitv_set_frombitv_init() {
         let lengths = [10, 64, 100];
         for &b in bools.iter() {
             for &l in lengths.iter() {
-                let bitset = BitvSet::from_bitv(Bitv::new(l, b));
+                let bitset = BitvSet::from_bitv(Bitv::with_capacity(l, b));
                 assert_eq!(bitset.contains(&1u), b)
                 assert_eq!(bitset.contains(&(l-1u)), b)
                 assert!(!bitset.contains(&l))
@@ -1425,60 +1391,80 @@ fn test_bitv_set_frombitv_init() {
 
     #[test]
     fn test_small_difference() {
-        let mut b1 = Bitv::new(3, false);
-        let mut b2 = Bitv::new(3, false);
+        let mut b1 = Bitv::with_capacity(3, false);
+        let mut b2 = Bitv::with_capacity(3, false);
         b1.set(0, true);
         b1.set(1, true);
         b2.set(1, true);
         b2.set(2, true);
         assert!(b1.difference(&b2));
-        assert!(b1[0]);
-        assert!(!b1[1]);
-        assert!(!b1[2]);
+        assert!(b1.get(0));
+        assert!(!b1.get(1));
+        assert!(!b1.get(2));
     }
 
     #[test]
     fn test_big_difference() {
-        let mut b1 = Bitv::new(100, false);
-        let mut b2 = Bitv::new(100, false);
+        let mut b1 = Bitv::with_capacity(100, false);
+        let mut b2 = Bitv::with_capacity(100, false);
         b1.set(0, true);
         b1.set(40, true);
         b2.set(40, true);
         b2.set(80, true);
         assert!(b1.difference(&b2));
-        assert!(b1[0]);
-        assert!(!b1[40]);
-        assert!(!b1[80]);
+        assert!(b1.get(0));
+        assert!(!b1.get(40));
+        assert!(!b1.get(80));
     }
 
     #[test]
     fn test_small_clear() {
-        let mut b = Bitv::new(14, true);
+        let mut b = Bitv::with_capacity(14, true);
         b.clear();
-        b.ones(|i| {
-            fail!("found 1 at {:?}", i)
-        });
+        assert!(b.none());
     }
 
     #[test]
     fn test_big_clear() {
-        let mut b = Bitv::new(140, true);
+        let mut b = Bitv::with_capacity(140, true);
         b.clear();
-        b.ones(|i| {
-            fail!("found 1 at {:?}", i)
-        });
+        assert!(b.none());
+    }
+
+    #[test]
+    fn test_bitv_masking() {
+        let b = Bitv::with_capacity(140, true);
+        let mut bs = BitvSet::from_bitv(b);
+        assert!(bs.contains(&139));
+        assert!(!bs.contains(&140));
+        assert!(bs.insert(150));
+        assert!(!bs.contains(&140));
+        assert!(!bs.contains(&149));
+        assert!(bs.contains(&150));
+        assert!(!bs.contains(&151));
     }
 
     #[test]
     fn test_bitv_set_basic() {
+        // calculate nbits with uint::BITS granularity
+        fn calc_nbits(bits: uint) -> uint {
+            uint::BITS * ((bits + uint::BITS - 1) / uint::BITS)
+        }
+
         let mut b = BitvSet::new();
+        assert_eq!(b.capacity(), calc_nbits(0));
         assert!(b.insert(3));
+        assert_eq!(b.capacity(), calc_nbits(3));
         assert!(!b.insert(3));
         assert!(b.contains(&3));
+        assert!(b.insert(4));
+        assert!(!b.insert(4));
+        assert!(b.contains(&3));
         assert!(b.insert(400));
+        assert_eq!(b.capacity(), calc_nbits(400));
         assert!(!b.insert(400));
         assert!(b.contains(&400));
-        assert_eq!(b.len(), 2);
+        assert_eq!(b.len(), 3);
     }
 
     #[test]
@@ -1499,14 +1485,9 @@ fn test_bitv_set_intersection() {
         assert!(b.insert(5));
         assert!(b.insert(3));
 
-        let mut i = 0;
         let expected = [3, 5, 11, 77];
-        a.intersection(&b, |x| {
-            assert_eq!(*x, expected[i]);
-            i += 1;
-            true
-        });
-        assert_eq!(i, expected.len());
+        let actual = a.intersection(&b).collect::<Vec<uint>>();
+        assert_eq!(actual.as_slice(), expected.as_slice());
     }
 
     #[test]
@@ -1523,14 +1504,9 @@ fn test_bitv_set_difference() {
         assert!(b.insert(3));
         assert!(b.insert(200));
 
-        let mut i = 0;
         let expected = [1, 5, 500];
-        a.difference(&b, |x| {
-            assert_eq!(*x, expected[i]);
-            i += 1;
-            true
-        });
-        assert_eq!(i, expected.len());
+        let actual = a.difference(&b).collect::<Vec<uint>>();
+        assert_eq!(actual.as_slice(), expected.as_slice());
     }
 
     #[test]
@@ -1549,14 +1525,9 @@ fn test_bitv_set_symmetric_difference() {
         assert!(b.insert(14));
         assert!(b.insert(220));
 
-        let mut i = 0;
         let expected = [1, 5, 11, 14, 220];
-        a.symmetric_difference(&b, |x| {
-            assert_eq!(*x, expected[i]);
-            i += 1;
-            true
-        });
-        assert_eq!(i, expected.len());
+        let actual = a.symmetric_difference(&b).collect::<Vec<uint>>();
+        assert_eq!(actual.as_slice(), expected.as_slice());
     }
 
     #[test]
@@ -1578,14 +1549,35 @@ fn test_bitv_set_union() {
         assert!(b.insert(13));
         assert!(b.insert(19));
 
-        let mut i = 0;
         let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160];
-        a.union(&b, |x| {
-            assert_eq!(*x, expected[i]);
-            i += 1;
-            true
-        });
-        assert_eq!(i, expected.len());
+        let actual = a.union(&b).collect::<Vec<uint>>();
+        assert_eq!(actual.as_slice(), expected.as_slice());
+    }
+
+    #[test]
+    fn test_bitv_set_subset() {
+        let mut set1 = BitvSet::new();
+        let mut set2 = BitvSet::new();
+
+        assert!(set1.is_subset(&set2)); //  {}  {}
+        set2.insert(100);
+        assert!(set1.is_subset(&set2)); //  {}  { 1 }
+        set2.insert(200);
+        assert!(set1.is_subset(&set2)); //  {}  { 1, 2 }
+        set1.insert(200);
+        assert!(set1.is_subset(&set2)); //  { 2 }  { 1, 2 }
+        set1.insert(300);
+        assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 1, 2 }
+        set2.insert(300);
+        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3 }
+        set2.insert(400);
+        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3, 4 }
+        set2.remove(&100);
+        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 2, 3, 4 }
+        set2.remove(&300);
+        assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 2, 4 }
+        set1.remove(&300);
+        assert!(set1.is_subset(&set2)); // { 2 }  { 2, 4 }
     }
 
     #[test]
@@ -1600,6 +1592,7 @@ fn test_bitv_remove() {
 
         assert!(a.insert(1000));
         assert!(a.remove(&1000));
+        a.shrink_to_fit();
         assert_eq!(a.capacity(), uint::BITS);
     }
 
@@ -1667,6 +1660,97 @@ fn test_big_bitv_tests() {
         assert!(!v.none());
     }
 
+    #[test]
+    fn test_bitv_push_pop() {
+        let mut s = Bitv::with_capacity(5 * uint::BITS - 2, false);
+        assert_eq!(s.len(), 5 * uint::BITS - 2);
+        assert_eq!(s.get(5 * uint::BITS - 3), false);
+        s.push(true);
+        s.push(true);
+        assert_eq!(s.get(5 * uint::BITS - 2), true);
+        assert_eq!(s.get(5 * uint::BITS - 1), true);
+        // Here the internal vector will need to be extended
+        s.push(false);
+        assert_eq!(s.get(5 * uint::BITS), false);
+        s.push(false);
+        assert_eq!(s.get(5 * uint::BITS + 1), false);
+        assert_eq!(s.len(), 5 * uint::BITS + 2);
+        // Pop it all off
+        assert_eq!(s.pop(), false);
+        assert_eq!(s.pop(), false);
+        assert_eq!(s.pop(), true);
+        assert_eq!(s.pop(), true);
+        assert_eq!(s.len(), 5 * uint::BITS - 2);
+    }
+
+    #[test]
+    fn test_bitv_truncate() {
+        let mut s = Bitv::with_capacity(5 * uint::BITS, true);
+
+        assert_eq!(s, Bitv::with_capacity(5 * uint::BITS, true));
+        assert_eq!(s.len(), 5 * uint::BITS);
+        s.truncate(4 * uint::BITS);
+        assert_eq!(s, Bitv::with_capacity(4 * uint::BITS, true));
+        assert_eq!(s.len(), 4 * uint::BITS);
+        // Truncating to a size > s.len() should be a noop
+        s.truncate(5 * uint::BITS);
+        assert_eq!(s, Bitv::with_capacity(4 * uint::BITS, true));
+        assert_eq!(s.len(), 4 * uint::BITS);
+        s.truncate(3 * uint::BITS - 10);
+        assert_eq!(s, Bitv::with_capacity(3 * uint::BITS - 10, true));
+        assert_eq!(s.len(), 3 * uint::BITS - 10);
+        s.truncate(0);
+        assert_eq!(s, Bitv::with_capacity(0, true));
+        assert_eq!(s.len(), 0);
+    }
+
+    #[test]
+    fn test_bitv_reserve() {
+        let mut s = Bitv::with_capacity(5 * uint::BITS, true);
+        // Check capacity
+        assert_eq!(s.capacity(), 5 * uint::BITS);
+        s.reserve(2 * uint::BITS);
+        assert_eq!(s.capacity(), 5 * uint::BITS);
+        s.reserve(7 * uint::BITS);
+        assert_eq!(s.capacity(), 7 * uint::BITS);
+        s.reserve(7 * uint::BITS);
+        assert_eq!(s.capacity(), 7 * uint::BITS);
+        s.reserve(7 * uint::BITS + 1);
+        assert_eq!(s.capacity(), 8 * uint::BITS);
+        // Check that length hasn't changed
+        assert_eq!(s.len(), 5 * uint::BITS);
+        s.push(true);
+        s.push(false);
+        s.push(true);
+        assert_eq!(s.get(5 * uint::BITS - 1), true);
+        assert_eq!(s.get(5 * uint::BITS - 0), true);
+        assert_eq!(s.get(5 * uint::BITS + 1), false);
+        assert_eq!(s.get(5 * uint::BITS + 2), true);
+    }
+
+    #[test]
+    fn test_bitv_grow() {
+        let mut bitv = from_bytes([0b10110110, 0b00000000, 0b10101010]);
+        bitv.grow(32, true);
+        assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+                                     0xFF, 0xFF, 0xFF, 0xFF]));
+        bitv.grow(64, false);
+        assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+                                     0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
+        bitv.grow(16, true);
+        assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+                                     0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
+    }
+
+    #[test]
+    fn test_bitv_extend() {
+        let mut bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
+        let ext = from_bytes([0b01001001, 0b10010010, 0b10111101]);
+        bitv.extend(ext.iter());
+        assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b11111111,
+                                     0b01001001, 0b10010010, 0b10111101]));
+    }
+
     #[test]
     fn test_bitv_set_show() {
         let mut s = BitvSet::new();
@@ -1674,7 +1758,7 @@ fn test_bitv_set_show() {
         s.insert(10);
         s.insert(50);
         s.insert(2);
-        assert_eq!("{1, 2, 10, 50}".to_string(), s.to_str());
+        assert_eq!("{1, 2, 10, 50}".to_string(), s.to_string());
     }
 
     fn rng() -> rand::IsaacRng {
@@ -1692,42 +1776,10 @@ fn bench_uint_small(b: &mut Bencher) {
         })
     }
 
-    #[bench]
-    fn bench_small_bitv_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bitv = SmallBitv::new(uint::BITS);
-        b.iter(|| {
-            bitv.set((r.next_u32() as uint) % uint::BITS, true);
-            &bitv
-        })
-    }
-
-    #[bench]
-    fn bench_big_bitv_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bitv = BigBitv::new(vec!(0));
-        b.iter(|| {
-            bitv.set((r.next_u32() as uint) % uint::BITS, true);
-            &bitv
-        })
-    }
-
-    #[bench]
-    fn bench_big_bitv_big(b: &mut Bencher) {
-        let mut r = rng();
-        let mut storage = vec!();
-        storage.grow(BENCH_BITS / uint::BITS, &0u);
-        let mut bitv = BigBitv::new(storage);
-        b.iter(|| {
-            bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
-            &bitv
-        })
-    }
-
     #[bench]
     fn bench_bitv_big(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::new(BENCH_BITS, false);
+        let mut bitv = Bitv::with_capacity(BENCH_BITS, false);
         b.iter(|| {
             bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
             &bitv
@@ -1737,7 +1789,7 @@ fn bench_bitv_big(b: &mut Bencher) {
     #[bench]
     fn bench_bitv_small(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::new(uint::BITS, false);
+        let mut bitv = Bitv::with_capacity(uint::BITS, false);
         b.iter(|| {
             bitv.set((r.next_u32() as uint) % uint::BITS, true);
             &bitv
@@ -1766,8 +1818,8 @@ fn bench_bitv_set_big(b: &mut Bencher) {
 
     #[bench]
     fn bench_bitv_big_union(b: &mut Bencher) {
-        let mut b1 = Bitv::new(BENCH_BITS, false);
-        let b2 = Bitv::new(BENCH_BITS, false);
+        let mut b1 = Bitv::with_capacity(BENCH_BITS, false);
+        let b2 = Bitv::with_capacity(BENCH_BITS, false);
         b.iter(|| {
             b1.union(&b2);
         })
@@ -1775,7 +1827,7 @@ fn bench_bitv_big_union(b: &mut Bencher) {
 
     #[bench]
     fn bench_btv_small_iter(b: &mut Bencher) {
-        let bitv = Bitv::new(uint::BITS, false);
+        let bitv = Bitv::with_capacity(uint::BITS, false);
         b.iter(|| {
             let mut _sum = 0;
             for pres in bitv.iter() {
@@ -1786,7 +1838,7 @@ fn bench_btv_small_iter(b: &mut Bencher) {
 
     #[bench]
     fn bench_bitv_big_iter(b: &mut Bencher) {
-        let bitv = Bitv::new(BENCH_BITS, false);
+        let bitv = Bitv::with_capacity(BENCH_BITS, false);
         b.iter(|| {
             let mut _sum = 0;
             for pres in bitv.iter() {
index 92abfaad3483301016fa4449e51221967446f2c9..6ee68f74438fecc08460858d83abdcb1ea589310 100644 (file)
@@ -20,7 +20,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::fmt;
 use core::fmt::Show;
 
@@ -787,7 +787,6 @@ mod test_btree {
     fn insert_test_one() {
         let b = BTree::new(1i, "abc".to_string(), 2);
         let is_insert = b.insert(2i, "xyz".to_string());
-        //println!("{}", is_insert.clone().to_str());
         assert!(is_insert.root.is_leaf());
     }
 
@@ -798,7 +797,7 @@ fn insert_test_two() {
         let leaf_elt_3 = LeafElt::new(3i, "ccc".to_string());
         let n = Node::new_leaf(vec!(leaf_elt_1, leaf_elt_2, leaf_elt_3));
         let b = BTree::new_with_node_len(n, 3, 2);
-        //println!("{}", b.clone().insert(4, "ddd".to_string()).to_str());
+        //println!("{}", b.clone().insert(4, "ddd".to_string()).to_string());
         assert!(b.insert(4, "ddd".to_string()).root.is_leaf());
     }
 
@@ -810,7 +809,7 @@ fn insert_test_three() {
         let leaf_elt_4 = LeafElt::new(4i, "ddd".to_string());
         let n = Node::new_leaf(vec!(leaf_elt_1, leaf_elt_2, leaf_elt_3, leaf_elt_4));
         let b = BTree::new_with_node_len(n, 3, 2);
-        //println!("{}", b.clone().insert(5, "eee".to_string()).to_str());
+        //println!("{}", b.clone().insert(5, "eee".to_string()).to_string());
         assert!(!b.insert(5, "eee".to_string()).root.is_leaf());
     }
 
@@ -827,7 +826,7 @@ fn insert_test_four() {
         b = b.clone().insert(7, "ggg".to_string());
         b = b.clone().insert(8, "hhh".to_string());
         b = b.clone().insert(0, "omg".to_string());
-        //println!("{}", b.clone().to_str());
+        //println!("{}", b.clone().to_string());
         assert!(!b.root.is_leaf());
     }
 
@@ -905,11 +904,11 @@ fn btree_cmp_test_greater() {
         assert!(&b2.cmp(&b) == &Greater)
     }
 
-    //Tests the BTree's to_str() method.
+    //Tests the BTree's to_string() method.
     #[test]
     fn btree_tostr_test() {
         let b = BTree::new(1i, "abc".to_string(), 2);
-        assert_eq!(b.to_str(), "Key: 1, value: abc;".to_string())
+        assert_eq!(b.to_string(), "Key: 1, value: abc;".to_string())
     }
 
 }
index 4114c8cb1c4ddc8b7a5a489de9ea5ee1f7a8c518..226dd5a2356c93415db75bc49d2aa0b7d6a7b22c 100644 (file)
@@ -23,7 +23,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::default::Default;
 use core::fmt;
 use core::iter;
@@ -1041,12 +1041,12 @@ fn test_fuzz() {
     #[test]
     fn test_show() {
         let list: DList<int> = range(0i, 10).collect();
-        assert!(list.to_str().as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+        assert!(list.to_string().as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
 
         let list: DList<&str> = vec!["just", "one", "test", "more"].iter()
                                                                    .map(|&s| s)
                                                                    .collect();
-        assert!(list.to_str().as_slice() == "[just, one, test, more]");
+        assert!(list.to_string().as_slice() == "[just, one, test, more]");
     }
 
     #[cfg(test)]
index e3d1c9a3216bc8252c7110d079b5b6b6f7ff2799..357383207150ea047c70ca8989eadc453f40a171 100644 (file)
@@ -65,7 +65,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use alloc::rc::Rc;
 use core::intrinsics::TypeId;
 use core::mem;
index 4fd98538af7ddc93068901d28b657698a6d20f05..1c7e03f70c8896531a6c4b6bea254f6d06faff85 100644 (file)
@@ -269,7 +269,7 @@ pub fn hash_with_keys<T: Hash<SipState>>(k0: u64, k1: u64, value: &T) -> u64 {
 mod tests {
     use test::Bencher;
     use std::prelude::*;
-    use std::num::ToStrRadix;
+    use std::fmt;
 
     use str::Str;
     use string::String;
@@ -370,7 +370,7 @@ fn test_siphash() {
         fn to_hex_str(r: &[u8, ..8]) -> String {
             let mut s = String::new();
             for b in r.iter() {
-                s.push_str((*b as uint).to_str_radix(16u).as_slice());
+                s.push_str(format!("{}", fmt::radix(*b, 16)).as_slice());
             }
             s
         }
@@ -391,7 +391,7 @@ fn result_str(h: u64) -> String {
             let r = result_bytes(h);
             let mut s = String::new();
             for b in r.iter() {
-                s.push_str((*b as uint).to_str_radix(16u).as_slice());
+                s.push_str(format!("{}", fmt::radix(*b, 16)).as_slice());
             }
             s
         }
index c698b35c84811db2176daa87733a8394d99daafd..06ec2588ac332d96acb88afa7938469149078da4 100644 (file)
  * Collection types.
  */
 
-#![crate_id = "collections#0.11.0"]
+#![crate_name = "collections"]
 #![experimental]
 #![crate_type = "rlib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
@@ -26,6 +26,7 @@
 #![no_std]
 
 #[phase(plugin, link)] extern crate core;
+extern crate unicode;
 extern crate alloc;
 
 #[cfg(test)] extern crate native;
@@ -67,9 +68,6 @@
 pub mod vec;
 pub mod hash;
 
-// Internal unicode fiddly bits for the str module
-mod unicode;
-
 mod deque;
 
 /// A trait to represent mutable containers
index 14e41f3fef96546a257d531eb429e91e3b46e37e..ca62b1235d5549e01a6f3b6ed0fc522149a1ce71 100644 (file)
@@ -491,7 +491,7 @@ fn test_show() {
         map.insert(1, 2i);
         map.insert(3, 4i);
 
-        let map_str = map.to_str();
+        let map_str = map.to_string();
         let map_str = map_str.as_slice();
         assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
         assert_eq!(format!("{}", empty), "{}".to_string());
index ddba4b34e3a2a4e8a5664f54b61d95e08ffeb943..19db88453809fc9fe46145b71913d676d2c5a863 100644 (file)
@@ -69,7 +69,6 @@ fn main() {
 
 use core::prelude::*;
 
-use core::char;
 use core::default::Default;
 use core::fmt;
 use core::cmp;
@@ -79,15 +78,17 @@ fn main() {
 use Collection;
 use hash;
 use string::String;
+use unicode;
 use vec::Vec;
 
 pub use core::str::{from_utf8, CharEq, Chars, CharOffsets};
 pub use core::str::{Bytes, CharSplits};
-pub use core::str::{CharSplitsN, Words, AnyLines, MatchIndices, StrSplits};
+pub use core::str::{CharSplitsN, AnyLines, MatchIndices, StrSplits};
 pub use core::str::{eq_slice, is_utf8, is_utf16, Utf16Items};
 pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items};
 pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange};
 pub use core::str::{Str, StrSlice};
+pub use unicode::{Words, UnicodeStrSlice};
 
 /*
 Section: Creating a string
@@ -283,7 +284,7 @@ pub struct Decompositions<'a> {
 impl<'a> Iterator<char> for Decompositions<'a> {
     #[inline]
     fn next(&mut self) -> Option<char> {
-        use unicode::normalization::canonical_combining_class;
+        use unicode::canonical_combining_class;
 
         match self.buffer.as_slice().head() {
             Some(&(c, 0)) => {
@@ -299,8 +300,8 @@ fn next(&mut self) -> Option<char> {
         }
 
         let decomposer = match self.kind {
-            Canonical => char::decompose_canonical,
-            Compatible => char::decompose_compatible
+            Canonical => unicode::char::decompose_canonical,
+            Compatible => unicode::char::decompose_compatible
         };
 
         if !self.sorted {
@@ -351,6 +352,15 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 /// # Return value
 ///
 /// The original string with all occurrences of `from` replaced with `to`
+///
+/// # Example
+///
+/// ```rust
+/// use std::str;
+/// let string = "orange";
+/// let new_string = str::replace(string, "or", "str");
+/// assert_eq!(new_string.as_slice(), "strange");
+/// ```
 pub fn replace(s: &str, from: &str, to: &str) -> String {
     let mut result = String::new();
     let mut last_end = 0;
@@ -572,6 +582,14 @@ pub enum MaybeOwned<'a> {
 
 impl<'a> MaybeOwned<'a> {
     /// Returns `true` if this `MaybeOwned` wraps an owned string
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let string = String::from_str("orange");
+    /// let maybe_owned_string = string.into_maybe_owned();
+    /// assert_eq!(true, maybe_owned_string.is_owned());
+    /// ```
     #[inline]
     pub fn is_owned(&self) -> bool {
         match *self {
@@ -581,6 +599,14 @@ pub fn is_owned(&self) -> bool {
     }
 
     /// Returns `true` if this `MaybeOwned` wraps a borrowed string
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let string = "orange";
+    /// let maybe_owned_string = string.as_slice().into_maybe_owned();
+    /// assert_eq!(true, maybe_owned_string.is_slice());
+    /// ```
     #[inline]
     pub fn is_slice(&self) -> bool {
         match *self {
@@ -596,6 +622,13 @@ pub trait IntoMaybeOwned<'a> {
     fn into_maybe_owned(self) -> MaybeOwned<'a>;
 }
 
+/// # Example
+///
+/// ```rust
+/// let owned_string = String::from_str("orange");
+/// let maybe_owned_string = owned_string.into_maybe_owned();
+/// assert_eq!(true, maybe_owned_string.is_owned());
+/// ```
 impl<'a> IntoMaybeOwned<'a> for String {
     #[inline]
     fn into_maybe_owned(self) -> MaybeOwned<'a> {
@@ -603,11 +636,26 @@ fn into_maybe_owned(self) -> MaybeOwned<'a> {
     }
 }
 
+/// # Example
+///
+/// ```rust
+/// let string = "orange";
+/// let maybe_owned_str = string.as_slice().into_maybe_owned();
+/// assert_eq!(false, maybe_owned_str.is_owned());
+/// ```
 impl<'a> IntoMaybeOwned<'a> for &'a str {
     #[inline]
     fn into_maybe_owned(self) -> MaybeOwned<'a> { Slice(self) }
 }
 
+/// # Example
+///
+/// ```rust
+/// let str = "orange";
+/// let maybe_owned_str = str.as_slice().into_maybe_owned();
+/// let maybe_maybe_owned_str = maybe_owned_str.into_maybe_owned();
+/// assert_eq!(false, maybe_maybe_owned_str.is_owned());
+/// ```
 impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> {
     #[inline]
     fn into_maybe_owned(self) -> MaybeOwned<'a> { self }
@@ -657,7 +705,7 @@ impl<'a> StrAllocating for MaybeOwned<'a> {
     #[inline]
     fn into_string(self) -> String {
         match self {
-            Slice(s) => s.to_string(),
+            Slice(s) => String::from_str(s),
             Owned(s) => s
         }
     }
@@ -673,7 +721,7 @@ impl<'a> Clone for MaybeOwned<'a> {
     fn clone(&self) -> MaybeOwned<'a> {
         match *self {
             Slice(s) => Slice(s),
-            Owned(ref s) => Owned(s.to_string())
+            Owned(ref s) => Owned(String::from_str(s.as_slice()))
         }
     }
 }
@@ -762,7 +810,7 @@ fn test_from_buf_len() {
             let a = vec![65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
             let b = a.as_ptr();
             let c = from_buf_len(b, 3u);
-            assert_eq!(c, "AAA".to_string());
+            assert_eq!(c, String::from_str("AAA"));
         }
     }
 }
@@ -776,12 +824,6 @@ pub trait StrAllocating: Str {
     /// Convert `self` into a `String`, not making a copy if possible.
     fn into_string(self) -> String;
 
-    /// Convert `self` into a `String`.
-    #[inline]
-    fn to_string(&self) -> String {
-        String::from_str(self.as_slice())
-    }
-
     #[allow(missing_doc)]
     #[deprecated = "replaced by .into_string()"]
     fn into_owned(self) -> String {
@@ -933,7 +975,7 @@ fn nfkd_chars<'a>(&'a self) -> Decompositions<'a> {
 impl<'a> StrAllocating for &'a str {
     #[inline]
     fn into_string(self) -> String {
-        self.to_string()
+        String::from_str(self)
     }
 }
 
@@ -963,14 +1005,24 @@ fn append(mut self, rhs: &str) -> String {
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::*;
     use std::iter::AdditiveIterator;
     use std::default::Default;
+    use std::char::Char;
+    use std::clone::Clone;
+    use std::cmp::{Equal, Greater, Less, Ord, Eq, PartialOrd, PartialEq, Equiv};
+    use std::result::{Ok, Err};
+    use std::option::{Some, None};
+    use std::ptr::RawPtr;
+    use std::iter::{Iterator, DoubleEndedIterator};
+    use Collection;
 
-    use str::*;
+    use super::*;
+    use std::slice::{Vector, ImmutableVector};
     use string::String;
     use vec::Vec;
 
+    use unicode::UnicodeChar;
+
     #[test]
     fn test_eq_slice() {
         assert!((eq_slice("foobar".slice(0, 3), "foo")));
@@ -1028,17 +1080,17 @@ fn test_rfind() {
 
     #[test]
     fn test_collect() {
-        let empty = "".to_string();
+        let empty = String::from_str("");
         let s: String = empty.as_slice().chars().collect();
         assert_eq!(empty, s);
-        let data = "ประเทศไทย中".to_string();
+        let data = String::from_str("ประเทศไทย中");
         let s: String = data.as_slice().chars().collect();
         assert_eq!(data, s);
     }
 
     #[test]
     fn test_into_bytes() {
-        let data = "asdf".to_string();
+        let data = String::from_str("asdf");
         let buf = data.into_bytes();
         assert_eq!(b"asdf", buf.as_slice());
     }
@@ -1055,7 +1107,7 @@ fn test_find_str() {
         assert!(data.slice(2u, 4u).find_str("ab").is_none());
 
         let string = "ประเทศไทย中华Việt Nam";
-        let mut data = string.to_string();
+        let mut data = String::from_str(string);
         data.push_str(string);
         assert!(data.as_slice().find_str("ไท华").is_none());
         assert_eq!(data.as_slice().slice(0u, 43u).find_str(""), Some(0u));
@@ -1092,11 +1144,13 @@ fn test_concat() {
         fn t(v: &[String], s: &str) {
             assert_eq!(v.concat().as_slice(), s);
         }
-        t(["you".to_string(), "know".to_string(), "I'm".to_string(),
-          "no".to_string(), "good".to_string()], "youknowI'mnogood");
+        t([String::from_str("you"), String::from_str("know"),
+           String::from_str("I'm"),
+           String::from_str("no"), String::from_str("good")],
+          "youknowI'mnogood");
         let v: &[String] = [];
         t(v, "");
-        t(["hi".to_string()], "hi");
+        t([String::from_str("hi")], "hi");
     }
 
     #[test]
@@ -1104,12 +1158,13 @@ fn test_connect() {
         fn t(v: &[String], sep: &str, s: &str) {
             assert_eq!(v.connect(sep).as_slice(), s);
         }
-        t(["you".to_string(), "know".to_string(), "I'm".to_string(),
-           "no".to_string(), "good".to_string()],
+        t([String::from_str("you"), String::from_str("know"),
+           String::from_str("I'm"),
+           String::from_str("no"), String::from_str("good")],
           " ", "you know I'm no good");
         let v: &[String] = [];
         t(v, " ", "");
-        t(["hi".to_string()], " ", "hi");
+        t([String::from_str("hi")], " ", "hi");
     }
 
     #[test]
@@ -1136,11 +1191,11 @@ fn t(v: &[&str], sep: &str, s: &str) {
 
     #[test]
     fn test_repeat() {
-        assert_eq!("x".repeat(4), "xxxx".to_string());
-        assert_eq!("hi".repeat(4), "hihihihi".to_string());
-        assert_eq!("ไท华".repeat(3), "ไท华ไท华ไท华".to_string());
-        assert_eq!("".repeat(4), "".to_string());
-        assert_eq!("hi".repeat(0), "".to_string());
+        assert_eq!("x".repeat(4), String::from_str("xxxx"));
+        assert_eq!("hi".repeat(4), String::from_str("hihihihi"));
+        assert_eq!("ไท华".repeat(3), String::from_str("ไท华ไท华ไท华"));
+        assert_eq!("".repeat(4), String::from_str(""));
+        assert_eq!("hi".repeat(0), String::from_str(""));
     }
 
     #[test]
@@ -1168,9 +1223,9 @@ fn half_a_million_letter_a() -> String {
         }
         let letters = a_million_letter_a();
         assert!(half_a_million_letter_a() ==
-            unsafe {raw::slice_bytes(letters.as_slice(),
+            unsafe {String::from_str(raw::slice_bytes(letters.as_slice(),
                                      0u,
-                                     500000)}.to_string());
+                                     500000))});
     }
 
     #[test]
@@ -1204,13 +1259,13 @@ fn test_is_empty() {
     #[test]
     fn test_replace() {
         let a = "a";
-        assert_eq!("".replace(a, "b"), "".to_string());
-        assert_eq!("a".replace(a, "b"), "b".to_string());
-        assert_eq!("ab".replace(a, "b"), "bb".to_string());
+        assert_eq!("".replace(a, "b"), String::from_str(""));
+        assert_eq!("a".replace(a, "b"), String::from_str("b"));
+        assert_eq!("ab".replace(a, "b"), String::from_str("bb"));
         let test = "test";
         assert!(" test test ".replace(test, "toast") ==
-            " toast toast ".to_string());
-        assert_eq!(" test test ".replace(test, ""), "   ".to_string());
+            String::from_str(" toast toast "));
+        assert_eq!(" test test ".replace(test, ""), String::from_str("   "));
     }
 
     #[test]
@@ -1285,7 +1340,7 @@ fn half_a_million_letter_x() -> String {
         }
         let letters = a_million_letter_x();
         assert!(half_a_million_letter_x() ==
-            letters.as_slice().slice(0u, 3u * 500000u).to_string());
+            String::from_str(letters.as_slice().slice(0u, 3u * 500000u)));
     }
 
     #[test]
@@ -1513,7 +1568,7 @@ fn test_raw_from_c_str() {
             let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
             let b = a.as_ptr();
             let c = raw::from_c_str(b);
-            assert_eq!(c, "AAAAAAA".to_string());
+            assert_eq!(c, String::from_str("AAAAAAA"));
         }
     }
 
@@ -1535,7 +1590,7 @@ fn test_as_bytes() {
     fn test_as_bytes_fail() {
         // Don't double free. (I'm not sure if this exercises the
         // original problem code path anymore.)
-        let s = "".to_string();
+        let s = String::from_str("");
         let _bytes = s.as_bytes();
         fail!();
     }
@@ -1578,10 +1633,10 @@ fn test_subslice_offset_2() {
 
     #[test]
     fn vec_str_conversions() {
-        let s1: String = "All mimsy were the borogoves".to_string();
+        let s1: String = String::from_str("All mimsy were the borogoves");
 
         let v: Vec<u8> = Vec::from_slice(s1.as_bytes());
-        let s2: String = from_utf8(v.as_slice()).unwrap().to_string();
+        let s2: String = String::from_str(from_utf8(v.as_slice()).unwrap());
         let mut i: uint = 0u;
         let n1: uint = s1.len();
         let n2: uint = v.len();
@@ -1624,13 +1679,13 @@ fn test_contains_char() {
     #[test]
     fn test_utf16() {
         let pairs =
-            [("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n".to_string(),
+            [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
               vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
                 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
                 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
                 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
 
-             ("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n".to_string(),
+             (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
               vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
                 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
                 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
@@ -1638,7 +1693,7 @@ fn test_utf16() {
                 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
                 0x000a_u16]),
 
-             ("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n".to_string(),
+             (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
               vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
                 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
                 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
@@ -1647,7 +1702,7 @@ fn test_utf16() {
                 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
                 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
 
-             ("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n".to_string(),
+             (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
               vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
                 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
                 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
@@ -1660,7 +1715,7 @@ fn test_utf16() {
                 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
                 0x000a_u16 ]),
              // Issue #12318, even-numbered non-BMP planes
-             ("\U00020000".to_string(),
+             (String::from_str("\U00020000"),
               vec![0xD840, 0xDC00])];
 
         for p in pairs.iter() {
@@ -1698,16 +1753,16 @@ fn test_utf16_invalid() {
     fn test_utf16_lossy() {
         // completely positive cases tested above.
         // lead + eof
-        assert_eq!(from_utf16_lossy([0xD800]), "\uFFFD".to_string());
+        assert_eq!(from_utf16_lossy([0xD800]), String::from_str("\uFFFD"));
         // lead + lead
-        assert_eq!(from_utf16_lossy([0xD800, 0xD800]), "\uFFFD\uFFFD".to_string());
+        assert_eq!(from_utf16_lossy([0xD800, 0xD800]), String::from_str("\uFFFD\uFFFD"));
 
         // isolated trail
-        assert_eq!(from_utf16_lossy([0x0061, 0xDC00]), "a\uFFFD".to_string());
+        assert_eq!(from_utf16_lossy([0x0061, 0xDC00]), String::from_str("a\uFFFD"));
 
         // general
         assert_eq!(from_utf16_lossy([0xD800, 0xd801, 0xdc8b, 0xD800]),
-                   "\uFFFD𐒋\uFFFD".to_string());
+                   String::from_str("\uFFFD𐒋\uFFFD"));
     }
 
     #[test]
@@ -1752,27 +1807,29 @@ fn test_char_at_reverse() {
 
     #[test]
     fn test_escape_unicode() {
-        assert_eq!("abc".escape_unicode(), "\\x61\\x62\\x63".to_string());
-        assert_eq!("a c".escape_unicode(), "\\x61\\x20\\x63".to_string());
-        assert_eq!("\r\n\t".escape_unicode(), "\\x0d\\x0a\\x09".to_string());
-        assert_eq!("'\"\\".escape_unicode(), "\\x27\\x22\\x5c".to_string());
-        assert_eq!("\x00\x01\xfe\xff".escape_unicode(), "\\x00\\x01\\xfe\\xff".to_string());
-        assert_eq!("\u0100\uffff".escape_unicode(), "\\u0100\\uffff".to_string());
-        assert_eq!("\U00010000\U0010ffff".escape_unicode(), "\\U00010000\\U0010ffff".to_string());
-        assert_eq!("ab\ufb00".escape_unicode(), "\\x61\\x62\\ufb00".to_string());
-        assert_eq!("\U0001d4ea\r".escape_unicode(), "\\U0001d4ea\\x0d".to_string());
+        assert_eq!("abc".escape_unicode(), String::from_str("\\x61\\x62\\x63"));
+        assert_eq!("a c".escape_unicode(), String::from_str("\\x61\\x20\\x63"));
+        assert_eq!("\r\n\t".escape_unicode(), String::from_str("\\x0d\\x0a\\x09"));
+        assert_eq!("'\"\\".escape_unicode(), String::from_str("\\x27\\x22\\x5c"));
+        assert_eq!("\x00\x01\xfe\xff".escape_unicode(), String::from_str("\\x00\\x01\\xfe\\xff"));
+        assert_eq!("\u0100\uffff".escape_unicode(), String::from_str("\\u0100\\uffff"));
+        assert_eq!("\U00010000\U0010ffff".escape_unicode(),
+                   String::from_str("\\U00010000\\U0010ffff"));
+        assert_eq!("ab\ufb00".escape_unicode(), String::from_str("\\x61\\x62\\ufb00"));
+        assert_eq!("\U0001d4ea\r".escape_unicode(), String::from_str("\\U0001d4ea\\x0d"));
     }
 
     #[test]
     fn test_escape_default() {
-        assert_eq!("abc".escape_default(), "abc".to_string());
-        assert_eq!("a c".escape_default(), "a c".to_string());
-        assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t".to_string());
-        assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\".to_string());
-        assert_eq!("\u0100\uffff".escape_default(), "\\u0100\\uffff".to_string());
-        assert_eq!("\U00010000\U0010ffff".escape_default(), "\\U00010000\\U0010ffff".to_string());
-        assert_eq!("ab\ufb00".escape_default(), "ab\\ufb00".to_string());
-        assert_eq!("\U0001d4ea\r".escape_default(), "\\U0001d4ea\\r".to_string());
+        assert_eq!("abc".escape_default(), String::from_str("abc"));
+        assert_eq!("a c".escape_default(), String::from_str("a c"));
+        assert_eq!("\r\n\t".escape_default(), String::from_str("\\r\\n\\t"));
+        assert_eq!("'\"\\".escape_default(), String::from_str("\\'\\\"\\\\"));
+        assert_eq!("\u0100\uffff".escape_default(), String::from_str("\\u0100\\uffff"));
+        assert_eq!("\U00010000\U0010ffff".escape_default(),
+                   String::from_str("\\U00010000\\U0010ffff"));
+        assert_eq!("ab\ufb00".escape_default(), String::from_str("ab\\ufb00"));
+        assert_eq!("\U0001d4ea\r".escape_default(), String::from_str("\\U0001d4ea\\r"));
     }
 
     #[test]
@@ -2013,30 +2070,39 @@ fn test_words() {
 
     #[test]
     fn test_nfd_chars() {
-        assert_eq!("abc".nfd_chars().collect::<String>(), "abc".to_string());
-        assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<String>(), "d\u0307\u01c4".to_string());
-        assert_eq!("\u2026".nfd_chars().collect::<String>(), "\u2026".to_string());
-        assert_eq!("\u2126".nfd_chars().collect::<String>(), "\u03a9".to_string());
-        assert_eq!("\u1e0b\u0323".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("\u1e0d\u0307".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("a\u0301".nfd_chars().collect::<String>(), "a\u0301".to_string());
-        assert_eq!("\u0301a".nfd_chars().collect::<String>(), "\u0301a".to_string());
-        assert_eq!("\ud4db".nfd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
-        assert_eq!("\uac1c".nfd_chars().collect::<String>(), "\u1100\u1162".to_string());
+        assert_eq!("abc".nfd_chars().collect::<String>(), String::from_str("abc"));
+        assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<String>(),
+                   String::from_str("d\u0307\u01c4"));
+        assert_eq!("\u2026".nfd_chars().collect::<String>(), String::from_str("\u2026"));
+        assert_eq!("\u2126".nfd_chars().collect::<String>(), String::from_str("\u03a9"));
+        assert_eq!("\u1e0b\u0323".nfd_chars().collect::<String>(),
+                   String::from_str("d\u0323\u0307"));
+        assert_eq!("\u1e0d\u0307".nfd_chars().collect::<String>(),
+                   String::from_str("d\u0323\u0307"));
+        assert_eq!("a\u0301".nfd_chars().collect::<String>(), String::from_str("a\u0301"));
+        assert_eq!("\u0301a".nfd_chars().collect::<String>(), String::from_str("\u0301a"));
+        assert_eq!("\ud4db".nfd_chars().collect::<String>(),
+                   String::from_str("\u1111\u1171\u11b6"));
+        assert_eq!("\uac1c".nfd_chars().collect::<String>(), String::from_str("\u1100\u1162"));
     }
 
     #[test]
     fn test_nfkd_chars() {
-        assert_eq!("abc".nfkd_chars().collect::<String>(), "abc".to_string());
-        assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<String>(), "d\u0307DZ\u030c".to_string());
-        assert_eq!("\u2026".nfkd_chars().collect::<String>(), "...".to_string());
-        assert_eq!("\u2126".nfkd_chars().collect::<String>(), "\u03a9".to_string());
-        assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("a\u0301".nfkd_chars().collect::<String>(), "a\u0301".to_string());
-        assert_eq!("\u0301a".nfkd_chars().collect::<String>(), "\u0301a".to_string());
-        assert_eq!("\ud4db".nfkd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
-        assert_eq!("\uac1c".nfkd_chars().collect::<String>(), "\u1100\u1162".to_string());
+        assert_eq!("abc".nfkd_chars().collect::<String>(), String::from_str("abc"));
+        assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<String>(),
+                   String::from_str("d\u0307DZ\u030c"));
+        assert_eq!("\u2026".nfkd_chars().collect::<String>(), String::from_str("..."));
+        assert_eq!("\u2126".nfkd_chars().collect::<String>(), String::from_str("\u03a9"));
+        assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<String>(),
+                   String::from_str("d\u0323\u0307"));
+        assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<String>(),
+                   String::from_str("d\u0323\u0307"));
+        assert_eq!("a\u0301".nfkd_chars().collect::<String>(), String::from_str("a\u0301"));
+        assert_eq!("\u0301a".nfkd_chars().collect::<String>(),
+                   String::from_str("\u0301a"));
+        assert_eq!("\ud4db".nfkd_chars().collect::<String>(),
+String::from_str("\u1111\u1171\u11b6"));
+        assert_eq!("\uac1c".nfkd_chars().collect::<String>(), String::from_str("\u1100\u1162"));
     }
 
     #[test]
@@ -2090,10 +2156,10 @@ fn sum_len<S: Collection>(v: &[S]) -> uint {
             v.iter().map(|x| x.len()).sum()
         }
 
-        let s = "01234".to_string();
+        let s = String::from_str("01234");
         assert_eq!(5, sum_len(["012", "", "34"]));
-        assert_eq!(5, sum_len(["01".to_string(), "2".to_string(),
-                               "34".to_string(), "".to_string()]));
+        assert_eq!(5, sum_len([String::from_str("01"), String::from_str("2"),
+                               String::from_str("34"), String::from_str("")]));
         assert_eq!(5, sum_len([s.as_slice()]));
     }
 
@@ -2112,10 +2178,10 @@ fn test_str_from_utf8() {
     #[test]
     fn test_str_from_utf8_owned() {
         let xs = Vec::from_slice(b"hello");
-        assert_eq!(from_utf8_owned(xs), Ok("hello".to_string()));
+        assert_eq!(from_utf8_owned(xs), Ok(String::from_str("hello")));
 
         let xs = Vec::from_slice("ศไทย中华Việt Nam".as_bytes());
-        assert_eq!(from_utf8_owned(xs), Ok("ศไทย中华Việt Nam".to_string()));
+        assert_eq!(from_utf8_owned(xs), Ok(String::from_str("ศไทย中华Việt Nam")));
 
         let xs = Vec::from_slice(b"hello\xFF");
         assert_eq!(from_utf8_owned(xs),
@@ -2131,34 +2197,30 @@ fn test_str_from_utf8_lossy() {
         assert_eq!(from_utf8_lossy(xs), Slice("ศไทย中华Việt Nam"));
 
         let xs = b"Hello\xC2 There\xFF Goodbye";
-        assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD There\uFFFD Goodbye".to_string()));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("Hello\uFFFD There\uFFFD Goodbye")));
 
         let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
-        assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD\uFFFD There\uFFFD Goodbye".to_string()));
+        assert_eq!(from_utf8_lossy(xs),
+                   Owned(String::from_str("Hello\uFFFD\uFFFD There\uFFFD Goodbye")));
 
         let xs = b"\xF5foo\xF5\x80bar";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFD\uFFFDbar".to_string()));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFDfoo\uFFFD\uFFFDbar")));
 
         let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFDbaz".to_string()));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFDfoo\uFFFDbar\uFFFDbaz")));
 
         let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz".to_string()));
+        assert_eq!(from_utf8_lossy(xs),
+                   Owned(String::from_str("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz")));
 
         let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFD\uFFFD\
-                                               foo\U00010000bar".to_string()));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFD\uFFFD\uFFFD\uFFFD\
+                                               foo\U00010000bar")));
 
         // surrogates
         let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFDfoo\
-                                               \uFFFD\uFFFD\uFFFDbar".to_string()));
-    }
-
-    #[test]
-    fn test_from_str() {
-      let owned: Option<::std::string::String> = from_str("string");
-      assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
+        assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFD\uFFFD\uFFFDfoo\
+                                               \uFFFD\uFFFD\uFFFDbar")));
     }
 
     #[test]
@@ -2166,18 +2228,18 @@ fn test_maybe_owned_traits() {
         let s = Slice("abcde");
         assert_eq!(s.len(), 5);
         assert_eq!(s.as_slice(), "abcde");
-        assert_eq!(s.to_str().as_slice(), "abcde");
+        assert_eq!(String::from_str(s.as_slice()).as_slice(), "abcde");
         assert_eq!(format!("{}", s).as_slice(), "abcde");
-        assert!(s.lt(&Owned("bcdef".to_string())));
+        assert!(s.lt(&Owned(String::from_str("bcdef"))));
         assert_eq!(Slice(""), Default::default());
 
-        let o = Owned("abcde".to_string());
+        let o = Owned(String::from_str("abcde"));
         assert_eq!(o.len(), 5);
         assert_eq!(o.as_slice(), "abcde");
-        assert_eq!(o.to_str().as_slice(), "abcde");
+        assert_eq!(String::from_str(o.as_slice()).as_slice(), "abcde");
         assert_eq!(format!("{}", o).as_slice(), "abcde");
         assert!(o.lt(&Slice("bcdef")));
-        assert_eq!(Owned("".to_string()), Default::default());
+        assert_eq!(Owned(String::from_str("")), Default::default());
 
         assert!(s.cmp(&o) == Equal);
         assert!(s.equiv(&o));
@@ -2192,31 +2254,33 @@ fn test_maybe_owned_methods() {
         assert!(s.is_slice());
         assert!(!s.is_owned());
 
-        let o = Owned("abcde".to_string());
+        let o = Owned(String::from_str("abcde"));
         assert!(!o.is_slice());
         assert!(o.is_owned());
     }
 
     #[test]
     fn test_maybe_owned_clone() {
-        assert_eq!(Owned("abcde".to_string()), Slice("abcde").clone());
-        assert_eq!(Owned("abcde".to_string()), Owned("abcde".to_string()).clone());
+        assert_eq!(Owned(String::from_str("abcde")), Slice("abcde").clone());
+        assert_eq!(Owned(String::from_str("abcde")), Owned(String::from_str("abcde")).clone());
         assert_eq!(Slice("abcde"), Slice("abcde").clone());
-        assert_eq!(Slice("abcde"), Owned("abcde".to_string()).clone());
+        assert_eq!(Slice("abcde"), Owned(String::from_str("abcde")).clone());
     }
 
     #[test]
     fn test_maybe_owned_into_string() {
-        assert_eq!(Slice("abcde").into_string(), "abcde".to_string());
-        assert_eq!(Owned("abcde".to_string()).into_string(), "abcde".to_string());
+        assert_eq!(Slice("abcde").into_string(), String::from_str("abcde"));
+        assert_eq!(Owned(String::from_str("abcde")).into_string(),
+                   String::from_str("abcde"));
     }
 
     #[test]
     fn test_into_maybe_owned() {
         assert_eq!("abcde".into_maybe_owned(), Slice("abcde"));
-        assert_eq!(("abcde".to_string()).into_maybe_owned(), Slice("abcde"));
-        assert_eq!("abcde".into_maybe_owned(), Owned("abcde".to_string()));
-        assert_eq!(("abcde".to_string()).into_maybe_owned(), Owned("abcde".to_string()));
+        assert_eq!((String::from_str("abcde")).into_maybe_owned(), Slice("abcde"));
+        assert_eq!("abcde".into_maybe_owned(), Owned(String::from_str("abcde")));
+        assert_eq!((String::from_str("abcde")).into_maybe_owned(),
+                   Owned(String::from_str("abcde")));
     }
 }
 
@@ -2224,7 +2288,10 @@ fn test_into_maybe_owned() {
 mod bench {
     use test::Bencher;
     use super::*;
-    use std::prelude::*;
+    use vec::Vec;
+    use std::iter::{Iterator, DoubleEndedIterator};
+    use std::collections::Collection;
+    use std::slice::Vector;
 
     #[bench]
     fn char_iterator(b: &mut Bencher) {
index 936e60388a66ae8223cca470b4f837d626399bfc..74b9465f2a5690c560837f70598e63fbc03e5ee9 100644 (file)
@@ -208,7 +208,7 @@ pub fn truncate(&mut self, len: uint) {
     /// Appends a byte to this string buffer. The caller must preserve the valid UTF-8 property.
     #[inline]
     pub unsafe fn push_byte(&mut self, byte: u8) {
-        self.push_bytes([byte])
+        self.vec.push(byte)
     }
 
     /// Removes the last byte from the string buffer and returns it. Returns `None` if this string
@@ -354,7 +354,7 @@ fn equiv(&self, other: &S) -> bool {
 
 impl<S: Str> Add<S, String> for String {
     fn add(&self, other: &S) -> String {
-        let mut s = self.to_string();
+        let mut s = String::from_str(self.as_slice());
         s.push_str(other.as_slice());
         return s;
     }
@@ -369,6 +369,12 @@ mod tests {
     use str::{Str, StrSlice};
     use super::String;
 
+    #[test]
+    fn test_from_str() {
+      let owned: Option<::std::string::String> = from_str("string");
+      assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
+    }
+
     #[bench]
     fn bench_with_capacity(b: &mut Bencher) {
         b.iter(|| {
index becceffe6d0270254fe0017f0c3be5e4cee6abb9..3d4973373e26763fbfa756bd6b85ce7f5833f086 100644 (file)
@@ -14,7 +14,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::default::Default;
 use core::fmt;
 use core::fmt::Show;
@@ -22,6 +22,7 @@
 use core::iter;
 use core::mem::{replace, swap};
 use core::ptr;
+use std::hash::{Writer, Hash};
 
 use {Collection, Mutable, Set, MutableSet, MutableMap, Map};
 use vec::Vec;
@@ -88,27 +89,18 @@ fn clear(&mut self) {
 }
 
 impl<K: Ord, V> Map<K, V> for TreeMap<K, V> {
+    // See comments on tree_find_with
+    #[inline]
     fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
-        let mut current: &'a Option<Box<TreeNode<K, V>>> = &self.root;
-        loop {
-            match *current {
-              Some(ref r) => {
-                match key.cmp(&r.key) {
-                  Less => current = &r.left,
-                  Greater => current = &r.right,
-                  Equal => return Some(&r.value)
-                }
-              }
-              None => return None
-            }
-        }
+        tree_find_with(&self.root, |k2| key.cmp(k2))
     }
 }
 
 impl<K: Ord, V> MutableMap<K, V> for TreeMap<K, V> {
+    // See comments on def_tree_find_mut_with
     #[inline]
     fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
-        find_mut(&mut self.root, key)
+        tree_find_mut_with(&mut self.root, |x| key.cmp(x))
     }
 
     fn swap(&mut self, key: K, value: V) -> Option<V> {
@@ -181,11 +173,60 @@ pub fn move_iter(self) -> MoveEntries<K, V> {
     }
 }
 
+impl<K, V> TreeMap<K, V> {
+    /// Return the value for which f(key) returns Equal. f is invoked
+    /// with current key and helps to navigate the tree
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::ascii::StrAsciiExt;
+    ///
+    /// let mut t = collections::treemap::TreeMap::new();
+    /// t.insert("Content-Type", "application/xml");
+    /// t.insert("User-Agent", "Curl-Rust/0.1");
+    ///
+    /// let ua_key = "user-agent";
+    /// let ua = t.find_with(|&k| {
+    ///    ua_key.cmp(&k.to_ascii_lower().as_slice())
+    /// });
+    ///
+    /// assert_eq!(*ua.unwrap(), "Curl-Rust/0.1");
+    /// ```
+    #[inline]
+    pub fn find_with<'a>(&'a self, f:|&K| -> Ordering) -> Option<&'a V> {
+        tree_find_with(&self.root, f)
+    }
+
+    /// Return the value for which f(key) returns Equal. f is invoked
+    /// with current key and helps to navigate the tree
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let mut t = collections::treemap::TreeMap::new();
+    /// t.insert("Content-Type", "application/xml");
+    /// t.insert("User-Agent", "Curl-Rust/0.1");
+    ///
+    /// let new_ua = "Safari/156.0";
+    /// match t.find_mut_with(|k| "User-Agent".cmp(k)) {
+    ///    Some(x) => *x = new_ua,
+    ///    None => fail!(),
+    /// }
+    ///
+    /// assert_eq!(t.find(&"User-Agent"), Some(&new_ua));
+    /// ```
+    #[inline]
+    pub fn find_mut_with<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
+        tree_find_mut_with(&mut self.root, f)
+    }
+}
+
 // range iterators.
 
 macro_rules! bound_setup {
     // initialiser of the iterator to manipulate
-    ($iter:expr,
+    ($iter:expr, $k:expr,
      // whether we are looking for the lower or upper bound.
      $is_lower_bound:expr) => {
         {
@@ -193,7 +234,7 @@ macro_rules! bound_setup {
             loop {
                 if !iter.node.is_null() {
                     let node_k = unsafe {&(*iter.node).key};
-                    match k.cmp(node_k) {
+                    match $k.cmp(node_k) {
                         Less => iter.traverse_left(),
                         Greater => iter.traverse_right(),
                         Equal => {
@@ -230,13 +271,13 @@ fn iter_for_traversal<'a>(&'a self) -> Entries<'a, K, V> {
     /// Return a lazy iterator to the first key-value pair whose key is not less than `k`
     /// If all keys in map are less than `k` an empty iterator is returned.
     pub fn lower_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
-        bound_setup!(self.iter_for_traversal(), true)
+        bound_setup!(self.iter_for_traversal(), k, true)
     }
 
     /// Return a lazy iterator to the first key-value pair whose key is greater than `k`
     /// If all keys in map are not greater than `k` an empty iterator is returned.
     pub fn upper_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
-        bound_setup!(self.iter_for_traversal(), false)
+        bound_setup!(self.iter_for_traversal(), k, false)
     }
 
     /// Get a lazy iterator that should be initialized using
@@ -256,7 +297,7 @@ fn mut_iter_for_traversal<'a>(&'a mut self) -> MutEntries<'a, K, V> {
     /// If all keys in map are less than `k` an empty iterator is
     /// returned.
     pub fn mut_lower_bound<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
-        bound_setup!(self.mut_iter_for_traversal(), true)
+        bound_setup!(self.mut_iter_for_traversal(), k, true)
     }
 
     /// Return a lazy iterator to the first key-value pair (with the
@@ -265,7 +306,7 @@ pub fn mut_lower_bound<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
     /// If all keys in map are not greater than `k` an empty iterator
     /// is returned.
     pub fn mut_upper_bound<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
-        bound_setup!(self.mut_iter_for_traversal(), false)
+        bound_setup!(self.mut_iter_for_traversal(), k, false)
     }
 }
 
@@ -840,18 +881,48 @@ fn split<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
     }
 }
 
-fn find_mut<'r, K: Ord, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
-                                key: &K)
-                             -> Option<&'r mut V> {
-    match *node {
-      Some(ref mut x) => {
-        match key.cmp(&x.key) {
-          Less => find_mut(&mut x.left, key),
-          Greater => find_mut(&mut x.right, key),
-          Equal => Some(&mut x.value),
+// Next 2 functions have the same conventions
+//
+// The only difference is that non-mutable version uses loop instead
+// of recursion (performance considerations)
+// It seems to be impossible to avoid recursion with mutability
+//
+// So convention is that comparator is gets at input current key
+// and returns search_key cmp cur_key (i.e. search_key.cmp(cur_key))
+fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
+                            f: |&K| -> Ordering) -> Option<&'r V> {
+    let mut current: &'r Option<Box<TreeNode<K, V>>> = node;
+    loop {
+        match *current {
+            Some(ref r) => {
+                match f(&r.key) {
+                    Less => current = &r.left,
+                    Greater => current = &r.right,
+                    Equal => return Some(&r.value)
+                }
+            }
+            None => return None
+        }
+    }
+}
+
+// See comments above tree_find_with
+fn tree_find_mut_with<'r, K, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
+                                f: |&K| -> Ordering) -> Option<&'r mut V> {
+
+    let mut current = node;
+    loop {
+        let temp = current; // hack to appease borrowck
+        match *temp {
+            Some(ref mut r) => {
+                match f(&r.key) {
+                    Less => current = &mut r.left,
+                    Greater => current = &mut r.right,
+                    Equal => return Some(&mut r.value)
+                }
+            }
+            None => return None
         }
-      }
-      None => None
     }
 }
 
@@ -985,6 +1056,14 @@ fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
     }
 }
 
+impl<S: Writer, K: Ord + Hash<S>, V: Hash<S>> Hash<S> for TreeMap<K, V> {
+    fn hash(&self, state: &mut S) {
+        for elt in self.iter() {
+            elt.hash(state);
+        }
+    }
+}
+
 impl<T: Ord> FromIterator<T> for TreeSet<T> {
     fn from_iter<Iter: Iterator<T>>(iter: Iter) -> TreeSet<T> {
         let mut set = TreeSet::new();
@@ -1002,6 +1081,14 @@ fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
     }
 }
 
+impl<S: Writer, T: Ord + Hash<S>> Hash<S> for TreeSet<T> {
+    fn hash(&self, state: &mut S) {
+        for elt in self.iter() {
+            elt.hash(state);
+        }
+    }
+}
+
 #[cfg(test)]
 mod test_treemap {
     use std::prelude::*;
@@ -1026,6 +1113,30 @@ fn find_not_found() {
         assert_eq!(m.find(&2), None);
     }
 
+    #[test]
+    fn find_with_empty() {
+        let m: TreeMap<&'static str,int> = TreeMap::new();
+        assert!(m.find_with(|k| "test".cmp(k)) == None);
+    }
+
+    #[test]
+    fn find_with_not_found() {
+        let mut m = TreeMap::new();
+        assert!(m.insert("test1", 2i));
+        assert!(m.insert("test2", 3i));
+        assert!(m.insert("test3", 3i));
+        assert_eq!(m.find_with(|k| "test4".cmp(k)), None);
+    }
+
+    #[test]
+    fn find_with_found() {
+        let mut m = TreeMap::new();
+        assert!(m.insert("test1", 2i));
+        assert!(m.insert("test2", 3i));
+        assert!(m.insert("test3", 4i));
+        assert_eq!(m.find_with(|k| "test2".cmp(k)), Some(&3i));
+    }
+
     #[test]
     fn test_find_mut() {
         let mut m = TreeMap::new();
@@ -1039,6 +1150,19 @@ fn test_find_mut() {
         assert_eq!(m.find(&5), Some(&new));
     }
 
+    #[test]
+    fn test_find_with_mut() {
+        let mut m = TreeMap::new();
+        assert!(m.insert("t1", 12i));
+        assert!(m.insert("t2", 8));
+        assert!(m.insert("t5", 14));
+        let new = 100;
+        match m.find_mut_with(|k| "t5".cmp(k)) {
+          None => fail!(), Some(x) => *x = new
+        }
+        assert_eq!(m.find_with(|k| "t5".cmp(k)), Some(&new));
+    }
+
     #[test]
     fn insert_replace() {
         let mut m = TreeMap::new();
@@ -1501,6 +1625,7 @@ pub fn find_seq_10_000(b: &mut Bencher) {
 #[cfg(test)]
 mod test_set {
     use std::prelude::*;
+    use std::hash;
 
     use {Set, MutableSet, Mutable, MutableMap};
     use super::{TreeMap, TreeSet};
@@ -1641,6 +1766,22 @@ fn test_clone_eq() {
       assert!(m.clone() == m);
     }
 
+    #[test]
+    fn test_hash() {
+      let mut x = TreeSet::new();
+      let mut y = TreeSet::new();
+
+      x.insert(1i);
+      x.insert(2);
+      x.insert(3);
+
+      y.insert(3i);
+      y.insert(2);
+      y.insert(1);
+
+      assert!(hash::hash(&x) == hash::hash(&y));
+    }
+
     fn check(a: &[int],
              b: &[int],
              expected: &[int],
@@ -1663,7 +1804,7 @@ fn check(a: &[int],
     #[test]
     fn test_intersection() {
         fn check_intersection(a: &[int], b: &[int], expected: &[int]) {
-            check(a, b, expected, |x, y, f| x.intersection(y).advance(f))
+            check(a, b, expected, |x, y, f| x.intersection(y).all(f))
         }
 
         check_intersection([], [], []);
@@ -1679,7 +1820,7 @@ fn check_intersection(a: &[int], b: &[int], expected: &[int]) {
     #[test]
     fn test_difference() {
         fn check_difference(a: &[int], b: &[int], expected: &[int]) {
-            check(a, b, expected, |x, y, f| x.difference(y).advance(f))
+            check(a, b, expected, |x, y, f| x.difference(y).all(f))
         }
 
         check_difference([], [], []);
@@ -1697,7 +1838,7 @@ fn check_difference(a: &[int], b: &[int], expected: &[int]) {
     fn test_symmetric_difference() {
         fn check_symmetric_difference(a: &[int], b: &[int],
                                       expected: &[int]) {
-            check(a, b, expected, |x, y, f| x.symmetric_difference(y).advance(f))
+            check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
         }
 
         check_symmetric_difference([], [], []);
@@ -1712,7 +1853,7 @@ fn check_symmetric_difference(a: &[int], b: &[int],
     fn test_union() {
         fn check_union(a: &[int], b: &[int],
                                       expected: &[int]) {
-            check(a, b, expected, |x, y, f| x.union(y).advance(f))
+            check(a, b, expected, |x, y, f| x.union(y).all(f))
         }
 
         check_union([], [], []);
index 9b6355e121bea459af7c7e4336e3e7396256648d..29ec85590b32044a14d900e7a92ffae09bc1230f 100644 (file)
@@ -12,7 +12,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::default::Default;
 use core::mem::zeroed;
 use core::mem;
diff --git a/src/libcollections/unicode.rs b/src/libcollections/unicode.rs
deleted file mode 100644 (file)
index 4402901..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2012-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.
-
-// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
-
-#![allow(missing_doc, non_uppercase_statics)]
-
-pub mod normalization {
-    use core::prelude::*;
-
-    fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
-        match r.bsearch(|&(lo, hi, _)| {
-            if lo <= c && c <= hi { Equal }
-            else if hi < c { Less }
-            else { Greater }
-        }) {
-            Some(idx) => {
-                let (_, _, result) = r[idx];
-                result
-            }
-            None => 0
-        }
-    }
-
-
-    static combining_class_table : &'static [(char, char, u8)] = &[
-        ('\u0300', '\u0314', 230), ('\u0315', '\u0315', 232),
-        ('\u0316', '\u0319', 220), ('\u031a', '\u031a', 232),
-        ('\u031b', '\u031b', 216), ('\u031c', '\u0320', 220),
-        ('\u0321', '\u0322', 202), ('\u0323', '\u0326', 220),
-        ('\u0327', '\u0328', 202), ('\u0329', '\u0333', 220),
-        ('\u0334', '\u0338', 1), ('\u0339', '\u033c', 220),
-        ('\u033d', '\u0344', 230), ('\u0345', '\u0345', 240),
-        ('\u0346', '\u0346', 230), ('\u0347', '\u0349', 220),
-        ('\u034a', '\u034c', 230), ('\u034d', '\u034e', 220),
-        ('\u0350', '\u0352', 230), ('\u0353', '\u0356', 220),
-        ('\u0357', '\u0357', 230), ('\u0358', '\u0358', 232),
-        ('\u0359', '\u035a', 220), ('\u035b', '\u035b', 230),
-        ('\u035c', '\u035c', 233), ('\u035d', '\u035e', 234),
-        ('\u035f', '\u035f', 233), ('\u0360', '\u0361', 234),
-        ('\u0362', '\u0362', 233), ('\u0363', '\u036f', 230),
-        ('\u0483', '\u0487', 230), ('\u0591', '\u0591', 220),
-        ('\u0592', '\u0595', 230), ('\u0596', '\u0596', 220),
-        ('\u0597', '\u0599', 230), ('\u059a', '\u059a', 222),
-        ('\u059b', '\u059b', 220), ('\u059c', '\u05a1', 230),
-        ('\u05a2', '\u05a7', 220), ('\u05a8', '\u05a9', 230),
-        ('\u05aa', '\u05aa', 220), ('\u05ab', '\u05ac', 230),
-        ('\u05ad', '\u05ad', 222), ('\u05ae', '\u05ae', 228),
-        ('\u05af', '\u05af', 230), ('\u05b0', '\u05b0', 10),
-        ('\u05b1', '\u05b1', 11), ('\u05b2', '\u05b2', 12),
-        ('\u05b3', '\u05b3', 13), ('\u05b4', '\u05b4', 14),
-        ('\u05b5', '\u05b5', 15), ('\u05b6', '\u05b6', 16),
-        ('\u05b7', '\u05b7', 17), ('\u05b8', '\u05b8', 18),
-        ('\u05b9', '\u05ba', 19), ('\u05bb', '\u05bb', 20),
-        ('\u05bc', '\u05bc', 21), ('\u05bd', '\u05bd', 22),
-        ('\u05bf', '\u05bf', 23), ('\u05c1', '\u05c1', 24),
-        ('\u05c2', '\u05c2', 25), ('\u05c4', '\u05c4', 230),
-        ('\u05c5', '\u05c5', 220), ('\u05c7', '\u05c7', 18),
-        ('\u0610', '\u0617', 230), ('\u0618', '\u0618', 30),
-        ('\u0619', '\u0619', 31), ('\u061a', '\u061a', 32),
-        ('\u064b', '\u064b', 27), ('\u064c', '\u064c', 28),
-        ('\u064d', '\u064d', 29), ('\u064e', '\u064e', 30),
-        ('\u064f', '\u064f', 31), ('\u0650', '\u0650', 32),
-        ('\u0651', '\u0651', 33), ('\u0652', '\u0652', 34),
-        ('\u0653', '\u0654', 230), ('\u0655', '\u0656', 220),
-        ('\u0657', '\u065b', 230), ('\u065c', '\u065c', 220),
-        ('\u065d', '\u065e', 230), ('\u065f', '\u065f', 220),
-        ('\u0670', '\u0670', 35), ('\u06d6', '\u06dc', 230),
-        ('\u06df', '\u06e2', 230), ('\u06e3', '\u06e3', 220),
-        ('\u06e4', '\u06e4', 230), ('\u06e7', '\u06e8', 230),
-        ('\u06ea', '\u06ea', 220), ('\u06eb', '\u06ec', 230),
-        ('\u06ed', '\u06ed', 220), ('\u0711', '\u0711', 36),
-        ('\u0730', '\u0730', 230), ('\u0731', '\u0731', 220),
-        ('\u0732', '\u0733', 230), ('\u0734', '\u0734', 220),
-        ('\u0735', '\u0736', 230), ('\u0737', '\u0739', 220),
-        ('\u073a', '\u073a', 230), ('\u073b', '\u073c', 220),
-        ('\u073d', '\u073d', 230), ('\u073e', '\u073e', 220),
-        ('\u073f', '\u0741', 230), ('\u0742', '\u0742', 220),
-        ('\u0743', '\u0743', 230), ('\u0744', '\u0744', 220),
-        ('\u0745', '\u0745', 230), ('\u0746', '\u0746', 220),
-        ('\u0747', '\u0747', 230), ('\u0748', '\u0748', 220),
-        ('\u0749', '\u074a', 230), ('\u07eb', '\u07f1', 230),
-        ('\u07f2', '\u07f2', 220), ('\u07f3', '\u07f3', 230),
-        ('\u0816', '\u0819', 230), ('\u081b', '\u0823', 230),
-        ('\u0825', '\u0827', 230), ('\u0829', '\u082d', 230),
-        ('\u0859', '\u085b', 220), ('\u08e4', '\u08e5', 230),
-        ('\u08e6', '\u08e6', 220), ('\u08e7', '\u08e8', 230),
-        ('\u08e9', '\u08e9', 220), ('\u08ea', '\u08ec', 230),
-        ('\u08ed', '\u08ef', 220), ('\u08f0', '\u08f0', 27),
-        ('\u08f1', '\u08f1', 28), ('\u08f2', '\u08f2', 29),
-        ('\u08f3', '\u08f5', 230), ('\u08f6', '\u08f6', 220),
-        ('\u08f7', '\u08f8', 230), ('\u08f9', '\u08fa', 220),
-        ('\u08fb', '\u08fe', 230), ('\u093c', '\u093c', 7),
-        ('\u094d', '\u094d', 9), ('\u0951', '\u0951', 230),
-        ('\u0952', '\u0952', 220), ('\u0953', '\u0954', 230),
-        ('\u09bc', '\u09bc', 7), ('\u09cd', '\u09cd', 9),
-        ('\u0a3c', '\u0a3c', 7), ('\u0a4d', '\u0a4d', 9),
-        ('\u0abc', '\u0abc', 7), ('\u0acd', '\u0acd', 9),
-        ('\u0b3c', '\u0b3c', 7), ('\u0b4d', '\u0b4d', 9),
-        ('\u0bcd', '\u0bcd', 9), ('\u0c4d', '\u0c4d', 9),
-        ('\u0c55', '\u0c55', 84), ('\u0c56', '\u0c56', 91),
-        ('\u0cbc', '\u0cbc', 7), ('\u0ccd', '\u0ccd', 9),
-        ('\u0d4d', '\u0d4d', 9), ('\u0dca', '\u0dca', 9),
-        ('\u0e38', '\u0e39', 103), ('\u0e3a', '\u0e3a', 9),
-        ('\u0e48', '\u0e4b', 107), ('\u0eb8', '\u0eb9', 118),
-        ('\u0ec8', '\u0ecb', 122), ('\u0f18', '\u0f19', 220),
-        ('\u0f35', '\u0f35', 220), ('\u0f37', '\u0f37', 220),
-        ('\u0f39', '\u0f39', 216), ('\u0f71', '\u0f71', 129),
-        ('\u0f72', '\u0f72', 130), ('\u0f74', '\u0f74', 132),
-        ('\u0f7a', '\u0f7d', 130), ('\u0f80', '\u0f80', 130),
-        ('\u0f82', '\u0f83', 230), ('\u0f84', '\u0f84', 9),
-        ('\u0f86', '\u0f87', 230), ('\u0fc6', '\u0fc6', 220),
-        ('\u1037', '\u1037', 7), ('\u1039', '\u103a', 9),
-        ('\u108d', '\u108d', 220), ('\u135d', '\u135f', 230),
-        ('\u1714', '\u1714', 9), ('\u1734', '\u1734', 9),
-        ('\u17d2', '\u17d2', 9), ('\u17dd', '\u17dd', 230),
-        ('\u18a9', '\u18a9', 228), ('\u1939', '\u1939', 222),
-        ('\u193a', '\u193a', 230), ('\u193b', '\u193b', 220),
-        ('\u1a17', '\u1a17', 230), ('\u1a18', '\u1a18', 220),
-        ('\u1a60', '\u1a60', 9), ('\u1a75', '\u1a7c', 230),
-        ('\u1a7f', '\u1a7f', 220), ('\u1b34', '\u1b34', 7),
-        ('\u1b44', '\u1b44', 9), ('\u1b6b', '\u1b6b', 230),
-        ('\u1b6c', '\u1b6c', 220), ('\u1b6d', '\u1b73', 230),
-        ('\u1baa', '\u1bab', 9), ('\u1be6', '\u1be6', 7),
-        ('\u1bf2', '\u1bf3', 9), ('\u1c37', '\u1c37', 7),
-        ('\u1cd0', '\u1cd2', 230), ('\u1cd4', '\u1cd4', 1),
-        ('\u1cd5', '\u1cd9', 220), ('\u1cda', '\u1cdb', 230),
-        ('\u1cdc', '\u1cdf', 220), ('\u1ce0', '\u1ce0', 230),
-        ('\u1ce2', '\u1ce8', 1), ('\u1ced', '\u1ced', 220),
-        ('\u1cf4', '\u1cf4', 230), ('\u1dc0', '\u1dc1', 230),
-        ('\u1dc2', '\u1dc2', 220), ('\u1dc3', '\u1dc9', 230),
-        ('\u1dca', '\u1dca', 220), ('\u1dcb', '\u1dcc', 230),
-        ('\u1dcd', '\u1dcd', 234), ('\u1dce', '\u1dce', 214),
-        ('\u1dcf', '\u1dcf', 220), ('\u1dd0', '\u1dd0', 202),
-        ('\u1dd1', '\u1de6', 230), ('\u1dfc', '\u1dfc', 233),
-        ('\u1dfd', '\u1dfd', 220), ('\u1dfe', '\u1dfe', 230),
-        ('\u1dff', '\u1dff', 220), ('\u20d0', '\u20d1', 230),
-        ('\u20d2', '\u20d3', 1), ('\u20d4', '\u20d7', 230),
-        ('\u20d8', '\u20da', 1), ('\u20db', '\u20dc', 230),
-        ('\u20e1', '\u20e1', 230), ('\u20e5', '\u20e6', 1),
-        ('\u20e7', '\u20e7', 230), ('\u20e8', '\u20e8', 220),
-        ('\u20e9', '\u20e9', 230), ('\u20ea', '\u20eb', 1),
-        ('\u20ec', '\u20ef', 220), ('\u20f0', '\u20f0', 230),
-        ('\u2cef', '\u2cf1', 230), ('\u2d7f', '\u2d7f', 9),
-        ('\u2de0', '\u2dff', 230), ('\u302a', '\u302a', 218),
-        ('\u302b', '\u302b', 228), ('\u302c', '\u302c', 232),
-        ('\u302d', '\u302d', 222), ('\u302e', '\u302f', 224),
-        ('\u3099', '\u309a', 8), ('\ua66f', '\ua66f', 230),
-        ('\ua674', '\ua67d', 230), ('\ua69f', '\ua69f', 230),
-        ('\ua6f0', '\ua6f1', 230), ('\ua806', '\ua806', 9),
-        ('\ua8c4', '\ua8c4', 9), ('\ua8e0', '\ua8f1', 230),
-        ('\ua92b', '\ua92d', 220), ('\ua953', '\ua953', 9),
-        ('\ua9b3', '\ua9b3', 7), ('\ua9c0', '\ua9c0', 9),
-        ('\uaab0', '\uaab0', 230), ('\uaab2', '\uaab3', 230),
-        ('\uaab4', '\uaab4', 220), ('\uaab7', '\uaab8', 230),
-        ('\uaabe', '\uaabf', 230), ('\uaac1', '\uaac1', 230),
-        ('\uaaf6', '\uaaf6', 9), ('\uabed', '\uabed', 9),
-        ('\ufb1e', '\ufb1e', 26), ('\ufe20', '\ufe26', 230),
-        ('\U000101fd', '\U000101fd', 220), ('\U00010a0d', '\U00010a0d', 220),
-        ('\U00010a0f', '\U00010a0f', 230), ('\U00010a38', '\U00010a38', 230),
-        ('\U00010a39', '\U00010a39', 1), ('\U00010a3a', '\U00010a3a', 220),
-        ('\U00010a3f', '\U00010a3f', 9), ('\U00011046', '\U00011046', 9),
-        ('\U000110b9', '\U000110b9', 9), ('\U000110ba', '\U000110ba', 7),
-        ('\U00011100', '\U00011102', 230), ('\U00011133', '\U00011134', 9),
-        ('\U000111c0', '\U000111c0', 9), ('\U000116b6', '\U000116b6', 9),
-        ('\U000116b7', '\U000116b7', 7), ('\U0001d165', '\U0001d166', 216),
-        ('\U0001d167', '\U0001d169', 1), ('\U0001d16d', '\U0001d16d', 226),
-        ('\U0001d16e', '\U0001d172', 216), ('\U0001d17b', '\U0001d182', 220),
-        ('\U0001d185', '\U0001d189', 230), ('\U0001d18a', '\U0001d18b', 220),
-        ('\U0001d1aa', '\U0001d1ad', 230), ('\U0001d242', '\U0001d244', 230)
-    ];
-
-    pub fn canonical_combining_class(c: char) -> u8 {
-        bsearch_range_value_table(c, combining_class_table)
-    }
-}
index d53ecabd5a9cb147e5093e7ce172dd91acf1835a..1e96588dac5f896a9217b791228cac9533f0a52d 100644 (file)
 use slice::{MutableOrdVector, MutableVectorAllocating, CloneableVector};
 use slice::{Items, MutItems};
 
+
+#[doc(hidden)]
+pub static PTR_MARKER: u8 = 0;
+
 /// An owned, growable vector.
 ///
 /// # Examples
@@ -71,7 +75,11 @@ impl<T> Vec<T> {
     /// ```
     #[inline]
     pub fn new() -> Vec<T> {
-        Vec { len: 0, cap: 0, ptr: 0 as *mut T }
+        // We want ptr to never be NULL so instead we set it to some arbitrary
+        // non-null value which is fine since we never call deallocate on the ptr
+        // if cap is 0. The reason for this is because the pointer of a slice
+        // being NULL would break the null pointer optimization for enums.
+        Vec { len: 0, cap: 0, ptr: &PTR_MARKER as *const _ as *mut T }
     }
 
     /// Constructs a new, empty `Vec` with the specified capacity.
@@ -88,7 +96,7 @@ pub fn new() -> Vec<T> {
     #[inline]
     pub fn with_capacity(capacity: uint) -> Vec<T> {
         if mem::size_of::<T>() == 0 {
-            Vec { len: 0, cap: uint::MAX, ptr: 0 as *mut T }
+            Vec { len: 0, cap: uint::MAX, ptr: &PTR_MARKER as *const _ as *mut T }
         } else if capacity == 0 {
             Vec::new()
         } else {
@@ -197,7 +205,9 @@ pub fn append(mut self, second: &[T]) -> Vec<T> {
     /// ```
     #[inline]
     pub fn from_slice(values: &[T]) -> Vec<T> {
-        values.iter().map(|x| x.clone()).collect()
+        let mut vector = Vec::new();
+        vector.push_all(values);
+        vector
     }
 
     /// Constructs a `Vec` with copies of a value.
@@ -238,7 +248,21 @@ pub fn from_elem(length: uint, value: T) -> Vec<T> {
     /// ```
     #[inline]
     pub fn push_all(&mut self, other: &[T]) {
-        self.extend(other.iter().map(|e| e.clone()));
+        self.reserve_additional(other.len());
+
+        for i in range(0, other.len()) {
+            let len = self.len();
+
+            // Unsafe code so this can be optimised to a memcpy (or something similarly
+            // fast) when T is Copy. LLVM is easily confused, so any extra operations
+            // during the loop can prevent this optimisation.
+            unsafe {
+                ptr::write(
+                    self.as_mut_slice().unsafe_mut_ref(len),
+                    other.unsafe_ref(i).clone());
+                self.set_len(len + 1);
+            }
+        }
     }
 
     /// Grows the `Vec` in-place.
@@ -318,24 +342,7 @@ pub fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
 #[unstable]
 impl<T:Clone> Clone for Vec<T> {
     fn clone(&self) -> Vec<T> {
-        let len = self.len;
-        let mut vector = Vec::with_capacity(len);
-        // Unsafe code so this can be optimised to a memcpy (or something
-        // similarly fast) when T is Copy. LLVM is easily confused, so any
-        // extra operations during the loop can prevent this optimisation
-        {
-            let this_slice = self.as_slice();
-            while vector.len < len {
-                unsafe {
-                    let len = vector.len;
-                    ptr::write(
-                        vector.as_mut_slice().unsafe_mut_ref(len),
-                        this_slice.unsafe_ref(len).clone());
-                }
-                vector.len += 1;
-            }
-        }
-        vector
+        Vec::from_slice(self.as_slice())
     }
 
     fn clone_from(&mut self, other: &Vec<T>) {
@@ -351,8 +358,8 @@ fn clone_from(&mut self, other: &Vec<T>) {
 
         // self.len <= other.len due to the truncate above, so the
         // slice here is always in-bounds.
-        let len = self.len();
-        self.extend(other.slice_from(len).iter().map(|x| x.clone()));
+        let slice = other.slice_from(self.len());
+        self.push_all(slice);
     }
 }
 
@@ -1206,15 +1213,7 @@ pub fn init<'a>(&'a self) -> &'a [T] {
     /// would also make any pointers to it invalid.
     #[inline]
     pub fn as_ptr(&self) -> *const T {
-        // If we have a 0-sized vector, then the base pointer should not be NULL
-        // because an iterator over the slice will attempt to yield the base
-        // pointer as the first element in the vector, but this will end up
-        // being Some(NULL) which is optimized to None.
-        if mem::size_of::<T>() == 0 {
-            1 as *const T
-        } else {
-            self.ptr as *const T
-        }
+        self.ptr as *const T
     }
 
     /// Returns a mutable unsafe pointer to the vector's buffer.
@@ -1226,12 +1225,7 @@ pub fn as_ptr(&self) -> *const T {
     /// would also make any pointers to it invalid.
     #[inline]
     pub fn as_mut_ptr(&mut self) -> *mut T {
-        // see above for the 0-size check
-        if mem::size_of::<T>() == 0 {
-            1 as *mut T
-        } else {
-            self.ptr
-        }
+        self.ptr
     }
 
     /// Retains only the elements specified by the predicate.
@@ -1555,7 +1549,6 @@ pub unsafe fn from_buf<T>(ptr: *const T, elts: uint) -> Vec<T> {
     }
 }
 
-
 #[cfg(test)]
 mod tests {
     extern crate test;
@@ -1857,107 +1850,480 @@ fn drop(&mut self) {
     #[bench]
     fn bench_new(b: &mut Bencher) {
         b.iter(|| {
-            let v: Vec<int> = Vec::new();
+            let v: Vec<uint> = Vec::new();
+            assert_eq!(v.len(), 0);
             assert_eq!(v.capacity(), 0);
-            assert!(v.as_slice() == []);
         })
     }
 
-    #[bench]
-    fn bench_with_capacity_0(b: &mut Bencher) {
+    fn do_bench_with_capacity(b: &mut Bencher, src_len: uint) {
+        b.bytes = src_len as u64;
+
         b.iter(|| {
-            let v: Vec<int> = Vec::with_capacity(0);
-            assert_eq!(v.capacity(), 0);
-            assert!(v.as_slice() == []);
+            let v: Vec<uint> = Vec::with_capacity(src_len);
+            assert_eq!(v.len(), 0);
+            assert_eq!(v.capacity(), src_len);
         })
     }
 
+    #[bench]
+    fn bench_with_capacity_0000(b: &mut Bencher) {
+        do_bench_with_capacity(b, 0)
+    }
 
     #[bench]
-    fn bench_with_capacity_5(b: &mut Bencher) {
-        b.iter(|| {
-            let v: Vec<int> = Vec::with_capacity(5);
-            assert_eq!(v.capacity(), 5);
-            assert!(v.as_slice() == []);
-        })
+    fn bench_with_capacity_0010(b: &mut Bencher) {
+        do_bench_with_capacity(b, 10)
+    }
+
+    #[bench]
+    fn bench_with_capacity_0100(b: &mut Bencher) {
+        do_bench_with_capacity(b, 100)
     }
 
     #[bench]
-    fn bench_with_capacity_100(b: &mut Bencher) {
+    fn bench_with_capacity_1000(b: &mut Bencher) {
+        do_bench_with_capacity(b, 1000)
+    }
+
+    fn do_bench_from_fn(b: &mut Bencher, src_len: uint) {
+        b.bytes = src_len as u64;
+
         b.iter(|| {
-            let v: Vec<int> = Vec::with_capacity(100);
-            assert_eq!(v.capacity(), 100);
-            assert!(v.as_slice() == []);
+            let dst = Vec::from_fn(src_len, |i| i);
+            assert_eq!(dst.len(), src_len);
+            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
         })
     }
 
     #[bench]
-    fn bench_from_fn_0(b: &mut Bencher) {
+    fn bench_from_fn_0000(b: &mut Bencher) {
+        do_bench_from_fn(b, 0)
+    }
+
+    #[bench]
+    fn bench_from_fn_0010(b: &mut Bencher) {
+        do_bench_from_fn(b, 10)
+    }
+
+    #[bench]
+    fn bench_from_fn_0100(b: &mut Bencher) {
+        do_bench_from_fn(b, 100)
+    }
+
+    #[bench]
+    fn bench_from_fn_1000(b: &mut Bencher) {
+        do_bench_from_fn(b, 1000)
+    }
+
+    fn do_bench_from_elem(b: &mut Bencher, src_len: uint) {
+        b.bytes = src_len as u64;
+
         b.iter(|| {
-            let v: Vec<int> = Vec::from_fn(0, |_| 5);
-            assert!(v.as_slice() == []);
+            let dst: Vec<uint> = Vec::from_elem(src_len, 5);
+            assert_eq!(dst.len(), src_len);
+            assert!(dst.iter().all(|x| *x == 5));
         })
     }
 
     #[bench]
-    fn bench_from_fn_5(b: &mut Bencher) {
+    fn bench_from_elem_0000(b: &mut Bencher) {
+        do_bench_from_elem(b, 0)
+    }
+
+    #[bench]
+    fn bench_from_elem_0010(b: &mut Bencher) {
+        do_bench_from_elem(b, 10)
+    }
+
+    #[bench]
+    fn bench_from_elem_0100(b: &mut Bencher) {
+        do_bench_from_elem(b, 100)
+    }
+
+    #[bench]
+    fn bench_from_elem_1000(b: &mut Bencher) {
+        do_bench_from_elem(b, 1000)
+    }
+
+    fn do_bench_from_slice(b: &mut Bencher, src_len: uint) {
+        let src: Vec<uint> = FromIterator::from_iter(range(0, src_len));
+
+        b.bytes = src_len as u64;
+
         b.iter(|| {
-            let v: Vec<int> = Vec::from_fn(5, |_| 5);
-            assert!(v.as_slice() == [5, 5, 5, 5, 5]);
-        })
+            let dst = Vec::from_slice(src.clone().as_slice());
+            assert_eq!(dst.len(), src_len);
+            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+        });
+    }
+
+    #[bench]
+    fn bench_from_slice_0000(b: &mut Bencher) {
+        do_bench_from_slice(b, 0)
+    }
+
+    #[bench]
+    fn bench_from_slice_0010(b: &mut Bencher) {
+        do_bench_from_slice(b, 10)
+    }
+
+    #[bench]
+    fn bench_from_slice_0100(b: &mut Bencher) {
+        do_bench_from_slice(b, 100)
     }
 
     #[bench]
-    fn bench_from_slice_0(b: &mut Bencher) {
+    fn bench_from_slice_1000(b: &mut Bencher) {
+        do_bench_from_slice(b, 1000)
+    }
+
+    fn do_bench_from_iter(b: &mut Bencher, src_len: uint) {
+        let src: Vec<uint> = FromIterator::from_iter(range(0, src_len));
+
+        b.bytes = src_len as u64;
+
         b.iter(|| {
-            let v: Vec<int> = Vec::from_slice([]);
-            assert!(v.as_slice() == []);
-        })
+            let dst: Vec<uint> = FromIterator::from_iter(src.clone().move_iter());
+            assert_eq!(dst.len(), src_len);
+            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+        });
+    }
+
+    #[bench]
+    fn bench_from_iter_0000(b: &mut Bencher) {
+        do_bench_from_iter(b, 0)
     }
 
     #[bench]
-    fn bench_from_slice_5(b: &mut Bencher) {
+    fn bench_from_iter_0010(b: &mut Bencher) {
+        do_bench_from_iter(b, 10)
+    }
+
+    #[bench]
+    fn bench_from_iter_0100(b: &mut Bencher) {
+        do_bench_from_iter(b, 100)
+    }
+
+    #[bench]
+    fn bench_from_iter_1000(b: &mut Bencher) {
+        do_bench_from_iter(b, 1000)
+    }
+
+    fn do_bench_extend(b: &mut Bencher, dst_len: uint, src_len: uint) {
+        let dst: Vec<uint> = FromIterator::from_iter(range(0, dst_len));
+        let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
+
+        b.bytes = src_len as u64;
+
         b.iter(|| {
-            let v: Vec<int> = Vec::from_slice([1i, 2, 3, 4, 5]);
-            assert!(v.as_slice() == [1, 2, 3, 4, 5]);
-        })
+            let mut dst = dst.clone();
+            dst.extend(src.clone().move_iter());
+            assert_eq!(dst.len(), dst_len + src_len);
+            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+        });
+    }
+
+    #[bench]
+    fn bench_extend_0000_0000(b: &mut Bencher) {
+        do_bench_extend(b, 0, 0)
+    }
+
+    #[bench]
+    fn bench_extend_0000_0010(b: &mut Bencher) {
+        do_bench_extend(b, 0, 10)
+    }
+
+    #[bench]
+    fn bench_extend_0000_0100(b: &mut Bencher) {
+        do_bench_extend(b, 0, 100)
+    }
+
+    #[bench]
+    fn bench_extend_0000_1000(b: &mut Bencher) {
+        do_bench_extend(b, 0, 1000)
     }
 
     #[bench]
-    fn bench_from_iter_0(b: &mut Bencher) {
+    fn bench_extend_0010_0010(b: &mut Bencher) {
+        do_bench_extend(b, 10, 10)
+    }
+
+    #[bench]
+    fn bench_extend_0100_0100(b: &mut Bencher) {
+        do_bench_extend(b, 100, 100)
+    }
+
+    #[bench]
+    fn bench_extend_1000_1000(b: &mut Bencher) {
+        do_bench_extend(b, 1000, 1000)
+    }
+
+    fn do_bench_push_all(b: &mut Bencher, dst_len: uint, src_len: uint) {
+        let dst: Vec<uint> = FromIterator::from_iter(range(0, dst_len));
+        let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
+
+        b.bytes = src_len as u64;
+
         b.iter(|| {
-            let v0: Vec<int> = vec!();
-            let v1: Vec<int> = FromIterator::from_iter(v0.move_iter());
-            assert!(v1.as_slice() == []);
-        })
+            let mut dst = dst.clone();
+            dst.push_all(src.as_slice());
+            assert_eq!(dst.len(), dst_len + src_len);
+            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+        });
+    }
+
+    #[bench]
+    fn bench_push_all_0000_0000(b: &mut Bencher) {
+        do_bench_push_all(b, 0, 0)
+    }
+
+    #[bench]
+    fn bench_push_all_0000_0010(b: &mut Bencher) {
+        do_bench_push_all(b, 0, 10)
+    }
+
+    #[bench]
+    fn bench_push_all_0000_0100(b: &mut Bencher) {
+        do_bench_push_all(b, 0, 100)
+    }
+
+    #[bench]
+    fn bench_push_all_0000_1000(b: &mut Bencher) {
+        do_bench_push_all(b, 0, 1000)
     }
 
     #[bench]
-    fn bench_from_iter_5(b: &mut Bencher) {
+    fn bench_push_all_0010_0010(b: &mut Bencher) {
+        do_bench_push_all(b, 10, 10)
+    }
+
+    #[bench]
+    fn bench_push_all_0100_0100(b: &mut Bencher) {
+        do_bench_push_all(b, 100, 100)
+    }
+
+    #[bench]
+    fn bench_push_all_1000_1000(b: &mut Bencher) {
+        do_bench_push_all(b, 1000, 1000)
+    }
+
+    fn do_bench_push_all_move(b: &mut Bencher, dst_len: uint, src_len: uint) {
+        let dst: Vec<uint> = FromIterator::from_iter(range(0u, dst_len));
+        let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
+
+        b.bytes = src_len as u64;
+
         b.iter(|| {
-            let v0: Vec<int> = vec!(1, 2, 3, 4, 5);
-            let v1: Vec<int> = FromIterator::from_iter(v0.move_iter());
-            assert!(v1.as_slice() == [1, 2, 3, 4, 5]);
-        })
+            let mut dst = dst.clone();
+            dst.push_all_move(src.clone());
+            assert_eq!(dst.len(), dst_len + src_len);
+            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+        });
+    }
+
+    #[bench]
+    fn bench_push_all_move_0000_0000(b: &mut Bencher) {
+        do_bench_push_all_move(b, 0, 0)
     }
 
     #[bench]
-    fn bench_extend_0(b: &mut Bencher) {
+    fn bench_push_all_move_0000_0010(b: &mut Bencher) {
+        do_bench_push_all_move(b, 0, 10)
+    }
+
+    #[bench]
+    fn bench_push_all_move_0000_0100(b: &mut Bencher) {
+        do_bench_push_all_move(b, 0, 100)
+    }
+
+    #[bench]
+    fn bench_push_all_move_0000_1000(b: &mut Bencher) {
+        do_bench_push_all_move(b, 0, 1000)
+    }
+
+    #[bench]
+    fn bench_push_all_move_0010_0010(b: &mut Bencher) {
+        do_bench_push_all_move(b, 10, 10)
+    }
+
+    #[bench]
+    fn bench_push_all_move_0100_0100(b: &mut Bencher) {
+        do_bench_push_all_move(b, 100, 100)
+    }
+
+    #[bench]
+    fn bench_push_all_move_1000_1000(b: &mut Bencher) {
+        do_bench_push_all_move(b, 1000, 1000)
+    }
+
+    fn do_bench_clone(b: &mut Bencher, src_len: uint) {
+        let src: Vec<uint> = FromIterator::from_iter(range(0, src_len));
+
+        b.bytes = src_len as u64;
+
         b.iter(|| {
-            let v0: Vec<int> = vec!();
-            let mut v1: Vec<int> = vec!(1, 2, 3, 4, 5);
-            v1.extend(v0.move_iter());
-            assert!(v1.as_slice() == [1, 2, 3, 4, 5]);
-        })
+            let dst = src.clone();
+            assert_eq!(dst.len(), src_len);
+            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+        });
+    }
+
+    #[bench]
+    fn bench_clone_0000(b: &mut Bencher) {
+        do_bench_clone(b, 0)
+    }
+
+    #[bench]
+    fn bench_clone_0010(b: &mut Bencher) {
+        do_bench_clone(b, 10)
+    }
+
+    #[bench]
+    fn bench_clone_0100(b: &mut Bencher) {
+        do_bench_clone(b, 100)
     }
 
     #[bench]
-    fn bench_extend_5(b: &mut Bencher) {
+    fn bench_clone_1000(b: &mut Bencher) {
+        do_bench_clone(b, 1000)
+    }
+
+    fn do_bench_clone_from(b: &mut Bencher, times: uint, dst_len: uint, src_len: uint) {
+        let dst: Vec<uint> = FromIterator::from_iter(range(0, src_len));
+        let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
+
+        b.bytes = (times * src_len) as u64;
+
         b.iter(|| {
-            let v0: Vec<int> = vec!(1, 2, 3, 4, 5);
-            let mut v1: Vec<int> = vec!(1, 2, 3, 4, 5);
-            v1.extend(v0.move_iter());
-            assert!(v1.as_slice() == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]);
-        })
+            let mut dst = dst.clone();
+
+            for _ in range(0, times) {
+                dst.clone_from(&src);
+
+                assert_eq!(dst.len(), src_len);
+                assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x));
+            }
+        });
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 0, 0)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 0, 10)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 0, 100)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 0, 1000)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 10, 10)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 100, 100)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 1000, 1000)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 10, 100)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 100, 1000)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 10, 0)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 100, 10)
+    }
+
+    #[bench]
+    fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
+        do_bench_clone_from(b, 1, 1000, 100)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 0, 0)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 0, 10)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 0, 100)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 0, 1000)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 10, 10)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 100, 100)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 1000, 1000)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 10, 100)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 100, 1000)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 10, 0)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 100, 10)
+    }
+
+    #[bench]
+    fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
+        do_bench_clone_from(b, 10, 1000, 100)
     }
 }
index 8021fa50d8f4647ac3155d8050f9d329c6aff435..e0ac20d2fbf4263d9d49858eba17894369ad7b9c 100644 (file)
 //! This module implements the `Any` trait, which enables dynamic typing
 //! of any `'static` type through runtime reflection.
 //!
-//! `Any` itself can be used to get a `TypeId`, and has more features when used as a trait object.
-//! As `&Any` (a borrowed trait object), it has the `is` and `as_ref` methods, to test if the
-//! contained value is of a given type, and to get a reference to the inner value as a type. As
-//! `&mut Any`, there is also the `as_mut` method, for getting a mutable reference to the inner
-//! value. `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the object.  See
-//! the extension traits (`*Ext`) for the full details.
+//! `Any` itself can be used to get a `TypeId`, and has more features when used
+//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
+//! `as_ref` methods, to test if the contained value is of a given type, and to
+//! get a reference to the inner value as a type. As`&mut Any`, there is also
+//! the `as_mut` method, for getting a mutable reference to the inner value.
+//! `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the
+//! object.  See the extension traits (`*Ext`) for the full details.
+//!
+//! Note that &Any is limited to testing whether a value is of a specified
+//! concrete type, and cannot be used to test whether a type implements a trait.
+//!
+//! # Examples
+//!
+//! Consider a situation where we want to log out a value passed to a function.
+//! We know the value we're working on implements Show, but we don't know its
+//! concrete type.  We want to give special treatment to certain types: in this
+//! case printing out the length of String values prior to their value.
+//! We don't know the concrete type of our value at compile time, so we need to
+//! use runtime reflection instead.
+//!
+//! ```rust
+//! use std::fmt::Show;
+//! use std::any::{Any, AnyRefExt};
+//!
+//! // Logger function for any type that implements Show.
+//! fn log<T: Any+Show>(value: &T) {
+//!     let value_any = value as &Any;
+//!
+//!     // try to convert our value to a String.  If successful, we want to
+//!     // output the String's length as well as its value.  If not, it's a
+//!     // different type: just print it out unadorned.
+//!     match value_any.as_ref::<String>() {
+//!         Some(as_string) => {
+//!             println!("String ({}): {}", as_string.len(), as_string);
+//!         }
+//!         None => {
+//!             println!("{}", value);
+//!         }
+//!     }
+//! }
+//!
+//! // This function wants to log its parameter out prior to doing work with it.
+//! fn do_work<T: Show>(value: &T) {
+//!     log(value);
+//!     // ...do some other work
+//! }
+//!
+//! fn main() {
+//!     let my_string = "Hello World".to_string();
+//!     do_work(&my_string);
+//!
+//!     let my_i8: i8 = 100;
+//!     do_work(&my_i8);
+//! }
+//! ```
 
 use mem::{transmute, transmute_copy};
 use option::{Option, Some, None};
index 971799acc7862e61efb2112990ddf8fa045a5bef..e022fa2c370f2b8aeb69d3a99f3419c6199aee24 100644 (file)
@@ -141,7 +141,7 @@ pub fn swap(&self, val: bool, order: Ordering) -> bool {
     ///
     /// fn with_lock(spinlock: &Arc<AtomicBool>, f: || -> ()) {
     ///     // CAS loop until we are able to replace `false` with `true`
-    ///     while spinlock.compare_and_swap(false, true, SeqCst) == false {
+    ///     while spinlock.compare_and_swap(false, true, SeqCst) != false {
     ///         // Since tasks may not be preemptive (if they are green threads)
     ///         // yield to the scheduler to let the other task run. Low level
     ///         // concurrent code needs to take into account Rust's two threading
index 355ee7c7a16f010c48b2f954b4d58eef7e2adbcb..51b5d0aded800b2fd6ec3fbc0d9c72856e3fb693 100644 (file)
 use ty::Unsafe;
 
 /// A mutable memory location that admits only `Copy` data.
+#[unstable = "likely to be renamed; otherwise stable"]
 pub struct Cell<T> {
     value: Unsafe<T>,
     noshare: marker::NoShare,
 }
 
+#[stable]
 impl<T:Copy> Cell<T> {
     /// Creates a new `Cell` containing the given value.
     pub fn new(value: T) -> Cell<T> {
@@ -192,13 +194,14 @@ pub fn set(&self, value: T) {
     }
 }
 
-#[unstable]
+#[unstable = "waiting for `Clone` trait to become stable"]
 impl<T:Copy> Clone for Cell<T> {
     fn clone(&self) -> Cell<T> {
         Cell::new(self.get())
     }
 }
 
+#[unstable = "waiting for `PartialEq` trait to become stable"]
 impl<T:PartialEq + Copy> PartialEq for Cell<T> {
     fn eq(&self, other: &Cell<T>) -> bool {
         self.get() == other.get()
@@ -206,6 +209,7 @@ fn eq(&self, other: &Cell<T>) -> bool {
 }
 
 /// A mutable memory location with dynamically checked borrow rules
+#[unstable = "likely to be renamed; otherwise stable"]
 pub struct RefCell<T> {
     value: Unsafe<T>,
     borrow: Cell<BorrowFlag>,
@@ -221,6 +225,7 @@ pub struct RefCell<T> {
 
 impl<T> RefCell<T> {
     /// Create a new `RefCell` containing `value`
+    #[stable]
     pub fn new(value: T) -> RefCell<T> {
         RefCell {
             value: Unsafe::new(value),
@@ -231,6 +236,7 @@ pub fn new(value: T) -> RefCell<T> {
     }
 
     /// Consumes the `RefCell`, returning the wrapped value.
+    #[unstable = "may be renamed, depending on global conventions"]
     pub fn unwrap(self) -> T {
         debug_assert!(self.borrow.get() == UNUSED);
         unsafe{self.value.unwrap()}
@@ -242,6 +248,7 @@ pub fn unwrap(self) -> T {
     /// immutable borrows can be taken out at the same time.
     ///
     /// Returns `None` if the value is currently mutably borrowed.
+    #[unstable = "may be renamed, depending on global conventions"]
     pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
         match self.borrow.get() {
             WRITING => None,
@@ -260,6 +267,7 @@ pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
     /// # Failure
     ///
     /// Fails if the value is currently mutably borrowed.
+    #[unstable]
     pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
         match self.try_borrow() {
             Some(ptr) => ptr,
@@ -273,6 +281,7 @@ pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
     /// cannot be borrowed while this borrow is active.
     ///
     /// Returns `None` if the value is currently borrowed.
+    #[unstable = "may be renamed, depending on global conventions"]
     pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
         match self.borrow.get() {
             UNUSED => {
@@ -291,6 +300,7 @@ pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
     /// # Failure
     ///
     /// Fails if the value is currently borrowed.
+    #[unstable]
     pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
         match self.try_borrow_mut() {
             Some(ptr) => ptr,
@@ -299,13 +309,14 @@ pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
     }
 }
 
-#[unstable]
+#[unstable = "waiting for `Clone` to become stable"]
 impl<T: Clone> Clone for RefCell<T> {
     fn clone(&self) -> RefCell<T> {
         RefCell::new(self.borrow().clone())
     }
 }
 
+#[unstable = "waiting for `PartialEq` to become stable"]
 impl<T: PartialEq> PartialEq for RefCell<T> {
     fn eq(&self, other: &RefCell<T>) -> bool {
         *self.borrow() == *other.borrow()
@@ -313,6 +324,7 @@ fn eq(&self, other: &RefCell<T>) -> bool {
 }
 
 /// Wraps a borrowed reference to a value in a `RefCell` box.
+#[unstable]
 pub struct Ref<'b, T> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
@@ -320,6 +332,7 @@ pub struct Ref<'b, T> {
 }
 
 #[unsafe_destructor]
+#[unstable]
 impl<'b, T> Drop for Ref<'b, T> {
     fn drop(&mut self) {
         let borrow = self._parent.borrow.get();
@@ -328,6 +341,7 @@ fn drop(&mut self) {
     }
 }
 
+#[unstable = "waiting for `Deref` to become stable"]
 impl<'b, T> Deref<T> for Ref<'b, T> {
     #[inline]
     fn deref<'a>(&'a self) -> &'a T {
@@ -341,7 +355,7 @@ fn deref<'a>(&'a self) -> &'a T {
 ///
 /// A `Clone` implementation would interfere with the widespread
 /// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
-#[experimental]
+#[experimental = "likely to be moved to a method, pending language changes"]
 pub fn clone_ref<'b, T>(orig: &Ref<'b, T>) -> Ref<'b, T> {
     // Since this Ref exists, we know the borrow flag
     // is not set to WRITING.
@@ -355,6 +369,7 @@ pub fn clone_ref<'b, T>(orig: &Ref<'b, T>) -> Ref<'b, T> {
 }
 
 /// Wraps a mutable borrowed reference to a value in a `RefCell` box.
+#[unstable]
 pub struct RefMut<'b, T> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
@@ -362,6 +377,7 @@ pub struct RefMut<'b, T> {
 }
 
 #[unsafe_destructor]
+#[unstable]
 impl<'b, T> Drop for RefMut<'b, T> {
     fn drop(&mut self) {
         let borrow = self._parent.borrow.get();
@@ -370,6 +386,7 @@ fn drop(&mut self) {
     }
 }
 
+#[unstable = "waiting for `Deref` to become stable"]
 impl<'b, T> Deref<T> for RefMut<'b, T> {
     #[inline]
     fn deref<'a>(&'a self) -> &'a T {
@@ -377,6 +394,7 @@ fn deref<'a>(&'a self) -> &'a T {
     }
 }
 
+#[unstable = "waiting for `DerefMut` to become stable"]
 impl<'b, T> DerefMut<T> for RefMut<'b, T> {
     #[inline]
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
index da67772d0f1229c3a311bfeaf2166c549c6f1037..99c5722699e8d966180fc86a68971f3dab5b4879 100644 (file)
@@ -8,20 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Character manipulation (`char` type, Unicode Scalar Value)
+//! Character manipulation.
 //!
-//! This module  provides the `Char` trait, as well as its implementation
-//! for the primitive `char` type, in order to allow basic character manipulation.
-//!
-//! A `char` actually represents a
-//! *[Unicode Scalar Value](http://www.unicode.org/glossary/#unicode_scalar_value)*,
-//! as it can contain any Unicode code point except high-surrogate and
-//! low-surrogate code points.
-//!
-//! As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
-//! (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
-//! however the converse is not always true due to the above range limits
-//! and, as such, should be performed via the `from_u32` function..
+//! For more details, see ::unicode::char (a.k.a. std::char)
 
 #![allow(non_snake_case_functions)]
 #![doc(primitive = "char")]
 use mem::transmute;
 use option::{None, Option, Some};
 use iter::{Iterator, range_step};
-use unicode::{derived_property, property, general_category, conversions};
-
-/// Returns the canonical decomposition of a character.
-pub use unicode::normalization::decompose_canonical;
-/// Returns the compatibility decomposition of a character.
-pub use unicode::normalization::decompose_compatible;
 
 // UTF-8 ranges and tags for encoding characters
 static TAG_CONT: u8    = 0b1000_0000u8;
@@ -93,84 +76,6 @@ pub fn from_u32(i: u32) -> Option<char> {
     }
 }
 
-/// Returns whether the specified `char` is considered a Unicode alphabetic
-/// code point
-pub fn is_alphabetic(c: char) -> bool   { derived_property::Alphabetic(c) }
-
-/// Returns whether the specified `char` satisfies the 'XID_Start' Unicode property
-///
-/// 'XID_Start' is a Unicode Derived Property specified in
-/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-/// mostly similar to ID_Start but modified for closure under NFKx.
-pub fn is_XID_start(c: char) -> bool    { derived_property::XID_Start(c) }
-
-/// Returns whether the specified `char` satisfies the 'XID_Continue' Unicode property
-///
-/// 'XID_Continue' is a Unicode Derived Property specified in
-/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-/// mostly similar to 'ID_Continue' but modified for closure under NFKx.
-pub fn is_XID_continue(c: char) -> bool { derived_property::XID_Continue(c) }
-
-///
-/// Indicates whether a `char` is in lower case
-///
-/// This is defined according to the terms of the Unicode Derived Core Property 'Lowercase'.
-///
-#[inline]
-pub fn is_lowercase(c: char) -> bool { derived_property::Lowercase(c) }
-
-///
-/// Indicates whether a `char` is in upper case
-///
-/// This is defined according to the terms of the Unicode Derived Core Property 'Uppercase'.
-///
-#[inline]
-pub fn is_uppercase(c: char) -> bool { derived_property::Uppercase(c) }
-
-///
-/// Indicates whether a `char` is whitespace
-///
-/// Whitespace is defined in terms of the Unicode Property 'White_Space'.
-///
-#[inline]
-pub fn is_whitespace(c: char) -> bool {
-    // As an optimization ASCII whitespace characters are checked separately
-    c == ' '
-        || ('\x09' <= c && c <= '\x0d')
-        || property::White_Space(c)
-}
-
-///
-/// Indicates whether a `char` is alphanumeric
-///
-/// Alphanumericness is defined in terms of the Unicode General Categories
-/// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
-///
-#[inline]
-pub fn is_alphanumeric(c: char) -> bool {
-    derived_property::Alphabetic(c)
-        || general_category::Nd(c)
-        || general_category::Nl(c)
-        || general_category::No(c)
-}
-
-///
-/// Indicates whether a `char` is a control code point
-///
-/// Control code points are defined in terms of the Unicode General Category
-/// 'Cc'.
-///
-#[inline]
-pub fn is_control(c: char) -> bool { general_category::Cc(c) }
-
-/// Indicates whether the `char` is numeric (Nd, Nl, or No)
-#[inline]
-pub fn is_digit(c: char) -> bool {
-    general_category::Nd(c)
-        || general_category::Nl(c)
-        || general_category::No(c)
-}
-
 ///
 /// Checks if a `char` parses as a numeric digit in the given radix
 ///
@@ -227,38 +132,6 @@ pub fn to_digit(c: char, radix: uint) -> Option<uint> {
     else { None }
 }
 
-/// Convert a char to its uppercase equivalent
-///
-/// The case-folding performed is the common or simple mapping:
-/// it maps one unicode codepoint (one char in Rust) to its uppercase equivalent according
-/// to the Unicode database at ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
-/// The additional SpecialCasing.txt is not considered here, as it expands to multiple
-/// codepoints in some cases.
-///
-/// A full reference can be found here
-/// http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
-///
-/// # Return value
-///
-/// Returns the char itself if no conversion was made
-#[inline]
-pub fn to_uppercase(c: char) -> char {
-    conversions::to_upper(c)
-}
-
-/// Convert a char to its lowercase equivalent
-///
-/// The case-folding performed is the common or simple mapping
-/// see `to_uppercase` for references and more information
-///
-/// # Return value
-///
-/// Returns the char itself if no conversion if possible
-#[inline]
-pub fn to_lowercase(c: char) -> char {
-    conversions::to_lower(c)
-}
-
 ///
 /// Converts a number to the character representing it
 ///
@@ -355,61 +228,8 @@ pub fn len_utf8_bytes(c: char) -> uint {
     }
 }
 
-/// Useful functions for Unicode characters.
+/// Basic `char` manipulations.
 pub trait Char {
-    /// Returns whether the specified character is considered a Unicode
-    /// alphabetic code point.
-    fn is_alphabetic(&self) -> bool;
-
-    /// Returns whether the specified character satisfies the 'XID_Start'
-    /// Unicode property.
-    ///
-    /// 'XID_Start' is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to ID_Start but modified for closure under NFKx.
-    fn is_XID_start(&self) -> bool;
-
-    /// Returns whether the specified `char` satisfies the 'XID_Continue'
-    /// Unicode property.
-    ///
-    /// 'XID_Continue' is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
-    fn is_XID_continue(&self) -> bool;
-
-
-    /// Indicates whether a character is in lowercase.
-    ///
-    /// This is defined according to the terms of the Unicode Derived Core
-    /// Property `Lowercase`.
-    fn is_lowercase(&self) -> bool;
-
-    /// Indicates whether a character is in uppercase.
-    ///
-    /// This is defined according to the terms of the Unicode Derived Core
-    /// Property `Uppercase`.
-    fn is_uppercase(&self) -> bool;
-
-    /// Indicates whether a character is whitespace.
-    ///
-    /// Whitespace is defined in terms of the Unicode Property `White_Space`.
-    fn is_whitespace(&self) -> bool;
-
-    /// Indicates whether a character is alphanumeric.
-    ///
-    /// Alphanumericness is defined in terms of the Unicode General Categories
-    /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
-    fn is_alphanumeric(&self) -> bool;
-
-    /// Indicates whether a character is a control code point.
-    ///
-    /// Control code points are defined in terms of the Unicode General
-    /// Category `Cc`.
-    fn is_control(&self) -> bool;
-
-    /// Indicates whether the character is numeric (Nd, Nl, or No).
-    fn is_digit(&self) -> bool;
-
     /// Checks if a `char` parses as a numeric digit in the given radix.
     ///
     /// Compared to `is_digit()`, this function only recognizes the characters
@@ -438,37 +258,6 @@ pub trait Char {
     /// Fails if given a radix outside the range [0..36].
     fn to_digit(&self, radix: uint) -> Option<uint>;
 
-    /// Converts a character to its lowercase equivalent.
-    ///
-    /// The case-folding performed is the common or simple mapping. See
-    /// `to_uppercase()` for references and more information.
-    ///
-    /// # Return value
-    ///
-    /// Returns the lowercase equivalent of the character, or the character
-    /// itself if no conversion is possible.
-    fn to_lowercase(&self) -> char;
-
-    /// Converts a character to its uppercase equivalent.
-    ///
-    /// The case-folding performed is the common or simple mapping: it maps
-    /// one unicode codepoint (one character in Rust) to its uppercase
-    /// equivalent according to the Unicode database [1]. The additional
-    /// `SpecialCasing.txt` is not considered here, as it expands to multiple
-    /// codepoints in some cases.
-    ///
-    /// A full reference can be found here [2].
-    ///
-    /// # Return value
-    ///
-    /// Returns the uppercase equivalent of the character, or the character
-    /// itself if no conversion was made.
-    ///
-    /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
-    ///
-    /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
-    fn to_uppercase(&self) -> char;
-
     /// Converts a number to the character representing it.
     ///
     /// # Return value
@@ -526,32 +315,10 @@ pub trait Char {
 }
 
 impl Char for char {
-    fn is_alphabetic(&self) -> bool { is_alphabetic(*self) }
-
-    fn is_XID_start(&self) -> bool { is_XID_start(*self) }
-
-    fn is_XID_continue(&self) -> bool { is_XID_continue(*self) }
-
-    fn is_lowercase(&self) -> bool { is_lowercase(*self) }
-
-    fn is_uppercase(&self) -> bool { is_uppercase(*self) }
-
-    fn is_whitespace(&self) -> bool { is_whitespace(*self) }
-
-    fn is_alphanumeric(&self) -> bool { is_alphanumeric(*self) }
-
-    fn is_control(&self) -> bool { is_control(*self) }
-
-    fn is_digit(&self) -> bool { is_digit(*self) }
-
     fn is_digit_radix(&self, radix: uint) -> bool { is_digit_radix(*self, radix) }
 
     fn to_digit(&self, radix: uint) -> Option<uint> { to_digit(*self, radix) }
 
-    fn to_lowercase(&self) -> char { to_lowercase(*self) }
-
-    fn to_uppercase(&self) -> char { to_uppercase(*self) }
-
     fn from_digit(num: uint, radix: uint) -> Option<char> { from_digit(num, radix) }
 
     fn escape_unicode(&self, f: |char|) { escape_unicode(*self, f) }
@@ -600,5 +367,3 @@ fn encode_utf16(&self, dst: &mut [u16]) -> uint {
         }
     }
 }
-
-
index 8696d385c44884d6d257b03818de2360e7f574c3..f374d2e9a274338ac647206853624c4f4d9baf47 100644 (file)
@@ -38,8 +38,6 @@
 //! ```
 
 use option::{Option, Some};
-#[cfg(stage0)]
-use option::None;
 
 /// Trait for values that can be compared for equality and inequality.
 ///
@@ -162,19 +160,6 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
 pub trait PartialOrd: PartialEq {
     /// This method returns an ordering between `self` and `other` values
     /// if one exists.
-    #[cfg(stage0)]
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        match (!self.lt(other), !other.lt(self)) {
-            (false, false) => None,
-            (false, true) => Some(Less),
-            (true, false) => Some(Greater),
-            (true, true) => Some(Equal),
-        }
-    }
-
-    /// This method returns an ordering between `self` and `other` values
-    /// if one exists.
-    #[cfg(not(stage0))]
     fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
 
     /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
index f326195be1607f270e6283c4a0830b6c9816b563..ef5b51fd00b3f5a6894db5356f68371fac385d98 100644 (file)
@@ -70,7 +70,7 @@ pub enum SignFormat {
 /**
  * Converts a number to its string representation as a byte vector.
  * This is meant to be a common base implementation for all numeric string
- * conversion functions like `to_str()` or `to_str_radix()`.
+ * conversion functions like `to_string()` or `to_str_radix()`.
  *
  * # Arguments
  * - `num`           - The number to convert. Accepts any number that
index 161dd7cef7e13fc3efdde9818fb24ece8df3ec6d..002babf7df976dd174a3cb84cc4a1973eb1075b3 100644 (file)
@@ -326,19 +326,73 @@ fn visit_leave_fn(&mut self, purity: uint, proto: uint,
     /// integer, since the conversion would throw away aliasing information.
     pub fn offset<T>(dst: *const T, offset: int) -> *const T;
 
-    /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
-    /// a size of `count` * `size_of::<T>()` and an alignment of
-    /// `min_align_of::<T>()`
+    /// Copies data from one location to another.
+    ///
+    /// Copies `count` elements (not bytes) from `src` to `dst`. The source
+    /// and destination may *not* overlap.
+    ///
+    /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
+    ///
+    /// # Example
+    ///
+    /// A safe swap function:
+    ///
+    /// ```
+    /// use std::mem;
+    /// use std::ptr;
+    ///
+    /// fn swap<T>(x: &mut T, y: &mut T) {
+    ///     unsafe {
+    ///         // Give ourselves some scratch space to work with
+    ///         let mut t: T = mem::uninitialized();
+    ///
+    ///         // Perform the swap, `&mut` pointers never alias
+    ///         ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
+    ///         ptr::copy_nonoverlapping_memory(x, &*y, 1);
+    ///         ptr::copy_nonoverlapping_memory(y, &t, 1);
+    ///
+    ///         // y and t now point to the same thing, but we need to completely forget `tmp`
+    ///         // because it's no longer relevant.
+    ///         mem::forget(t);
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// # Safety Note
+    ///
+    /// If the source and destination overlap then the behavior of this
+    /// function is undefined.
+    #[unstable]
     pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint);
 
-    /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
-    /// a size of `count` * `size_of::<T>()` and an alignment of
-    /// `min_align_of::<T>()`
+    /// Copies data from one location to another.
+    ///
+    /// Copies `count` elements (not bytes) from `src` to `dst`. The source
+    /// and destination may overlap.
+    ///
+    /// `copy_memory` is semantically equivalent to C's `memmove`.
+    ///
+    /// # Example
+    ///
+    /// Efficiently create a Rust vector from an unsafe buffer:
+    ///
+    /// ```
+    /// use std::ptr;
+    ///
+    /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
+    ///     let mut dst = Vec::with_capacity(elts);
+    ///     dst.set_len(elts);
+    ///     ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
+    ///     dst
+    /// }
+    /// ```
+    ///
+    #[unstable]
     pub fn copy_memory<T>(dst: *mut T, src: *const T, count: uint);
 
-    /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
-    /// size of `count` * `size_of::<T>()` and an alignment of
-    /// `min_align_of::<T>()`
+    /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
+    /// bytes of memory starting at `dst` to `c`.
+    #[experimental = "uncertain about naming and semantics"]
     pub fn set_memory<T>(dst: *mut T, val: u8, count: uint);
 
     /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
index 5895d871dbe18e2bb3467f72c09f1fb630e3b9c0..855bccb07a7418305a90f1e19d83187a1e13af6b 100644 (file)
@@ -64,14 +64,14 @@ trait defined in this module. For loops can be viewed as a syntactical expansion
 
 */
 
+use clone::Clone;
 use cmp;
+use cmp::{PartialEq, PartialOrd, Ord};
+use mem;
 use num::{Zero, One, CheckedAdd, CheckedSub, Saturating, ToPrimitive, Int};
-use option::{Option, Some, None};
 use ops::{Add, Mul, Sub};
-use cmp::{PartialEq, PartialOrd, Ord};
-use clone::Clone;
+use option::{Option, Some, None};
 use uint;
-use mem;
 
 /// Conversion from an `Iterator`
 pub trait FromIterator<A> {
@@ -435,9 +435,10 @@ fn by_ref<'r>(&'r mut self) -> ByRef<'r, Self> {
     ///
     /// # Example
     ///
-    /// ```rust
+    /// ```rust,ignore
     /// range(0u, 5).advance(|x| {print!("{} ", x); true});
     /// ```
+    #[deprecated = "use the `all` method instead"]
     #[inline]
     fn advance(&mut self, f: |A| -> bool) -> bool {
         loop {
@@ -750,6 +751,7 @@ impl<A, B, T: ExactSize<A>, U: ExactSize<B>> ExactSize<(A, B)> for Zip<T, U> {}
 
 /// An double-ended iterator with the direction inverted
 #[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Rev<T> {
     iter: T
 }
@@ -778,6 +780,7 @@ fn idx(&mut self, index: uint) -> Option<A> {
 }
 
 /// A mutable reference to an iterator
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct ByRef<'a, T> {
     iter: &'a mut T
 }
@@ -1038,6 +1041,7 @@ fn cycle(self) -> Cycle<T> {
 
 /// An iterator that repeats endlessly
 #[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Cycle<T> {
     orig: T,
     iter: T,
@@ -1089,6 +1093,7 @@ fn idx(&mut self, index: uint) -> Option<A> {
 
 /// An iterator which strings two iterators together
 #[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Chain<T, U> {
     a: T,
     b: U,
@@ -1158,6 +1163,7 @@ fn idx(&mut self, index: uint) -> Option<A> {
 
 /// An iterator which iterates two other iterators simultaneously
 #[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Zip<T, U> {
     a: T,
     b: U
@@ -1236,6 +1242,7 @@ fn idx(&mut self, index: uint) -> Option<(A, B)> {
 }
 
 /// An iterator which maps the values of `iter` with `f`
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Map<'a, A, B, T> {
     iter: T,
     f: |A|: 'a -> B
@@ -1286,6 +1293,7 @@ fn idx(&mut self, index: uint) -> Option<B> {
 }
 
 /// An iterator which filters the elements of `iter` with `predicate`
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Filter<'a, A, T> {
     iter: T,
     predicate: |&A|: 'a -> bool
@@ -1330,6 +1338,7 @@ fn next_back(&mut self) -> Option<A> {
 }
 
 /// An iterator which uses `f` to both filter and map elements from `iter`
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct FilterMap<'a, A, B, T> {
     iter: T,
     f: |A|: 'a -> Option<B>
@@ -1374,6 +1383,7 @@ fn next_back(&mut self) -> Option<B> {
 
 /// An iterator which yields the current count and the element during iteration
 #[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Enumerate<T> {
     iter: T,
     count: uint
@@ -1428,6 +1438,7 @@ fn idx(&mut self, index: uint) -> Option<(uint, A)> {
 }
 
 /// An iterator with a `peek()` that returns an optional reference to the next element.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Peekable<A, T> {
     iter: T,
     peeked: Option<A>,
@@ -1478,6 +1489,7 @@ pub fn is_empty(&mut self) -> bool {
 }
 
 /// An iterator which rejects elements while `predicate` is true
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct SkipWhile<'a, A, T> {
     iter: T,
     flag: bool,
@@ -1516,6 +1528,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 }
 
 /// An iterator which only accepts elements while `predicate` is true
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct TakeWhile<'a, A, T> {
     iter: T,
     flag: bool,
@@ -1551,6 +1564,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 
 /// An iterator which skips over `n` elements of `iter`.
 #[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Skip<T> {
     iter: T,
     n: uint
@@ -1615,6 +1629,7 @@ fn idx(&mut self, index: uint) -> Option<A> {
 
 /// An iterator which only iterates over the first `n` iterations of `iter`.
 #[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Take<T> {
     iter: T,
     n: uint
@@ -1664,6 +1679,7 @@ fn idx(&mut self, index: uint) -> Option<A> {
 
 
 /// An iterator to maintain state while iterating another iterator
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Scan<'a, A, B, T, St> {
     iter: T,
     f: |&mut St, A|: 'a -> Option<B>,
@@ -1688,6 +1704,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 /// An iterator that maps each element to an iterator,
 /// and yields the elements of the produced iterators
 ///
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct FlatMap<'a, A, T, U> {
     iter: T,
     f: |A|: 'a -> U,
@@ -1747,6 +1764,7 @@ fn next_back(&mut self) -> Option<B> {
 /// An iterator that yields `None` forever after the underlying iterator
 /// yields `None` once.
 #[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Fuse<T> {
     iter: T,
     done: bool
@@ -1819,6 +1837,7 @@ pub fn reset_fuse(&mut self) {
 
 /// An iterator that calls a function with a reference to each
 /// element before yielding it.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 pub struct Inspect<'a, A, T> {
     iter: T,
     f: |&A|: 'a
@@ -2173,6 +2192,27 @@ fn indexable(&self) -> uint { uint::MAX }
     fn idx(&mut self, _: uint) -> Option<A> { Some(self.element.clone()) }
 }
 
+type IterateState<'a, T> = (|T|: 'a -> T, Option<T>, bool);
+
+/// An iterator that repeatedly applies a given function, starting
+/// from a given seed value.
+pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>;
+
+/// Creates a new iterator that produces an infinite sequence of
+/// repeated applications of the given function `f`.
+#[allow(visible_private_types)]
+pub fn iterate<'a, T: Clone>(f: |T|: 'a -> T, seed: T) -> Iterate<'a, T> {
+    Unfold::new((f, Some(seed), true), |st| {
+        let &(ref mut f, ref mut val, ref mut first) = st;
+        if *first {
+            *first = false;
+        } else {
+            val.mutate(|x| (*f)(x));
+        }
+        val.clone()
+    })
+}
+
 /// Functions for lexicographical ordering of sequences.
 ///
 /// Lexicographical ordering through `<`, `<=`, `>=`, `>` requires
@@ -2298,4 +2338,3 @@ pub fn ge<A: PartialOrd, T: Iterator<A>, S: Iterator<A>>(mut a: T, mut b: S) ->
         }
     }
 }
-
index 5e238aeae32711004f1c5bfc6397985d06c63e1d..faa4b75d7faab6fe2df726a97af6b9ee2b4d0cbf 100644 (file)
 // Since libcore defines many fundamental lang items, all tests live in a
 // separate crate, libcoretest, to avoid bizarre issues.
 
-#![crate_id = "core#0.11.0"]
+#![crate_name = "core"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![no_std]
 
 /* Core types and methods on primitives */
 
-mod unicode;
 pub mod any;
 pub mod atomics;
 pub mod bool;
index cadc874891d2042109c0316e3db1a65439a1941f..82745663e0cad3bd8711493bc88af8065e0e7ae7 100644 (file)
@@ -11,6 +11,8 @@
 //! Operations and constants for 32-bits floats (`f32` type)
 
 #![doc(primitive = "f32")]
+// FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353
+#![allow(type_overflow)]
 
 use intrinsics;
 use mem;
index 5e19015dd02819209f3d69f1f932dc6cc932e582..a3a82aeec5ec78f1cb8cbf453a8435ee874f15fc 100644 (file)
@@ -11,6 +11,8 @@
 //! Operations and constants for 64-bits floats (`f64` type)
 
 #![doc(primitive = "f64")]
+// FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353
+#![allow(type_overflow)]
 
 use intrinsics;
 use mem;
index 1fae362471d9c8f168c77160af8182a871fac88b..3230873883e19113bcf78fc8e4b9a785080fa7c7 100644 (file)
@@ -769,16 +769,16 @@ fn to_f64(&self) -> Option<f64> {
 }
 
 macro_rules! impl_to_primitive_int_to_int(
-    ($SrcT:ty, $DstT:ty) => (
+    ($SrcT:ty, $DstT:ty, $slf:expr) => (
         {
             if size_of::<$SrcT>() <= size_of::<$DstT>() {
-                Some(*self as $DstT)
+                Some($slf as $DstT)
             } else {
-                let n = *self as i64;
+                let n = $slf as i64;
                 let min_value: $DstT = Bounded::min_value();
                 let max_value: $DstT = Bounded::max_value();
                 if min_value as i64 <= n && n <= max_value as i64 {
-                    Some(*self as $DstT)
+                    Some($slf as $DstT)
                 } else {
                     None
                 }
@@ -788,12 +788,12 @@ macro_rules! impl_to_primitive_int_to_int(
 )
 
 macro_rules! impl_to_primitive_int_to_uint(
-    ($SrcT:ty, $DstT:ty) => (
+    ($SrcT:ty, $DstT:ty, $slf:expr) => (
         {
             let zero: $SrcT = Zero::zero();
             let max_value: $DstT = Bounded::max_value();
-            if zero <= *self && *self as u64 <= max_value as u64 {
-                Some(*self as $DstT)
+            if zero <= $slf && $slf as u64 <= max_value as u64 {
+                Some($slf as $DstT)
             } else {
                 None
             }
@@ -805,26 +805,26 @@ macro_rules! impl_to_primitive_int(
     ($T:ty) => (
         impl ToPrimitive for $T {
             #[inline]
-            fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int) }
+            fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int, *self) }
             #[inline]
-            fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8) }
+            fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
             #[inline]
-            fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16) }
+            fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
             #[inline]
-            fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32) }
+            fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32, *self) }
             #[inline]
-            fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64) }
+            fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
 
             #[inline]
-            fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint) }
+            fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint, *self) }
             #[inline]
-            fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8) }
+            fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
             #[inline]
-            fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16) }
+            fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
             #[inline]
-            fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32) }
+            fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32, *self) }
             #[inline]
-            fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64) }
+            fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64, *self) }
 
             #[inline]
             fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
@@ -841,11 +841,11 @@ fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
 impl_to_primitive_int!(i64)
 
 macro_rules! impl_to_primitive_uint_to_int(
-    ($DstT:ty) => (
+    ($DstT:ty, $slf:expr) => (
         {
             let max_value: $DstT = Bounded::max_value();
-            if *self as u64 <= max_value as u64 {
-                Some(*self as $DstT)
+            if $slf as u64 <= max_value as u64 {
+                Some($slf as $DstT)
             } else {
                 None
             }
@@ -854,15 +854,15 @@ macro_rules! impl_to_primitive_uint_to_int(
 )
 
 macro_rules! impl_to_primitive_uint_to_uint(
-    ($SrcT:ty, $DstT:ty) => (
+    ($SrcT:ty, $DstT:ty, $slf:expr) => (
         {
             if size_of::<$SrcT>() <= size_of::<$DstT>() {
-                Some(*self as $DstT)
+                Some($slf as $DstT)
             } else {
                 let zero: $SrcT = Zero::zero();
                 let max_value: $DstT = Bounded::max_value();
-                if zero <= *self && *self as u64 <= max_value as u64 {
-                    Some(*self as $DstT)
+                if zero <= $slf && $slf as u64 <= max_value as u64 {
+                    Some($slf as $DstT)
                 } else {
                     None
                 }
@@ -875,26 +875,26 @@ macro_rules! impl_to_primitive_uint(
     ($T:ty) => (
         impl ToPrimitive for $T {
             #[inline]
-            fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int) }
+            fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int, *self) }
             #[inline]
-            fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8) }
+            fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
             #[inline]
-            fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16) }
+            fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
             #[inline]
-            fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32) }
+            fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32, *self) }
             #[inline]
-            fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64) }
+            fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
 
             #[inline]
-            fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint) }
+            fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint, *self) }
             #[inline]
-            fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8) }
+            fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
             #[inline]
-            fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16) }
+            fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
             #[inline]
-            fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32) }
+            fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32, *self) }
             #[inline]
-            fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64) }
+            fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64, *self) }
 
             #[inline]
             fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
@@ -911,14 +911,14 @@ fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
 impl_to_primitive_uint!(u64)
 
 macro_rules! impl_to_primitive_float_to_float(
-    ($SrcT:ty, $DstT:ty) => (
+    ($SrcT:ty, $DstT:ty, $slf:expr) => (
         if size_of::<$SrcT>() <= size_of::<$DstT>() {
-            Some(*self as $DstT)
+            Some($slf as $DstT)
         } else {
-            let n = *self as f64;
+            let n = $slf as f64;
             let max_value: $SrcT = Bounded::max_value();
             if -max_value as f64 <= n && n <= max_value as f64 {
-                Some(*self as $DstT)
+                Some($slf as $DstT)
             } else {
                 None
             }
@@ -952,9 +952,9 @@ fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
             fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
 
             #[inline]
-            fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32) }
+            fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
             #[inline]
-            fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64) }
+            fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
         }
     )
 )
@@ -1104,38 +1104,38 @@ pub fn from_f64<A: FromPrimitive>(n: f64) -> Option<A> {
 }
 
 macro_rules! impl_from_primitive(
-    ($T:ty, $to_ty:expr) => (
+    ($T:ty, $to_ty:ident) => (
         impl FromPrimitive for $T {
-            #[inline] fn from_int(n: int) -> Option<$T> { $to_ty }
-            #[inline] fn from_i8(n: i8) -> Option<$T> { $to_ty }
-            #[inline] fn from_i16(n: i16) -> Option<$T> { $to_ty }
-            #[inline] fn from_i32(n: i32) -> Option<$T> { $to_ty }
-            #[inline] fn from_i64(n: i64) -> Option<$T> { $to_ty }
-
-            #[inline] fn from_uint(n: uint) -> Option<$T> { $to_ty }
-            #[inline] fn from_u8(n: u8) -> Option<$T> { $to_ty }
-            #[inline] fn from_u16(n: u16) -> Option<$T> { $to_ty }
-            #[inline] fn from_u32(n: u32) -> Option<$T> { $to_ty }
-            #[inline] fn from_u64(n: u64) -> Option<$T> { $to_ty }
-
-            #[inline] fn from_f32(n: f32) -> Option<$T> { $to_ty }
-            #[inline] fn from_f64(n: f64) -> Option<$T> { $to_ty }
+            #[inline] fn from_int(n: int) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
+
+            #[inline] fn from_uint(n: uint) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
+
+            #[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
         }
     )
 )
 
-impl_from_primitive!(int, n.to_int())
-impl_from_primitive!(i8, n.to_i8())
-impl_from_primitive!(i16, n.to_i16())
-impl_from_primitive!(i32, n.to_i32())
-impl_from_primitive!(i64, n.to_i64())
-impl_from_primitive!(uint, n.to_uint())
-impl_from_primitive!(u8, n.to_u8())
-impl_from_primitive!(u16, n.to_u16())
-impl_from_primitive!(u32, n.to_u32())
-impl_from_primitive!(u64, n.to_u64())
-impl_from_primitive!(f32, n.to_f32())
-impl_from_primitive!(f64, n.to_f64())
+impl_from_primitive!(int, to_int)
+impl_from_primitive!(i8, to_i8)
+impl_from_primitive!(i16, to_i16)
+impl_from_primitive!(i32, to_i32)
+impl_from_primitive!(i64, to_i64)
+impl_from_primitive!(uint, to_uint)
+impl_from_primitive!(u8, to_u8)
+impl_from_primitive!(u16, to_u16)
+impl_from_primitive!(u32, to_u32)
+impl_from_primitive!(u64, to_u64)
+impl_from_primitive!(f32, to_f32)
+impl_from_primitive!(f64, to_f64)
 
 /// Cast from one machine scalar to another.
 ///
index d42c09b8163dd1d6159264109b8ae85847f84d58..53179df4cb9b322ebdbda9d741ae76cbb4721a3b 100644 (file)
@@ -613,7 +613,7 @@ fn shr(&self, other: &$t) -> $t { (*self) >> (*other as uint) }
 /**
  *
  * The `Index` trait is used to specify the functionality of indexing operations
- * like `arr[idx]`.
+ * like `arr[idx]` when used in an immutable context.
  *
  * # Example
  *
@@ -624,9 +624,9 @@ fn shr(&self, other: &$t) -> $t { (*self) >> (*other as uint) }
  * struct Foo;
  *
  * impl Index<Foo, Foo> for Foo {
- *     fn index(&self, _rhs: &Foo) -> Foo {
+ *     fn index<'a>(&'a self, _rhs: &Foo) -> &'a Foo {
  *         println!("Indexing!");
- *         *self
+ *         self
  *     }
  * }
  *
@@ -638,7 +638,38 @@ fn shr(&self, other: &$t) -> $t { (*self) >> (*other as uint) }
 #[lang="index"]
 pub trait Index<Index,Result> {
     /// The method for the indexing (`Foo[Bar]`) operation
-    fn index(&self, index: &Index) -> Result;
+    fn index<'a>(&'a self, index: &Index) -> &'a Result;
+}
+
+/**
+ *
+ * The `IndexMut` trait is used to specify the functionality of indexing
+ * operations like `arr[idx]`, when used in a mutable context.
+ *
+ * # Example
+ *
+ * A trivial implementation of `IndexMut`. When `Foo[Foo]` happens, it ends up
+ * calling `index`, and therefore, `main` prints `Indexing!`.
+ *
+ * ```
+ * struct Foo;
+ *
+ * impl IndexMut<Foo, Foo> for Foo {
+ *     fn index_mut<'a>(&'a mut self, _rhs: &Foo) -> &'a mut Foo {
+ *         println!("Indexing!");
+ *         self
+ *     }
+ * }
+ *
+ * fn main() {
+ *     &mut Foo[Foo];
+ * }
+ * ```
+ */
+#[lang="index_mut"]
+pub trait IndexMut<Index,Result> {
+    /// The method for the indexing (`Foo[Bar]`) operation
+    fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
 }
 
 /**
index df9c0e67b0d6d3ab1176df298b39aacffd3db9d4..d8ab89fd504f57076164f8ae0db78d3ddcbe551e 100644 (file)
@@ -33,7 +33,8 @@
 pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
 pub use ops::{BitAnd, BitOr, BitXor};
 pub use ops::{Drop, Deref, DerefMut};
-pub use ops::{Shl, Shr, Index};
+pub use ops::{Shl, Shr};
+pub use ops::{Index, IndexMut};
 pub use option::{Option, Some, None};
 pub use result::{Result, Ok, Err};
 
index 093591cd796d1cf4026605f338da2be55a87af46..ed1d4d481100b920952b68a3c5ba12a8b16dbe7c 100644 (file)
 
 use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
 
+pub use intrinsics::copy_memory;
+pub use intrinsics::copy_nonoverlapping_memory;
+pub use intrinsics::set_memory;
+
 /// Create a null pointer.
 ///
 /// # Example
@@ -123,86 +127,6 @@ pub fn null<T>() -> *const T { 0 as *const T }
 #[unstable = "may need a different name after pending changes to pointer types"]
 pub fn mut_null<T>() -> *mut T { 0 as *mut T }
 
-/// Copies data from one location to another.
-///
-/// Copies `count` elements (not bytes) from `src` to `dst`. The source
-/// and destination may overlap.
-///
-/// `copy_memory` is semantically equivalent to C's `memmove`.
-///
-/// # Example
-///
-/// Efficiently create a Rust vector from an unsafe buffer:
-///
-/// ```
-/// use std::ptr;
-///
-/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
-///     let mut dst = Vec::with_capacity(elts);
-///     dst.set_len(elts);
-///     ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
-///     dst
-/// }
-/// ```
-///
-#[inline]
-#[unstable]
-pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
-    intrinsics::copy_memory(dst, src, count)
-}
-
-/// Copies data from one location to another.
-///
-/// Copies `count` elements (not bytes) from `src` to `dst`. The source
-/// and destination may *not* overlap.
-///
-/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
-///
-/// # Example
-///
-/// A safe swap function:
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// fn swap<T>(x: &mut T, y: &mut T) {
-///     unsafe {
-///         // Give ourselves some scratch space to work with
-///         let mut t: T = mem::uninitialized();
-///
-///         // Perform the swap, `&mut` pointers never alias
-///         ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
-///         ptr::copy_nonoverlapping_memory(x, &*y, 1);
-///         ptr::copy_nonoverlapping_memory(y, &t, 1);
-///
-///         // y and t now point to the same thing, but we need to completely forget `tmp`
-///         // because it's no longer relevant.
-///         mem::forget(t);
-///     }
-/// }
-/// ```
-///
-/// # Safety Note
-///
-/// If the source and destination overlap then the behavior of this
-/// function is undefined.
-#[inline]
-#[unstable]
-pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
-                                            src: *const T,
-                                            count: uint) {
-    intrinsics::copy_nonoverlapping_memory(dst, src, count)
-}
-
-/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
-/// bytes of memory starting at `dst` to `c`.
-#[inline]
-#[experimental = "uncertain about naming and semantics"]
-pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
-    intrinsics::set_memory(dst, c, count)
-}
-
 /// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
 #[inline]
 #[experimental = "uncertain about naming and semantics"]
index 5cbbf30cd360721c912bdb4e63fd07031c6e93c9..980a9c7506f362291695eaa20e81a40cc8af74a2 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Error handling with the `Result` type
 //!
-//! `Result<T>` is the type used for returning and propagating
+//! `Result<T, E>` is the type used for returning and propagating
 //! errors. It is an enum with the variants, `Ok(T)`, representing
 //! success and containing a value, and `Err(E)`, representing error
 //! and containing an error value.
@@ -536,7 +536,10 @@ pub fn unwrap_or_handle(self, op: |E| -> T) -> T {
 impl<T, E: Show> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Ok`.
     ///
-    /// Fails if the value is an `Err`.
+    /// # Failure
+    ///
+    /// Fails if the value is an `Err`, with a custom failure message provided
+    /// by the `Err`'s value.
     #[inline]
     pub fn unwrap(self) -> T {
         match self {
@@ -550,7 +553,10 @@ pub fn unwrap(self) -> T {
 impl<T: Show, E> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Err`.
     ///
-    /// Fails if the value is an `Ok`.
+    /// # Failure
+    ///
+    /// Fails if the value is an `Ok`, with a custom failure message provided
+    /// by the `Ok`'s value.
     #[inline]
     pub fn unwrap_err(self) -> E {
         match self {
index 0178c0318b81c2afde7be72eec396e4cfc55a425..8197a7c2dcbe2dc3904f20d1fbbc3457a0f1f68a 100644 (file)
@@ -884,17 +884,20 @@ fn next(&mut self) -> Option<$elem> {
                     if self.ptr == self.end {
                         None
                     } else {
-                        let old = self.ptr;
-                        self.ptr = if mem::size_of::<T>() == 0 {
+                        if mem::size_of::<T>() == 0 {
                             // purposefully don't use 'ptr.offset' because for
                             // vectors with 0-size elements this would return the
                             // same pointer.
-                            transmute(self.ptr as uint + 1)
+                            self.ptr = transmute(self.ptr as uint + 1);
+
+                            // Use a non-null pointer value
+                            Some(transmute(1u))
                         } else {
-                            self.ptr.offset(1)
-                        };
+                            let old = self.ptr;
+                            self.ptr = self.ptr.offset(1);
 
-                        Some(transmute(old))
+                            Some(transmute(old))
+                        }
                     }
                 }
             }
@@ -916,13 +919,17 @@ fn next_back(&mut self) -> Option<$elem> {
                     if self.end == self.ptr {
                         None
                     } else {
-                        self.end = if mem::size_of::<T>() == 0 {
+                        if mem::size_of::<T>() == 0 {
                             // See above for why 'ptr.offset' isn't used
-                            transmute(self.end as uint - 1)
+                            self.end = transmute(self.end as uint - 1);
+
+                            // Use a non-null pointer value
+                            Some(transmute(1u))
                         } else {
-                            self.end.offset(-1)
-                        };
-                        Some(transmute(self.end))
+                            self.end = self.end.offset(-1);
+
+                            Some(transmute(self.end))
+                        }
                     }
                 }
             }
@@ -956,7 +963,12 @@ fn indexable(&self) -> uint {
     fn idx(&mut self, index: uint) -> Option<&'a T> {
         unsafe {
             if index < self.indexable() {
-                transmute(self.ptr.offset(index as int))
+                if mem::size_of::<T>() == 0 {
+                    // Use a non-null pointer value
+                    Some(transmute(1u))
+                } else {
+                    Some(transmute(self.ptr.offset(index as int)))
+                }
             } else {
                 None
             }
index 94df7a5a6c2d9c7548a089e8e949fbc32936f226..aa2050dacf1aa46da39ff1872e6b89c9f20eb661 100644 (file)
@@ -22,7 +22,7 @@
 use cmp::{PartialEq, Eq};
 use collections::Collection;
 use default::Default;
-use iter::{Filter, Map, Iterator};
+use iter::{Map, Iterator};
 use iter::{DoubleEndedIterator, ExactSize};
 use iter::range;
 use num::{CheckedMul, Saturating};
@@ -204,10 +204,6 @@ pub struct CharSplitsN<'a, Sep> {
     invert: bool,
 }
 
-/// An iterator over the words of a string, separated by a sequence of whitespace
-pub type Words<'a> =
-    Filter<'a, &'a str, CharSplits<'a, extern "Rust" fn(char) -> bool>>;
-
 /// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
 pub type AnyLines<'a> =
     Map<'a, &'a str, &'a str, CharSplits<'a, char>>;
@@ -1209,48 +1205,6 @@ pub trait StrSlice<'a> {
     /// ```
     fn lines_any(&self) -> AnyLines<'a>;
 
-    /// An iterator over the words of a string (subsequences separated
-    /// by any sequence of whitespace). Sequences of whitespace are
-    /// collapsed, so empty "words" are not included.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let some_words = " Mary   had\ta little  \n\t lamb";
-    /// let v: Vec<&str> = some_words.words().collect();
-    /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
-    /// ```
-    fn words(&self) -> Words<'a>;
-
-    /// Returns true if the string contains only whitespace.
-    ///
-    /// Whitespace characters are determined by `char::is_whitespace`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// assert!(" \t\n".is_whitespace());
-    /// assert!("".is_whitespace());
-    ///
-    /// assert!( !"abc".is_whitespace());
-    /// ```
-    fn is_whitespace(&self) -> bool;
-
-    /// Returns true if the string contains only alphanumeric code
-    /// points.
-    ///
-    /// Alphanumeric characters are determined by `char::is_alphanumeric`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// assert!("Löwe老虎Léopard123".is_alphanumeric());
-    /// assert!("".is_alphanumeric());
-    ///
-    /// assert!( !" &*~".is_alphanumeric());
-    /// ```
-    fn is_alphanumeric(&self) -> bool;
-
     /// Returns the number of Unicode code points (`char`) that a
     /// string holds.
     ///
@@ -1368,15 +1322,6 @@ pub trait StrSlice<'a> {
     /// Returns true if `needle` is a suffix of the string.
     fn ends_with(&self, needle: &str) -> bool;
 
-    /// Returns a string with leading and trailing whitespace removed.
-    fn trim(&self) -> &'a str;
-
-    /// Returns a string with leading whitespace removed.
-    fn trim_left(&self) -> &'a str;
-
-    /// Returns a string with trailing whitespace removed.
-    fn trim_right(&self) -> &'a str;
-
     /// Returns a string with characters that match `to_trim` removed.
     ///
     /// # Arguments
@@ -1748,23 +1693,14 @@ fn lines_any(&self) -> AnyLines<'a> {
         })
     }
 
-    #[inline]
-    fn words(&self) -> Words<'a> {
-        self.split(char::is_whitespace).filter(|s| !s.is_empty())
-    }
-
-    #[inline]
-    fn is_whitespace(&self) -> bool { self.chars().all(char::is_whitespace) }
-
-    #[inline]
-    fn is_alphanumeric(&self) -> bool { self.chars().all(char::is_alphanumeric) }
-
     #[inline]
     fn char_len(&self) -> uint { self.chars().count() }
 
     #[inline]
     fn slice(&self, begin: uint, end: uint) -> &'a str {
-        assert!(self.is_char_boundary(begin) && self.is_char_boundary(end));
+        assert!(self.is_char_boundary(begin) && self.is_char_boundary(end),
+                "index {} and/or {} in `{}` do not lie on character boundary", begin,
+                end, *self);
         unsafe { raw::slice_bytes(*self, begin, end) }
     }
 
@@ -1775,7 +1711,8 @@ fn slice_from(&self, begin: uint) -> &'a str {
 
     #[inline]
     fn slice_to(&self, end: uint) -> &'a str {
-        assert!(self.is_char_boundary(end));
+        assert!(self.is_char_boundary(end), "index {} in `{}` does not lie on \
+                a character boundary", end, *self);
         unsafe { raw::slice_bytes(*self, 0, end) }
     }
 
@@ -1814,21 +1751,6 @@ fn ends_with(&self, needle: &str) -> bool {
         m >= n && needle.as_bytes() == self.as_bytes().slice_from(m - n)
     }
 
-    #[inline]
-    fn trim(&self) -> &'a str {
-        self.trim_left().trim_right()
-    }
-
-    #[inline]
-    fn trim_left(&self) -> &'a str {
-        self.trim_left_chars(char::is_whitespace)
-    }
-
-    #[inline]
-    fn trim_right(&self) -> &'a str {
-        self.trim_right_chars(char::is_whitespace)
-    }
-
     #[inline]
     fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
         let cur = match self.find(|c: char| !to_trim.matches(c)) {
diff --git a/src/libcore/unicode.rs b/src/libcore/unicode.rs
deleted file mode 100644 (file)
index c6fc5f1..0000000
+++ /dev/null
@@ -1,5056 +0,0 @@
-// Copyright 2012-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.
-
-// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
-
-#![allow(missing_doc, non_uppercase_statics, non_snake_case_functions)]
-
-
-fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
-    use cmp::{Equal, Less, Greater};
-    use slice::ImmutableVector;
-    use option::None;
-    r.bsearch(|&(lo,hi)| {
-        if lo <= c && c <= hi { Equal }
-        else if hi < c { Less }
-        else { Greater }
-    }) != None
-}
-
-pub mod general_category {
-    static Cc_table : &'static [(char,char)] = &[
-        ('\x00', '\x1f'), ('\x7f', '\x9f')
-    ];
-
-    pub fn Cc(c: char) -> bool {
-        super::bsearch_range_table(c, Cc_table)
-    }
-
-    static Nd_table : &'static [(char,char)] = &[
-        ('\x30', '\x39'), ('\u0660', '\u0669'),
-        ('\u06f0', '\u06f9'), ('\u07c0', '\u07c9'),
-        ('\u0966', '\u096f'), ('\u09e6', '\u09ef'),
-        ('\u0a66', '\u0a6f'), ('\u0ae6', '\u0aef'),
-        ('\u0b66', '\u0b6f'), ('\u0be6', '\u0bef'),
-        ('\u0c66', '\u0c6f'), ('\u0ce6', '\u0cef'),
-        ('\u0d66', '\u0d6f'), ('\u0e50', '\u0e59'),
-        ('\u0ed0', '\u0ed9'), ('\u0f20', '\u0f29'),
-        ('\u1040', '\u1049'), ('\u1090', '\u1099'),
-        ('\u17e0', '\u17e9'), ('\u1810', '\u1819'),
-        ('\u1946', '\u194f'), ('\u19d0', '\u19d9'),
-        ('\u1a80', '\u1a99'), ('\u1b50', '\u1b59'),
-        ('\u1bb0', '\u1bb9'), ('\u1c40', '\u1c49'),
-        ('\u1c50', '\u1c59'), ('\ua620', '\ua629'),
-        ('\ua8d0', '\ua8d9'), ('\ua900', '\ua909'),
-        ('\ua9d0', '\ua9d9'), ('\uaa50', '\uaa59'),
-        ('\uabf0', '\uabf9'), ('\uff10', '\uff19'),
-        ('\U000104a0', '\U000104a9'), ('\U00011066', '\U0001106f'),
-        ('\U000110f0', '\U000110f9'), ('\U00011136', '\U0001113f'),
-        ('\U000111d0', '\U000111d9'), ('\U000116c0', '\U000116c9'),
-        ('\U0001d7ce', '\U0001d7ff')
-    ];
-
-    pub fn Nd(c: char) -> bool {
-        super::bsearch_range_table(c, Nd_table)
-    }
-
-    static Nl_table : &'static [(char,char)] = &[
-        ('\u16ee', '\u16f0'), ('\u2160', '\u2182'),
-        ('\u2185', '\u2188'), ('\u3007', '\u3007'),
-        ('\u3021', '\u3029'), ('\u3038', '\u303a'),
-        ('\ua6e6', '\ua6ef'), ('\U00010140', '\U00010174'),
-        ('\U00010341', '\U00010341'), ('\U0001034a', '\U0001034a'),
-        ('\U000103d1', '\U000103d5'), ('\U00012400', '\U00012462')
-    ];
-
-    pub fn Nl(c: char) -> bool {
-        super::bsearch_range_table(c, Nl_table)
-    }
-
-    static No_table : &'static [(char,char)] = &[
-        ('\xb2', '\xb3'), ('\xb9', '\xb9'),
-        ('\xbc', '\xbe'), ('\u09f4', '\u09f9'),
-        ('\u0b72', '\u0b77'), ('\u0bf0', '\u0bf2'),
-        ('\u0c78', '\u0c7e'), ('\u0d70', '\u0d75'),
-        ('\u0f2a', '\u0f33'), ('\u1369', '\u137c'),
-        ('\u17f0', '\u17f9'), ('\u19da', '\u19da'),
-        ('\u2070', '\u2070'), ('\u2074', '\u2079'),
-        ('\u2080', '\u2089'), ('\u2150', '\u215f'),
-        ('\u2189', '\u2189'), ('\u2460', '\u249b'),
-        ('\u24ea', '\u24ff'), ('\u2776', '\u2793'),
-        ('\u2cfd', '\u2cfd'), ('\u3192', '\u3195'),
-        ('\u3220', '\u3229'), ('\u3248', '\u324f'),
-        ('\u3251', '\u325f'), ('\u3280', '\u3289'),
-        ('\u32b1', '\u32bf'), ('\ua830', '\ua835'),
-        ('\U00010107', '\U00010133'), ('\U00010175', '\U00010178'),
-        ('\U0001018a', '\U0001018a'), ('\U00010320', '\U00010323'),
-        ('\U00010858', '\U0001085f'), ('\U00010916', '\U0001091b'),
-        ('\U00010a40', '\U00010a47'), ('\U00010a7d', '\U00010a7e'),
-        ('\U00010b58', '\U00010b5f'), ('\U00010b78', '\U00010b7f'),
-        ('\U00010e60', '\U00010e7e'), ('\U00011052', '\U00011065'),
-        ('\U0001d360', '\U0001d371'), ('\U0001f100', '\U0001f10a')
-    ];
-
-    pub fn No(c: char) -> bool {
-        super::bsearch_range_table(c, No_table)
-    }
-
-}
-
-pub mod normalization {
-    use option::Option;
-    use option::{Some, None};
-    use slice::ImmutableVector;
-
-    fn bsearch_table(c: char, r: &'static [(char, &'static [char])]) -> Option<&'static [char]> {
-        use cmp::{Equal, Less, Greater};
-        match r.bsearch(|&(val, _)| {
-            if c == val { Equal }
-            else if val < c { Less }
-            else { Greater }
-        }) {
-            Some(idx) => {
-                let (_, result) = r[idx];
-                Some(result)
-            }
-            None => None
-        }
-    }
-
-
-    // Canonical decompositions
-    static canonical_table : &'static [(char, &'static [char])] = &[
-        ('\xc0', &['\x41', '\u0300']), ('\xc1', &['\x41', '\u0301']), ('\xc2', &['\x41', '\u0302']),
-        ('\xc3', &['\x41', '\u0303']), ('\xc4', &['\x41', '\u0308']), ('\xc5', &['\x41', '\u030a']),
-        ('\xc7', &['\x43', '\u0327']), ('\xc8', &['\x45', '\u0300']), ('\xc9', &['\x45', '\u0301']),
-        ('\xca', &['\x45', '\u0302']), ('\xcb', &['\x45', '\u0308']), ('\xcc', &['\x49', '\u0300']),
-        ('\xcd', &['\x49', '\u0301']), ('\xce', &['\x49', '\u0302']), ('\xcf', &['\x49', '\u0308']),
-        ('\xd1', &['\x4e', '\u0303']), ('\xd2', &['\x4f', '\u0300']), ('\xd3', &['\x4f', '\u0301']),
-        ('\xd4', &['\x4f', '\u0302']), ('\xd5', &['\x4f', '\u0303']), ('\xd6', &['\x4f', '\u0308']),
-        ('\xd9', &['\x55', '\u0300']), ('\xda', &['\x55', '\u0301']), ('\xdb', &['\x55', '\u0302']),
-        ('\xdc', &['\x55', '\u0308']), ('\xdd', &['\x59', '\u0301']), ('\xe0', &['\x61', '\u0300']),
-        ('\xe1', &['\x61', '\u0301']), ('\xe2', &['\x61', '\u0302']), ('\xe3', &['\x61', '\u0303']),
-        ('\xe4', &['\x61', '\u0308']), ('\xe5', &['\x61', '\u030a']), ('\xe7', &['\x63', '\u0327']),
-        ('\xe8', &['\x65', '\u0300']), ('\xe9', &['\x65', '\u0301']), ('\xea', &['\x65', '\u0302']),
-        ('\xeb', &['\x65', '\u0308']), ('\xec', &['\x69', '\u0300']), ('\xed', &['\x69', '\u0301']),
-        ('\xee', &['\x69', '\u0302']), ('\xef', &['\x69', '\u0308']), ('\xf1', &['\x6e', '\u0303']),
-        ('\xf2', &['\x6f', '\u0300']), ('\xf3', &['\x6f', '\u0301']), ('\xf4', &['\x6f', '\u0302']),
-        ('\xf5', &['\x6f', '\u0303']), ('\xf6', &['\x6f', '\u0308']), ('\xf9', &['\x75', '\u0300']),
-        ('\xfa', &['\x75', '\u0301']), ('\xfb', &['\x75', '\u0302']), ('\xfc', &['\x75', '\u0308']),
-        ('\xfd', &['\x79', '\u0301']), ('\xff', &['\x79', '\u0308']), ('\u0100', &['\x41',
-        '\u0304']), ('\u0101', &['\x61', '\u0304']), ('\u0102', &['\x41', '\u0306']), ('\u0103',
-        &['\x61', '\u0306']), ('\u0104', &['\x41', '\u0328']), ('\u0105', &['\x61', '\u0328']),
-        ('\u0106', &['\x43', '\u0301']), ('\u0107', &['\x63', '\u0301']), ('\u0108', &['\x43',
-        '\u0302']), ('\u0109', &['\x63', '\u0302']), ('\u010a', &['\x43', '\u0307']), ('\u010b',
-        &['\x63', '\u0307']), ('\u010c', &['\x43', '\u030c']), ('\u010d', &['\x63', '\u030c']),
-        ('\u010e', &['\x44', '\u030c']), ('\u010f', &['\x64', '\u030c']), ('\u0112', &['\x45',
-        '\u0304']), ('\u0113', &['\x65', '\u0304']), ('\u0114', &['\x45', '\u0306']), ('\u0115',
-        &['\x65', '\u0306']), ('\u0116', &['\x45', '\u0307']), ('\u0117', &['\x65', '\u0307']),
-        ('\u0118', &['\x45', '\u0328']), ('\u0119', &['\x65', '\u0328']), ('\u011a', &['\x45',
-        '\u030c']), ('\u011b', &['\x65', '\u030c']), ('\u011c', &['\x47', '\u0302']), ('\u011d',
-        &['\x67', '\u0302']), ('\u011e', &['\x47', '\u0306']), ('\u011f', &['\x67', '\u0306']),
-        ('\u0120', &['\x47', '\u0307']), ('\u0121', &['\x67', '\u0307']), ('\u0122', &['\x47',
-        '\u0327']), ('\u0123', &['\x67', '\u0327']), ('\u0124', &['\x48', '\u0302']), ('\u0125',
-        &['\x68', '\u0302']), ('\u0128', &['\x49', '\u0303']), ('\u0129', &['\x69', '\u0303']),
-        ('\u012a', &['\x49', '\u0304']), ('\u012b', &['\x69', '\u0304']), ('\u012c', &['\x49',
-        '\u0306']), ('\u012d', &['\x69', '\u0306']), ('\u012e', &['\x49', '\u0328']), ('\u012f',
-        &['\x69', '\u0328']), ('\u0130', &['\x49', '\u0307']), ('\u0134', &['\x4a', '\u0302']),
-        ('\u0135', &['\x6a', '\u0302']), ('\u0136', &['\x4b', '\u0327']), ('\u0137', &['\x6b',
-        '\u0327']), ('\u0139', &['\x4c', '\u0301']), ('\u013a', &['\x6c', '\u0301']), ('\u013b',
-        &['\x4c', '\u0327']), ('\u013c', &['\x6c', '\u0327']), ('\u013d', &['\x4c', '\u030c']),
-        ('\u013e', &['\x6c', '\u030c']), ('\u0143', &['\x4e', '\u0301']), ('\u0144', &['\x6e',
-        '\u0301']), ('\u0145', &['\x4e', '\u0327']), ('\u0146', &['\x6e', '\u0327']), ('\u0147',
-        &['\x4e', '\u030c']), ('\u0148', &['\x6e', '\u030c']), ('\u014c', &['\x4f', '\u0304']),
-        ('\u014d', &['\x6f', '\u0304']), ('\u014e', &['\x4f', '\u0306']), ('\u014f', &['\x6f',
-        '\u0306']), ('\u0150', &['\x4f', '\u030b']), ('\u0151', &['\x6f', '\u030b']), ('\u0154',
-        &['\x52', '\u0301']), ('\u0155', &['\x72', '\u0301']), ('\u0156', &['\x52', '\u0327']),
-        ('\u0157', &['\x72', '\u0327']), ('\u0158', &['\x52', '\u030c']), ('\u0159', &['\x72',
-        '\u030c']), ('\u015a', &['\x53', '\u0301']), ('\u015b', &['\x73', '\u0301']), ('\u015c',
-        &['\x53', '\u0302']), ('\u015d', &['\x73', '\u0302']), ('\u015e', &['\x53', '\u0327']),
-        ('\u015f', &['\x73', '\u0327']), ('\u0160', &['\x53', '\u030c']), ('\u0161', &['\x73',
-        '\u030c']), ('\u0162', &['\x54', '\u0327']), ('\u0163', &['\x74', '\u0327']), ('\u0164',
-        &['\x54', '\u030c']), ('\u0165', &['\x74', '\u030c']), ('\u0168', &['\x55', '\u0303']),
-        ('\u0169', &['\x75', '\u0303']), ('\u016a', &['\x55', '\u0304']), ('\u016b', &['\x75',
-        '\u0304']), ('\u016c', &['\x55', '\u0306']), ('\u016d', &['\x75', '\u0306']), ('\u016e',
-        &['\x55', '\u030a']), ('\u016f', &['\x75', '\u030a']), ('\u0170', &['\x55', '\u030b']),
-        ('\u0171', &['\x75', '\u030b']), ('\u0172', &['\x55', '\u0328']), ('\u0173', &['\x75',
-        '\u0328']), ('\u0174', &['\x57', '\u0302']), ('\u0175', &['\x77', '\u0302']), ('\u0176',
-        &['\x59', '\u0302']), ('\u0177', &['\x79', '\u0302']), ('\u0178', &['\x59', '\u0308']),
-        ('\u0179', &['\x5a', '\u0301']), ('\u017a', &['\x7a', '\u0301']), ('\u017b', &['\x5a',
-        '\u0307']), ('\u017c', &['\x7a', '\u0307']), ('\u017d', &['\x5a', '\u030c']), ('\u017e',
-        &['\x7a', '\u030c']), ('\u01a0', &['\x4f', '\u031b']), ('\u01a1', &['\x6f', '\u031b']),
-        ('\u01af', &['\x55', '\u031b']), ('\u01b0', &['\x75', '\u031b']), ('\u01cd', &['\x41',
-        '\u030c']), ('\u01ce', &['\x61', '\u030c']), ('\u01cf', &['\x49', '\u030c']), ('\u01d0',
-        &['\x69', '\u030c']), ('\u01d1', &['\x4f', '\u030c']), ('\u01d2', &['\x6f', '\u030c']),
-        ('\u01d3', &['\x55', '\u030c']), ('\u01d4', &['\x75', '\u030c']), ('\u01d5', &['\xdc',
-        '\u0304']), ('\u01d6', &['\xfc', '\u0304']), ('\u01d7', &['\xdc', '\u0301']), ('\u01d8',
-        &['\xfc', '\u0301']), ('\u01d9', &['\xdc', '\u030c']), ('\u01da', &['\xfc', '\u030c']),
-        ('\u01db', &['\xdc', '\u0300']), ('\u01dc', &['\xfc', '\u0300']), ('\u01de', &['\xc4',
-        '\u0304']), ('\u01df', &['\xe4', '\u0304']), ('\u01e0', &['\u0226', '\u0304']), ('\u01e1',
-        &['\u0227', '\u0304']), ('\u01e2', &['\xc6', '\u0304']), ('\u01e3', &['\xe6', '\u0304']),
-        ('\u01e6', &['\x47', '\u030c']), ('\u01e7', &['\x67', '\u030c']), ('\u01e8', &['\x4b',
-        '\u030c']), ('\u01e9', &['\x6b', '\u030c']), ('\u01ea', &['\x4f', '\u0328']), ('\u01eb',
-        &['\x6f', '\u0328']), ('\u01ec', &['\u01ea', '\u0304']), ('\u01ed', &['\u01eb', '\u0304']),
-        ('\u01ee', &['\u01b7', '\u030c']), ('\u01ef', &['\u0292', '\u030c']), ('\u01f0', &['\x6a',
-        '\u030c']), ('\u01f4', &['\x47', '\u0301']), ('\u01f5', &['\x67', '\u0301']), ('\u01f8',
-        &['\x4e', '\u0300']), ('\u01f9', &['\x6e', '\u0300']), ('\u01fa', &['\xc5', '\u0301']),
-        ('\u01fb', &['\xe5', '\u0301']), ('\u01fc', &['\xc6', '\u0301']), ('\u01fd', &['\xe6',
-        '\u0301']), ('\u01fe', &['\xd8', '\u0301']), ('\u01ff', &['\xf8', '\u0301']), ('\u0200',
-        &['\x41', '\u030f']), ('\u0201', &['\x61', '\u030f']), ('\u0202', &['\x41', '\u0311']),
-        ('\u0203', &['\x61', '\u0311']), ('\u0204', &['\x45', '\u030f']), ('\u0205', &['\x65',
-        '\u030f']), ('\u0206', &['\x45', '\u0311']), ('\u0207', &['\x65', '\u0311']), ('\u0208',
-        &['\x49', '\u030f']), ('\u0209', &['\x69', '\u030f']), ('\u020a', &['\x49', '\u0311']),
-        ('\u020b', &['\x69', '\u0311']), ('\u020c', &['\x4f', '\u030f']), ('\u020d', &['\x6f',
-        '\u030f']), ('\u020e', &['\x4f', '\u0311']), ('\u020f', &['\x6f', '\u0311']), ('\u0210',
-        &['\x52', '\u030f']), ('\u0211', &['\x72', '\u030f']), ('\u0212', &['\x52', '\u0311']),
-        ('\u0213', &['\x72', '\u0311']), ('\u0214', &['\x55', '\u030f']), ('\u0215', &['\x75',
-        '\u030f']), ('\u0216', &['\x55', '\u0311']), ('\u0217', &['\x75', '\u0311']), ('\u0218',
-        &['\x53', '\u0326']), ('\u0219', &['\x73', '\u0326']), ('\u021a', &['\x54', '\u0326']),
-        ('\u021b', &['\x74', '\u0326']), ('\u021e', &['\x48', '\u030c']), ('\u021f', &['\x68',
-        '\u030c']), ('\u0226', &['\x41', '\u0307']), ('\u0227', &['\x61', '\u0307']), ('\u0228',
-        &['\x45', '\u0327']), ('\u0229', &['\x65', '\u0327']), ('\u022a', &['\xd6', '\u0304']),
-        ('\u022b', &['\xf6', '\u0304']), ('\u022c', &['\xd5', '\u0304']), ('\u022d', &['\xf5',
-        '\u0304']), ('\u022e', &['\x4f', '\u0307']), ('\u022f', &['\x6f', '\u0307']), ('\u0230',
-        &['\u022e', '\u0304']), ('\u0231', &['\u022f', '\u0304']), ('\u0232', &['\x59', '\u0304']),
-        ('\u0233', &['\x79', '\u0304']), ('\u0340', &['\u0300']), ('\u0341', &['\u0301']),
-        ('\u0343', &['\u0313']), ('\u0344', &['\u0308', '\u0301']), ('\u0374', &['\u02b9']),
-        ('\u037e', &['\x3b']), ('\u0385', &['\xa8', '\u0301']), ('\u0386', &['\u0391', '\u0301']),
-        ('\u0387', &['\xb7']), ('\u0388', &['\u0395', '\u0301']), ('\u0389', &['\u0397', '\u0301']),
-        ('\u038a', &['\u0399', '\u0301']), ('\u038c', &['\u039f', '\u0301']), ('\u038e', &['\u03a5',
-        '\u0301']), ('\u038f', &['\u03a9', '\u0301']), ('\u0390', &['\u03ca', '\u0301']), ('\u03aa',
-        &['\u0399', '\u0308']), ('\u03ab', &['\u03a5', '\u0308']), ('\u03ac', &['\u03b1',
-        '\u0301']), ('\u03ad', &['\u03b5', '\u0301']), ('\u03ae', &['\u03b7', '\u0301']), ('\u03af',
-        &['\u03b9', '\u0301']), ('\u03b0', &['\u03cb', '\u0301']), ('\u03ca', &['\u03b9',
-        '\u0308']), ('\u03cb', &['\u03c5', '\u0308']), ('\u03cc', &['\u03bf', '\u0301']), ('\u03cd',
-        &['\u03c5', '\u0301']), ('\u03ce', &['\u03c9', '\u0301']), ('\u03d3', &['\u03d2',
-        '\u0301']), ('\u03d4', &['\u03d2', '\u0308']), ('\u0400', &['\u0415', '\u0300']), ('\u0401',
-        &['\u0415', '\u0308']), ('\u0403', &['\u0413', '\u0301']), ('\u0407', &['\u0406',
-        '\u0308']), ('\u040c', &['\u041a', '\u0301']), ('\u040d', &['\u0418', '\u0300']), ('\u040e',
-        &['\u0423', '\u0306']), ('\u0419', &['\u0418', '\u0306']), ('\u0439', &['\u0438',
-        '\u0306']), ('\u0450', &['\u0435', '\u0300']), ('\u0451', &['\u0435', '\u0308']), ('\u0453',
-        &['\u0433', '\u0301']), ('\u0457', &['\u0456', '\u0308']), ('\u045c', &['\u043a',
-        '\u0301']), ('\u045d', &['\u0438', '\u0300']), ('\u045e', &['\u0443', '\u0306']), ('\u0476',
-        &['\u0474', '\u030f']), ('\u0477', &['\u0475', '\u030f']), ('\u04c1', &['\u0416',
-        '\u0306']), ('\u04c2', &['\u0436', '\u0306']), ('\u04d0', &['\u0410', '\u0306']), ('\u04d1',
-        &['\u0430', '\u0306']), ('\u04d2', &['\u0410', '\u0308']), ('\u04d3', &['\u0430',
-        '\u0308']), ('\u04d6', &['\u0415', '\u0306']), ('\u04d7', &['\u0435', '\u0306']), ('\u04da',
-        &['\u04d8', '\u0308']), ('\u04db', &['\u04d9', '\u0308']), ('\u04dc', &['\u0416',
-        '\u0308']), ('\u04dd', &['\u0436', '\u0308']), ('\u04de', &['\u0417', '\u0308']), ('\u04df',
-        &['\u0437', '\u0308']), ('\u04e2', &['\u0418', '\u0304']), ('\u04e3', &['\u0438',
-        '\u0304']), ('\u04e4', &['\u0418', '\u0308']), ('\u04e5', &['\u0438', '\u0308']), ('\u04e6',
-        &['\u041e', '\u0308']), ('\u04e7', &['\u043e', '\u0308']), ('\u04ea', &['\u04e8',
-        '\u0308']), ('\u04eb', &['\u04e9', '\u0308']), ('\u04ec', &['\u042d', '\u0308']), ('\u04ed',
-        &['\u044d', '\u0308']), ('\u04ee', &['\u0423', '\u0304']), ('\u04ef', &['\u0443',
-        '\u0304']), ('\u04f0', &['\u0423', '\u0308']), ('\u04f1', &['\u0443', '\u0308']), ('\u04f2',
-        &['\u0423', '\u030b']), ('\u04f3', &['\u0443', '\u030b']), ('\u04f4', &['\u0427',
-        '\u0308']), ('\u04f5', &['\u0447', '\u0308']), ('\u04f8', &['\u042b', '\u0308']), ('\u04f9',
-        &['\u044b', '\u0308']), ('\u0622', &['\u0627', '\u0653']), ('\u0623', &['\u0627',
-        '\u0654']), ('\u0624', &['\u0648', '\u0654']), ('\u0625', &['\u0627', '\u0655']), ('\u0626',
-        &['\u064a', '\u0654']), ('\u06c0', &['\u06d5', '\u0654']), ('\u06c2', &['\u06c1',
-        '\u0654']), ('\u06d3', &['\u06d2', '\u0654']), ('\u0929', &['\u0928', '\u093c']), ('\u0931',
-        &['\u0930', '\u093c']), ('\u0934', &['\u0933', '\u093c']), ('\u0958', &['\u0915',
-        '\u093c']), ('\u0959', &['\u0916', '\u093c']), ('\u095a', &['\u0917', '\u093c']), ('\u095b',
-        &['\u091c', '\u093c']), ('\u095c', &['\u0921', '\u093c']), ('\u095d', &['\u0922',
-        '\u093c']), ('\u095e', &['\u092b', '\u093c']), ('\u095f', &['\u092f', '\u093c']), ('\u09cb',
-        &['\u09c7', '\u09be']), ('\u09cc', &['\u09c7', '\u09d7']), ('\u09dc', &['\u09a1',
-        '\u09bc']), ('\u09dd', &['\u09a2', '\u09bc']), ('\u09df', &['\u09af', '\u09bc']), ('\u0a33',
-        &['\u0a32', '\u0a3c']), ('\u0a36', &['\u0a38', '\u0a3c']), ('\u0a59', &['\u0a16',
-        '\u0a3c']), ('\u0a5a', &['\u0a17', '\u0a3c']), ('\u0a5b', &['\u0a1c', '\u0a3c']), ('\u0a5e',
-        &['\u0a2b', '\u0a3c']), ('\u0b48', &['\u0b47', '\u0b56']), ('\u0b4b', &['\u0b47',
-        '\u0b3e']), ('\u0b4c', &['\u0b47', '\u0b57']), ('\u0b5c', &['\u0b21', '\u0b3c']), ('\u0b5d',
-        &['\u0b22', '\u0b3c']), ('\u0b94', &['\u0b92', '\u0bd7']), ('\u0bca', &['\u0bc6',
-        '\u0bbe']), ('\u0bcb', &['\u0bc7', '\u0bbe']), ('\u0bcc', &['\u0bc6', '\u0bd7']), ('\u0c48',
-        &['\u0c46', '\u0c56']), ('\u0cc0', &['\u0cbf', '\u0cd5']), ('\u0cc7', &['\u0cc6',
-        '\u0cd5']), ('\u0cc8', &['\u0cc6', '\u0cd6']), ('\u0cca', &['\u0cc6', '\u0cc2']), ('\u0ccb',
-        &['\u0cca', '\u0cd5']), ('\u0d4a', &['\u0d46', '\u0d3e']), ('\u0d4b', &['\u0d47',
-        '\u0d3e']), ('\u0d4c', &['\u0d46', '\u0d57']), ('\u0dda', &['\u0dd9', '\u0dca']), ('\u0ddc',
-        &['\u0dd9', '\u0dcf']), ('\u0ddd', &['\u0ddc', '\u0dca']), ('\u0dde', &['\u0dd9',
-        '\u0ddf']), ('\u0f43', &['\u0f42', '\u0fb7']), ('\u0f4d', &['\u0f4c', '\u0fb7']), ('\u0f52',
-        &['\u0f51', '\u0fb7']), ('\u0f57', &['\u0f56', '\u0fb7']), ('\u0f5c', &['\u0f5b',
-        '\u0fb7']), ('\u0f69', &['\u0f40', '\u0fb5']), ('\u0f73', &['\u0f71', '\u0f72']), ('\u0f75',
-        &['\u0f71', '\u0f74']), ('\u0f76', &['\u0fb2', '\u0f80']), ('\u0f78', &['\u0fb3',
-        '\u0f80']), ('\u0f81', &['\u0f71', '\u0f80']), ('\u0f93', &['\u0f92', '\u0fb7']), ('\u0f9d',
-        &['\u0f9c', '\u0fb7']), ('\u0fa2', &['\u0fa1', '\u0fb7']), ('\u0fa7', &['\u0fa6',
-        '\u0fb7']), ('\u0fac', &['\u0fab', '\u0fb7']), ('\u0fb9', &['\u0f90', '\u0fb5']), ('\u1026',
-        &['\u1025', '\u102e']), ('\u1b06', &['\u1b05', '\u1b35']), ('\u1b08', &['\u1b07',
-        '\u1b35']), ('\u1b0a', &['\u1b09', '\u1b35']), ('\u1b0c', &['\u1b0b', '\u1b35']), ('\u1b0e',
-        &['\u1b0d', '\u1b35']), ('\u1b12', &['\u1b11', '\u1b35']), ('\u1b3b', &['\u1b3a',
-        '\u1b35']), ('\u1b3d', &['\u1b3c', '\u1b35']), ('\u1b40', &['\u1b3e', '\u1b35']), ('\u1b41',
-        &['\u1b3f', '\u1b35']), ('\u1b43', &['\u1b42', '\u1b35']), ('\u1e00', &['\x41', '\u0325']),
-        ('\u1e01', &['\x61', '\u0325']), ('\u1e02', &['\x42', '\u0307']), ('\u1e03', &['\x62',
-        '\u0307']), ('\u1e04', &['\x42', '\u0323']), ('\u1e05', &['\x62', '\u0323']), ('\u1e06',
-        &['\x42', '\u0331']), ('\u1e07', &['\x62', '\u0331']), ('\u1e08', &['\xc7', '\u0301']),
-        ('\u1e09', &['\xe7', '\u0301']), ('\u1e0a', &['\x44', '\u0307']), ('\u1e0b', &['\x64',
-        '\u0307']), ('\u1e0c', &['\x44', '\u0323']), ('\u1e0d', &['\x64', '\u0323']), ('\u1e0e',
-        &['\x44', '\u0331']), ('\u1e0f', &['\x64', '\u0331']), ('\u1e10', &['\x44', '\u0327']),
-        ('\u1e11', &['\x64', '\u0327']), ('\u1e12', &['\x44', '\u032d']), ('\u1e13', &['\x64',
-        '\u032d']), ('\u1e14', &['\u0112', '\u0300']), ('\u1e15', &['\u0113', '\u0300']), ('\u1e16',
-        &['\u0112', '\u0301']), ('\u1e17', &['\u0113', '\u0301']), ('\u1e18', &['\x45', '\u032d']),
-        ('\u1e19', &['\x65', '\u032d']), ('\u1e1a', &['\x45', '\u0330']), ('\u1e1b', &['\x65',
-        '\u0330']), ('\u1e1c', &['\u0228', '\u0306']), ('\u1e1d', &['\u0229', '\u0306']), ('\u1e1e',
-        &['\x46', '\u0307']), ('\u1e1f', &['\x66', '\u0307']), ('\u1e20', &['\x47', '\u0304']),
-        ('\u1e21', &['\x67', '\u0304']), ('\u1e22', &['\x48', '\u0307']), ('\u1e23', &['\x68',
-        '\u0307']), ('\u1e24', &['\x48', '\u0323']), ('\u1e25', &['\x68', '\u0323']), ('\u1e26',
-        &['\x48', '\u0308']), ('\u1e27', &['\x68', '\u0308']), ('\u1e28', &['\x48', '\u0327']),
-        ('\u1e29', &['\x68', '\u0327']), ('\u1e2a', &['\x48', '\u032e']), ('\u1e2b', &['\x68',
-        '\u032e']), ('\u1e2c', &['\x49', '\u0330']), ('\u1e2d', &['\x69', '\u0330']), ('\u1e2e',
-        &['\xcf', '\u0301']), ('\u1e2f', &['\xef', '\u0301']), ('\u1e30', &['\x4b', '\u0301']),
-        ('\u1e31', &['\x6b', '\u0301']), ('\u1e32', &['\x4b', '\u0323']), ('\u1e33', &['\x6b',
-        '\u0323']), ('\u1e34', &['\x4b', '\u0331']), ('\u1e35', &['\x6b', '\u0331']), ('\u1e36',
-        &['\x4c', '\u0323']), ('\u1e37', &['\x6c', '\u0323']), ('\u1e38', &['\u1e36', '\u0304']),
-        ('\u1e39', &['\u1e37', '\u0304']), ('\u1e3a', &['\x4c', '\u0331']), ('\u1e3b', &['\x6c',
-        '\u0331']), ('\u1e3c', &['\x4c', '\u032d']), ('\u1e3d', &['\x6c', '\u032d']), ('\u1e3e',
-        &['\x4d', '\u0301']), ('\u1e3f', &['\x6d', '\u0301']), ('\u1e40', &['\x4d', '\u0307']),
-        ('\u1e41', &['\x6d', '\u0307']), ('\u1e42', &['\x4d', '\u0323']), ('\u1e43', &['\x6d',
-        '\u0323']), ('\u1e44', &['\x4e', '\u0307']), ('\u1e45', &['\x6e', '\u0307']), ('\u1e46',
-        &['\x4e', '\u0323']), ('\u1e47', &['\x6e', '\u0323']), ('\u1e48', &['\x4e', '\u0331']),
-        ('\u1e49', &['\x6e', '\u0331']), ('\u1e4a', &['\x4e', '\u032d']), ('\u1e4b', &['\x6e',
-        '\u032d']), ('\u1e4c', &['\xd5', '\u0301']), ('\u1e4d', &['\xf5', '\u0301']), ('\u1e4e',
-        &['\xd5', '\u0308']), ('\u1e4f', &['\xf5', '\u0308']), ('\u1e50', &['\u014c', '\u0300']),
-        ('\u1e51', &['\u014d', '\u0300']), ('\u1e52', &['\u014c', '\u0301']), ('\u1e53', &['\u014d',
-        '\u0301']), ('\u1e54', &['\x50', '\u0301']), ('\u1e55', &['\x70', '\u0301']), ('\u1e56',
-        &['\x50', '\u0307']), ('\u1e57', &['\x70', '\u0307']), ('\u1e58', &['\x52', '\u0307']),
-        ('\u1e59', &['\x72', '\u0307']), ('\u1e5a', &['\x52', '\u0323']), ('\u1e5b', &['\x72',
-        '\u0323']), ('\u1e5c', &['\u1e5a', '\u0304']), ('\u1e5d', &['\u1e5b', '\u0304']), ('\u1e5e',
-        &['\x52', '\u0331']), ('\u1e5f', &['\x72', '\u0331']), ('\u1e60', &['\x53', '\u0307']),
-        ('\u1e61', &['\x73', '\u0307']), ('\u1e62', &['\x53', '\u0323']), ('\u1e63', &['\x73',
-        '\u0323']), ('\u1e64', &['\u015a', '\u0307']), ('\u1e65', &['\u015b', '\u0307']), ('\u1e66',
-        &['\u0160', '\u0307']), ('\u1e67', &['\u0161', '\u0307']), ('\u1e68', &['\u1e62',
-        '\u0307']), ('\u1e69', &['\u1e63', '\u0307']), ('\u1e6a', &['\x54', '\u0307']), ('\u1e6b',
-        &['\x74', '\u0307']), ('\u1e6c', &['\x54', '\u0323']), ('\u1e6d', &['\x74', '\u0323']),
-        ('\u1e6e', &['\x54', '\u0331']), ('\u1e6f', &['\x74', '\u0331']), ('\u1e70', &['\x54',
-        '\u032d']), ('\u1e71', &['\x74', '\u032d']), ('\u1e72', &['\x55', '\u0324']), ('\u1e73',
-        &['\x75', '\u0324']), ('\u1e74', &['\x55', '\u0330']), ('\u1e75', &['\x75', '\u0330']),
-        ('\u1e76', &['\x55', '\u032d']), ('\u1e77', &['\x75', '\u032d']), ('\u1e78', &['\u0168',
-        '\u0301']), ('\u1e79', &['\u0169', '\u0301']), ('\u1e7a', &['\u016a', '\u0308']), ('\u1e7b',
-        &['\u016b', '\u0308']), ('\u1e7c', &['\x56', '\u0303']), ('\u1e7d', &['\x76', '\u0303']),
-        ('\u1e7e', &['\x56', '\u0323']), ('\u1e7f', &['\x76', '\u0323']), ('\u1e80', &['\x57',
-        '\u0300']), ('\u1e81', &['\x77', '\u0300']), ('\u1e82', &['\x57', '\u0301']), ('\u1e83',
-        &['\x77', '\u0301']), ('\u1e84', &['\x57', '\u0308']), ('\u1e85', &['\x77', '\u0308']),
-        ('\u1e86', &['\x57', '\u0307']), ('\u1e87', &['\x77', '\u0307']), ('\u1e88', &['\x57',
-        '\u0323']), ('\u1e89', &['\x77', '\u0323']), ('\u1e8a', &['\x58', '\u0307']), ('\u1e8b',
-        &['\x78', '\u0307']), ('\u1e8c', &['\x58', '\u0308']), ('\u1e8d', &['\x78', '\u0308']),
-        ('\u1e8e', &['\x59', '\u0307']), ('\u1e8f', &['\x79', '\u0307']), ('\u1e90', &['\x5a',
-        '\u0302']), ('\u1e91', &['\x7a', '\u0302']), ('\u1e92', &['\x5a', '\u0323']), ('\u1e93',
-        &['\x7a', '\u0323']), ('\u1e94', &['\x5a', '\u0331']), ('\u1e95', &['\x7a', '\u0331']),
-        ('\u1e96', &['\x68', '\u0331']), ('\u1e97', &['\x74', '\u0308']), ('\u1e98', &['\x77',
-        '\u030a']), ('\u1e99', &['\x79', '\u030a']), ('\u1e9b', &['\u017f', '\u0307']), ('\u1ea0',
-        &['\x41', '\u0323']), ('\u1ea1', &['\x61', '\u0323']), ('\u1ea2', &['\x41', '\u0309']),
-        ('\u1ea3', &['\x61', '\u0309']), ('\u1ea4', &['\xc2', '\u0301']), ('\u1ea5', &['\xe2',
-        '\u0301']), ('\u1ea6', &['\xc2', '\u0300']), ('\u1ea7', &['\xe2', '\u0300']), ('\u1ea8',
-        &['\xc2', '\u0309']), ('\u1ea9', &['\xe2', '\u0309']), ('\u1eaa', &['\xc2', '\u0303']),
-        ('\u1eab', &['\xe2', '\u0303']), ('\u1eac', &['\u1ea0', '\u0302']), ('\u1ead', &['\u1ea1',
-        '\u0302']), ('\u1eae', &['\u0102', '\u0301']), ('\u1eaf', &['\u0103', '\u0301']), ('\u1eb0',
-        &['\u0102', '\u0300']), ('\u1eb1', &['\u0103', '\u0300']), ('\u1eb2', &['\u0102',
-        '\u0309']), ('\u1eb3', &['\u0103', '\u0309']), ('\u1eb4', &['\u0102', '\u0303']), ('\u1eb5',
-        &['\u0103', '\u0303']), ('\u1eb6', &['\u1ea0', '\u0306']), ('\u1eb7', &['\u1ea1',
-        '\u0306']), ('\u1eb8', &['\x45', '\u0323']), ('\u1eb9', &['\x65', '\u0323']), ('\u1eba',
-        &['\x45', '\u0309']), ('\u1ebb', &['\x65', '\u0309']), ('\u1ebc', &['\x45', '\u0303']),
-        ('\u1ebd', &['\x65', '\u0303']), ('\u1ebe', &['\xca', '\u0301']), ('\u1ebf', &['\xea',
-        '\u0301']), ('\u1ec0', &['\xca', '\u0300']), ('\u1ec1', &['\xea', '\u0300']), ('\u1ec2',
-        &['\xca', '\u0309']), ('\u1ec3', &['\xea', '\u0309']), ('\u1ec4', &['\xca', '\u0303']),
-        ('\u1ec5', &['\xea', '\u0303']), ('\u1ec6', &['\u1eb8', '\u0302']), ('\u1ec7', &['\u1eb9',
-        '\u0302']), ('\u1ec8', &['\x49', '\u0309']), ('\u1ec9', &['\x69', '\u0309']), ('\u1eca',
-        &['\x49', '\u0323']), ('\u1ecb', &['\x69', '\u0323']), ('\u1ecc', &['\x4f', '\u0323']),
-        ('\u1ecd', &['\x6f', '\u0323']), ('\u1ece', &['\x4f', '\u0309']), ('\u1ecf', &['\x6f',
-        '\u0309']), ('\u1ed0', &['\xd4', '\u0301']), ('\u1ed1', &['\xf4', '\u0301']), ('\u1ed2',
-        &['\xd4', '\u0300']), ('\u1ed3', &['\xf4', '\u0300']), ('\u1ed4', &['\xd4', '\u0309']),
-        ('\u1ed5', &['\xf4', '\u0309']), ('\u1ed6', &['\xd4', '\u0303']), ('\u1ed7', &['\xf4',
-        '\u0303']), ('\u1ed8', &['\u1ecc', '\u0302']), ('\u1ed9', &['\u1ecd', '\u0302']), ('\u1eda',
-        &['\u01a0', '\u0301']), ('\u1edb', &['\u01a1', '\u0301']), ('\u1edc', &['\u01a0',
-        '\u0300']), ('\u1edd', &['\u01a1', '\u0300']), ('\u1ede', &['\u01a0', '\u0309']), ('\u1edf',
-        &['\u01a1', '\u0309']), ('\u1ee0', &['\u01a0', '\u0303']), ('\u1ee1', &['\u01a1',
-        '\u0303']), ('\u1ee2', &['\u01a0', '\u0323']), ('\u1ee3', &['\u01a1', '\u0323']), ('\u1ee4',
-        &['\x55', '\u0323']), ('\u1ee5', &['\x75', '\u0323']), ('\u1ee6', &['\x55', '\u0309']),
-        ('\u1ee7', &['\x75', '\u0309']), ('\u1ee8', &['\u01af', '\u0301']), ('\u1ee9', &['\u01b0',
-        '\u0301']), ('\u1eea', &['\u01af', '\u0300']), ('\u1eeb', &['\u01b0', '\u0300']), ('\u1eec',
-        &['\u01af', '\u0309']), ('\u1eed', &['\u01b0', '\u0309']), ('\u1eee', &['\u01af',
-        '\u0303']), ('\u1eef', &['\u01b0', '\u0303']), ('\u1ef0', &['\u01af', '\u0323']), ('\u1ef1',
-        &['\u01b0', '\u0323']), ('\u1ef2', &['\x59', '\u0300']), ('\u1ef3', &['\x79', '\u0300']),
-        ('\u1ef4', &['\x59', '\u0323']), ('\u1ef5', &['\x79', '\u0323']), ('\u1ef6', &['\x59',
-        '\u0309']), ('\u1ef7', &['\x79', '\u0309']), ('\u1ef8', &['\x59', '\u0303']), ('\u1ef9',
-        &['\x79', '\u0303']), ('\u1f00', &['\u03b1', '\u0313']), ('\u1f01', &['\u03b1', '\u0314']),
-        ('\u1f02', &['\u1f00', '\u0300']), ('\u1f03', &['\u1f01', '\u0300']), ('\u1f04', &['\u1f00',
-        '\u0301']), ('\u1f05', &['\u1f01', '\u0301']), ('\u1f06', &['\u1f00', '\u0342']), ('\u1f07',
-        &['\u1f01', '\u0342']), ('\u1f08', &['\u0391', '\u0313']), ('\u1f09', &['\u0391',
-        '\u0314']), ('\u1f0a', &['\u1f08', '\u0300']), ('\u1f0b', &['\u1f09', '\u0300']), ('\u1f0c',
-        &['\u1f08', '\u0301']), ('\u1f0d', &['\u1f09', '\u0301']), ('\u1f0e', &['\u1f08',
-        '\u0342']), ('\u1f0f', &['\u1f09', '\u0342']), ('\u1f10', &['\u03b5', '\u0313']), ('\u1f11',
-        &['\u03b5', '\u0314']), ('\u1f12', &['\u1f10', '\u0300']), ('\u1f13', &['\u1f11',
-        '\u0300']), ('\u1f14', &['\u1f10', '\u0301']), ('\u1f15', &['\u1f11', '\u0301']), ('\u1f18',
-        &['\u0395', '\u0313']), ('\u1f19', &['\u0395', '\u0314']), ('\u1f1a', &['\u1f18',
-        '\u0300']), ('\u1f1b', &['\u1f19', '\u0300']), ('\u1f1c', &['\u1f18', '\u0301']), ('\u1f1d',
-        &['\u1f19', '\u0301']), ('\u1f20', &['\u03b7', '\u0313']), ('\u1f21', &['\u03b7',
-        '\u0314']), ('\u1f22', &['\u1f20', '\u0300']), ('\u1f23', &['\u1f21', '\u0300']), ('\u1f24',
-        &['\u1f20', '\u0301']), ('\u1f25', &['\u1f21', '\u0301']), ('\u1f26', &['\u1f20',
-        '\u0342']), ('\u1f27', &['\u1f21', '\u0342']), ('\u1f28', &['\u0397', '\u0313']), ('\u1f29',
-        &['\u0397', '\u0314']), ('\u1f2a', &['\u1f28', '\u0300']), ('\u1f2b', &['\u1f29',
-        '\u0300']), ('\u1f2c', &['\u1f28', '\u0301']), ('\u1f2d', &['\u1f29', '\u0301']), ('\u1f2e',
-        &['\u1f28', '\u0342']), ('\u1f2f', &['\u1f29', '\u0342']), ('\u1f30', &['\u03b9',
-        '\u0313']), ('\u1f31', &['\u03b9', '\u0314']), ('\u1f32', &['\u1f30', '\u0300']), ('\u1f33',
-        &['\u1f31', '\u0300']), ('\u1f34', &['\u1f30', '\u0301']), ('\u1f35', &['\u1f31',
-        '\u0301']), ('\u1f36', &['\u1f30', '\u0342']), ('\u1f37', &['\u1f31', '\u0342']), ('\u1f38',
-        &['\u0399', '\u0313']), ('\u1f39', &['\u0399', '\u0314']), ('\u1f3a', &['\u1f38',
-        '\u0300']), ('\u1f3b', &['\u1f39', '\u0300']), ('\u1f3c', &['\u1f38', '\u0301']), ('\u1f3d',
-        &['\u1f39', '\u0301']), ('\u1f3e', &['\u1f38', '\u0342']), ('\u1f3f', &['\u1f39',
-        '\u0342']), ('\u1f40', &['\u03bf', '\u0313']), ('\u1f41', &['\u03bf', '\u0314']), ('\u1f42',
-        &['\u1f40', '\u0300']), ('\u1f43', &['\u1f41', '\u0300']), ('\u1f44', &['\u1f40',
-        '\u0301']), ('\u1f45', &['\u1f41', '\u0301']), ('\u1f48', &['\u039f', '\u0313']), ('\u1f49',
-        &['\u039f', '\u0314']), ('\u1f4a', &['\u1f48', '\u0300']), ('\u1f4b', &['\u1f49',
-        '\u0300']), ('\u1f4c', &['\u1f48', '\u0301']), ('\u1f4d', &['\u1f49', '\u0301']), ('\u1f50',
-        &['\u03c5', '\u0313']), ('\u1f51', &['\u03c5', '\u0314']), ('\u1f52', &['\u1f50',
-        '\u0300']), ('\u1f53', &['\u1f51', '\u0300']), ('\u1f54', &['\u1f50', '\u0301']), ('\u1f55',
-        &['\u1f51', '\u0301']), ('\u1f56', &['\u1f50', '\u0342']), ('\u1f57', &['\u1f51',
-        '\u0342']), ('\u1f59', &['\u03a5', '\u0314']), ('\u1f5b', &['\u1f59', '\u0300']), ('\u1f5d',
-        &['\u1f59', '\u0301']), ('\u1f5f', &['\u1f59', '\u0342']), ('\u1f60', &['\u03c9',
-        '\u0313']), ('\u1f61', &['\u03c9', '\u0314']), ('\u1f62', &['\u1f60', '\u0300']), ('\u1f63',
-        &['\u1f61', '\u0300']), ('\u1f64', &['\u1f60', '\u0301']), ('\u1f65', &['\u1f61',
-        '\u0301']), ('\u1f66', &['\u1f60', '\u0342']), ('\u1f67', &['\u1f61', '\u0342']), ('\u1f68',
-        &['\u03a9', '\u0313']), ('\u1f69', &['\u03a9', '\u0314']), ('\u1f6a', &['\u1f68',
-        '\u0300']), ('\u1f6b', &['\u1f69', '\u0300']), ('\u1f6c', &['\u1f68', '\u0301']), ('\u1f6d',
-        &['\u1f69', '\u0301']), ('\u1f6e', &['\u1f68', '\u0342']), ('\u1f6f', &['\u1f69',
-        '\u0342']), ('\u1f70', &['\u03b1', '\u0300']), ('\u1f71', &['\u03ac']), ('\u1f72',
-        &['\u03b5', '\u0300']), ('\u1f73', &['\u03ad']), ('\u1f74', &['\u03b7', '\u0300']),
-        ('\u1f75', &['\u03ae']), ('\u1f76', &['\u03b9', '\u0300']), ('\u1f77', &['\u03af']),
-        ('\u1f78', &['\u03bf', '\u0300']), ('\u1f79', &['\u03cc']), ('\u1f7a', &['\u03c5',
-        '\u0300']), ('\u1f7b', &['\u03cd']), ('\u1f7c', &['\u03c9', '\u0300']), ('\u1f7d',
-        &['\u03ce']), ('\u1f80', &['\u1f00', '\u0345']), ('\u1f81', &['\u1f01', '\u0345']),
-        ('\u1f82', &['\u1f02', '\u0345']), ('\u1f83', &['\u1f03', '\u0345']), ('\u1f84', &['\u1f04',
-        '\u0345']), ('\u1f85', &['\u1f05', '\u0345']), ('\u1f86', &['\u1f06', '\u0345']), ('\u1f87',
-        &['\u1f07', '\u0345']), ('\u1f88', &['\u1f08', '\u0345']), ('\u1f89', &['\u1f09',
-        '\u0345']), ('\u1f8a', &['\u1f0a', '\u0345']), ('\u1f8b', &['\u1f0b', '\u0345']), ('\u1f8c',
-        &['\u1f0c', '\u0345']), ('\u1f8d', &['\u1f0d', '\u0345']), ('\u1f8e', &['\u1f0e',
-        '\u0345']), ('\u1f8f', &['\u1f0f', '\u0345']), ('\u1f90', &['\u1f20', '\u0345']), ('\u1f91',
-        &['\u1f21', '\u0345']), ('\u1f92', &['\u1f22', '\u0345']), ('\u1f93', &['\u1f23',
-        '\u0345']), ('\u1f94', &['\u1f24', '\u0345']), ('\u1f95', &['\u1f25', '\u0345']), ('\u1f96',
-        &['\u1f26', '\u0345']), ('\u1f97', &['\u1f27', '\u0345']), ('\u1f98', &['\u1f28',
-        '\u0345']), ('\u1f99', &['\u1f29', '\u0345']), ('\u1f9a', &['\u1f2a', '\u0345']), ('\u1f9b',
-        &['\u1f2b', '\u0345']), ('\u1f9c', &['\u1f2c', '\u0345']), ('\u1f9d', &['\u1f2d',
-        '\u0345']), ('\u1f9e', &['\u1f2e', '\u0345']), ('\u1f9f', &['\u1f2f', '\u0345']), ('\u1fa0',
-        &['\u1f60', '\u0345']), ('\u1fa1', &['\u1f61', '\u0345']), ('\u1fa2', &['\u1f62',
-        '\u0345']), ('\u1fa3', &['\u1f63', '\u0345']), ('\u1fa4', &['\u1f64', '\u0345']), ('\u1fa5',
-        &['\u1f65', '\u0345']), ('\u1fa6', &['\u1f66', '\u0345']), ('\u1fa7', &['\u1f67',
-        '\u0345']), ('\u1fa8', &['\u1f68', '\u0345']), ('\u1fa9', &['\u1f69', '\u0345']), ('\u1faa',
-        &['\u1f6a', '\u0345']), ('\u1fab', &['\u1f6b', '\u0345']), ('\u1fac', &['\u1f6c',
-        '\u0345']), ('\u1fad', &['\u1f6d', '\u0345']), ('\u1fae', &['\u1f6e', '\u0345']), ('\u1faf',
-        &['\u1f6f', '\u0345']), ('\u1fb0', &['\u03b1', '\u0306']), ('\u1fb1', &['\u03b1',
-        '\u0304']), ('\u1fb2', &['\u1f70', '\u0345']), ('\u1fb3', &['\u03b1', '\u0345']), ('\u1fb4',
-        &['\u03ac', '\u0345']), ('\u1fb6', &['\u03b1', '\u0342']), ('\u1fb7', &['\u1fb6',
-        '\u0345']), ('\u1fb8', &['\u0391', '\u0306']), ('\u1fb9', &['\u0391', '\u0304']), ('\u1fba',
-        &['\u0391', '\u0300']), ('\u1fbb', &['\u0386']), ('\u1fbc', &['\u0391', '\u0345']),
-        ('\u1fbe', &['\u03b9']), ('\u1fc1', &['\xa8', '\u0342']), ('\u1fc2', &['\u1f74', '\u0345']),
-        ('\u1fc3', &['\u03b7', '\u0345']), ('\u1fc4', &['\u03ae', '\u0345']), ('\u1fc6', &['\u03b7',
-        '\u0342']), ('\u1fc7', &['\u1fc6', '\u0345']), ('\u1fc8', &['\u0395', '\u0300']), ('\u1fc9',
-        &['\u0388']), ('\u1fca', &['\u0397', '\u0300']), ('\u1fcb', &['\u0389']), ('\u1fcc',
-        &['\u0397', '\u0345']), ('\u1fcd', &['\u1fbf', '\u0300']), ('\u1fce', &['\u1fbf',
-        '\u0301']), ('\u1fcf', &['\u1fbf', '\u0342']), ('\u1fd0', &['\u03b9', '\u0306']), ('\u1fd1',
-        &['\u03b9', '\u0304']), ('\u1fd2', &['\u03ca', '\u0300']), ('\u1fd3', &['\u0390']),
-        ('\u1fd6', &['\u03b9', '\u0342']), ('\u1fd7', &['\u03ca', '\u0342']), ('\u1fd8', &['\u0399',
-        '\u0306']), ('\u1fd9', &['\u0399', '\u0304']), ('\u1fda', &['\u0399', '\u0300']), ('\u1fdb',
-        &['\u038a']), ('\u1fdd', &['\u1ffe', '\u0300']), ('\u1fde', &['\u1ffe', '\u0301']),
-        ('\u1fdf', &['\u1ffe', '\u0342']), ('\u1fe0', &['\u03c5', '\u0306']), ('\u1fe1', &['\u03c5',
-        '\u0304']), ('\u1fe2', &['\u03cb', '\u0300']), ('\u1fe3', &['\u03b0']), ('\u1fe4',
-        &['\u03c1', '\u0313']), ('\u1fe5', &['\u03c1', '\u0314']), ('\u1fe6', &['\u03c5',
-        '\u0342']), ('\u1fe7', &['\u03cb', '\u0342']), ('\u1fe8', &['\u03a5', '\u0306']), ('\u1fe9',
-        &['\u03a5', '\u0304']), ('\u1fea', &['\u03a5', '\u0300']), ('\u1feb', &['\u038e']),
-        ('\u1fec', &['\u03a1', '\u0314']), ('\u1fed', &['\xa8', '\u0300']), ('\u1fee', &['\u0385']),
-        ('\u1fef', &['\x60']), ('\u1ff2', &['\u1f7c', '\u0345']), ('\u1ff3', &['\u03c9', '\u0345']),
-        ('\u1ff4', &['\u03ce', '\u0345']), ('\u1ff6', &['\u03c9', '\u0342']), ('\u1ff7', &['\u1ff6',
-        '\u0345']), ('\u1ff8', &['\u039f', '\u0300']), ('\u1ff9', &['\u038c']), ('\u1ffa',
-        &['\u03a9', '\u0300']), ('\u1ffb', &['\u038f']), ('\u1ffc', &['\u03a9', '\u0345']),
-        ('\u1ffd', &['\xb4']), ('\u2000', &['\u2002']), ('\u2001', &['\u2003']), ('\u2126',
-        &['\u03a9']), ('\u212a', &['\x4b']), ('\u212b', &['\xc5']), ('\u219a', &['\u2190',
-        '\u0338']), ('\u219b', &['\u2192', '\u0338']), ('\u21ae', &['\u2194', '\u0338']), ('\u21cd',
-        &['\u21d0', '\u0338']), ('\u21ce', &['\u21d4', '\u0338']), ('\u21cf', &['\u21d2',
-        '\u0338']), ('\u2204', &['\u2203', '\u0338']), ('\u2209', &['\u2208', '\u0338']), ('\u220c',
-        &['\u220b', '\u0338']), ('\u2224', &['\u2223', '\u0338']), ('\u2226', &['\u2225',
-        '\u0338']), ('\u2241', &['\u223c', '\u0338']), ('\u2244', &['\u2243', '\u0338']), ('\u2247',
-        &['\u2245', '\u0338']), ('\u2249', &['\u2248', '\u0338']), ('\u2260', &['\x3d', '\u0338']),
-        ('\u2262', &['\u2261', '\u0338']), ('\u226d', &['\u224d', '\u0338']), ('\u226e', &['\x3c',
-        '\u0338']), ('\u226f', &['\x3e', '\u0338']), ('\u2270', &['\u2264', '\u0338']), ('\u2271',
-        &['\u2265', '\u0338']), ('\u2274', &['\u2272', '\u0338']), ('\u2275', &['\u2273',
-        '\u0338']), ('\u2278', &['\u2276', '\u0338']), ('\u2279', &['\u2277', '\u0338']), ('\u2280',
-        &['\u227a', '\u0338']), ('\u2281', &['\u227b', '\u0338']), ('\u2284', &['\u2282',
-        '\u0338']), ('\u2285', &['\u2283', '\u0338']), ('\u2288', &['\u2286', '\u0338']), ('\u2289',
-        &['\u2287', '\u0338']), ('\u22ac', &['\u22a2', '\u0338']), ('\u22ad', &['\u22a8',
-        '\u0338']), ('\u22ae', &['\u22a9', '\u0338']), ('\u22af', &['\u22ab', '\u0338']), ('\u22e0',
-        &['\u227c', '\u0338']), ('\u22e1', &['\u227d', '\u0338']), ('\u22e2', &['\u2291',
-        '\u0338']), ('\u22e3', &['\u2292', '\u0338']), ('\u22ea', &['\u22b2', '\u0338']), ('\u22eb',
-        &['\u22b3', '\u0338']), ('\u22ec', &['\u22b4', '\u0338']), ('\u22ed', &['\u22b5',
-        '\u0338']), ('\u2329', &['\u3008']), ('\u232a', &['\u3009']), ('\u2adc', &['\u2add',
-        '\u0338']), ('\u304c', &['\u304b', '\u3099']), ('\u304e', &['\u304d', '\u3099']), ('\u3050',
-        &['\u304f', '\u3099']), ('\u3052', &['\u3051', '\u3099']), ('\u3054', &['\u3053',
-        '\u3099']), ('\u3056', &['\u3055', '\u3099']), ('\u3058', &['\u3057', '\u3099']), ('\u305a',
-        &['\u3059', '\u3099']), ('\u305c', &['\u305b', '\u3099']), ('\u305e', &['\u305d',
-        '\u3099']), ('\u3060', &['\u305f', '\u3099']), ('\u3062', &['\u3061', '\u3099']), ('\u3065',
-        &['\u3064', '\u3099']), ('\u3067', &['\u3066', '\u3099']), ('\u3069', &['\u3068',
-        '\u3099']), ('\u3070', &['\u306f', '\u3099']), ('\u3071', &['\u306f', '\u309a']), ('\u3073',
-        &['\u3072', '\u3099']), ('\u3074', &['\u3072', '\u309a']), ('\u3076', &['\u3075',
-        '\u3099']), ('\u3077', &['\u3075', '\u309a']), ('\u3079', &['\u3078', '\u3099']), ('\u307a',
-        &['\u3078', '\u309a']), ('\u307c', &['\u307b', '\u3099']), ('\u307d', &['\u307b',
-        '\u309a']), ('\u3094', &['\u3046', '\u3099']), ('\u309e', &['\u309d', '\u3099']), ('\u30ac',
-        &['\u30ab', '\u3099']), ('\u30ae', &['\u30ad', '\u3099']), ('\u30b0', &['\u30af',
-        '\u3099']), ('\u30b2', &['\u30b1', '\u3099']), ('\u30b4', &['\u30b3', '\u3099']), ('\u30b6',
-        &['\u30b5', '\u3099']), ('\u30b8', &['\u30b7', '\u3099']), ('\u30ba', &['\u30b9',
-        '\u3099']), ('\u30bc', &['\u30bb', '\u3099']), ('\u30be', &['\u30bd', '\u3099']), ('\u30c0',
-        &['\u30bf', '\u3099']), ('\u30c2', &['\u30c1', '\u3099']), ('\u30c5', &['\u30c4',
-        '\u3099']), ('\u30c7', &['\u30c6', '\u3099']), ('\u30c9', &['\u30c8', '\u3099']), ('\u30d0',
-        &['\u30cf', '\u3099']), ('\u30d1', &['\u30cf', '\u309a']), ('\u30d3', &['\u30d2',
-        '\u3099']), ('\u30d4', &['\u30d2', '\u309a']), ('\u30d6', &['\u30d5', '\u3099']), ('\u30d7',
-        &['\u30d5', '\u309a']), ('\u30d9', &['\u30d8', '\u3099']), ('\u30da', &['\u30d8',
-        '\u309a']), ('\u30dc', &['\u30db', '\u3099']), ('\u30dd', &['\u30db', '\u309a']), ('\u30f4',
-        &['\u30a6', '\u3099']), ('\u30f7', &['\u30ef', '\u3099']), ('\u30f8', &['\u30f0',
-        '\u3099']), ('\u30f9', &['\u30f1', '\u3099']), ('\u30fa', &['\u30f2', '\u3099']), ('\u30fe',
-        &['\u30fd', '\u3099']), ('\uf900', &['\u8c48']), ('\uf901', &['\u66f4']), ('\uf902',
-        &['\u8eca']), ('\uf903', &['\u8cc8']), ('\uf904', &['\u6ed1']), ('\uf905', &['\u4e32']),
-        ('\uf906', &['\u53e5']), ('\uf907', &['\u9f9c']), ('\uf908', &['\u9f9c']), ('\uf909',
-        &['\u5951']), ('\uf90a', &['\u91d1']), ('\uf90b', &['\u5587']), ('\uf90c', &['\u5948']),
-        ('\uf90d', &['\u61f6']), ('\uf90e', &['\u7669']), ('\uf90f', &['\u7f85']), ('\uf910',
-        &['\u863f']), ('\uf911', &['\u87ba']), ('\uf912', &['\u88f8']), ('\uf913', &['\u908f']),
-        ('\uf914', &['\u6a02']), ('\uf915', &['\u6d1b']), ('\uf916', &['\u70d9']), ('\uf917',
-        &['\u73de']), ('\uf918', &['\u843d']), ('\uf919', &['\u916a']), ('\uf91a', &['\u99f1']),
-        ('\uf91b', &['\u4e82']), ('\uf91c', &['\u5375']), ('\uf91d', &['\u6b04']), ('\uf91e',
-        &['\u721b']), ('\uf91f', &['\u862d']), ('\uf920', &['\u9e1e']), ('\uf921', &['\u5d50']),
-        ('\uf922', &['\u6feb']), ('\uf923', &['\u85cd']), ('\uf924', &['\u8964']), ('\uf925',
-        &['\u62c9']), ('\uf926', &['\u81d8']), ('\uf927', &['\u881f']), ('\uf928', &['\u5eca']),
-        ('\uf929', &['\u6717']), ('\uf92a', &['\u6d6a']), ('\uf92b', &['\u72fc']), ('\uf92c',
-        &['\u90ce']), ('\uf92d', &['\u4f86']), ('\uf92e', &['\u51b7']), ('\uf92f', &['\u52de']),
-        ('\uf930', &['\u64c4']), ('\uf931', &['\u6ad3']), ('\uf932', &['\u7210']), ('\uf933',
-        &['\u76e7']), ('\uf934', &['\u8001']), ('\uf935', &['\u8606']), ('\uf936', &['\u865c']),
-        ('\uf937', &['\u8def']), ('\uf938', &['\u9732']), ('\uf939', &['\u9b6f']), ('\uf93a',
-        &['\u9dfa']), ('\uf93b', &['\u788c']), ('\uf93c', &['\u797f']), ('\uf93d', &['\u7da0']),
-        ('\uf93e', &['\u83c9']), ('\uf93f', &['\u9304']), ('\uf940', &['\u9e7f']), ('\uf941',
-        &['\u8ad6']), ('\uf942', &['\u58df']), ('\uf943', &['\u5f04']), ('\uf944', &['\u7c60']),
-        ('\uf945', &['\u807e']), ('\uf946', &['\u7262']), ('\uf947', &['\u78ca']), ('\uf948',
-        &['\u8cc2']), ('\uf949', &['\u96f7']), ('\uf94a', &['\u58d8']), ('\uf94b', &['\u5c62']),
-        ('\uf94c', &['\u6a13']), ('\uf94d', &['\u6dda']), ('\uf94e', &['\u6f0f']), ('\uf94f',
-        &['\u7d2f']), ('\uf950', &['\u7e37']), ('\uf951', &['\u964b']), ('\uf952', &['\u52d2']),
-        ('\uf953', &['\u808b']), ('\uf954', &['\u51dc']), ('\uf955', &['\u51cc']), ('\uf956',
-        &['\u7a1c']), ('\uf957', &['\u7dbe']), ('\uf958', &['\u83f1']), ('\uf959', &['\u9675']),
-        ('\uf95a', &['\u8b80']), ('\uf95b', &['\u62cf']), ('\uf95c', &['\u6a02']), ('\uf95d',
-        &['\u8afe']), ('\uf95e', &['\u4e39']), ('\uf95f', &['\u5be7']), ('\uf960', &['\u6012']),
-        ('\uf961', &['\u7387']), ('\uf962', &['\u7570']), ('\uf963', &['\u5317']), ('\uf964',
-        &['\u78fb']), ('\uf965', &['\u4fbf']), ('\uf966', &['\u5fa9']), ('\uf967', &['\u4e0d']),
-        ('\uf968', &['\u6ccc']), ('\uf969', &['\u6578']), ('\uf96a', &['\u7d22']), ('\uf96b',
-        &['\u53c3']), ('\uf96c', &['\u585e']), ('\uf96d', &['\u7701']), ('\uf96e', &['\u8449']),
-        ('\uf96f', &['\u8aaa']), ('\uf970', &['\u6bba']), ('\uf971', &['\u8fb0']), ('\uf972',
-        &['\u6c88']), ('\uf973', &['\u62fe']), ('\uf974', &['\u82e5']), ('\uf975', &['\u63a0']),
-        ('\uf976', &['\u7565']), ('\uf977', &['\u4eae']), ('\uf978', &['\u5169']), ('\uf979',
-        &['\u51c9']), ('\uf97a', &['\u6881']), ('\uf97b', &['\u7ce7']), ('\uf97c', &['\u826f']),
-        ('\uf97d', &['\u8ad2']), ('\uf97e', &['\u91cf']), ('\uf97f', &['\u52f5']), ('\uf980',
-        &['\u5442']), ('\uf981', &['\u5973']), ('\uf982', &['\u5eec']), ('\uf983', &['\u65c5']),
-        ('\uf984', &['\u6ffe']), ('\uf985', &['\u792a']), ('\uf986', &['\u95ad']), ('\uf987',
-        &['\u9a6a']), ('\uf988', &['\u9e97']), ('\uf989', &['\u9ece']), ('\uf98a', &['\u529b']),
-        ('\uf98b', &['\u66c6']), ('\uf98c', &['\u6b77']), ('\uf98d', &['\u8f62']), ('\uf98e',
-        &['\u5e74']), ('\uf98f', &['\u6190']), ('\uf990', &['\u6200']), ('\uf991', &['\u649a']),
-        ('\uf992', &['\u6f23']), ('\uf993', &['\u7149']), ('\uf994', &['\u7489']), ('\uf995',
-        &['\u79ca']), ('\uf996', &['\u7df4']), ('\uf997', &['\u806f']), ('\uf998', &['\u8f26']),
-        ('\uf999', &['\u84ee']), ('\uf99a', &['\u9023']), ('\uf99b', &['\u934a']), ('\uf99c',
-        &['\u5217']), ('\uf99d', &['\u52a3']), ('\uf99e', &['\u54bd']), ('\uf99f', &['\u70c8']),
-        ('\uf9a0', &['\u88c2']), ('\uf9a1', &['\u8aaa']), ('\uf9a2', &['\u5ec9']), ('\uf9a3',
-        &['\u5ff5']), ('\uf9a4', &['\u637b']), ('\uf9a5', &['\u6bae']), ('\uf9a6', &['\u7c3e']),
-        ('\uf9a7', &['\u7375']), ('\uf9a8', &['\u4ee4']), ('\uf9a9', &['\u56f9']), ('\uf9aa',
-        &['\u5be7']), ('\uf9ab', &['\u5dba']), ('\uf9ac', &['\u601c']), ('\uf9ad', &['\u73b2']),
-        ('\uf9ae', &['\u7469']), ('\uf9af', &['\u7f9a']), ('\uf9b0', &['\u8046']), ('\uf9b1',
-        &['\u9234']), ('\uf9b2', &['\u96f6']), ('\uf9b3', &['\u9748']), ('\uf9b4', &['\u9818']),
-        ('\uf9b5', &['\u4f8b']), ('\uf9b6', &['\u79ae']), ('\uf9b7', &['\u91b4']), ('\uf9b8',
-        &['\u96b8']), ('\uf9b9', &['\u60e1']), ('\uf9ba', &['\u4e86']), ('\uf9bb', &['\u50da']),
-        ('\uf9bc', &['\u5bee']), ('\uf9bd', &['\u5c3f']), ('\uf9be', &['\u6599']), ('\uf9bf',
-        &['\u6a02']), ('\uf9c0', &['\u71ce']), ('\uf9c1', &['\u7642']), ('\uf9c2', &['\u84fc']),
-        ('\uf9c3', &['\u907c']), ('\uf9c4', &['\u9f8d']), ('\uf9c5', &['\u6688']), ('\uf9c6',
-        &['\u962e']), ('\uf9c7', &['\u5289']), ('\uf9c8', &['\u677b']), ('\uf9c9', &['\u67f3']),
-        ('\uf9ca', &['\u6d41']), ('\uf9cb', &['\u6e9c']), ('\uf9cc', &['\u7409']), ('\uf9cd',
-        &['\u7559']), ('\uf9ce', &['\u786b']), ('\uf9cf', &['\u7d10']), ('\uf9d0', &['\u985e']),
-        ('\uf9d1', &['\u516d']), ('\uf9d2', &['\u622e']), ('\uf9d3', &['\u9678']), ('\uf9d4',
-        &['\u502b']), ('\uf9d5', &['\u5d19']), ('\uf9d6', &['\u6dea']), ('\uf9d7', &['\u8f2a']),
-        ('\uf9d8', &['\u5f8b']), ('\uf9d9', &['\u6144']), ('\uf9da', &['\u6817']), ('\uf9db',
-        &['\u7387']), ('\uf9dc', &['\u9686']), ('\uf9dd', &['\u5229']), ('\uf9de', &['\u540f']),
-        ('\uf9df', &['\u5c65']), ('\uf9e0', &['\u6613']), ('\uf9e1', &['\u674e']), ('\uf9e2',
-        &['\u68a8']), ('\uf9e3', &['\u6ce5']), ('\uf9e4', &['\u7406']), ('\uf9e5', &['\u75e2']),
-        ('\uf9e6', &['\u7f79']), ('\uf9e7', &['\u88cf']), ('\uf9e8', &['\u88e1']), ('\uf9e9',
-        &['\u91cc']), ('\uf9ea', &['\u96e2']), ('\uf9eb', &['\u533f']), ('\uf9ec', &['\u6eba']),
-        ('\uf9ed', &['\u541d']), ('\uf9ee', &['\u71d0']), ('\uf9ef', &['\u7498']), ('\uf9f0',
-        &['\u85fa']), ('\uf9f1', &['\u96a3']), ('\uf9f2', &['\u9c57']), ('\uf9f3', &['\u9e9f']),
-        ('\uf9f4', &['\u6797']), ('\uf9f5', &['\u6dcb']), ('\uf9f6', &['\u81e8']), ('\uf9f7',
-        &['\u7acb']), ('\uf9f8', &['\u7b20']), ('\uf9f9', &['\u7c92']), ('\uf9fa', &['\u72c0']),
-        ('\uf9fb', &['\u7099']), ('\uf9fc', &['\u8b58']), ('\uf9fd', &['\u4ec0']), ('\uf9fe',
-        &['\u8336']), ('\uf9ff', &['\u523a']), ('\ufa00', &['\u5207']), ('\ufa01', &['\u5ea6']),
-        ('\ufa02', &['\u62d3']), ('\ufa03', &['\u7cd6']), ('\ufa04', &['\u5b85']), ('\ufa05',
-        &['\u6d1e']), ('\ufa06', &['\u66b4']), ('\ufa07', &['\u8f3b']), ('\ufa08', &['\u884c']),
-        ('\ufa09', &['\u964d']), ('\ufa0a', &['\u898b']), ('\ufa0b', &['\u5ed3']), ('\ufa0c',
-        &['\u5140']), ('\ufa0d', &['\u55c0']), ('\ufa10', &['\u585a']), ('\ufa12', &['\u6674']),
-        ('\ufa15', &['\u51de']), ('\ufa16', &['\u732a']), ('\ufa17', &['\u76ca']), ('\ufa18',
-        &['\u793c']), ('\ufa19', &['\u795e']), ('\ufa1a', &['\u7965']), ('\ufa1b', &['\u798f']),
-        ('\ufa1c', &['\u9756']), ('\ufa1d', &['\u7cbe']), ('\ufa1e', &['\u7fbd']), ('\ufa20',
-        &['\u8612']), ('\ufa22', &['\u8af8']), ('\ufa25', &['\u9038']), ('\ufa26', &['\u90fd']),
-        ('\ufa2a', &['\u98ef']), ('\ufa2b', &['\u98fc']), ('\ufa2c', &['\u9928']), ('\ufa2d',
-        &['\u9db4']), ('\ufa2e', &['\u90de']), ('\ufa2f', &['\u96b7']), ('\ufa30', &['\u4fae']),
-        ('\ufa31', &['\u50e7']), ('\ufa32', &['\u514d']), ('\ufa33', &['\u52c9']), ('\ufa34',
-        &['\u52e4']), ('\ufa35', &['\u5351']), ('\ufa36', &['\u559d']), ('\ufa37', &['\u5606']),
-        ('\ufa38', &['\u5668']), ('\ufa39', &['\u5840']), ('\ufa3a', &['\u58a8']), ('\ufa3b',
-        &['\u5c64']), ('\ufa3c', &['\u5c6e']), ('\ufa3d', &['\u6094']), ('\ufa3e', &['\u6168']),
-        ('\ufa3f', &['\u618e']), ('\ufa40', &['\u61f2']), ('\ufa41', &['\u654f']), ('\ufa42',
-        &['\u65e2']), ('\ufa43', &['\u6691']), ('\ufa44', &['\u6885']), ('\ufa45', &['\u6d77']),
-        ('\ufa46', &['\u6e1a']), ('\ufa47', &['\u6f22']), ('\ufa48', &['\u716e']), ('\ufa49',
-        &['\u722b']), ('\ufa4a', &['\u7422']), ('\ufa4b', &['\u7891']), ('\ufa4c', &['\u793e']),
-        ('\ufa4d', &['\u7949']), ('\ufa4e', &['\u7948']), ('\ufa4f', &['\u7950']), ('\ufa50',
-        &['\u7956']), ('\ufa51', &['\u795d']), ('\ufa52', &['\u798d']), ('\ufa53', &['\u798e']),
-        ('\ufa54', &['\u7a40']), ('\ufa55', &['\u7a81']), ('\ufa56', &['\u7bc0']), ('\ufa57',
-        &['\u7df4']), ('\ufa58', &['\u7e09']), ('\ufa59', &['\u7e41']), ('\ufa5a', &['\u7f72']),
-        ('\ufa5b', &['\u8005']), ('\ufa5c', &['\u81ed']), ('\ufa5d', &['\u8279']), ('\ufa5e',
-        &['\u8279']), ('\ufa5f', &['\u8457']), ('\ufa60', &['\u8910']), ('\ufa61', &['\u8996']),
-        ('\ufa62', &['\u8b01']), ('\ufa63', &['\u8b39']), ('\ufa64', &['\u8cd3']), ('\ufa65',
-        &['\u8d08']), ('\ufa66', &['\u8fb6']), ('\ufa67', &['\u9038']), ('\ufa68', &['\u96e3']),
-        ('\ufa69', &['\u97ff']), ('\ufa6a', &['\u983b']), ('\ufa6b', &['\u6075']), ('\ufa6c',
-        &['\U000242ee']), ('\ufa6d', &['\u8218']), ('\ufa70', &['\u4e26']), ('\ufa71', &['\u51b5']),
-        ('\ufa72', &['\u5168']), ('\ufa73', &['\u4f80']), ('\ufa74', &['\u5145']), ('\ufa75',
-        &['\u5180']), ('\ufa76', &['\u52c7']), ('\ufa77', &['\u52fa']), ('\ufa78', &['\u559d']),
-        ('\ufa79', &['\u5555']), ('\ufa7a', &['\u5599']), ('\ufa7b', &['\u55e2']), ('\ufa7c',
-        &['\u585a']), ('\ufa7d', &['\u58b3']), ('\ufa7e', &['\u5944']), ('\ufa7f', &['\u5954']),
-        ('\ufa80', &['\u5a62']), ('\ufa81', &['\u5b28']), ('\ufa82', &['\u5ed2']), ('\ufa83',
-        &['\u5ed9']), ('\ufa84', &['\u5f69']), ('\ufa85', &['\u5fad']), ('\ufa86', &['\u60d8']),
-        ('\ufa87', &['\u614e']), ('\ufa88', &['\u6108']), ('\ufa89', &['\u618e']), ('\ufa8a',
-        &['\u6160']), ('\ufa8b', &['\u61f2']), ('\ufa8c', &['\u6234']), ('\ufa8d', &['\u63c4']),
-        ('\ufa8e', &['\u641c']), ('\ufa8f', &['\u6452']), ('\ufa90', &['\u6556']), ('\ufa91',
-        &['\u6674']), ('\ufa92', &['\u6717']), ('\ufa93', &['\u671b']), ('\ufa94', &['\u6756']),
-        ('\ufa95', &['\u6b79']), ('\ufa96', &['\u6bba']), ('\ufa97', &['\u6d41']), ('\ufa98',
-        &['\u6edb']), ('\ufa99', &['\u6ecb']), ('\ufa9a', &['\u6f22']), ('\ufa9b', &['\u701e']),
-        ('\ufa9c', &['\u716e']), ('\ufa9d', &['\u77a7']), ('\ufa9e', &['\u7235']), ('\ufa9f',
-        &['\u72af']), ('\ufaa0', &['\u732a']), ('\ufaa1', &['\u7471']), ('\ufaa2', &['\u7506']),
-        ('\ufaa3', &['\u753b']), ('\ufaa4', &['\u761d']), ('\ufaa5', &['\u761f']), ('\ufaa6',
-        &['\u76ca']), ('\ufaa7', &['\u76db']), ('\ufaa8', &['\u76f4']), ('\ufaa9', &['\u774a']),
-        ('\ufaaa', &['\u7740']), ('\ufaab', &['\u78cc']), ('\ufaac', &['\u7ab1']), ('\ufaad',
-        &['\u7bc0']), ('\ufaae', &['\u7c7b']), ('\ufaaf', &['\u7d5b']), ('\ufab0', &['\u7df4']),
-        ('\ufab1', &['\u7f3e']), ('\ufab2', &['\u8005']), ('\ufab3', &['\u8352']), ('\ufab4',
-        &['\u83ef']), ('\ufab5', &['\u8779']), ('\ufab6', &['\u8941']), ('\ufab7', &['\u8986']),
-        ('\ufab8', &['\u8996']), ('\ufab9', &['\u8abf']), ('\ufaba', &['\u8af8']), ('\ufabb',
-        &['\u8acb']), ('\ufabc', &['\u8b01']), ('\ufabd', &['\u8afe']), ('\ufabe', &['\u8aed']),
-        ('\ufabf', &['\u8b39']), ('\ufac0', &['\u8b8a']), ('\ufac1', &['\u8d08']), ('\ufac2',
-        &['\u8f38']), ('\ufac3', &['\u9072']), ('\ufac4', &['\u9199']), ('\ufac5', &['\u9276']),
-        ('\ufac6', &['\u967c']), ('\ufac7', &['\u96e3']), ('\ufac8', &['\u9756']), ('\ufac9',
-        &['\u97db']), ('\ufaca', &['\u97ff']), ('\ufacb', &['\u980b']), ('\ufacc', &['\u983b']),
-        ('\ufacd', &['\u9b12']), ('\uface', &['\u9f9c']), ('\ufacf', &['\U0002284a']), ('\ufad0',
-        &['\U00022844']), ('\ufad1', &['\U000233d5']), ('\ufad2', &['\u3b9d']), ('\ufad3',
-        &['\u4018']), ('\ufad4', &['\u4039']), ('\ufad5', &['\U00025249']), ('\ufad6',
-        &['\U00025cd0']), ('\ufad7', &['\U00027ed3']), ('\ufad8', &['\u9f43']), ('\ufad9',
-        &['\u9f8e']), ('\ufb1d', &['\u05d9', '\u05b4']), ('\ufb1f', &['\u05f2', '\u05b7']),
-        ('\ufb2a', &['\u05e9', '\u05c1']), ('\ufb2b', &['\u05e9', '\u05c2']), ('\ufb2c', &['\ufb49',
-        '\u05c1']), ('\ufb2d', &['\ufb49', '\u05c2']), ('\ufb2e', &['\u05d0', '\u05b7']), ('\ufb2f',
-        &['\u05d0', '\u05b8']), ('\ufb30', &['\u05d0', '\u05bc']), ('\ufb31', &['\u05d1',
-        '\u05bc']), ('\ufb32', &['\u05d2', '\u05bc']), ('\ufb33', &['\u05d3', '\u05bc']), ('\ufb34',
-        &['\u05d4', '\u05bc']), ('\ufb35', &['\u05d5', '\u05bc']), ('\ufb36', &['\u05d6',
-        '\u05bc']), ('\ufb38', &['\u05d8', '\u05bc']), ('\ufb39', &['\u05d9', '\u05bc']), ('\ufb3a',
-        &['\u05da', '\u05bc']), ('\ufb3b', &['\u05db', '\u05bc']), ('\ufb3c', &['\u05dc',
-        '\u05bc']), ('\ufb3e', &['\u05de', '\u05bc']), ('\ufb40', &['\u05e0', '\u05bc']), ('\ufb41',
-        &['\u05e1', '\u05bc']), ('\ufb43', &['\u05e3', '\u05bc']), ('\ufb44', &['\u05e4',
-        '\u05bc']), ('\ufb46', &['\u05e6', '\u05bc']), ('\ufb47', &['\u05e7', '\u05bc']), ('\ufb48',
-        &['\u05e8', '\u05bc']), ('\ufb49', &['\u05e9', '\u05bc']), ('\ufb4a', &['\u05ea',
-        '\u05bc']), ('\ufb4b', &['\u05d5', '\u05b9']), ('\ufb4c', &['\u05d1', '\u05bf']), ('\ufb4d',
-        &['\u05db', '\u05bf']), ('\ufb4e', &['\u05e4', '\u05bf']), ('\U0001109a', &['\U00011099',
-        '\U000110ba']), ('\U0001109c', &['\U0001109b', '\U000110ba']), ('\U000110ab',
-        &['\U000110a5', '\U000110ba']), ('\U0001112e', &['\U00011131', '\U00011127']),
-        ('\U0001112f', &['\U00011132', '\U00011127']), ('\U0001d15e', &['\U0001d157',
-        '\U0001d165']), ('\U0001d15f', &['\U0001d158', '\U0001d165']), ('\U0001d160',
-        &['\U0001d15f', '\U0001d16e']), ('\U0001d161', &['\U0001d15f', '\U0001d16f']),
-        ('\U0001d162', &['\U0001d15f', '\U0001d170']), ('\U0001d163', &['\U0001d15f',
-        '\U0001d171']), ('\U0001d164', &['\U0001d15f', '\U0001d172']), ('\U0001d1bb',
-        &['\U0001d1b9', '\U0001d165']), ('\U0001d1bc', &['\U0001d1ba', '\U0001d165']),
-        ('\U0001d1bd', &['\U0001d1bb', '\U0001d16e']), ('\U0001d1be', &['\U0001d1bc',
-        '\U0001d16e']), ('\U0001d1bf', &['\U0001d1bb', '\U0001d16f']), ('\U0001d1c0',
-        &['\U0001d1bc', '\U0001d16f']), ('\U0002f800', &['\u4e3d']), ('\U0002f801', &['\u4e38']),
-        ('\U0002f802', &['\u4e41']), ('\U0002f803', &['\U00020122']), ('\U0002f804', &['\u4f60']),
-        ('\U0002f805', &['\u4fae']), ('\U0002f806', &['\u4fbb']), ('\U0002f807', &['\u5002']),
-        ('\U0002f808', &['\u507a']), ('\U0002f809', &['\u5099']), ('\U0002f80a', &['\u50e7']),
-        ('\U0002f80b', &['\u50cf']), ('\U0002f80c', &['\u349e']), ('\U0002f80d', &['\U0002063a']),
-        ('\U0002f80e', &['\u514d']), ('\U0002f80f', &['\u5154']), ('\U0002f810', &['\u5164']),
-        ('\U0002f811', &['\u5177']), ('\U0002f812', &['\U0002051c']), ('\U0002f813', &['\u34b9']),
-        ('\U0002f814', &['\u5167']), ('\U0002f815', &['\u518d']), ('\U0002f816', &['\U0002054b']),
-        ('\U0002f817', &['\u5197']), ('\U0002f818', &['\u51a4']), ('\U0002f819', &['\u4ecc']),
-        ('\U0002f81a', &['\u51ac']), ('\U0002f81b', &['\u51b5']), ('\U0002f81c', &['\U000291df']),
-        ('\U0002f81d', &['\u51f5']), ('\U0002f81e', &['\u5203']), ('\U0002f81f', &['\u34df']),
-        ('\U0002f820', &['\u523b']), ('\U0002f821', &['\u5246']), ('\U0002f822', &['\u5272']),
-        ('\U0002f823', &['\u5277']), ('\U0002f824', &['\u3515']), ('\U0002f825', &['\u52c7']),
-        ('\U0002f826', &['\u52c9']), ('\U0002f827', &['\u52e4']), ('\U0002f828', &['\u52fa']),
-        ('\U0002f829', &['\u5305']), ('\U0002f82a', &['\u5306']), ('\U0002f82b', &['\u5317']),
-        ('\U0002f82c', &['\u5349']), ('\U0002f82d', &['\u5351']), ('\U0002f82e', &['\u535a']),
-        ('\U0002f82f', &['\u5373']), ('\U0002f830', &['\u537d']), ('\U0002f831', &['\u537f']),
-        ('\U0002f832', &['\u537f']), ('\U0002f833', &['\u537f']), ('\U0002f834', &['\U00020a2c']),
-        ('\U0002f835', &['\u7070']), ('\U0002f836', &['\u53ca']), ('\U0002f837', &['\u53df']),
-        ('\U0002f838', &['\U00020b63']), ('\U0002f839', &['\u53eb']), ('\U0002f83a', &['\u53f1']),
-        ('\U0002f83b', &['\u5406']), ('\U0002f83c', &['\u549e']), ('\U0002f83d', &['\u5438']),
-        ('\U0002f83e', &['\u5448']), ('\U0002f83f', &['\u5468']), ('\U0002f840', &['\u54a2']),
-        ('\U0002f841', &['\u54f6']), ('\U0002f842', &['\u5510']), ('\U0002f843', &['\u5553']),
-        ('\U0002f844', &['\u5563']), ('\U0002f845', &['\u5584']), ('\U0002f846', &['\u5584']),
-        ('\U0002f847', &['\u5599']), ('\U0002f848', &['\u55ab']), ('\U0002f849', &['\u55b3']),
-        ('\U0002f84a', &['\u55c2']), ('\U0002f84b', &['\u5716']), ('\U0002f84c', &['\u5606']),
-        ('\U0002f84d', &['\u5717']), ('\U0002f84e', &['\u5651']), ('\U0002f84f', &['\u5674']),
-        ('\U0002f850', &['\u5207']), ('\U0002f851', &['\u58ee']), ('\U0002f852', &['\u57ce']),
-        ('\U0002f853', &['\u57f4']), ('\U0002f854', &['\u580d']), ('\U0002f855', &['\u578b']),
-        ('\U0002f856', &['\u5832']), ('\U0002f857', &['\u5831']), ('\U0002f858', &['\u58ac']),
-        ('\U0002f859', &['\U000214e4']), ('\U0002f85a', &['\u58f2']), ('\U0002f85b', &['\u58f7']),
-        ('\U0002f85c', &['\u5906']), ('\U0002f85d', &['\u591a']), ('\U0002f85e', &['\u5922']),
-        ('\U0002f85f', &['\u5962']), ('\U0002f860', &['\U000216a8']), ('\U0002f861',
-        &['\U000216ea']), ('\U0002f862', &['\u59ec']), ('\U0002f863', &['\u5a1b']), ('\U0002f864',
-        &['\u5a27']), ('\U0002f865', &['\u59d8']), ('\U0002f866', &['\u5a66']), ('\U0002f867',
-        &['\u36ee']), ('\U0002f868', &['\u36fc']), ('\U0002f869', &['\u5b08']), ('\U0002f86a',
-        &['\u5b3e']), ('\U0002f86b', &['\u5b3e']), ('\U0002f86c', &['\U000219c8']), ('\U0002f86d',
-        &['\u5bc3']), ('\U0002f86e', &['\u5bd8']), ('\U0002f86f', &['\u5be7']), ('\U0002f870',
-        &['\u5bf3']), ('\U0002f871', &['\U00021b18']), ('\U0002f872', &['\u5bff']), ('\U0002f873',
-        &['\u5c06']), ('\U0002f874', &['\u5f53']), ('\U0002f875', &['\u5c22']), ('\U0002f876',
-        &['\u3781']), ('\U0002f877', &['\u5c60']), ('\U0002f878', &['\u5c6e']), ('\U0002f879',
-        &['\u5cc0']), ('\U0002f87a', &['\u5c8d']), ('\U0002f87b', &['\U00021de4']), ('\U0002f87c',
-        &['\u5d43']), ('\U0002f87d', &['\U00021de6']), ('\U0002f87e', &['\u5d6e']), ('\U0002f87f',
-        &['\u5d6b']), ('\U0002f880', &['\u5d7c']), ('\U0002f881', &['\u5de1']), ('\U0002f882',
-        &['\u5de2']), ('\U0002f883', &['\u382f']), ('\U0002f884', &['\u5dfd']), ('\U0002f885',
-        &['\u5e28']), ('\U0002f886', &['\u5e3d']), ('\U0002f887', &['\u5e69']), ('\U0002f888',
-        &['\u3862']), ('\U0002f889', &['\U00022183']), ('\U0002f88a', &['\u387c']), ('\U0002f88b',
-        &['\u5eb0']), ('\U0002f88c', &['\u5eb3']), ('\U0002f88d', &['\u5eb6']), ('\U0002f88e',
-        &['\u5eca']), ('\U0002f88f', &['\U0002a392']), ('\U0002f890', &['\u5efe']), ('\U0002f891',
-        &['\U00022331']), ('\U0002f892', &['\U00022331']), ('\U0002f893', &['\u8201']),
-        ('\U0002f894', &['\u5f22']), ('\U0002f895', &['\u5f22']), ('\U0002f896', &['\u38c7']),
-        ('\U0002f897', &['\U000232b8']), ('\U0002f898', &['\U000261da']), ('\U0002f899',
-        &['\u5f62']), ('\U0002f89a', &['\u5f6b']), ('\U0002f89b', &['\u38e3']), ('\U0002f89c',
-        &['\u5f9a']), ('\U0002f89d', &['\u5fcd']), ('\U0002f89e', &['\u5fd7']), ('\U0002f89f',
-        &['\u5ff9']), ('\U0002f8a0', &['\u6081']), ('\U0002f8a1', &['\u393a']), ('\U0002f8a2',
-        &['\u391c']), ('\U0002f8a3', &['\u6094']), ('\U0002f8a4', &['\U000226d4']), ('\U0002f8a5',
-        &['\u60c7']), ('\U0002f8a6', &['\u6148']), ('\U0002f8a7', &['\u614c']), ('\U0002f8a8',
-        &['\u614e']), ('\U0002f8a9', &['\u614c']), ('\U0002f8aa', &['\u617a']), ('\U0002f8ab',
-        &['\u618e']), ('\U0002f8ac', &['\u61b2']), ('\U0002f8ad', &['\u61a4']), ('\U0002f8ae',
-        &['\u61af']), ('\U0002f8af', &['\u61de']), ('\U0002f8b0', &['\u61f2']), ('\U0002f8b1',
-        &['\u61f6']), ('\U0002f8b2', &['\u6210']), ('\U0002f8b3', &['\u621b']), ('\U0002f8b4',
-        &['\u625d']), ('\U0002f8b5', &['\u62b1']), ('\U0002f8b6', &['\u62d4']), ('\U0002f8b7',
-        &['\u6350']), ('\U0002f8b8', &['\U00022b0c']), ('\U0002f8b9', &['\u633d']), ('\U0002f8ba',
-        &['\u62fc']), ('\U0002f8bb', &['\u6368']), ('\U0002f8bc', &['\u6383']), ('\U0002f8bd',
-        &['\u63e4']), ('\U0002f8be', &['\U00022bf1']), ('\U0002f8bf', &['\u6422']), ('\U0002f8c0',
-        &['\u63c5']), ('\U0002f8c1', &['\u63a9']), ('\U0002f8c2', &['\u3a2e']), ('\U0002f8c3',
-        &['\u6469']), ('\U0002f8c4', &['\u647e']), ('\U0002f8c5', &['\u649d']), ('\U0002f8c6',
-        &['\u6477']), ('\U0002f8c7', &['\u3a6c']), ('\U0002f8c8', &['\u654f']), ('\U0002f8c9',
-        &['\u656c']), ('\U0002f8ca', &['\U0002300a']), ('\U0002f8cb', &['\u65e3']), ('\U0002f8cc',
-        &['\u66f8']), ('\U0002f8cd', &['\u6649']), ('\U0002f8ce', &['\u3b19']), ('\U0002f8cf',
-        &['\u6691']), ('\U0002f8d0', &['\u3b08']), ('\U0002f8d1', &['\u3ae4']), ('\U0002f8d2',
-        &['\u5192']), ('\U0002f8d3', &['\u5195']), ('\U0002f8d4', &['\u6700']), ('\U0002f8d5',
-        &['\u669c']), ('\U0002f8d6', &['\u80ad']), ('\U0002f8d7', &['\u43d9']), ('\U0002f8d8',
-        &['\u6717']), ('\U0002f8d9', &['\u671b']), ('\U0002f8da', &['\u6721']), ('\U0002f8db',
-        &['\u675e']), ('\U0002f8dc', &['\u6753']), ('\U0002f8dd', &['\U000233c3']), ('\U0002f8de',
-        &['\u3b49']), ('\U0002f8df', &['\u67fa']), ('\U0002f8e0', &['\u6785']), ('\U0002f8e1',
-        &['\u6852']), ('\U0002f8e2', &['\u6885']), ('\U0002f8e3', &['\U0002346d']), ('\U0002f8e4',
-        &['\u688e']), ('\U0002f8e5', &['\u681f']), ('\U0002f8e6', &['\u6914']), ('\U0002f8e7',
-        &['\u3b9d']), ('\U0002f8e8', &['\u6942']), ('\U0002f8e9', &['\u69a3']), ('\U0002f8ea',
-        &['\u69ea']), ('\U0002f8eb', &['\u6aa8']), ('\U0002f8ec', &['\U000236a3']), ('\U0002f8ed',
-        &['\u6adb']), ('\U0002f8ee', &['\u3c18']), ('\U0002f8ef', &['\u6b21']), ('\U0002f8f0',
-        &['\U000238a7']), ('\U0002f8f1', &['\u6b54']), ('\U0002f8f2', &['\u3c4e']), ('\U0002f8f3',
-        &['\u6b72']), ('\U0002f8f4', &['\u6b9f']), ('\U0002f8f5', &['\u6bba']), ('\U0002f8f6',
-        &['\u6bbb']), ('\U0002f8f7', &['\U00023a8d']), ('\U0002f8f8', &['\U00021d0b']),
-        ('\U0002f8f9', &['\U00023afa']), ('\U0002f8fa', &['\u6c4e']), ('\U0002f8fb',
-        &['\U00023cbc']), ('\U0002f8fc', &['\u6cbf']), ('\U0002f8fd', &['\u6ccd']), ('\U0002f8fe',
-        &['\u6c67']), ('\U0002f8ff', &['\u6d16']), ('\U0002f900', &['\u6d3e']), ('\U0002f901',
-        &['\u6d77']), ('\U0002f902', &['\u6d41']), ('\U0002f903', &['\u6d69']), ('\U0002f904',
-        &['\u6d78']), ('\U0002f905', &['\u6d85']), ('\U0002f906', &['\U00023d1e']), ('\U0002f907',
-        &['\u6d34']), ('\U0002f908', &['\u6e2f']), ('\U0002f909', &['\u6e6e']), ('\U0002f90a',
-        &['\u3d33']), ('\U0002f90b', &['\u6ecb']), ('\U0002f90c', &['\u6ec7']), ('\U0002f90d',
-        &['\U00023ed1']), ('\U0002f90e', &['\u6df9']), ('\U0002f90f', &['\u6f6e']), ('\U0002f910',
-        &['\U00023f5e']), ('\U0002f911', &['\U00023f8e']), ('\U0002f912', &['\u6fc6']),
-        ('\U0002f913', &['\u7039']), ('\U0002f914', &['\u701e']), ('\U0002f915', &['\u701b']),
-        ('\U0002f916', &['\u3d96']), ('\U0002f917', &['\u704a']), ('\U0002f918', &['\u707d']),
-        ('\U0002f919', &['\u7077']), ('\U0002f91a', &['\u70ad']), ('\U0002f91b', &['\U00020525']),
-        ('\U0002f91c', &['\u7145']), ('\U0002f91d', &['\U00024263']), ('\U0002f91e', &['\u719c']),
-        ('\U0002f91f', &['\U000243ab']), ('\U0002f920', &['\u7228']), ('\U0002f921', &['\u7235']),
-        ('\U0002f922', &['\u7250']), ('\U0002f923', &['\U00024608']), ('\U0002f924', &['\u7280']),
-        ('\U0002f925', &['\u7295']), ('\U0002f926', &['\U00024735']), ('\U0002f927',
-        &['\U00024814']), ('\U0002f928', &['\u737a']), ('\U0002f929', &['\u738b']), ('\U0002f92a',
-        &['\u3eac']), ('\U0002f92b', &['\u73a5']), ('\U0002f92c', &['\u3eb8']), ('\U0002f92d',
-        &['\u3eb8']), ('\U0002f92e', &['\u7447']), ('\U0002f92f', &['\u745c']), ('\U0002f930',
-        &['\u7471']), ('\U0002f931', &['\u7485']), ('\U0002f932', &['\u74ca']), ('\U0002f933',
-        &['\u3f1b']), ('\U0002f934', &['\u7524']), ('\U0002f935', &['\U00024c36']), ('\U0002f936',
-        &['\u753e']), ('\U0002f937', &['\U00024c92']), ('\U0002f938', &['\u7570']), ('\U0002f939',
-        &['\U0002219f']), ('\U0002f93a', &['\u7610']), ('\U0002f93b', &['\U00024fa1']),
-        ('\U0002f93c', &['\U00024fb8']), ('\U0002f93d', &['\U00025044']), ('\U0002f93e',
-        &['\u3ffc']), ('\U0002f93f', &['\u4008']), ('\U0002f940', &['\u76f4']), ('\U0002f941',
-        &['\U000250f3']), ('\U0002f942', &['\U000250f2']), ('\U0002f943', &['\U00025119']),
-        ('\U0002f944', &['\U00025133']), ('\U0002f945', &['\u771e']), ('\U0002f946', &['\u771f']),
-        ('\U0002f947', &['\u771f']), ('\U0002f948', &['\u774a']), ('\U0002f949', &['\u4039']),
-        ('\U0002f94a', &['\u778b']), ('\U0002f94b', &['\u4046']), ('\U0002f94c', &['\u4096']),
-        ('\U0002f94d', &['\U0002541d']), ('\U0002f94e', &['\u784e']), ('\U0002f94f', &['\u788c']),
-        ('\U0002f950', &['\u78cc']), ('\U0002f951', &['\u40e3']), ('\U0002f952', &['\U00025626']),
-        ('\U0002f953', &['\u7956']), ('\U0002f954', &['\U0002569a']), ('\U0002f955',
-        &['\U000256c5']), ('\U0002f956', &['\u798f']), ('\U0002f957', &['\u79eb']), ('\U0002f958',
-        &['\u412f']), ('\U0002f959', &['\u7a40']), ('\U0002f95a', &['\u7a4a']), ('\U0002f95b',
-        &['\u7a4f']), ('\U0002f95c', &['\U0002597c']), ('\U0002f95d', &['\U00025aa7']),
-        ('\U0002f95e', &['\U00025aa7']), ('\U0002f95f', &['\u7aee']), ('\U0002f960', &['\u4202']),
-        ('\U0002f961', &['\U00025bab']), ('\U0002f962', &['\u7bc6']), ('\U0002f963', &['\u7bc9']),
-        ('\U0002f964', &['\u4227']), ('\U0002f965', &['\U00025c80']), ('\U0002f966', &['\u7cd2']),
-        ('\U0002f967', &['\u42a0']), ('\U0002f968', &['\u7ce8']), ('\U0002f969', &['\u7ce3']),
-        ('\U0002f96a', &['\u7d00']), ('\U0002f96b', &['\U00025f86']), ('\U0002f96c', &['\u7d63']),
-        ('\U0002f96d', &['\u4301']), ('\U0002f96e', &['\u7dc7']), ('\U0002f96f', &['\u7e02']),
-        ('\U0002f970', &['\u7e45']), ('\U0002f971', &['\u4334']), ('\U0002f972', &['\U00026228']),
-        ('\U0002f973', &['\U00026247']), ('\U0002f974', &['\u4359']), ('\U0002f975',
-        &['\U000262d9']), ('\U0002f976', &['\u7f7a']), ('\U0002f977', &['\U0002633e']),
-        ('\U0002f978', &['\u7f95']), ('\U0002f979', &['\u7ffa']), ('\U0002f97a', &['\u8005']),
-        ('\U0002f97b', &['\U000264da']), ('\U0002f97c', &['\U00026523']), ('\U0002f97d',
-        &['\u8060']), ('\U0002f97e', &['\U000265a8']), ('\U0002f97f', &['\u8070']), ('\U0002f980',
-        &['\U0002335f']), ('\U0002f981', &['\u43d5']), ('\U0002f982', &['\u80b2']), ('\U0002f983',
-        &['\u8103']), ('\U0002f984', &['\u440b']), ('\U0002f985', &['\u813e']), ('\U0002f986',
-        &['\u5ab5']), ('\U0002f987', &['\U000267a7']), ('\U0002f988', &['\U000267b5']),
-        ('\U0002f989', &['\U00023393']), ('\U0002f98a', &['\U0002339c']), ('\U0002f98b',
-        &['\u8201']), ('\U0002f98c', &['\u8204']), ('\U0002f98d', &['\u8f9e']), ('\U0002f98e',
-        &['\u446b']), ('\U0002f98f', &['\u8291']), ('\U0002f990', &['\u828b']), ('\U0002f991',
-        &['\u829d']), ('\U0002f992', &['\u52b3']), ('\U0002f993', &['\u82b1']), ('\U0002f994',
-        &['\u82b3']), ('\U0002f995', &['\u82bd']), ('\U0002f996', &['\u82e6']), ('\U0002f997',
-        &['\U00026b3c']), ('\U0002f998', &['\u82e5']), ('\U0002f999', &['\u831d']), ('\U0002f99a',
-        &['\u8363']), ('\U0002f99b', &['\u83ad']), ('\U0002f99c', &['\u8323']), ('\U0002f99d',
-        &['\u83bd']), ('\U0002f99e', &['\u83e7']), ('\U0002f99f', &['\u8457']), ('\U0002f9a0',
-        &['\u8353']), ('\U0002f9a1', &['\u83ca']), ('\U0002f9a2', &['\u83cc']), ('\U0002f9a3',
-        &['\u83dc']), ('\U0002f9a4', &['\U00026c36']), ('\U0002f9a5', &['\U00026d6b']),
-        ('\U0002f9a6', &['\U00026cd5']), ('\U0002f9a7', &['\u452b']), ('\U0002f9a8', &['\u84f1']),
-        ('\U0002f9a9', &['\u84f3']), ('\U0002f9aa', &['\u8516']), ('\U0002f9ab', &['\U000273ca']),
-        ('\U0002f9ac', &['\u8564']), ('\U0002f9ad', &['\U00026f2c']), ('\U0002f9ae', &['\u455d']),
-        ('\U0002f9af', &['\u4561']), ('\U0002f9b0', &['\U00026fb1']), ('\U0002f9b1',
-        &['\U000270d2']), ('\U0002f9b2', &['\u456b']), ('\U0002f9b3', &['\u8650']), ('\U0002f9b4',
-        &['\u865c']), ('\U0002f9b5', &['\u8667']), ('\U0002f9b6', &['\u8669']), ('\U0002f9b7',
-        &['\u86a9']), ('\U0002f9b8', &['\u8688']), ('\U0002f9b9', &['\u870e']), ('\U0002f9ba',
-        &['\u86e2']), ('\U0002f9bb', &['\u8779']), ('\U0002f9bc', &['\u8728']), ('\U0002f9bd',
-        &['\u876b']), ('\U0002f9be', &['\u8786']), ('\U0002f9bf', &['\u45d7']), ('\U0002f9c0',
-        &['\u87e1']), ('\U0002f9c1', &['\u8801']), ('\U0002f9c2', &['\u45f9']), ('\U0002f9c3',
-        &['\u8860']), ('\U0002f9c4', &['\u8863']), ('\U0002f9c5', &['\U00027667']), ('\U0002f9c6',
-        &['\u88d7']), ('\U0002f9c7', &['\u88de']), ('\U0002f9c8', &['\u4635']), ('\U0002f9c9',
-        &['\u88fa']), ('\U0002f9ca', &['\u34bb']), ('\U0002f9cb', &['\U000278ae']), ('\U0002f9cc',
-        &['\U00027966']), ('\U0002f9cd', &['\u46be']), ('\U0002f9ce', &['\u46c7']), ('\U0002f9cf',
-        &['\u8aa0']), ('\U0002f9d0', &['\u8aed']), ('\U0002f9d1', &['\u8b8a']), ('\U0002f9d2',
-        &['\u8c55']), ('\U0002f9d3', &['\U00027ca8']), ('\U0002f9d4', &['\u8cab']), ('\U0002f9d5',
-        &['\u8cc1']), ('\U0002f9d6', &['\u8d1b']), ('\U0002f9d7', &['\u8d77']), ('\U0002f9d8',
-        &['\U00027f2f']), ('\U0002f9d9', &['\U00020804']), ('\U0002f9da', &['\u8dcb']),
-        ('\U0002f9db', &['\u8dbc']), ('\U0002f9dc', &['\u8df0']), ('\U0002f9dd', &['\U000208de']),
-        ('\U0002f9de', &['\u8ed4']), ('\U0002f9df', &['\u8f38']), ('\U0002f9e0', &['\U000285d2']),
-        ('\U0002f9e1', &['\U000285ed']), ('\U0002f9e2', &['\u9094']), ('\U0002f9e3', &['\u90f1']),
-        ('\U0002f9e4', &['\u9111']), ('\U0002f9e5', &['\U0002872e']), ('\U0002f9e6', &['\u911b']),
-        ('\U0002f9e7', &['\u9238']), ('\U0002f9e8', &['\u92d7']), ('\U0002f9e9', &['\u92d8']),
-        ('\U0002f9ea', &['\u927c']), ('\U0002f9eb', &['\u93f9']), ('\U0002f9ec', &['\u9415']),
-        ('\U0002f9ed', &['\U00028bfa']), ('\U0002f9ee', &['\u958b']), ('\U0002f9ef', &['\u4995']),
-        ('\U0002f9f0', &['\u95b7']), ('\U0002f9f1', &['\U00028d77']), ('\U0002f9f2', &['\u49e6']),
-        ('\U0002f9f3', &['\u96c3']), ('\U0002f9f4', &['\u5db2']), ('\U0002f9f5', &['\u9723']),
-        ('\U0002f9f6', &['\U00029145']), ('\U0002f9f7', &['\U0002921a']), ('\U0002f9f8',
-        &['\u4a6e']), ('\U0002f9f9', &['\u4a76']), ('\U0002f9fa', &['\u97e0']), ('\U0002f9fb',
-        &['\U0002940a']), ('\U0002f9fc', &['\u4ab2']), ('\U0002f9fd', &['\U00029496']),
-        ('\U0002f9fe', &['\u980b']), ('\U0002f9ff', &['\u980b']), ('\U0002fa00', &['\u9829']),
-        ('\U0002fa01', &['\U000295b6']), ('\U0002fa02', &['\u98e2']), ('\U0002fa03', &['\u4b33']),
-        ('\U0002fa04', &['\u9929']), ('\U0002fa05', &['\u99a7']), ('\U0002fa06', &['\u99c2']),
-        ('\U0002fa07', &['\u99fe']), ('\U0002fa08', &['\u4bce']), ('\U0002fa09', &['\U00029b30']),
-        ('\U0002fa0a', &['\u9b12']), ('\U0002fa0b', &['\u9c40']), ('\U0002fa0c', &['\u9cfd']),
-        ('\U0002fa0d', &['\u4cce']), ('\U0002fa0e', &['\u4ced']), ('\U0002fa0f', &['\u9d67']),
-        ('\U0002fa10', &['\U0002a0ce']), ('\U0002fa11', &['\u4cf8']), ('\U0002fa12',
-        &['\U0002a105']), ('\U0002fa13', &['\U0002a20e']), ('\U0002fa14', &['\U0002a291']),
-        ('\U0002fa15', &['\u9ebb']), ('\U0002fa16', &['\u4d56']), ('\U0002fa17', &['\u9ef9']),
-        ('\U0002fa18', &['\u9efe']), ('\U0002fa19', &['\u9f05']), ('\U0002fa1a', &['\u9f0f']),
-        ('\U0002fa1b', &['\u9f16']), ('\U0002fa1c', &['\u9f3b']), ('\U0002fa1d', &['\U0002a600'])
-    ];
-
-    // Compatibility decompositions
-    static compatibility_table : &'static [(char, &'static [char])] = &[
-        ('\xa0', &['\x20']), ('\xa8', &['\x20', '\u0308']), ('\xaa', &['\x61']), ('\xaf', &['\x20',
-        '\u0304']), ('\xb2', &['\x32']), ('\xb3', &['\x33']), ('\xb4', &['\x20', '\u0301']),
-        ('\xb5', &['\u03bc']), ('\xb8', &['\x20', '\u0327']), ('\xb9', &['\x31']), ('\xba',
-        &['\x6f']), ('\xbc', &['\x31', '\u2044', '\x34']), ('\xbd', &['\x31', '\u2044', '\x32']),
-        ('\xbe', &['\x33', '\u2044', '\x34']), ('\u0132', &['\x49', '\x4a']), ('\u0133', &['\x69',
-        '\x6a']), ('\u013f', &['\x4c', '\xb7']), ('\u0140', &['\x6c', '\xb7']), ('\u0149',
-        &['\u02bc', '\x6e']), ('\u017f', &['\x73']), ('\u01c4', &['\x44', '\u017d']), ('\u01c5',
-        &['\x44', '\u017e']), ('\u01c6', &['\x64', '\u017e']), ('\u01c7', &['\x4c', '\x4a']),
-        ('\u01c8', &['\x4c', '\x6a']), ('\u01c9', &['\x6c', '\x6a']), ('\u01ca', &['\x4e', '\x4a']),
-        ('\u01cb', &['\x4e', '\x6a']), ('\u01cc', &['\x6e', '\x6a']), ('\u01f1', &['\x44', '\x5a']),
-        ('\u01f2', &['\x44', '\x7a']), ('\u01f3', &['\x64', '\x7a']), ('\u02b0', &['\x68']),
-        ('\u02b1', &['\u0266']), ('\u02b2', &['\x6a']), ('\u02b3', &['\x72']), ('\u02b4',
-        &['\u0279']), ('\u02b5', &['\u027b']), ('\u02b6', &['\u0281']), ('\u02b7', &['\x77']),
-        ('\u02b8', &['\x79']), ('\u02d8', &['\x20', '\u0306']), ('\u02d9', &['\x20', '\u0307']),
-        ('\u02da', &['\x20', '\u030a']), ('\u02db', &['\x20', '\u0328']), ('\u02dc', &['\x20',
-        '\u0303']), ('\u02dd', &['\x20', '\u030b']), ('\u02e0', &['\u0263']), ('\u02e1', &['\x6c']),
-        ('\u02e2', &['\x73']), ('\u02e3', &['\x78']), ('\u02e4', &['\u0295']), ('\u037a', &['\x20',
-        '\u0345']), ('\u0384', &['\x20', '\u0301']), ('\u03d0', &['\u03b2']), ('\u03d1',
-        &['\u03b8']), ('\u03d2', &['\u03a5']), ('\u03d5', &['\u03c6']), ('\u03d6', &['\u03c0']),
-        ('\u03f0', &['\u03ba']), ('\u03f1', &['\u03c1']), ('\u03f2', &['\u03c2']), ('\u03f4',
-        &['\u0398']), ('\u03f5', &['\u03b5']), ('\u03f9', &['\u03a3']), ('\u0587', &['\u0565',
-        '\u0582']), ('\u0675', &['\u0627', '\u0674']), ('\u0676', &['\u0648', '\u0674']), ('\u0677',
-        &['\u06c7', '\u0674']), ('\u0678', &['\u064a', '\u0674']), ('\u0e33', &['\u0e4d',
-        '\u0e32']), ('\u0eb3', &['\u0ecd', '\u0eb2']), ('\u0edc', &['\u0eab', '\u0e99']), ('\u0edd',
-        &['\u0eab', '\u0ea1']), ('\u0f0c', &['\u0f0b']), ('\u0f77', &['\u0fb2', '\u0f81']),
-        ('\u0f79', &['\u0fb3', '\u0f81']), ('\u10fc', &['\u10dc']), ('\u1d2c', &['\x41']),
-        ('\u1d2d', &['\xc6']), ('\u1d2e', &['\x42']), ('\u1d30', &['\x44']), ('\u1d31', &['\x45']),
-        ('\u1d32', &['\u018e']), ('\u1d33', &['\x47']), ('\u1d34', &['\x48']), ('\u1d35',
-        &['\x49']), ('\u1d36', &['\x4a']), ('\u1d37', &['\x4b']), ('\u1d38', &['\x4c']), ('\u1d39',
-        &['\x4d']), ('\u1d3a', &['\x4e']), ('\u1d3c', &['\x4f']), ('\u1d3d', &['\u0222']),
-        ('\u1d3e', &['\x50']), ('\u1d3f', &['\x52']), ('\u1d40', &['\x54']), ('\u1d41', &['\x55']),
-        ('\u1d42', &['\x57']), ('\u1d43', &['\x61']), ('\u1d44', &['\u0250']), ('\u1d45',
-        &['\u0251']), ('\u1d46', &['\u1d02']), ('\u1d47', &['\x62']), ('\u1d48', &['\x64']),
-        ('\u1d49', &['\x65']), ('\u1d4a', &['\u0259']), ('\u1d4b', &['\u025b']), ('\u1d4c',
-        &['\u025c']), ('\u1d4d', &['\x67']), ('\u1d4f', &['\x6b']), ('\u1d50', &['\x6d']),
-        ('\u1d51', &['\u014b']), ('\u1d52', &['\x6f']), ('\u1d53', &['\u0254']), ('\u1d54',
-        &['\u1d16']), ('\u1d55', &['\u1d17']), ('\u1d56', &['\x70']), ('\u1d57', &['\x74']),
-        ('\u1d58', &['\x75']), ('\u1d59', &['\u1d1d']), ('\u1d5a', &['\u026f']), ('\u1d5b',
-        &['\x76']), ('\u1d5c', &['\u1d25']), ('\u1d5d', &['\u03b2']), ('\u1d5e', &['\u03b3']),
-        ('\u1d5f', &['\u03b4']), ('\u1d60', &['\u03c6']), ('\u1d61', &['\u03c7']), ('\u1d62',
-        &['\x69']), ('\u1d63', &['\x72']), ('\u1d64', &['\x75']), ('\u1d65', &['\x76']), ('\u1d66',
-        &['\u03b2']), ('\u1d67', &['\u03b3']), ('\u1d68', &['\u03c1']), ('\u1d69', &['\u03c6']),
-        ('\u1d6a', &['\u03c7']), ('\u1d78', &['\u043d']), ('\u1d9b', &['\u0252']), ('\u1d9c',
-        &['\x63']), ('\u1d9d', &['\u0255']), ('\u1d9e', &['\xf0']), ('\u1d9f', &['\u025c']),
-        ('\u1da0', &['\x66']), ('\u1da1', &['\u025f']), ('\u1da2', &['\u0261']), ('\u1da3',
-        &['\u0265']), ('\u1da4', &['\u0268']), ('\u1da5', &['\u0269']), ('\u1da6', &['\u026a']),
-        ('\u1da7', &['\u1d7b']), ('\u1da8', &['\u029d']), ('\u1da9', &['\u026d']), ('\u1daa',
-        &['\u1d85']), ('\u1dab', &['\u029f']), ('\u1dac', &['\u0271']), ('\u1dad', &['\u0270']),
-        ('\u1dae', &['\u0272']), ('\u1daf', &['\u0273']), ('\u1db0', &['\u0274']), ('\u1db1',
-        &['\u0275']), ('\u1db2', &['\u0278']), ('\u1db3', &['\u0282']), ('\u1db4', &['\u0283']),
-        ('\u1db5', &['\u01ab']), ('\u1db6', &['\u0289']), ('\u1db7', &['\u028a']), ('\u1db8',
-        &['\u1d1c']), ('\u1db9', &['\u028b']), ('\u1dba', &['\u028c']), ('\u1dbb', &['\x7a']),
-        ('\u1dbc', &['\u0290']), ('\u1dbd', &['\u0291']), ('\u1dbe', &['\u0292']), ('\u1dbf',
-        &['\u03b8']), ('\u1e9a', &['\x61', '\u02be']), ('\u1fbd', &['\x20', '\u0313']), ('\u1fbf',
-        &['\x20', '\u0313']), ('\u1fc0', &['\x20', '\u0342']), ('\u1ffe', &['\x20', '\u0314']),
-        ('\u2002', &['\x20']), ('\u2003', &['\x20']), ('\u2004', &['\x20']), ('\u2005', &['\x20']),
-        ('\u2006', &['\x20']), ('\u2007', &['\x20']), ('\u2008', &['\x20']), ('\u2009', &['\x20']),
-        ('\u200a', &['\x20']), ('\u2011', &['\u2010']), ('\u2017', &['\x20', '\u0333']), ('\u2024',
-        &['\x2e']), ('\u2025', &['\x2e', '\x2e']), ('\u2026', &['\x2e', '\x2e', '\x2e']), ('\u202f',
-        &['\x20']), ('\u2033', &['\u2032', '\u2032']), ('\u2034', &['\u2032', '\u2032', '\u2032']),
-        ('\u2036', &['\u2035', '\u2035']), ('\u2037', &['\u2035', '\u2035', '\u2035']), ('\u203c',
-        &['\x21', '\x21']), ('\u203e', &['\x20', '\u0305']), ('\u2047', &['\x3f', '\x3f']),
-        ('\u2048', &['\x3f', '\x21']), ('\u2049', &['\x21', '\x3f']), ('\u2057', &['\u2032',
-        '\u2032', '\u2032', '\u2032']), ('\u205f', &['\x20']), ('\u2070', &['\x30']), ('\u2071',
-        &['\x69']), ('\u2074', &['\x34']), ('\u2075', &['\x35']), ('\u2076', &['\x36']), ('\u2077',
-        &['\x37']), ('\u2078', &['\x38']), ('\u2079', &['\x39']), ('\u207a', &['\x2b']), ('\u207b',
-        &['\u2212']), ('\u207c', &['\x3d']), ('\u207d', &['\x28']), ('\u207e', &['\x29']),
-        ('\u207f', &['\x6e']), ('\u2080', &['\x30']), ('\u2081', &['\x31']), ('\u2082', &['\x32']),
-        ('\u2083', &['\x33']), ('\u2084', &['\x34']), ('\u2085', &['\x35']), ('\u2086', &['\x36']),
-        ('\u2087', &['\x37']), ('\u2088', &['\x38']), ('\u2089', &['\x39']), ('\u208a', &['\x2b']),
-        ('\u208b', &['\u2212']), ('\u208c', &['\x3d']), ('\u208d', &['\x28']), ('\u208e',
-        &['\x29']), ('\u2090', &['\x61']), ('\u2091', &['\x65']), ('\u2092', &['\x6f']), ('\u2093',
-        &['\x78']), ('\u2094', &['\u0259']), ('\u2095', &['\x68']), ('\u2096', &['\x6b']),
-        ('\u2097', &['\x6c']), ('\u2098', &['\x6d']), ('\u2099', &['\x6e']), ('\u209a', &['\x70']),
-        ('\u209b', &['\x73']), ('\u209c', &['\x74']), ('\u20a8', &['\x52', '\x73']), ('\u2100',
-        &['\x61', '\x2f', '\x63']), ('\u2101', &['\x61', '\x2f', '\x73']), ('\u2102', &['\x43']),
-        ('\u2103', &['\xb0', '\x43']), ('\u2105', &['\x63', '\x2f', '\x6f']), ('\u2106', &['\x63',
-        '\x2f', '\x75']), ('\u2107', &['\u0190']), ('\u2109', &['\xb0', '\x46']), ('\u210a',
-        &['\x67']), ('\u210b', &['\x48']), ('\u210c', &['\x48']), ('\u210d', &['\x48']), ('\u210e',
-        &['\x68']), ('\u210f', &['\u0127']), ('\u2110', &['\x49']), ('\u2111', &['\x49']),
-        ('\u2112', &['\x4c']), ('\u2113', &['\x6c']), ('\u2115', &['\x4e']), ('\u2116', &['\x4e',
-        '\x6f']), ('\u2119', &['\x50']), ('\u211a', &['\x51']), ('\u211b', &['\x52']), ('\u211c',
-        &['\x52']), ('\u211d', &['\x52']), ('\u2120', &['\x53', '\x4d']), ('\u2121', &['\x54',
-        '\x45', '\x4c']), ('\u2122', &['\x54', '\x4d']), ('\u2124', &['\x5a']), ('\u2128',
-        &['\x5a']), ('\u212c', &['\x42']), ('\u212d', &['\x43']), ('\u212f', &['\x65']), ('\u2130',
-        &['\x45']), ('\u2131', &['\x46']), ('\u2133', &['\x4d']), ('\u2134', &['\x6f']), ('\u2135',
-        &['\u05d0']), ('\u2136', &['\u05d1']), ('\u2137', &['\u05d2']), ('\u2138', &['\u05d3']),
-        ('\u2139', &['\x69']), ('\u213b', &['\x46', '\x41', '\x58']), ('\u213c', &['\u03c0']),
-        ('\u213d', &['\u03b3']), ('\u213e', &['\u0393']), ('\u213f', &['\u03a0']), ('\u2140',
-        &['\u2211']), ('\u2145', &['\x44']), ('\u2146', &['\x64']), ('\u2147', &['\x65']),
-        ('\u2148', &['\x69']), ('\u2149', &['\x6a']), ('\u2150', &['\x31', '\u2044', '\x37']),
-        ('\u2151', &['\x31', '\u2044', '\x39']), ('\u2152', &['\x31', '\u2044', '\x31', '\x30']),
-        ('\u2153', &['\x31', '\u2044', '\x33']), ('\u2154', &['\x32', '\u2044', '\x33']), ('\u2155',
-        &['\x31', '\u2044', '\x35']), ('\u2156', &['\x32', '\u2044', '\x35']), ('\u2157', &['\x33',
-        '\u2044', '\x35']), ('\u2158', &['\x34', '\u2044', '\x35']), ('\u2159', &['\x31', '\u2044',
-        '\x36']), ('\u215a', &['\x35', '\u2044', '\x36']), ('\u215b', &['\x31', '\u2044', '\x38']),
-        ('\u215c', &['\x33', '\u2044', '\x38']), ('\u215d', &['\x35', '\u2044', '\x38']), ('\u215e',
-        &['\x37', '\u2044', '\x38']), ('\u215f', &['\x31', '\u2044']), ('\u2160', &['\x49']),
-        ('\u2161', &['\x49', '\x49']), ('\u2162', &['\x49', '\x49', '\x49']), ('\u2163', &['\x49',
-        '\x56']), ('\u2164', &['\x56']), ('\u2165', &['\x56', '\x49']), ('\u2166', &['\x56', '\x49',
-        '\x49']), ('\u2167', &['\x56', '\x49', '\x49', '\x49']), ('\u2168', &['\x49', '\x58']),
-        ('\u2169', &['\x58']), ('\u216a', &['\x58', '\x49']), ('\u216b', &['\x58', '\x49', '\x49']),
-        ('\u216c', &['\x4c']), ('\u216d', &['\x43']), ('\u216e', &['\x44']), ('\u216f', &['\x4d']),
-        ('\u2170', &['\x69']), ('\u2171', &['\x69', '\x69']), ('\u2172', &['\x69', '\x69', '\x69']),
-        ('\u2173', &['\x69', '\x76']), ('\u2174', &['\x76']), ('\u2175', &['\x76', '\x69']),
-        ('\u2176', &['\x76', '\x69', '\x69']), ('\u2177', &['\x76', '\x69', '\x69', '\x69']),
-        ('\u2178', &['\x69', '\x78']), ('\u2179', &['\x78']), ('\u217a', &['\x78', '\x69']),
-        ('\u217b', &['\x78', '\x69', '\x69']), ('\u217c', &['\x6c']), ('\u217d', &['\x63']),
-        ('\u217e', &['\x64']), ('\u217f', &['\x6d']), ('\u2189', &['\x30', '\u2044', '\x33']),
-        ('\u222c', &['\u222b', '\u222b']), ('\u222d', &['\u222b', '\u222b', '\u222b']), ('\u222f',
-        &['\u222e', '\u222e']), ('\u2230', &['\u222e', '\u222e', '\u222e']), ('\u2460', &['\x31']),
-        ('\u2461', &['\x32']), ('\u2462', &['\x33']), ('\u2463', &['\x34']), ('\u2464', &['\x35']),
-        ('\u2465', &['\x36']), ('\u2466', &['\x37']), ('\u2467', &['\x38']), ('\u2468', &['\x39']),
-        ('\u2469', &['\x31', '\x30']), ('\u246a', &['\x31', '\x31']), ('\u246b', &['\x31', '\x32']),
-        ('\u246c', &['\x31', '\x33']), ('\u246d', &['\x31', '\x34']), ('\u246e', &['\x31', '\x35']),
-        ('\u246f', &['\x31', '\x36']), ('\u2470', &['\x31', '\x37']), ('\u2471', &['\x31', '\x38']),
-        ('\u2472', &['\x31', '\x39']), ('\u2473', &['\x32', '\x30']), ('\u2474', &['\x28', '\x31',
-        '\x29']), ('\u2475', &['\x28', '\x32', '\x29']), ('\u2476', &['\x28', '\x33', '\x29']),
-        ('\u2477', &['\x28', '\x34', '\x29']), ('\u2478', &['\x28', '\x35', '\x29']), ('\u2479',
-        &['\x28', '\x36', '\x29']), ('\u247a', &['\x28', '\x37', '\x29']), ('\u247b', &['\x28',
-        '\x38', '\x29']), ('\u247c', &['\x28', '\x39', '\x29']), ('\u247d', &['\x28', '\x31',
-        '\x30', '\x29']), ('\u247e', &['\x28', '\x31', '\x31', '\x29']), ('\u247f', &['\x28',
-        '\x31', '\x32', '\x29']), ('\u2480', &['\x28', '\x31', '\x33', '\x29']), ('\u2481',
-        &['\x28', '\x31', '\x34', '\x29']), ('\u2482', &['\x28', '\x31', '\x35', '\x29']),
-        ('\u2483', &['\x28', '\x31', '\x36', '\x29']), ('\u2484', &['\x28', '\x31', '\x37',
-        '\x29']), ('\u2485', &['\x28', '\x31', '\x38', '\x29']), ('\u2486', &['\x28', '\x31',
-        '\x39', '\x29']), ('\u2487', &['\x28', '\x32', '\x30', '\x29']), ('\u2488', &['\x31',
-        '\x2e']), ('\u2489', &['\x32', '\x2e']), ('\u248a', &['\x33', '\x2e']), ('\u248b', &['\x34',
-        '\x2e']), ('\u248c', &['\x35', '\x2e']), ('\u248d', &['\x36', '\x2e']), ('\u248e', &['\x37',
-        '\x2e']), ('\u248f', &['\x38', '\x2e']), ('\u2490', &['\x39', '\x2e']), ('\u2491', &['\x31',
-        '\x30', '\x2e']), ('\u2492', &['\x31', '\x31', '\x2e']), ('\u2493', &['\x31', '\x32',
-        '\x2e']), ('\u2494', &['\x31', '\x33', '\x2e']), ('\u2495', &['\x31', '\x34', '\x2e']),
-        ('\u2496', &['\x31', '\x35', '\x2e']), ('\u2497', &['\x31', '\x36', '\x2e']), ('\u2498',
-        &['\x31', '\x37', '\x2e']), ('\u2499', &['\x31', '\x38', '\x2e']), ('\u249a', &['\x31',
-        '\x39', '\x2e']), ('\u249b', &['\x32', '\x30', '\x2e']), ('\u249c', &['\x28', '\x61',
-        '\x29']), ('\u249d', &['\x28', '\x62', '\x29']), ('\u249e', &['\x28', '\x63', '\x29']),
-        ('\u249f', &['\x28', '\x64', '\x29']), ('\u24a0', &['\x28', '\x65', '\x29']), ('\u24a1',
-        &['\x28', '\x66', '\x29']), ('\u24a2', &['\x28', '\x67', '\x29']), ('\u24a3', &['\x28',
-        '\x68', '\x29']), ('\u24a4', &['\x28', '\x69', '\x29']), ('\u24a5', &['\x28', '\x6a',
-        '\x29']), ('\u24a6', &['\x28', '\x6b', '\x29']), ('\u24a7', &['\x28', '\x6c', '\x29']),
-        ('\u24a8', &['\x28', '\x6d', '\x29']), ('\u24a9', &['\x28', '\x6e', '\x29']), ('\u24aa',
-        &['\x28', '\x6f', '\x29']), ('\u24ab', &['\x28', '\x70', '\x29']), ('\u24ac', &['\x28',
-        '\x71', '\x29']), ('\u24ad', &['\x28', '\x72', '\x29']), ('\u24ae', &['\x28', '\x73',
-        '\x29']), ('\u24af', &['\x28', '\x74', '\x29']), ('\u24b0', &['\x28', '\x75', '\x29']),
-        ('\u24b1', &['\x28', '\x76', '\x29']), ('\u24b2', &['\x28', '\x77', '\x29']), ('\u24b3',
-        &['\x28', '\x78', '\x29']), ('\u24b4', &['\x28', '\x79', '\x29']), ('\u24b5', &['\x28',
-        '\x7a', '\x29']), ('\u24b6', &['\x41']), ('\u24b7', &['\x42']), ('\u24b8', &['\x43']),
-        ('\u24b9', &['\x44']), ('\u24ba', &['\x45']), ('\u24bb', &['\x46']), ('\u24bc', &['\x47']),
-        ('\u24bd', &['\x48']), ('\u24be', &['\x49']), ('\u24bf', &['\x4a']), ('\u24c0', &['\x4b']),
-        ('\u24c1', &['\x4c']), ('\u24c2', &['\x4d']), ('\u24c3', &['\x4e']), ('\u24c4', &['\x4f']),
-        ('\u24c5', &['\x50']), ('\u24c6', &['\x51']), ('\u24c7', &['\x52']), ('\u24c8', &['\x53']),
-        ('\u24c9', &['\x54']), ('\u24ca', &['\x55']), ('\u24cb', &['\x56']), ('\u24cc', &['\x57']),
-        ('\u24cd', &['\x58']), ('\u24ce', &['\x59']), ('\u24cf', &['\x5a']), ('\u24d0', &['\x61']),
-        ('\u24d1', &['\x62']), ('\u24d2', &['\x63']), ('\u24d3', &['\x64']), ('\u24d4', &['\x65']),
-        ('\u24d5', &['\x66']), ('\u24d6', &['\x67']), ('\u24d7', &['\x68']), ('\u24d8', &['\x69']),
-        ('\u24d9', &['\x6a']), ('\u24da', &['\x6b']), ('\u24db', &['\x6c']), ('\u24dc', &['\x6d']),
-        ('\u24dd', &['\x6e']), ('\u24de', &['\x6f']), ('\u24df', &['\x70']), ('\u24e0', &['\x71']),
-        ('\u24e1', &['\x72']), ('\u24e2', &['\x73']), ('\u24e3', &['\x74']), ('\u24e4', &['\x75']),
-        ('\u24e5', &['\x76']), ('\u24e6', &['\x77']), ('\u24e7', &['\x78']), ('\u24e8', &['\x79']),
-        ('\u24e9', &['\x7a']), ('\u24ea', &['\x30']), ('\u2a0c', &['\u222b', '\u222b', '\u222b',
-        '\u222b']), ('\u2a74', &['\x3a', '\x3a', '\x3d']), ('\u2a75', &['\x3d', '\x3d']), ('\u2a76',
-        &['\x3d', '\x3d', '\x3d']), ('\u2c7c', &['\x6a']), ('\u2c7d', &['\x56']), ('\u2d6f',
-        &['\u2d61']), ('\u2e9f', &['\u6bcd']), ('\u2ef3', &['\u9f9f']), ('\u2f00', &['\u4e00']),
-        ('\u2f01', &['\u4e28']), ('\u2f02', &['\u4e36']), ('\u2f03', &['\u4e3f']), ('\u2f04',
-        &['\u4e59']), ('\u2f05', &['\u4e85']), ('\u2f06', &['\u4e8c']), ('\u2f07', &['\u4ea0']),
-        ('\u2f08', &['\u4eba']), ('\u2f09', &['\u513f']), ('\u2f0a', &['\u5165']), ('\u2f0b',
-        &['\u516b']), ('\u2f0c', &['\u5182']), ('\u2f0d', &['\u5196']), ('\u2f0e', &['\u51ab']),
-        ('\u2f0f', &['\u51e0']), ('\u2f10', &['\u51f5']), ('\u2f11', &['\u5200']), ('\u2f12',
-        &['\u529b']), ('\u2f13', &['\u52f9']), ('\u2f14', &['\u5315']), ('\u2f15', &['\u531a']),
-        ('\u2f16', &['\u5338']), ('\u2f17', &['\u5341']), ('\u2f18', &['\u535c']), ('\u2f19',
-        &['\u5369']), ('\u2f1a', &['\u5382']), ('\u2f1b', &['\u53b6']), ('\u2f1c', &['\u53c8']),
-        ('\u2f1d', &['\u53e3']), ('\u2f1e', &['\u56d7']), ('\u2f1f', &['\u571f']), ('\u2f20',
-        &['\u58eb']), ('\u2f21', &['\u5902']), ('\u2f22', &['\u590a']), ('\u2f23', &['\u5915']),
-        ('\u2f24', &['\u5927']), ('\u2f25', &['\u5973']), ('\u2f26', &['\u5b50']), ('\u2f27',
-        &['\u5b80']), ('\u2f28', &['\u5bf8']), ('\u2f29', &['\u5c0f']), ('\u2f2a', &['\u5c22']),
-        ('\u2f2b', &['\u5c38']), ('\u2f2c', &['\u5c6e']), ('\u2f2d', &['\u5c71']), ('\u2f2e',
-        &['\u5ddb']), ('\u2f2f', &['\u5de5']), ('\u2f30', &['\u5df1']), ('\u2f31', &['\u5dfe']),
-        ('\u2f32', &['\u5e72']), ('\u2f33', &['\u5e7a']), ('\u2f34', &['\u5e7f']), ('\u2f35',
-        &['\u5ef4']), ('\u2f36', &['\u5efe']), ('\u2f37', &['\u5f0b']), ('\u2f38', &['\u5f13']),
-        ('\u2f39', &['\u5f50']), ('\u2f3a', &['\u5f61']), ('\u2f3b', &['\u5f73']), ('\u2f3c',
-        &['\u5fc3']), ('\u2f3d', &['\u6208']), ('\u2f3e', &['\u6236']), ('\u2f3f', &['\u624b']),
-        ('\u2f40', &['\u652f']), ('\u2f41', &['\u6534']), ('\u2f42', &['\u6587']), ('\u2f43',
-        &['\u6597']), ('\u2f44', &['\u65a4']), ('\u2f45', &['\u65b9']), ('\u2f46', &['\u65e0']),
-        ('\u2f47', &['\u65e5']), ('\u2f48', &['\u66f0']), ('\u2f49', &['\u6708']), ('\u2f4a',
-        &['\u6728']), ('\u2f4b', &['\u6b20']), ('\u2f4c', &['\u6b62']), ('\u2f4d', &['\u6b79']),
-        ('\u2f4e', &['\u6bb3']), ('\u2f4f', &['\u6bcb']), ('\u2f50', &['\u6bd4']), ('\u2f51',
-        &['\u6bdb']), ('\u2f52', &['\u6c0f']), ('\u2f53', &['\u6c14']), ('\u2f54', &['\u6c34']),
-        ('\u2f55', &['\u706b']), ('\u2f56', &['\u722a']), ('\u2f57', &['\u7236']), ('\u2f58',
-        &['\u723b']), ('\u2f59', &['\u723f']), ('\u2f5a', &['\u7247']), ('\u2f5b', &['\u7259']),
-        ('\u2f5c', &['\u725b']), ('\u2f5d', &['\u72ac']), ('\u2f5e', &['\u7384']), ('\u2f5f',
-        &['\u7389']), ('\u2f60', &['\u74dc']), ('\u2f61', &['\u74e6']), ('\u2f62', &['\u7518']),
-        ('\u2f63', &['\u751f']), ('\u2f64', &['\u7528']), ('\u2f65', &['\u7530']), ('\u2f66',
-        &['\u758b']), ('\u2f67', &['\u7592']), ('\u2f68', &['\u7676']), ('\u2f69', &['\u767d']),
-        ('\u2f6a', &['\u76ae']), ('\u2f6b', &['\u76bf']), ('\u2f6c', &['\u76ee']), ('\u2f6d',
-        &['\u77db']), ('\u2f6e', &['\u77e2']), ('\u2f6f', &['\u77f3']), ('\u2f70', &['\u793a']),
-        ('\u2f71', &['\u79b8']), ('\u2f72', &['\u79be']), ('\u2f73', &['\u7a74']), ('\u2f74',
-        &['\u7acb']), ('\u2f75', &['\u7af9']), ('\u2f76', &['\u7c73']), ('\u2f77', &['\u7cf8']),
-        ('\u2f78', &['\u7f36']), ('\u2f79', &['\u7f51']), ('\u2f7a', &['\u7f8a']), ('\u2f7b',
-        &['\u7fbd']), ('\u2f7c', &['\u8001']), ('\u2f7d', &['\u800c']), ('\u2f7e', &['\u8012']),
-        ('\u2f7f', &['\u8033']), ('\u2f80', &['\u807f']), ('\u2f81', &['\u8089']), ('\u2f82',
-        &['\u81e3']), ('\u2f83', &['\u81ea']), ('\u2f84', &['\u81f3']), ('\u2f85', &['\u81fc']),
-        ('\u2f86', &['\u820c']), ('\u2f87', &['\u821b']), ('\u2f88', &['\u821f']), ('\u2f89',
-        &['\u826e']), ('\u2f8a', &['\u8272']), ('\u2f8b', &['\u8278']), ('\u2f8c', &['\u864d']),
-        ('\u2f8d', &['\u866b']), ('\u2f8e', &['\u8840']), ('\u2f8f', &['\u884c']), ('\u2f90',
-        &['\u8863']), ('\u2f91', &['\u897e']), ('\u2f92', &['\u898b']), ('\u2f93', &['\u89d2']),
-        ('\u2f94', &['\u8a00']), ('\u2f95', &['\u8c37']), ('\u2f96', &['\u8c46']), ('\u2f97',
-        &['\u8c55']), ('\u2f98', &['\u8c78']), ('\u2f99', &['\u8c9d']), ('\u2f9a', &['\u8d64']),
-        ('\u2f9b', &['\u8d70']), ('\u2f9c', &['\u8db3']), ('\u2f9d', &['\u8eab']), ('\u2f9e',
-        &['\u8eca']), ('\u2f9f', &['\u8f9b']), ('\u2fa0', &['\u8fb0']), ('\u2fa1', &['\u8fb5']),
-        ('\u2fa2', &['\u9091']), ('\u2fa3', &['\u9149']), ('\u2fa4', &['\u91c6']), ('\u2fa5',
-        &['\u91cc']), ('\u2fa6', &['\u91d1']), ('\u2fa7', &['\u9577']), ('\u2fa8', &['\u9580']),
-        ('\u2fa9', &['\u961c']), ('\u2faa', &['\u96b6']), ('\u2fab', &['\u96b9']), ('\u2fac',
-        &['\u96e8']), ('\u2fad', &['\u9751']), ('\u2fae', &['\u975e']), ('\u2faf', &['\u9762']),
-        ('\u2fb0', &['\u9769']), ('\u2fb1', &['\u97cb']), ('\u2fb2', &['\u97ed']), ('\u2fb3',
-        &['\u97f3']), ('\u2fb4', &['\u9801']), ('\u2fb5', &['\u98a8']), ('\u2fb6', &['\u98db']),
-        ('\u2fb7', &['\u98df']), ('\u2fb8', &['\u9996']), ('\u2fb9', &['\u9999']), ('\u2fba',
-        &['\u99ac']), ('\u2fbb', &['\u9aa8']), ('\u2fbc', &['\u9ad8']), ('\u2fbd', &['\u9adf']),
-        ('\u2fbe', &['\u9b25']), ('\u2fbf', &['\u9b2f']), ('\u2fc0', &['\u9b32']), ('\u2fc1',
-        &['\u9b3c']), ('\u2fc2', &['\u9b5a']), ('\u2fc3', &['\u9ce5']), ('\u2fc4', &['\u9e75']),
-        ('\u2fc5', &['\u9e7f']), ('\u2fc6', &['\u9ea5']), ('\u2fc7', &['\u9ebb']), ('\u2fc8',
-        &['\u9ec3']), ('\u2fc9', &['\u9ecd']), ('\u2fca', &['\u9ed1']), ('\u2fcb', &['\u9ef9']),
-        ('\u2fcc', &['\u9efd']), ('\u2fcd', &['\u9f0e']), ('\u2fce', &['\u9f13']), ('\u2fcf',
-        &['\u9f20']), ('\u2fd0', &['\u9f3b']), ('\u2fd1', &['\u9f4a']), ('\u2fd2', &['\u9f52']),
-        ('\u2fd3', &['\u9f8d']), ('\u2fd4', &['\u9f9c']), ('\u2fd5', &['\u9fa0']), ('\u3000',
-        &['\x20']), ('\u3036', &['\u3012']), ('\u3038', &['\u5341']), ('\u3039', &['\u5344']),
-        ('\u303a', &['\u5345']), ('\u309b', &['\x20', '\u3099']), ('\u309c', &['\x20', '\u309a']),
-        ('\u309f', &['\u3088', '\u308a']), ('\u30ff', &['\u30b3', '\u30c8']), ('\u3131',
-        &['\u1100']), ('\u3132', &['\u1101']), ('\u3133', &['\u11aa']), ('\u3134', &['\u1102']),
-        ('\u3135', &['\u11ac']), ('\u3136', &['\u11ad']), ('\u3137', &['\u1103']), ('\u3138',
-        &['\u1104']), ('\u3139', &['\u1105']), ('\u313a', &['\u11b0']), ('\u313b', &['\u11b1']),
-        ('\u313c', &['\u11b2']), ('\u313d', &['\u11b3']), ('\u313e', &['\u11b4']), ('\u313f',
-        &['\u11b5']), ('\u3140', &['\u111a']), ('\u3141', &['\u1106']), ('\u3142', &['\u1107']),
-        ('\u3143', &['\u1108']), ('\u3144', &['\u1121']), ('\u3145', &['\u1109']), ('\u3146',
-        &['\u110a']), ('\u3147', &['\u110b']), ('\u3148', &['\u110c']), ('\u3149', &['\u110d']),
-        ('\u314a', &['\u110e']), ('\u314b', &['\u110f']), ('\u314c', &['\u1110']), ('\u314d',
-        &['\u1111']), ('\u314e', &['\u1112']), ('\u314f', &['\u1161']), ('\u3150', &['\u1162']),
-        ('\u3151', &['\u1163']), ('\u3152', &['\u1164']), ('\u3153', &['\u1165']), ('\u3154',
-        &['\u1166']), ('\u3155', &['\u1167']), ('\u3156', &['\u1168']), ('\u3157', &['\u1169']),
-        ('\u3158', &['\u116a']), ('\u3159', &['\u116b']), ('\u315a', &['\u116c']), ('\u315b',
-        &['\u116d']), ('\u315c', &['\u116e']), ('\u315d', &['\u116f']), ('\u315e', &['\u1170']),
-        ('\u315f', &['\u1171']), ('\u3160', &['\u1172']), ('\u3161', &['\u1173']), ('\u3162',
-        &['\u1174']), ('\u3163', &['\u1175']), ('\u3164', &['\u1160']), ('\u3165', &['\u1114']),
-        ('\u3166', &['\u1115']), ('\u3167', &['\u11c7']), ('\u3168', &['\u11c8']), ('\u3169',
-        &['\u11cc']), ('\u316a', &['\u11ce']), ('\u316b', &['\u11d3']), ('\u316c', &['\u11d7']),
-        ('\u316d', &['\u11d9']), ('\u316e', &['\u111c']), ('\u316f', &['\u11dd']), ('\u3170',
-        &['\u11df']), ('\u3171', &['\u111d']), ('\u3172', &['\u111e']), ('\u3173', &['\u1120']),
-        ('\u3174', &['\u1122']), ('\u3175', &['\u1123']), ('\u3176', &['\u1127']), ('\u3177',
-        &['\u1129']), ('\u3178', &['\u112b']), ('\u3179', &['\u112c']), ('\u317a', &['\u112d']),
-        ('\u317b', &['\u112e']), ('\u317c', &['\u112f']), ('\u317d', &['\u1132']), ('\u317e',
-        &['\u1136']), ('\u317f', &['\u1140']), ('\u3180', &['\u1147']), ('\u3181', &['\u114c']),
-        ('\u3182', &['\u11f1']), ('\u3183', &['\u11f2']), ('\u3184', &['\u1157']), ('\u3185',
-        &['\u1158']), ('\u3186', &['\u1159']), ('\u3187', &['\u1184']), ('\u3188', &['\u1185']),
-        ('\u3189', &['\u1188']), ('\u318a', &['\u1191']), ('\u318b', &['\u1192']), ('\u318c',
-        &['\u1194']), ('\u318d', &['\u119e']), ('\u318e', &['\u11a1']), ('\u3192', &['\u4e00']),
-        ('\u3193', &['\u4e8c']), ('\u3194', &['\u4e09']), ('\u3195', &['\u56db']), ('\u3196',
-        &['\u4e0a']), ('\u3197', &['\u4e2d']), ('\u3198', &['\u4e0b']), ('\u3199', &['\u7532']),
-        ('\u319a', &['\u4e59']), ('\u319b', &['\u4e19']), ('\u319c', &['\u4e01']), ('\u319d',
-        &['\u5929']), ('\u319e', &['\u5730']), ('\u319f', &['\u4eba']), ('\u3200', &['\x28',
-        '\u1100', '\x29']), ('\u3201', &['\x28', '\u1102', '\x29']), ('\u3202', &['\x28', '\u1103',
-        '\x29']), ('\u3203', &['\x28', '\u1105', '\x29']), ('\u3204', &['\x28', '\u1106', '\x29']),
-        ('\u3205', &['\x28', '\u1107', '\x29']), ('\u3206', &['\x28', '\u1109', '\x29']), ('\u3207',
-        &['\x28', '\u110b', '\x29']), ('\u3208', &['\x28', '\u110c', '\x29']), ('\u3209', &['\x28',
-        '\u110e', '\x29']), ('\u320a', &['\x28', '\u110f', '\x29']), ('\u320b', &['\x28', '\u1110',
-        '\x29']), ('\u320c', &['\x28', '\u1111', '\x29']), ('\u320d', &['\x28', '\u1112', '\x29']),
-        ('\u320e', &['\x28', '\u1100', '\u1161', '\x29']), ('\u320f', &['\x28', '\u1102', '\u1161',
-        '\x29']), ('\u3210', &['\x28', '\u1103', '\u1161', '\x29']), ('\u3211', &['\x28', '\u1105',
-        '\u1161', '\x29']), ('\u3212', &['\x28', '\u1106', '\u1161', '\x29']), ('\u3213', &['\x28',
-        '\u1107', '\u1161', '\x29']), ('\u3214', &['\x28', '\u1109', '\u1161', '\x29']), ('\u3215',
-        &['\x28', '\u110b', '\u1161', '\x29']), ('\u3216', &['\x28', '\u110c', '\u1161', '\x29']),
-        ('\u3217', &['\x28', '\u110e', '\u1161', '\x29']), ('\u3218', &['\x28', '\u110f', '\u1161',
-        '\x29']), ('\u3219', &['\x28', '\u1110', '\u1161', '\x29']), ('\u321a', &['\x28', '\u1111',
-        '\u1161', '\x29']), ('\u321b', &['\x28', '\u1112', '\u1161', '\x29']), ('\u321c', &['\x28',
-        '\u110c', '\u116e', '\x29']), ('\u321d', &['\x28', '\u110b', '\u1169', '\u110c', '\u1165',
-        '\u11ab', '\x29']), ('\u321e', &['\x28', '\u110b', '\u1169', '\u1112', '\u116e', '\x29']),
-        ('\u3220', &['\x28', '\u4e00', '\x29']), ('\u3221', &['\x28', '\u4e8c', '\x29']), ('\u3222',
-        &['\x28', '\u4e09', '\x29']), ('\u3223', &['\x28', '\u56db', '\x29']), ('\u3224', &['\x28',
-        '\u4e94', '\x29']), ('\u3225', &['\x28', '\u516d', '\x29']), ('\u3226', &['\x28', '\u4e03',
-        '\x29']), ('\u3227', &['\x28', '\u516b', '\x29']), ('\u3228', &['\x28', '\u4e5d', '\x29']),
-        ('\u3229', &['\x28', '\u5341', '\x29']), ('\u322a', &['\x28', '\u6708', '\x29']), ('\u322b',
-        &['\x28', '\u706b', '\x29']), ('\u322c', &['\x28', '\u6c34', '\x29']), ('\u322d', &['\x28',
-        '\u6728', '\x29']), ('\u322e', &['\x28', '\u91d1', '\x29']), ('\u322f', &['\x28', '\u571f',
-        '\x29']), ('\u3230', &['\x28', '\u65e5', '\x29']), ('\u3231', &['\x28', '\u682a', '\x29']),
-        ('\u3232', &['\x28', '\u6709', '\x29']), ('\u3233', &['\x28', '\u793e', '\x29']), ('\u3234',
-        &['\x28', '\u540d', '\x29']), ('\u3235', &['\x28', '\u7279', '\x29']), ('\u3236', &['\x28',
-        '\u8ca1', '\x29']), ('\u3237', &['\x28', '\u795d', '\x29']), ('\u3238', &['\x28', '\u52b4',
-        '\x29']), ('\u3239', &['\x28', '\u4ee3', '\x29']), ('\u323a', &['\x28', '\u547c', '\x29']),
-        ('\u323b', &['\x28', '\u5b66', '\x29']), ('\u323c', &['\x28', '\u76e3', '\x29']), ('\u323d',
-        &['\x28', '\u4f01', '\x29']), ('\u323e', &['\x28', '\u8cc7', '\x29']), ('\u323f', &['\x28',
-        '\u5354', '\x29']), ('\u3240', &['\x28', '\u796d', '\x29']), ('\u3241', &['\x28', '\u4f11',
-        '\x29']), ('\u3242', &['\x28', '\u81ea', '\x29']), ('\u3243', &['\x28', '\u81f3', '\x29']),
-        ('\u3244', &['\u554f']), ('\u3245', &['\u5e7c']), ('\u3246', &['\u6587']), ('\u3247',
-        &['\u7b8f']), ('\u3250', &['\x50', '\x54', '\x45']), ('\u3251', &['\x32', '\x31']),
-        ('\u3252', &['\x32', '\x32']), ('\u3253', &['\x32', '\x33']), ('\u3254', &['\x32', '\x34']),
-        ('\u3255', &['\x32', '\x35']), ('\u3256', &['\x32', '\x36']), ('\u3257', &['\x32', '\x37']),
-        ('\u3258', &['\x32', '\x38']), ('\u3259', &['\x32', '\x39']), ('\u325a', &['\x33', '\x30']),
-        ('\u325b', &['\x33', '\x31']), ('\u325c', &['\x33', '\x32']), ('\u325d', &['\x33', '\x33']),
-        ('\u325e', &['\x33', '\x34']), ('\u325f', &['\x33', '\x35']), ('\u3260', &['\u1100']),
-        ('\u3261', &['\u1102']), ('\u3262', &['\u1103']), ('\u3263', &['\u1105']), ('\u3264',
-        &['\u1106']), ('\u3265', &['\u1107']), ('\u3266', &['\u1109']), ('\u3267', &['\u110b']),
-        ('\u3268', &['\u110c']), ('\u3269', &['\u110e']), ('\u326a', &['\u110f']), ('\u326b',
-        &['\u1110']), ('\u326c', &['\u1111']), ('\u326d', &['\u1112']), ('\u326e', &['\u1100',
-        '\u1161']), ('\u326f', &['\u1102', '\u1161']), ('\u3270', &['\u1103', '\u1161']), ('\u3271',
-        &['\u1105', '\u1161']), ('\u3272', &['\u1106', '\u1161']), ('\u3273', &['\u1107',
-        '\u1161']), ('\u3274', &['\u1109', '\u1161']), ('\u3275', &['\u110b', '\u1161']), ('\u3276',
-        &['\u110c', '\u1161']), ('\u3277', &['\u110e', '\u1161']), ('\u3278', &['\u110f',
-        '\u1161']), ('\u3279', &['\u1110', '\u1161']), ('\u327a', &['\u1111', '\u1161']), ('\u327b',
-        &['\u1112', '\u1161']), ('\u327c', &['\u110e', '\u1161', '\u11b7', '\u1100', '\u1169']),
-        ('\u327d', &['\u110c', '\u116e', '\u110b', '\u1174']), ('\u327e', &['\u110b', '\u116e']),
-        ('\u3280', &['\u4e00']), ('\u3281', &['\u4e8c']), ('\u3282', &['\u4e09']), ('\u3283',
-        &['\u56db']), ('\u3284', &['\u4e94']), ('\u3285', &['\u516d']), ('\u3286', &['\u4e03']),
-        ('\u3287', &['\u516b']), ('\u3288', &['\u4e5d']), ('\u3289', &['\u5341']), ('\u328a',
-        &['\u6708']), ('\u328b', &['\u706b']), ('\u328c', &['\u6c34']), ('\u328d', &['\u6728']),
-        ('\u328e', &['\u91d1']), ('\u328f', &['\u571f']), ('\u3290', &['\u65e5']), ('\u3291',
-        &['\u682a']), ('\u3292', &['\u6709']), ('\u3293', &['\u793e']), ('\u3294', &['\u540d']),
-        ('\u3295', &['\u7279']), ('\u3296', &['\u8ca1']), ('\u3297', &['\u795d']), ('\u3298',
-        &['\u52b4']), ('\u3299', &['\u79d8']), ('\u329a', &['\u7537']), ('\u329b', &['\u5973']),
-        ('\u329c', &['\u9069']), ('\u329d', &['\u512a']), ('\u329e', &['\u5370']), ('\u329f',
-        &['\u6ce8']), ('\u32a0', &['\u9805']), ('\u32a1', &['\u4f11']), ('\u32a2', &['\u5199']),
-        ('\u32a3', &['\u6b63']), ('\u32a4', &['\u4e0a']), ('\u32a5', &['\u4e2d']), ('\u32a6',
-        &['\u4e0b']), ('\u32a7', &['\u5de6']), ('\u32a8', &['\u53f3']), ('\u32a9', &['\u533b']),
-        ('\u32aa', &['\u5b97']), ('\u32ab', &['\u5b66']), ('\u32ac', &['\u76e3']), ('\u32ad',
-        &['\u4f01']), ('\u32ae', &['\u8cc7']), ('\u32af', &['\u5354']), ('\u32b0', &['\u591c']),
-        ('\u32b1', &['\x33', '\x36']), ('\u32b2', &['\x33', '\x37']), ('\u32b3', &['\x33', '\x38']),
-        ('\u32b4', &['\x33', '\x39']), ('\u32b5', &['\x34', '\x30']), ('\u32b6', &['\x34', '\x31']),
-        ('\u32b7', &['\x34', '\x32']), ('\u32b8', &['\x34', '\x33']), ('\u32b9', &['\x34', '\x34']),
-        ('\u32ba', &['\x34', '\x35']), ('\u32bb', &['\x34', '\x36']), ('\u32bc', &['\x34', '\x37']),
-        ('\u32bd', &['\x34', '\x38']), ('\u32be', &['\x34', '\x39']), ('\u32bf', &['\x35', '\x30']),
-        ('\u32c0', &['\x31', '\u6708']), ('\u32c1', &['\x32', '\u6708']), ('\u32c2', &['\x33',
-        '\u6708']), ('\u32c3', &['\x34', '\u6708']), ('\u32c4', &['\x35', '\u6708']), ('\u32c5',
-        &['\x36', '\u6708']), ('\u32c6', &['\x37', '\u6708']), ('\u32c7', &['\x38', '\u6708']),
-        ('\u32c8', &['\x39', '\u6708']), ('\u32c9', &['\x31', '\x30', '\u6708']), ('\u32ca',
-        &['\x31', '\x31', '\u6708']), ('\u32cb', &['\x31', '\x32', '\u6708']), ('\u32cc', &['\x48',
-        '\x67']), ('\u32cd', &['\x65', '\x72', '\x67']), ('\u32ce', &['\x65', '\x56']), ('\u32cf',
-        &['\x4c', '\x54', '\x44']), ('\u32d0', &['\u30a2']), ('\u32d1', &['\u30a4']), ('\u32d2',
-        &['\u30a6']), ('\u32d3', &['\u30a8']), ('\u32d4', &['\u30aa']), ('\u32d5', &['\u30ab']),
-        ('\u32d6', &['\u30ad']), ('\u32d7', &['\u30af']), ('\u32d8', &['\u30b1']), ('\u32d9',
-        &['\u30b3']), ('\u32da', &['\u30b5']), ('\u32db', &['\u30b7']), ('\u32dc', &['\u30b9']),
-        ('\u32dd', &['\u30bb']), ('\u32de', &['\u30bd']), ('\u32df', &['\u30bf']), ('\u32e0',
-        &['\u30c1']), ('\u32e1', &['\u30c4']), ('\u32e2', &['\u30c6']), ('\u32e3', &['\u30c8']),
-        ('\u32e4', &['\u30ca']), ('\u32e5', &['\u30cb']), ('\u32e6', &['\u30cc']), ('\u32e7',
-        &['\u30cd']), ('\u32e8', &['\u30ce']), ('\u32e9', &['\u30cf']), ('\u32ea', &['\u30d2']),
-        ('\u32eb', &['\u30d5']), ('\u32ec', &['\u30d8']), ('\u32ed', &['\u30db']), ('\u32ee',
-        &['\u30de']), ('\u32ef', &['\u30df']), ('\u32f0', &['\u30e0']), ('\u32f1', &['\u30e1']),
-        ('\u32f2', &['\u30e2']), ('\u32f3', &['\u30e4']), ('\u32f4', &['\u30e6']), ('\u32f5',
-        &['\u30e8']), ('\u32f6', &['\u30e9']), ('\u32f7', &['\u30ea']), ('\u32f8', &['\u30eb']),
-        ('\u32f9', &['\u30ec']), ('\u32fa', &['\u30ed']), ('\u32fb', &['\u30ef']), ('\u32fc',
-        &['\u30f0']), ('\u32fd', &['\u30f1']), ('\u32fe', &['\u30f2']), ('\u3300', &['\u30a2',
-        '\u30d1', '\u30fc', '\u30c8']), ('\u3301', &['\u30a2', '\u30eb', '\u30d5', '\u30a1']),
-        ('\u3302', &['\u30a2', '\u30f3', '\u30da', '\u30a2']), ('\u3303', &['\u30a2', '\u30fc',
-        '\u30eb']), ('\u3304', &['\u30a4', '\u30cb', '\u30f3', '\u30b0']), ('\u3305', &['\u30a4',
-        '\u30f3', '\u30c1']), ('\u3306', &['\u30a6', '\u30a9', '\u30f3']), ('\u3307', &['\u30a8',
-        '\u30b9', '\u30af', '\u30fc', '\u30c9']), ('\u3308', &['\u30a8', '\u30fc', '\u30ab',
-        '\u30fc']), ('\u3309', &['\u30aa', '\u30f3', '\u30b9']), ('\u330a', &['\u30aa', '\u30fc',
-        '\u30e0']), ('\u330b', &['\u30ab', '\u30a4', '\u30ea']), ('\u330c', &['\u30ab', '\u30e9',
-        '\u30c3', '\u30c8']), ('\u330d', &['\u30ab', '\u30ed', '\u30ea', '\u30fc']), ('\u330e',
-        &['\u30ac', '\u30ed', '\u30f3']), ('\u330f', &['\u30ac', '\u30f3', '\u30de']), ('\u3310',
-        &['\u30ae', '\u30ac']), ('\u3311', &['\u30ae', '\u30cb', '\u30fc']), ('\u3312', &['\u30ad',
-        '\u30e5', '\u30ea', '\u30fc']), ('\u3313', &['\u30ae', '\u30eb', '\u30c0', '\u30fc']),
-        ('\u3314', &['\u30ad', '\u30ed']), ('\u3315', &['\u30ad', '\u30ed', '\u30b0', '\u30e9',
-        '\u30e0']), ('\u3316', &['\u30ad', '\u30ed', '\u30e1', '\u30fc', '\u30c8', '\u30eb']),
-        ('\u3317', &['\u30ad', '\u30ed', '\u30ef', '\u30c3', '\u30c8']), ('\u3318', &['\u30b0',
-        '\u30e9', '\u30e0']), ('\u3319', &['\u30b0', '\u30e9', '\u30e0', '\u30c8', '\u30f3']),
-        ('\u331a', &['\u30af', '\u30eb', '\u30bc', '\u30a4', '\u30ed']), ('\u331b', &['\u30af',
-        '\u30ed', '\u30fc', '\u30cd']), ('\u331c', &['\u30b1', '\u30fc', '\u30b9']), ('\u331d',
-        &['\u30b3', '\u30eb', '\u30ca']), ('\u331e', &['\u30b3', '\u30fc', '\u30dd']), ('\u331f',
-        &['\u30b5', '\u30a4', '\u30af', '\u30eb']), ('\u3320', &['\u30b5', '\u30f3', '\u30c1',
-        '\u30fc', '\u30e0']), ('\u3321', &['\u30b7', '\u30ea', '\u30f3', '\u30b0']), ('\u3322',
-        &['\u30bb', '\u30f3', '\u30c1']), ('\u3323', &['\u30bb', '\u30f3', '\u30c8']), ('\u3324',
-        &['\u30c0', '\u30fc', '\u30b9']), ('\u3325', &['\u30c7', '\u30b7']), ('\u3326', &['\u30c9',
-        '\u30eb']), ('\u3327', &['\u30c8', '\u30f3']), ('\u3328', &['\u30ca', '\u30ce']), ('\u3329',
-        &['\u30ce', '\u30c3', '\u30c8']), ('\u332a', &['\u30cf', '\u30a4', '\u30c4']), ('\u332b',
-        &['\u30d1', '\u30fc', '\u30bb', '\u30f3', '\u30c8']), ('\u332c', &['\u30d1', '\u30fc',
-        '\u30c4']), ('\u332d', &['\u30d0', '\u30fc', '\u30ec', '\u30eb']), ('\u332e', &['\u30d4',
-        '\u30a2', '\u30b9', '\u30c8', '\u30eb']), ('\u332f', &['\u30d4', '\u30af', '\u30eb']),
-        ('\u3330', &['\u30d4', '\u30b3']), ('\u3331', &['\u30d3', '\u30eb']), ('\u3332', &['\u30d5',
-        '\u30a1', '\u30e9', '\u30c3', '\u30c9']), ('\u3333', &['\u30d5', '\u30a3', '\u30fc',
-        '\u30c8']), ('\u3334', &['\u30d6', '\u30c3', '\u30b7', '\u30a7', '\u30eb']), ('\u3335',
-        &['\u30d5', '\u30e9', '\u30f3']), ('\u3336', &['\u30d8', '\u30af', '\u30bf', '\u30fc',
-        '\u30eb']), ('\u3337', &['\u30da', '\u30bd']), ('\u3338', &['\u30da', '\u30cb', '\u30d2']),
-        ('\u3339', &['\u30d8', '\u30eb', '\u30c4']), ('\u333a', &['\u30da', '\u30f3', '\u30b9']),
-        ('\u333b', &['\u30da', '\u30fc', '\u30b8']), ('\u333c', &['\u30d9', '\u30fc', '\u30bf']),
-        ('\u333d', &['\u30dd', '\u30a4', '\u30f3', '\u30c8']), ('\u333e', &['\u30dc', '\u30eb',
-        '\u30c8']), ('\u333f', &['\u30db', '\u30f3']), ('\u3340', &['\u30dd', '\u30f3', '\u30c9']),
-        ('\u3341', &['\u30db', '\u30fc', '\u30eb']), ('\u3342', &['\u30db', '\u30fc', '\u30f3']),
-        ('\u3343', &['\u30de', '\u30a4', '\u30af', '\u30ed']), ('\u3344', &['\u30de', '\u30a4',
-        '\u30eb']), ('\u3345', &['\u30de', '\u30c3', '\u30cf']), ('\u3346', &['\u30de', '\u30eb',
-        '\u30af']), ('\u3347', &['\u30de', '\u30f3', '\u30b7', '\u30e7', '\u30f3']), ('\u3348',
-        &['\u30df', '\u30af', '\u30ed', '\u30f3']), ('\u3349', &['\u30df', '\u30ea']), ('\u334a',
-        &['\u30df', '\u30ea', '\u30d0', '\u30fc', '\u30eb']), ('\u334b', &['\u30e1', '\u30ac']),
-        ('\u334c', &['\u30e1', '\u30ac', '\u30c8', '\u30f3']), ('\u334d', &['\u30e1', '\u30fc',
-        '\u30c8', '\u30eb']), ('\u334e', &['\u30e4', '\u30fc', '\u30c9']), ('\u334f', &['\u30e4',
-        '\u30fc', '\u30eb']), ('\u3350', &['\u30e6', '\u30a2', '\u30f3']), ('\u3351', &['\u30ea',
-        '\u30c3', '\u30c8', '\u30eb']), ('\u3352', &['\u30ea', '\u30e9']), ('\u3353', &['\u30eb',
-        '\u30d4', '\u30fc']), ('\u3354', &['\u30eb', '\u30fc', '\u30d6', '\u30eb']), ('\u3355',
-        &['\u30ec', '\u30e0']), ('\u3356', &['\u30ec', '\u30f3', '\u30c8', '\u30b2', '\u30f3']),
-        ('\u3357', &['\u30ef', '\u30c3', '\u30c8']), ('\u3358', &['\x30', '\u70b9']), ('\u3359',
-        &['\x31', '\u70b9']), ('\u335a', &['\x32', '\u70b9']), ('\u335b', &['\x33', '\u70b9']),
-        ('\u335c', &['\x34', '\u70b9']), ('\u335d', &['\x35', '\u70b9']), ('\u335e', &['\x36',
-        '\u70b9']), ('\u335f', &['\x37', '\u70b9']), ('\u3360', &['\x38', '\u70b9']), ('\u3361',
-        &['\x39', '\u70b9']), ('\u3362', &['\x31', '\x30', '\u70b9']), ('\u3363', &['\x31', '\x31',
-        '\u70b9']), ('\u3364', &['\x31', '\x32', '\u70b9']), ('\u3365', &['\x31', '\x33',
-        '\u70b9']), ('\u3366', &['\x31', '\x34', '\u70b9']), ('\u3367', &['\x31', '\x35',
-        '\u70b9']), ('\u3368', &['\x31', '\x36', '\u70b9']), ('\u3369', &['\x31', '\x37',
-        '\u70b9']), ('\u336a', &['\x31', '\x38', '\u70b9']), ('\u336b', &['\x31', '\x39',
-        '\u70b9']), ('\u336c', &['\x32', '\x30', '\u70b9']), ('\u336d', &['\x32', '\x31',
-        '\u70b9']), ('\u336e', &['\x32', '\x32', '\u70b9']), ('\u336f', &['\x32', '\x33',
-        '\u70b9']), ('\u3370', &['\x32', '\x34', '\u70b9']), ('\u3371', &['\x68', '\x50', '\x61']),
-        ('\u3372', &['\x64', '\x61']), ('\u3373', &['\x41', '\x55']), ('\u3374', &['\x62', '\x61',
-        '\x72']), ('\u3375', &['\x6f', '\x56']), ('\u3376', &['\x70', '\x63']), ('\u3377', &['\x64',
-        '\x6d']), ('\u3378', &['\x64', '\x6d', '\xb2']), ('\u3379', &['\x64', '\x6d', '\xb3']),
-        ('\u337a', &['\x49', '\x55']), ('\u337b', &['\u5e73', '\u6210']), ('\u337c', &['\u662d',
-        '\u548c']), ('\u337d', &['\u5927', '\u6b63']), ('\u337e', &['\u660e', '\u6cbb']), ('\u337f',
-        &['\u682a', '\u5f0f', '\u4f1a', '\u793e']), ('\u3380', &['\x70', '\x41']), ('\u3381',
-        &['\x6e', '\x41']), ('\u3382', &['\u03bc', '\x41']), ('\u3383', &['\x6d', '\x41']),
-        ('\u3384', &['\x6b', '\x41']), ('\u3385', &['\x4b', '\x42']), ('\u3386', &['\x4d', '\x42']),
-        ('\u3387', &['\x47', '\x42']), ('\u3388', &['\x63', '\x61', '\x6c']), ('\u3389', &['\x6b',
-        '\x63', '\x61', '\x6c']), ('\u338a', &['\x70', '\x46']), ('\u338b', &['\x6e', '\x46']),
-        ('\u338c', &['\u03bc', '\x46']), ('\u338d', &['\u03bc', '\x67']), ('\u338e', &['\x6d',
-        '\x67']), ('\u338f', &['\x6b', '\x67']), ('\u3390', &['\x48', '\x7a']), ('\u3391', &['\x6b',
-        '\x48', '\x7a']), ('\u3392', &['\x4d', '\x48', '\x7a']), ('\u3393', &['\x47', '\x48',
-        '\x7a']), ('\u3394', &['\x54', '\x48', '\x7a']), ('\u3395', &['\u03bc', '\u2113']),
-        ('\u3396', &['\x6d', '\u2113']), ('\u3397', &['\x64', '\u2113']), ('\u3398', &['\x6b',
-        '\u2113']), ('\u3399', &['\x66', '\x6d']), ('\u339a', &['\x6e', '\x6d']), ('\u339b',
-        &['\u03bc', '\x6d']), ('\u339c', &['\x6d', '\x6d']), ('\u339d', &['\x63', '\x6d']),
-        ('\u339e', &['\x6b', '\x6d']), ('\u339f', &['\x6d', '\x6d', '\xb2']), ('\u33a0', &['\x63',
-        '\x6d', '\xb2']), ('\u33a1', &['\x6d', '\xb2']), ('\u33a2', &['\x6b', '\x6d', '\xb2']),
-        ('\u33a3', &['\x6d', '\x6d', '\xb3']), ('\u33a4', &['\x63', '\x6d', '\xb3']), ('\u33a5',
-        &['\x6d', '\xb3']), ('\u33a6', &['\x6b', '\x6d', '\xb3']), ('\u33a7', &['\x6d', '\u2215',
-        '\x73']), ('\u33a8', &['\x6d', '\u2215', '\x73', '\xb2']), ('\u33a9', &['\x50', '\x61']),
-        ('\u33aa', &['\x6b', '\x50', '\x61']), ('\u33ab', &['\x4d', '\x50', '\x61']), ('\u33ac',
-        &['\x47', '\x50', '\x61']), ('\u33ad', &['\x72', '\x61', '\x64']), ('\u33ae', &['\x72',
-        '\x61', '\x64', '\u2215', '\x73']), ('\u33af', &['\x72', '\x61', '\x64', '\u2215', '\x73',
-        '\xb2']), ('\u33b0', &['\x70', '\x73']), ('\u33b1', &['\x6e', '\x73']), ('\u33b2',
-        &['\u03bc', '\x73']), ('\u33b3', &['\x6d', '\x73']), ('\u33b4', &['\x70', '\x56']),
-        ('\u33b5', &['\x6e', '\x56']), ('\u33b6', &['\u03bc', '\x56']), ('\u33b7', &['\x6d',
-        '\x56']), ('\u33b8', &['\x6b', '\x56']), ('\u33b9', &['\x4d', '\x56']), ('\u33ba', &['\x70',
-        '\x57']), ('\u33bb', &['\x6e', '\x57']), ('\u33bc', &['\u03bc', '\x57']), ('\u33bd',
-        &['\x6d', '\x57']), ('\u33be', &['\x6b', '\x57']), ('\u33bf', &['\x4d', '\x57']), ('\u33c0',
-        &['\x6b', '\u03a9']), ('\u33c1', &['\x4d', '\u03a9']), ('\u33c2', &['\x61', '\x2e', '\x6d',
-        '\x2e']), ('\u33c3', &['\x42', '\x71']), ('\u33c4', &['\x63', '\x63']), ('\u33c5', &['\x63',
-        '\x64']), ('\u33c6', &['\x43', '\u2215', '\x6b', '\x67']), ('\u33c7', &['\x43', '\x6f',
-        '\x2e']), ('\u33c8', &['\x64', '\x42']), ('\u33c9', &['\x47', '\x79']), ('\u33ca', &['\x68',
-        '\x61']), ('\u33cb', &['\x48', '\x50']), ('\u33cc', &['\x69', '\x6e']), ('\u33cd', &['\x4b',
-        '\x4b']), ('\u33ce', &['\x4b', '\x4d']), ('\u33cf', &['\x6b', '\x74']), ('\u33d0', &['\x6c',
-        '\x6d']), ('\u33d1', &['\x6c', '\x6e']), ('\u33d2', &['\x6c', '\x6f', '\x67']), ('\u33d3',
-        &['\x6c', '\x78']), ('\u33d4', &['\x6d', '\x62']), ('\u33d5', &['\x6d', '\x69', '\x6c']),
-        ('\u33d6', &['\x6d', '\x6f', '\x6c']), ('\u33d7', &['\x50', '\x48']), ('\u33d8', &['\x70',
-        '\x2e', '\x6d', '\x2e']), ('\u33d9', &['\x50', '\x50', '\x4d']), ('\u33da', &['\x50',
-        '\x52']), ('\u33db', &['\x73', '\x72']), ('\u33dc', &['\x53', '\x76']), ('\u33dd', &['\x57',
-        '\x62']), ('\u33de', &['\x56', '\u2215', '\x6d']), ('\u33df', &['\x41', '\u2215', '\x6d']),
-        ('\u33e0', &['\x31', '\u65e5']), ('\u33e1', &['\x32', '\u65e5']), ('\u33e2', &['\x33',
-        '\u65e5']), ('\u33e3', &['\x34', '\u65e5']), ('\u33e4', &['\x35', '\u65e5']), ('\u33e5',
-        &['\x36', '\u65e5']), ('\u33e6', &['\x37', '\u65e5']), ('\u33e7', &['\x38', '\u65e5']),
-        ('\u33e8', &['\x39', '\u65e5']), ('\u33e9', &['\x31', '\x30', '\u65e5']), ('\u33ea',
-        &['\x31', '\x31', '\u65e5']), ('\u33eb', &['\x31', '\x32', '\u65e5']), ('\u33ec', &['\x31',
-        '\x33', '\u65e5']), ('\u33ed', &['\x31', '\x34', '\u65e5']), ('\u33ee', &['\x31', '\x35',
-        '\u65e5']), ('\u33ef', &['\x31', '\x36', '\u65e5']), ('\u33f0', &['\x31', '\x37',
-        '\u65e5']), ('\u33f1', &['\x31', '\x38', '\u65e5']), ('\u33f2', &['\x31', '\x39',
-        '\u65e5']), ('\u33f3', &['\x32', '\x30', '\u65e5']), ('\u33f4', &['\x32', '\x31',
-        '\u65e5']), ('\u33f5', &['\x32', '\x32', '\u65e5']), ('\u33f6', &['\x32', '\x33',
-        '\u65e5']), ('\u33f7', &['\x32', '\x34', '\u65e5']), ('\u33f8', &['\x32', '\x35',
-        '\u65e5']), ('\u33f9', &['\x32', '\x36', '\u65e5']), ('\u33fa', &['\x32', '\x37',
-        '\u65e5']), ('\u33fb', &['\x32', '\x38', '\u65e5']), ('\u33fc', &['\x32', '\x39',
-        '\u65e5']), ('\u33fd', &['\x33', '\x30', '\u65e5']), ('\u33fe', &['\x33', '\x31',
-        '\u65e5']), ('\u33ff', &['\x67', '\x61', '\x6c']), ('\ua770', &['\ua76f']), ('\ua7f8',
-        &['\u0126']), ('\ua7f9', &['\u0153']), ('\ufb00', &['\x66', '\x66']), ('\ufb01', &['\x66',
-        '\x69']), ('\ufb02', &['\x66', '\x6c']), ('\ufb03', &['\x66', '\x66', '\x69']), ('\ufb04',
-        &['\x66', '\x66', '\x6c']), ('\ufb05', &['\u017f', '\x74']), ('\ufb06', &['\x73', '\x74']),
-        ('\ufb13', &['\u0574', '\u0576']), ('\ufb14', &['\u0574', '\u0565']), ('\ufb15', &['\u0574',
-        '\u056b']), ('\ufb16', &['\u057e', '\u0576']), ('\ufb17', &['\u0574', '\u056d']), ('\ufb20',
-        &['\u05e2']), ('\ufb21', &['\u05d0']), ('\ufb22', &['\u05d3']), ('\ufb23', &['\u05d4']),
-        ('\ufb24', &['\u05db']), ('\ufb25', &['\u05dc']), ('\ufb26', &['\u05dd']), ('\ufb27',
-        &['\u05e8']), ('\ufb28', &['\u05ea']), ('\ufb29', &['\x2b']), ('\ufb4f', &['\u05d0',
-        '\u05dc']), ('\ufb50', &['\u0671']), ('\ufb51', &['\u0671']), ('\ufb52', &['\u067b']),
-        ('\ufb53', &['\u067b']), ('\ufb54', &['\u067b']), ('\ufb55', &['\u067b']), ('\ufb56',
-        &['\u067e']), ('\ufb57', &['\u067e']), ('\ufb58', &['\u067e']), ('\ufb59', &['\u067e']),
-        ('\ufb5a', &['\u0680']), ('\ufb5b', &['\u0680']), ('\ufb5c', &['\u0680']), ('\ufb5d',
-        &['\u0680']), ('\ufb5e', &['\u067a']), ('\ufb5f', &['\u067a']), ('\ufb60', &['\u067a']),
-        ('\ufb61', &['\u067a']), ('\ufb62', &['\u067f']), ('\ufb63', &['\u067f']), ('\ufb64',
-        &['\u067f']), ('\ufb65', &['\u067f']), ('\ufb66', &['\u0679']), ('\ufb67', &['\u0679']),
-        ('\ufb68', &['\u0679']), ('\ufb69', &['\u0679']), ('\ufb6a', &['\u06a4']), ('\ufb6b',
-        &['\u06a4']), ('\ufb6c', &['\u06a4']), ('\ufb6d', &['\u06a4']), ('\ufb6e', &['\u06a6']),
-        ('\ufb6f', &['\u06a6']), ('\ufb70', &['\u06a6']), ('\ufb71', &['\u06a6']), ('\ufb72',
-        &['\u0684']), ('\ufb73', &['\u0684']), ('\ufb74', &['\u0684']), ('\ufb75', &['\u0684']),
-        ('\ufb76', &['\u0683']), ('\ufb77', &['\u0683']), ('\ufb78', &['\u0683']), ('\ufb79',
-        &['\u0683']), ('\ufb7a', &['\u0686']), ('\ufb7b', &['\u0686']), ('\ufb7c', &['\u0686']),
-        ('\ufb7d', &['\u0686']), ('\ufb7e', &['\u0687']), ('\ufb7f', &['\u0687']), ('\ufb80',
-        &['\u0687']), ('\ufb81', &['\u0687']), ('\ufb82', &['\u068d']), ('\ufb83', &['\u068d']),
-        ('\ufb84', &['\u068c']), ('\ufb85', &['\u068c']), ('\ufb86', &['\u068e']), ('\ufb87',
-        &['\u068e']), ('\ufb88', &['\u0688']), ('\ufb89', &['\u0688']), ('\ufb8a', &['\u0698']),
-        ('\ufb8b', &['\u0698']), ('\ufb8c', &['\u0691']), ('\ufb8d', &['\u0691']), ('\ufb8e',
-        &['\u06a9']), ('\ufb8f', &['\u06a9']), ('\ufb90', &['\u06a9']), ('\ufb91', &['\u06a9']),
-        ('\ufb92', &['\u06af']), ('\ufb93', &['\u06af']), ('\ufb94', &['\u06af']), ('\ufb95',
-        &['\u06af']), ('\ufb96', &['\u06b3']), ('\ufb97', &['\u06b3']), ('\ufb98', &['\u06b3']),
-        ('\ufb99', &['\u06b3']), ('\ufb9a', &['\u06b1']), ('\ufb9b', &['\u06b1']), ('\ufb9c',
-        &['\u06b1']), ('\ufb9d', &['\u06b1']), ('\ufb9e', &['\u06ba']), ('\ufb9f', &['\u06ba']),
-        ('\ufba0', &['\u06bb']), ('\ufba1', &['\u06bb']), ('\ufba2', &['\u06bb']), ('\ufba3',
-        &['\u06bb']), ('\ufba4', &['\u06c0']), ('\ufba5', &['\u06c0']), ('\ufba6', &['\u06c1']),
-        ('\ufba7', &['\u06c1']), ('\ufba8', &['\u06c1']), ('\ufba9', &['\u06c1']), ('\ufbaa',
-        &['\u06be']), ('\ufbab', &['\u06be']), ('\ufbac', &['\u06be']), ('\ufbad', &['\u06be']),
-        ('\ufbae', &['\u06d2']), ('\ufbaf', &['\u06d2']), ('\ufbb0', &['\u06d3']), ('\ufbb1',
-        &['\u06d3']), ('\ufbd3', &['\u06ad']), ('\ufbd4', &['\u06ad']), ('\ufbd5', &['\u06ad']),
-        ('\ufbd6', &['\u06ad']), ('\ufbd7', &['\u06c7']), ('\ufbd8', &['\u06c7']), ('\ufbd9',
-        &['\u06c6']), ('\ufbda', &['\u06c6']), ('\ufbdb', &['\u06c8']), ('\ufbdc', &['\u06c8']),
-        ('\ufbdd', &['\u0677']), ('\ufbde', &['\u06cb']), ('\ufbdf', &['\u06cb']), ('\ufbe0',
-        &['\u06c5']), ('\ufbe1', &['\u06c5']), ('\ufbe2', &['\u06c9']), ('\ufbe3', &['\u06c9']),
-        ('\ufbe4', &['\u06d0']), ('\ufbe5', &['\u06d0']), ('\ufbe6', &['\u06d0']), ('\ufbe7',
-        &['\u06d0']), ('\ufbe8', &['\u0649']), ('\ufbe9', &['\u0649']), ('\ufbea', &['\u0626',
-        '\u0627']), ('\ufbeb', &['\u0626', '\u0627']), ('\ufbec', &['\u0626', '\u06d5']), ('\ufbed',
-        &['\u0626', '\u06d5']), ('\ufbee', &['\u0626', '\u0648']), ('\ufbef', &['\u0626',
-        '\u0648']), ('\ufbf0', &['\u0626', '\u06c7']), ('\ufbf1', &['\u0626', '\u06c7']), ('\ufbf2',
-        &['\u0626', '\u06c6']), ('\ufbf3', &['\u0626', '\u06c6']), ('\ufbf4', &['\u0626',
-        '\u06c8']), ('\ufbf5', &['\u0626', '\u06c8']), ('\ufbf6', &['\u0626', '\u06d0']), ('\ufbf7',
-        &['\u0626', '\u06d0']), ('\ufbf8', &['\u0626', '\u06d0']), ('\ufbf9', &['\u0626',
-        '\u0649']), ('\ufbfa', &['\u0626', '\u0649']), ('\ufbfb', &['\u0626', '\u0649']), ('\ufbfc',
-        &['\u06cc']), ('\ufbfd', &['\u06cc']), ('\ufbfe', &['\u06cc']), ('\ufbff', &['\u06cc']),
-        ('\ufc00', &['\u0626', '\u062c']), ('\ufc01', &['\u0626', '\u062d']), ('\ufc02', &['\u0626',
-        '\u0645']), ('\ufc03', &['\u0626', '\u0649']), ('\ufc04', &['\u0626', '\u064a']), ('\ufc05',
-        &['\u0628', '\u062c']), ('\ufc06', &['\u0628', '\u062d']), ('\ufc07', &['\u0628',
-        '\u062e']), ('\ufc08', &['\u0628', '\u0645']), ('\ufc09', &['\u0628', '\u0649']), ('\ufc0a',
-        &['\u0628', '\u064a']), ('\ufc0b', &['\u062a', '\u062c']), ('\ufc0c', &['\u062a',
-        '\u062d']), ('\ufc0d', &['\u062a', '\u062e']), ('\ufc0e', &['\u062a', '\u0645']), ('\ufc0f',
-        &['\u062a', '\u0649']), ('\ufc10', &['\u062a', '\u064a']), ('\ufc11', &['\u062b',
-        '\u062c']), ('\ufc12', &['\u062b', '\u0645']), ('\ufc13', &['\u062b', '\u0649']), ('\ufc14',
-        &['\u062b', '\u064a']), ('\ufc15', &['\u062c', '\u062d']), ('\ufc16', &['\u062c',
-        '\u0645']), ('\ufc17', &['\u062d', '\u062c']), ('\ufc18', &['\u062d', '\u0645']), ('\ufc19',
-        &['\u062e', '\u062c']), ('\ufc1a', &['\u062e', '\u062d']), ('\ufc1b', &['\u062e',
-        '\u0645']), ('\ufc1c', &['\u0633', '\u062c']), ('\ufc1d', &['\u0633', '\u062d']), ('\ufc1e',
-        &['\u0633', '\u062e']), ('\ufc1f', &['\u0633', '\u0645']), ('\ufc20', &['\u0635',
-        '\u062d']), ('\ufc21', &['\u0635', '\u0645']), ('\ufc22', &['\u0636', '\u062c']), ('\ufc23',
-        &['\u0636', '\u062d']), ('\ufc24', &['\u0636', '\u062e']), ('\ufc25', &['\u0636',
-        '\u0645']), ('\ufc26', &['\u0637', '\u062d']), ('\ufc27', &['\u0637', '\u0645']), ('\ufc28',
-        &['\u0638', '\u0645']), ('\ufc29', &['\u0639', '\u062c']), ('\ufc2a', &['\u0639',
-        '\u0645']), ('\ufc2b', &['\u063a', '\u062c']), ('\ufc2c', &['\u063a', '\u0645']), ('\ufc2d',
-        &['\u0641', '\u062c']), ('\ufc2e', &['\u0641', '\u062d']), ('\ufc2f', &['\u0641',
-        '\u062e']), ('\ufc30', &['\u0641', '\u0645']), ('\ufc31', &['\u0641', '\u0649']), ('\ufc32',
-        &['\u0641', '\u064a']), ('\ufc33', &['\u0642', '\u062d']), ('\ufc34', &['\u0642',
-        '\u0645']), ('\ufc35', &['\u0642', '\u0649']), ('\ufc36', &['\u0642', '\u064a']), ('\ufc37',
-        &['\u0643', '\u0627']), ('\ufc38', &['\u0643', '\u062c']), ('\ufc39', &['\u0643',
-        '\u062d']), ('\ufc3a', &['\u0643', '\u062e']), ('\ufc3b', &['\u0643', '\u0644']), ('\ufc3c',
-        &['\u0643', '\u0645']), ('\ufc3d', &['\u0643', '\u0649']), ('\ufc3e', &['\u0643',
-        '\u064a']), ('\ufc3f', &['\u0644', '\u062c']), ('\ufc40', &['\u0644', '\u062d']), ('\ufc41',
-        &['\u0644', '\u062e']), ('\ufc42', &['\u0644', '\u0645']), ('\ufc43', &['\u0644',
-        '\u0649']), ('\ufc44', &['\u0644', '\u064a']), ('\ufc45', &['\u0645', '\u062c']), ('\ufc46',
-        &['\u0645', '\u062d']), ('\ufc47', &['\u0645', '\u062e']), ('\ufc48', &['\u0645',
-        '\u0645']), ('\ufc49', &['\u0645', '\u0649']), ('\ufc4a', &['\u0645', '\u064a']), ('\ufc4b',
-        &['\u0646', '\u062c']), ('\ufc4c', &['\u0646', '\u062d']), ('\ufc4d', &['\u0646',
-        '\u062e']), ('\ufc4e', &['\u0646', '\u0645']), ('\ufc4f', &['\u0646', '\u0649']), ('\ufc50',
-        &['\u0646', '\u064a']), ('\ufc51', &['\u0647', '\u062c']), ('\ufc52', &['\u0647',
-        '\u0645']), ('\ufc53', &['\u0647', '\u0649']), ('\ufc54', &['\u0647', '\u064a']), ('\ufc55',
-        &['\u064a', '\u062c']), ('\ufc56', &['\u064a', '\u062d']), ('\ufc57', &['\u064a',
-        '\u062e']), ('\ufc58', &['\u064a', '\u0645']), ('\ufc59', &['\u064a', '\u0649']), ('\ufc5a',
-        &['\u064a', '\u064a']), ('\ufc5b', &['\u0630', '\u0670']), ('\ufc5c', &['\u0631',
-        '\u0670']), ('\ufc5d', &['\u0649', '\u0670']), ('\ufc5e', &['\x20', '\u064c', '\u0651']),
-        ('\ufc5f', &['\x20', '\u064d', '\u0651']), ('\ufc60', &['\x20', '\u064e', '\u0651']),
-        ('\ufc61', &['\x20', '\u064f', '\u0651']), ('\ufc62', &['\x20', '\u0650', '\u0651']),
-        ('\ufc63', &['\x20', '\u0651', '\u0670']), ('\ufc64', &['\u0626', '\u0631']), ('\ufc65',
-        &['\u0626', '\u0632']), ('\ufc66', &['\u0626', '\u0645']), ('\ufc67', &['\u0626',
-        '\u0646']), ('\ufc68', &['\u0626', '\u0649']), ('\ufc69', &['\u0626', '\u064a']), ('\ufc6a',
-        &['\u0628', '\u0631']), ('\ufc6b', &['\u0628', '\u0632']), ('\ufc6c', &['\u0628',
-        '\u0645']), ('\ufc6d', &['\u0628', '\u0646']), ('\ufc6e', &['\u0628', '\u0649']), ('\ufc6f',
-        &['\u0628', '\u064a']), ('\ufc70', &['\u062a', '\u0631']), ('\ufc71', &['\u062a',
-        '\u0632']), ('\ufc72', &['\u062a', '\u0645']), ('\ufc73', &['\u062a', '\u0646']), ('\ufc74',
-        &['\u062a', '\u0649']), ('\ufc75', &['\u062a', '\u064a']), ('\ufc76', &['\u062b',
-        '\u0631']), ('\ufc77', &['\u062b', '\u0632']), ('\ufc78', &['\u062b', '\u0645']), ('\ufc79',
-        &['\u062b', '\u0646']), ('\ufc7a', &['\u062b', '\u0649']), ('\ufc7b', &['\u062b',
-        '\u064a']), ('\ufc7c', &['\u0641', '\u0649']), ('\ufc7d', &['\u0641', '\u064a']), ('\ufc7e',
-        &['\u0642', '\u0649']), ('\ufc7f', &['\u0642', '\u064a']), ('\ufc80', &['\u0643',
-        '\u0627']), ('\ufc81', &['\u0643', '\u0644']), ('\ufc82', &['\u0643', '\u0645']), ('\ufc83',
-        &['\u0643', '\u0649']), ('\ufc84', &['\u0643', '\u064a']), ('\ufc85', &['\u0644',
-        '\u0645']), ('\ufc86', &['\u0644', '\u0649']), ('\ufc87', &['\u0644', '\u064a']), ('\ufc88',
-        &['\u0645', '\u0627']), ('\ufc89', &['\u0645', '\u0645']), ('\ufc8a', &['\u0646',
-        '\u0631']), ('\ufc8b', &['\u0646', '\u0632']), ('\ufc8c', &['\u0646', '\u0645']), ('\ufc8d',
-        &['\u0646', '\u0646']), ('\ufc8e', &['\u0646', '\u0649']), ('\ufc8f', &['\u0646',
-        '\u064a']), ('\ufc90', &['\u0649', '\u0670']), ('\ufc91', &['\u064a', '\u0631']), ('\ufc92',
-        &['\u064a', '\u0632']), ('\ufc93', &['\u064a', '\u0645']), ('\ufc94', &['\u064a',
-        '\u0646']), ('\ufc95', &['\u064a', '\u0649']), ('\ufc96', &['\u064a', '\u064a']), ('\ufc97',
-        &['\u0626', '\u062c']), ('\ufc98', &['\u0626', '\u062d']), ('\ufc99', &['\u0626',
-        '\u062e']), ('\ufc9a', &['\u0626', '\u0645']), ('\ufc9b', &['\u0626', '\u0647']), ('\ufc9c',
-        &['\u0628', '\u062c']), ('\ufc9d', &['\u0628', '\u062d']), ('\ufc9e', &['\u0628',
-        '\u062e']), ('\ufc9f', &['\u0628', '\u0645']), ('\ufca0', &['\u0628', '\u0647']), ('\ufca1',
-        &['\u062a', '\u062c']), ('\ufca2', &['\u062a', '\u062d']), ('\ufca3', &['\u062a',
-        '\u062e']), ('\ufca4', &['\u062a', '\u0645']), ('\ufca5', &['\u062a', '\u0647']), ('\ufca6',
-        &['\u062b', '\u0645']), ('\ufca7', &['\u062c', '\u062d']), ('\ufca8', &['\u062c',
-        '\u0645']), ('\ufca9', &['\u062d', '\u062c']), ('\ufcaa', &['\u062d', '\u0645']), ('\ufcab',
-        &['\u062e', '\u062c']), ('\ufcac', &['\u062e', '\u0645']), ('\ufcad', &['\u0633',
-        '\u062c']), ('\ufcae', &['\u0633', '\u062d']), ('\ufcaf', &['\u0633', '\u062e']), ('\ufcb0',
-        &['\u0633', '\u0645']), ('\ufcb1', &['\u0635', '\u062d']), ('\ufcb2', &['\u0635',
-        '\u062e']), ('\ufcb3', &['\u0635', '\u0645']), ('\ufcb4', &['\u0636', '\u062c']), ('\ufcb5',
-        &['\u0636', '\u062d']), ('\ufcb6', &['\u0636', '\u062e']), ('\ufcb7', &['\u0636',
-        '\u0645']), ('\ufcb8', &['\u0637', '\u062d']), ('\ufcb9', &['\u0638', '\u0645']), ('\ufcba',
-        &['\u0639', '\u062c']), ('\ufcbb', &['\u0639', '\u0645']), ('\ufcbc', &['\u063a',
-        '\u062c']), ('\ufcbd', &['\u063a', '\u0645']), ('\ufcbe', &['\u0641', '\u062c']), ('\ufcbf',
-        &['\u0641', '\u062d']), ('\ufcc0', &['\u0641', '\u062e']), ('\ufcc1', &['\u0641',
-        '\u0645']), ('\ufcc2', &['\u0642', '\u062d']), ('\ufcc3', &['\u0642', '\u0645']), ('\ufcc4',
-        &['\u0643', '\u062c']), ('\ufcc5', &['\u0643', '\u062d']), ('\ufcc6', &['\u0643',
-        '\u062e']), ('\ufcc7', &['\u0643', '\u0644']), ('\ufcc8', &['\u0643', '\u0645']), ('\ufcc9',
-        &['\u0644', '\u062c']), ('\ufcca', &['\u0644', '\u062d']), ('\ufccb', &['\u0644',
-        '\u062e']), ('\ufccc', &['\u0644', '\u0645']), ('\ufccd', &['\u0644', '\u0647']), ('\ufcce',
-        &['\u0645', '\u062c']), ('\ufccf', &['\u0645', '\u062d']), ('\ufcd0', &['\u0645',
-        '\u062e']), ('\ufcd1', &['\u0645', '\u0645']), ('\ufcd2', &['\u0646', '\u062c']), ('\ufcd3',
-        &['\u0646', '\u062d']), ('\ufcd4', &['\u0646', '\u062e']), ('\ufcd5', &['\u0646',
-        '\u0645']), ('\ufcd6', &['\u0646', '\u0647']), ('\ufcd7', &['\u0647', '\u062c']), ('\ufcd8',
-        &['\u0647', '\u0645']), ('\ufcd9', &['\u0647', '\u0670']), ('\ufcda', &['\u064a',
-        '\u062c']), ('\ufcdb', &['\u064a', '\u062d']), ('\ufcdc', &['\u064a', '\u062e']), ('\ufcdd',
-        &['\u064a', '\u0645']), ('\ufcde', &['\u064a', '\u0647']), ('\ufcdf', &['\u0626',
-        '\u0645']), ('\ufce0', &['\u0626', '\u0647']), ('\ufce1', &['\u0628', '\u0645']), ('\ufce2',
-        &['\u0628', '\u0647']), ('\ufce3', &['\u062a', '\u0645']), ('\ufce4', &['\u062a',
-        '\u0647']), ('\ufce5', &['\u062b', '\u0645']), ('\ufce6', &['\u062b', '\u0647']), ('\ufce7',
-        &['\u0633', '\u0645']), ('\ufce8', &['\u0633', '\u0647']), ('\ufce9', &['\u0634',
-        '\u0645']), ('\ufcea', &['\u0634', '\u0647']), ('\ufceb', &['\u0643', '\u0644']), ('\ufcec',
-        &['\u0643', '\u0645']), ('\ufced', &['\u0644', '\u0645']), ('\ufcee', &['\u0646',
-        '\u0645']), ('\ufcef', &['\u0646', '\u0647']), ('\ufcf0', &['\u064a', '\u0645']), ('\ufcf1',
-        &['\u064a', '\u0647']), ('\ufcf2', &['\u0640', '\u064e', '\u0651']), ('\ufcf3', &['\u0640',
-        '\u064f', '\u0651']), ('\ufcf4', &['\u0640', '\u0650', '\u0651']), ('\ufcf5', &['\u0637',
-        '\u0649']), ('\ufcf6', &['\u0637', '\u064a']), ('\ufcf7', &['\u0639', '\u0649']), ('\ufcf8',
-        &['\u0639', '\u064a']), ('\ufcf9', &['\u063a', '\u0649']), ('\ufcfa', &['\u063a',
-        '\u064a']), ('\ufcfb', &['\u0633', '\u0649']), ('\ufcfc', &['\u0633', '\u064a']), ('\ufcfd',
-        &['\u0634', '\u0649']), ('\ufcfe', &['\u0634', '\u064a']), ('\ufcff', &['\u062d',
-        '\u0649']), ('\ufd00', &['\u062d', '\u064a']), ('\ufd01', &['\u062c', '\u0649']), ('\ufd02',
-        &['\u062c', '\u064a']), ('\ufd03', &['\u062e', '\u0649']), ('\ufd04', &['\u062e',
-        '\u064a']), ('\ufd05', &['\u0635', '\u0649']), ('\ufd06', &['\u0635', '\u064a']), ('\ufd07',
-        &['\u0636', '\u0649']), ('\ufd08', &['\u0636', '\u064a']), ('\ufd09', &['\u0634',
-        '\u062c']), ('\ufd0a', &['\u0634', '\u062d']), ('\ufd0b', &['\u0634', '\u062e']), ('\ufd0c',
-        &['\u0634', '\u0645']), ('\ufd0d', &['\u0634', '\u0631']), ('\ufd0e', &['\u0633',
-        '\u0631']), ('\ufd0f', &['\u0635', '\u0631']), ('\ufd10', &['\u0636', '\u0631']), ('\ufd11',
-        &['\u0637', '\u0649']), ('\ufd12', &['\u0637', '\u064a']), ('\ufd13', &['\u0639',
-        '\u0649']), ('\ufd14', &['\u0639', '\u064a']), ('\ufd15', &['\u063a', '\u0649']), ('\ufd16',
-        &['\u063a', '\u064a']), ('\ufd17', &['\u0633', '\u0649']), ('\ufd18', &['\u0633',
-        '\u064a']), ('\ufd19', &['\u0634', '\u0649']), ('\ufd1a', &['\u0634', '\u064a']), ('\ufd1b',
-        &['\u062d', '\u0649']), ('\ufd1c', &['\u062d', '\u064a']), ('\ufd1d', &['\u062c',
-        '\u0649']), ('\ufd1e', &['\u062c', '\u064a']), ('\ufd1f', &['\u062e', '\u0649']), ('\ufd20',
-        &['\u062e', '\u064a']), ('\ufd21', &['\u0635', '\u0649']), ('\ufd22', &['\u0635',
-        '\u064a']), ('\ufd23', &['\u0636', '\u0649']), ('\ufd24', &['\u0636', '\u064a']), ('\ufd25',
-        &['\u0634', '\u062c']), ('\ufd26', &['\u0634', '\u062d']), ('\ufd27', &['\u0634',
-        '\u062e']), ('\ufd28', &['\u0634', '\u0645']), ('\ufd29', &['\u0634', '\u0631']), ('\ufd2a',
-        &['\u0633', '\u0631']), ('\ufd2b', &['\u0635', '\u0631']), ('\ufd2c', &['\u0636',
-        '\u0631']), ('\ufd2d', &['\u0634', '\u062c']), ('\ufd2e', &['\u0634', '\u062d']), ('\ufd2f',
-        &['\u0634', '\u062e']), ('\ufd30', &['\u0634', '\u0645']), ('\ufd31', &['\u0633',
-        '\u0647']), ('\ufd32', &['\u0634', '\u0647']), ('\ufd33', &['\u0637', '\u0645']), ('\ufd34',
-        &['\u0633', '\u062c']), ('\ufd35', &['\u0633', '\u062d']), ('\ufd36', &['\u0633',
-        '\u062e']), ('\ufd37', &['\u0634', '\u062c']), ('\ufd38', &['\u0634', '\u062d']), ('\ufd39',
-        &['\u0634', '\u062e']), ('\ufd3a', &['\u0637', '\u0645']), ('\ufd3b', &['\u0638',
-        '\u0645']), ('\ufd3c', &['\u0627', '\u064b']), ('\ufd3d', &['\u0627', '\u064b']), ('\ufd50',
-        &['\u062a', '\u062c', '\u0645']), ('\ufd51', &['\u062a', '\u062d', '\u062c']), ('\ufd52',
-        &['\u062a', '\u062d', '\u062c']), ('\ufd53', &['\u062a', '\u062d', '\u0645']), ('\ufd54',
-        &['\u062a', '\u062e', '\u0645']), ('\ufd55', &['\u062a', '\u0645', '\u062c']), ('\ufd56',
-        &['\u062a', '\u0645', '\u062d']), ('\ufd57', &['\u062a', '\u0645', '\u062e']), ('\ufd58',
-        &['\u062c', '\u0645', '\u062d']), ('\ufd59', &['\u062c', '\u0645', '\u062d']), ('\ufd5a',
-        &['\u062d', '\u0645', '\u064a']), ('\ufd5b', &['\u062d', '\u0645', '\u0649']), ('\ufd5c',
-        &['\u0633', '\u062d', '\u062c']), ('\ufd5d', &['\u0633', '\u062c', '\u062d']), ('\ufd5e',
-        &['\u0633', '\u062c', '\u0649']), ('\ufd5f', &['\u0633', '\u0645', '\u062d']), ('\ufd60',
-        &['\u0633', '\u0645', '\u062d']), ('\ufd61', &['\u0633', '\u0645', '\u062c']), ('\ufd62',
-        &['\u0633', '\u0645', '\u0645']), ('\ufd63', &['\u0633', '\u0645', '\u0645']), ('\ufd64',
-        &['\u0635', '\u062d', '\u062d']), ('\ufd65', &['\u0635', '\u062d', '\u062d']), ('\ufd66',
-        &['\u0635', '\u0645', '\u0645']), ('\ufd67', &['\u0634', '\u062d', '\u0645']), ('\ufd68',
-        &['\u0634', '\u062d', '\u0645']), ('\ufd69', &['\u0634', '\u062c', '\u064a']), ('\ufd6a',
-        &['\u0634', '\u0645', '\u062e']), ('\ufd6b', &['\u0634', '\u0645', '\u062e']), ('\ufd6c',
-        &['\u0634', '\u0645', '\u0645']), ('\ufd6d', &['\u0634', '\u0645', '\u0645']), ('\ufd6e',
-        &['\u0636', '\u062d', '\u0649']), ('\ufd6f', &['\u0636', '\u062e', '\u0645']), ('\ufd70',
-        &['\u0636', '\u062e', '\u0645']), ('\ufd71', &['\u0637', '\u0645', '\u062d']), ('\ufd72',
-        &['\u0637', '\u0645', '\u062d']), ('\ufd73', &['\u0637', '\u0645', '\u0645']), ('\ufd74',
-        &['\u0637', '\u0645', '\u064a']), ('\ufd75', &['\u0639', '\u062c', '\u0645']), ('\ufd76',
-        &['\u0639', '\u0645', '\u0645']), ('\ufd77', &['\u0639', '\u0645', '\u0645']), ('\ufd78',
-        &['\u0639', '\u0645', '\u0649']), ('\ufd79', &['\u063a', '\u0645', '\u0645']), ('\ufd7a',
-        &['\u063a', '\u0645', '\u064a']), ('\ufd7b', &['\u063a', '\u0645', '\u0649']), ('\ufd7c',
-        &['\u0641', '\u062e', '\u0645']), ('\ufd7d', &['\u0641', '\u062e', '\u0645']), ('\ufd7e',
-        &['\u0642', '\u0645', '\u062d']), ('\ufd7f', &['\u0642', '\u0645', '\u0645']), ('\ufd80',
-        &['\u0644', '\u062d', '\u0645']), ('\ufd81', &['\u0644', '\u062d', '\u064a']), ('\ufd82',
-        &['\u0644', '\u062d', '\u0649']), ('\ufd83', &['\u0644', '\u062c', '\u062c']), ('\ufd84',
-        &['\u0644', '\u062c', '\u062c']), ('\ufd85', &['\u0644', '\u062e', '\u0645']), ('\ufd86',
-        &['\u0644', '\u062e', '\u0645']), ('\ufd87', &['\u0644', '\u0645', '\u062d']), ('\ufd88',
-        &['\u0644', '\u0645', '\u062d']), ('\ufd89', &['\u0645', '\u062d', '\u062c']), ('\ufd8a',
-        &['\u0645', '\u062d', '\u0645']), ('\ufd8b', &['\u0645', '\u062d', '\u064a']), ('\ufd8c',
-        &['\u0645', '\u062c', '\u062d']), ('\ufd8d', &['\u0645', '\u062c', '\u0645']), ('\ufd8e',
-        &['\u0645', '\u062e', '\u062c']), ('\ufd8f', &['\u0645', '\u062e', '\u0645']), ('\ufd92',
-        &['\u0645', '\u062c', '\u062e']), ('\ufd93', &['\u0647', '\u0645', '\u062c']), ('\ufd94',
-        &['\u0647', '\u0645', '\u0645']), ('\ufd95', &['\u0646', '\u062d', '\u0645']), ('\ufd96',
-        &['\u0646', '\u062d', '\u0649']), ('\ufd97', &['\u0646', '\u062c', '\u0645']), ('\ufd98',
-        &['\u0646', '\u062c', '\u0645']), ('\ufd99', &['\u0646', '\u062c', '\u0649']), ('\ufd9a',
-        &['\u0646', '\u0645', '\u064a']), ('\ufd9b', &['\u0646', '\u0645', '\u0649']), ('\ufd9c',
-        &['\u064a', '\u0645', '\u0645']), ('\ufd9d', &['\u064a', '\u0645', '\u0645']), ('\ufd9e',
-        &['\u0628', '\u062e', '\u064a']), ('\ufd9f', &['\u062a', '\u062c', '\u064a']), ('\ufda0',
-        &['\u062a', '\u062c', '\u0649']), ('\ufda1', &['\u062a', '\u062e', '\u064a']), ('\ufda2',
-        &['\u062a', '\u062e', '\u0649']), ('\ufda3', &['\u062a', '\u0645', '\u064a']), ('\ufda4',
-        &['\u062a', '\u0645', '\u0649']), ('\ufda5', &['\u062c', '\u0645', '\u064a']), ('\ufda6',
-        &['\u062c', '\u062d', '\u0649']), ('\ufda7', &['\u062c', '\u0645', '\u0649']), ('\ufda8',
-        &['\u0633', '\u062e', '\u0649']), ('\ufda9', &['\u0635', '\u062d', '\u064a']), ('\ufdaa',
-        &['\u0634', '\u062d', '\u064a']), ('\ufdab', &['\u0636', '\u062d', '\u064a']), ('\ufdac',
-        &['\u0644', '\u062c', '\u064a']), ('\ufdad', &['\u0644', '\u0645', '\u064a']), ('\ufdae',
-        &['\u064a', '\u062d', '\u064a']), ('\ufdaf', &['\u064a', '\u062c', '\u064a']), ('\ufdb0',
-        &['\u064a', '\u0645', '\u064a']), ('\ufdb1', &['\u0645', '\u0645', '\u064a']), ('\ufdb2',
-        &['\u0642', '\u0645', '\u064a']), ('\ufdb3', &['\u0646', '\u062d', '\u064a']), ('\ufdb4',
-        &['\u0642', '\u0645', '\u062d']), ('\ufdb5', &['\u0644', '\u062d', '\u0645']), ('\ufdb6',
-        &['\u0639', '\u0645', '\u064a']), ('\ufdb7', &['\u0643', '\u0645', '\u064a']), ('\ufdb8',
-        &['\u0646', '\u062c', '\u062d']), ('\ufdb9', &['\u0645', '\u062e', '\u064a']), ('\ufdba',
-        &['\u0644', '\u062c', '\u0645']), ('\ufdbb', &['\u0643', '\u0645', '\u0645']), ('\ufdbc',
-        &['\u0644', '\u062c', '\u0645']), ('\ufdbd', &['\u0646', '\u062c', '\u062d']), ('\ufdbe',
-        &['\u062c', '\u062d', '\u064a']), ('\ufdbf', &['\u062d', '\u062c', '\u064a']), ('\ufdc0',
-        &['\u0645', '\u062c', '\u064a']), ('\ufdc1', &['\u0641', '\u0645', '\u064a']), ('\ufdc2',
-        &['\u0628', '\u062d', '\u064a']), ('\ufdc3', &['\u0643', '\u0645', '\u0645']), ('\ufdc4',
-        &['\u0639', '\u062c', '\u0645']), ('\ufdc5', &['\u0635', '\u0645', '\u0645']), ('\ufdc6',
-        &['\u0633', '\u062e', '\u064a']), ('\ufdc7', &['\u0646', '\u062c', '\u064a']), ('\ufdf0',
-        &['\u0635', '\u0644', '\u06d2']), ('\ufdf1', &['\u0642', '\u0644', '\u06d2']), ('\ufdf2',
-        &['\u0627', '\u0644', '\u0644', '\u0647']), ('\ufdf3', &['\u0627', '\u0643', '\u0628',
-        '\u0631']), ('\ufdf4', &['\u0645', '\u062d', '\u0645', '\u062f']), ('\ufdf5', &['\u0635',
-        '\u0644', '\u0639', '\u0645']), ('\ufdf6', &['\u0631', '\u0633', '\u0648', '\u0644']),
-        ('\ufdf7', &['\u0639', '\u0644', '\u064a', '\u0647']), ('\ufdf8', &['\u0648', '\u0633',
-        '\u0644', '\u0645']), ('\ufdf9', &['\u0635', '\u0644', '\u0649']), ('\ufdfa', &['\u0635',
-        '\u0644', '\u0649', '\x20', '\u0627', '\u0644', '\u0644', '\u0647', '\x20', '\u0639',
-        '\u0644', '\u064a', '\u0647', '\x20', '\u0648', '\u0633', '\u0644', '\u0645']), ('\ufdfb',
-        &['\u062c', '\u0644', '\x20', '\u062c', '\u0644', '\u0627', '\u0644', '\u0647']), ('\ufdfc',
-        &['\u0631', '\u06cc', '\u0627', '\u0644']), ('\ufe10', &['\x2c']), ('\ufe11', &['\u3001']),
-        ('\ufe12', &['\u3002']), ('\ufe13', &['\x3a']), ('\ufe14', &['\x3b']), ('\ufe15',
-        &['\x21']), ('\ufe16', &['\x3f']), ('\ufe17', &['\u3016']), ('\ufe18', &['\u3017']),
-        ('\ufe19', &['\u2026']), ('\ufe30', &['\u2025']), ('\ufe31', &['\u2014']), ('\ufe32',
-        &['\u2013']), ('\ufe33', &['\x5f']), ('\ufe34', &['\x5f']), ('\ufe35', &['\x28']),
-        ('\ufe36', &['\x29']), ('\ufe37', &['\x7b']), ('\ufe38', &['\x7d']), ('\ufe39',
-        &['\u3014']), ('\ufe3a', &['\u3015']), ('\ufe3b', &['\u3010']), ('\ufe3c', &['\u3011']),
-        ('\ufe3d', &['\u300a']), ('\ufe3e', &['\u300b']), ('\ufe3f', &['\u3008']), ('\ufe40',
-        &['\u3009']), ('\ufe41', &['\u300c']), ('\ufe42', &['\u300d']), ('\ufe43', &['\u300e']),
-        ('\ufe44', &['\u300f']), ('\ufe47', &['\x5b']), ('\ufe48', &['\x5d']), ('\ufe49',
-        &['\u203e']), ('\ufe4a', &['\u203e']), ('\ufe4b', &['\u203e']), ('\ufe4c', &['\u203e']),
-        ('\ufe4d', &['\x5f']), ('\ufe4e', &['\x5f']), ('\ufe4f', &['\x5f']), ('\ufe50', &['\x2c']),
-        ('\ufe51', &['\u3001']), ('\ufe52', &['\x2e']), ('\ufe54', &['\x3b']), ('\ufe55',
-        &['\x3a']), ('\ufe56', &['\x3f']), ('\ufe57', &['\x21']), ('\ufe58', &['\u2014']),
-        ('\ufe59', &['\x28']), ('\ufe5a', &['\x29']), ('\ufe5b', &['\x7b']), ('\ufe5c', &['\x7d']),
-        ('\ufe5d', &['\u3014']), ('\ufe5e', &['\u3015']), ('\ufe5f', &['\x23']), ('\ufe60',
-        &['\x26']), ('\ufe61', &['\x2a']), ('\ufe62', &['\x2b']), ('\ufe63', &['\x2d']), ('\ufe64',
-        &['\x3c']), ('\ufe65', &['\x3e']), ('\ufe66', &['\x3d']), ('\ufe68', &['\x5c']), ('\ufe69',
-        &['\x24']), ('\ufe6a', &['\x25']), ('\ufe6b', &['\x40']), ('\ufe70', &['\x20', '\u064b']),
-        ('\ufe71', &['\u0640', '\u064b']), ('\ufe72', &['\x20', '\u064c']), ('\ufe74', &['\x20',
-        '\u064d']), ('\ufe76', &['\x20', '\u064e']), ('\ufe77', &['\u0640', '\u064e']), ('\ufe78',
-        &['\x20', '\u064f']), ('\ufe79', &['\u0640', '\u064f']), ('\ufe7a', &['\x20', '\u0650']),
-        ('\ufe7b', &['\u0640', '\u0650']), ('\ufe7c', &['\x20', '\u0651']), ('\ufe7d', &['\u0640',
-        '\u0651']), ('\ufe7e', &['\x20', '\u0652']), ('\ufe7f', &['\u0640', '\u0652']), ('\ufe80',
-        &['\u0621']), ('\ufe81', &['\u0622']), ('\ufe82', &['\u0622']), ('\ufe83', &['\u0623']),
-        ('\ufe84', &['\u0623']), ('\ufe85', &['\u0624']), ('\ufe86', &['\u0624']), ('\ufe87',
-        &['\u0625']), ('\ufe88', &['\u0625']), ('\ufe89', &['\u0626']), ('\ufe8a', &['\u0626']),
-        ('\ufe8b', &['\u0626']), ('\ufe8c', &['\u0626']), ('\ufe8d', &['\u0627']), ('\ufe8e',
-        &['\u0627']), ('\ufe8f', &['\u0628']), ('\ufe90', &['\u0628']), ('\ufe91', &['\u0628']),
-        ('\ufe92', &['\u0628']), ('\ufe93', &['\u0629']), ('\ufe94', &['\u0629']), ('\ufe95',
-        &['\u062a']), ('\ufe96', &['\u062a']), ('\ufe97', &['\u062a']), ('\ufe98', &['\u062a']),
-        ('\ufe99', &['\u062b']), ('\ufe9a', &['\u062b']), ('\ufe9b', &['\u062b']), ('\ufe9c',
-        &['\u062b']), ('\ufe9d', &['\u062c']), ('\ufe9e', &['\u062c']), ('\ufe9f', &['\u062c']),
-        ('\ufea0', &['\u062c']), ('\ufea1', &['\u062d']), ('\ufea2', &['\u062d']), ('\ufea3',
-        &['\u062d']), ('\ufea4', &['\u062d']), ('\ufea5', &['\u062e']), ('\ufea6', &['\u062e']),
-        ('\ufea7', &['\u062e']), ('\ufea8', &['\u062e']), ('\ufea9', &['\u062f']), ('\ufeaa',
-        &['\u062f']), ('\ufeab', &['\u0630']), ('\ufeac', &['\u0630']), ('\ufead', &['\u0631']),
-        ('\ufeae', &['\u0631']), ('\ufeaf', &['\u0632']), ('\ufeb0', &['\u0632']), ('\ufeb1',
-        &['\u0633']), ('\ufeb2', &['\u0633']), ('\ufeb3', &['\u0633']), ('\ufeb4', &['\u0633']),
-        ('\ufeb5', &['\u0634']), ('\ufeb6', &['\u0634']), ('\ufeb7', &['\u0634']), ('\ufeb8',
-        &['\u0634']), ('\ufeb9', &['\u0635']), ('\ufeba', &['\u0635']), ('\ufebb', &['\u0635']),
-        ('\ufebc', &['\u0635']), ('\ufebd', &['\u0636']), ('\ufebe', &['\u0636']), ('\ufebf',
-        &['\u0636']), ('\ufec0', &['\u0636']), ('\ufec1', &['\u0637']), ('\ufec2', &['\u0637']),
-        ('\ufec3', &['\u0637']), ('\ufec4', &['\u0637']), ('\ufec5', &['\u0638']), ('\ufec6',
-        &['\u0638']), ('\ufec7', &['\u0638']), ('\ufec8', &['\u0638']), ('\ufec9', &['\u0639']),
-        ('\ufeca', &['\u0639']), ('\ufecb', &['\u0639']), ('\ufecc', &['\u0639']), ('\ufecd',
-        &['\u063a']), ('\ufece', &['\u063a']), ('\ufecf', &['\u063a']), ('\ufed0', &['\u063a']),
-        ('\ufed1', &['\u0641']), ('\ufed2', &['\u0641']), ('\ufed3', &['\u0641']), ('\ufed4',
-        &['\u0641']), ('\ufed5', &['\u0642']), ('\ufed6', &['\u0642']), ('\ufed7', &['\u0642']),
-        ('\ufed8', &['\u0642']), ('\ufed9', &['\u0643']), ('\ufeda', &['\u0643']), ('\ufedb',
-        &['\u0643']), ('\ufedc', &['\u0643']), ('\ufedd', &['\u0644']), ('\ufede', &['\u0644']),
-        ('\ufedf', &['\u0644']), ('\ufee0', &['\u0644']), ('\ufee1', &['\u0645']), ('\ufee2',
-        &['\u0645']), ('\ufee3', &['\u0645']), ('\ufee4', &['\u0645']), ('\ufee5', &['\u0646']),
-        ('\ufee6', &['\u0646']), ('\ufee7', &['\u0646']), ('\ufee8', &['\u0646']), ('\ufee9',
-        &['\u0647']), ('\ufeea', &['\u0647']), ('\ufeeb', &['\u0647']), ('\ufeec', &['\u0647']),
-        ('\ufeed', &['\u0648']), ('\ufeee', &['\u0648']), ('\ufeef', &['\u0649']), ('\ufef0',
-        &['\u0649']), ('\ufef1', &['\u064a']), ('\ufef2', &['\u064a']), ('\ufef3', &['\u064a']),
-        ('\ufef4', &['\u064a']), ('\ufef5', &['\u0644', '\u0622']), ('\ufef6', &['\u0644',
-        '\u0622']), ('\ufef7', &['\u0644', '\u0623']), ('\ufef8', &['\u0644', '\u0623']), ('\ufef9',
-        &['\u0644', '\u0625']), ('\ufefa', &['\u0644', '\u0625']), ('\ufefb', &['\u0644',
-        '\u0627']), ('\ufefc', &['\u0644', '\u0627']), ('\uff01', &['\x21']), ('\uff02', &['\x22']),
-        ('\uff03', &['\x23']), ('\uff04', &['\x24']), ('\uff05', &['\x25']), ('\uff06', &['\x26']),
-        ('\uff07', &['\x27']), ('\uff08', &['\x28']), ('\uff09', &['\x29']), ('\uff0a', &['\x2a']),
-        ('\uff0b', &['\x2b']), ('\uff0c', &['\x2c']), ('\uff0d', &['\x2d']), ('\uff0e', &['\x2e']),
-        ('\uff0f', &['\x2f']), ('\uff10', &['\x30']), ('\uff11', &['\x31']), ('\uff12', &['\x32']),
-        ('\uff13', &['\x33']), ('\uff14', &['\x34']), ('\uff15', &['\x35']), ('\uff16', &['\x36']),
-        ('\uff17', &['\x37']), ('\uff18', &['\x38']), ('\uff19', &['\x39']), ('\uff1a', &['\x3a']),
-        ('\uff1b', &['\x3b']), ('\uff1c', &['\x3c']), ('\uff1d', &['\x3d']), ('\uff1e', &['\x3e']),
-        ('\uff1f', &['\x3f']), ('\uff20', &['\x40']), ('\uff21', &['\x41']), ('\uff22', &['\x42']),
-        ('\uff23', &['\x43']), ('\uff24', &['\x44']), ('\uff25', &['\x45']), ('\uff26', &['\x46']),
-        ('\uff27', &['\x47']), ('\uff28', &['\x48']), ('\uff29', &['\x49']), ('\uff2a', &['\x4a']),
-        ('\uff2b', &['\x4b']), ('\uff2c', &['\x4c']), ('\uff2d', &['\x4d']), ('\uff2e', &['\x4e']),
-        ('\uff2f', &['\x4f']), ('\uff30', &['\x50']), ('\uff31', &['\x51']), ('\uff32', &['\x52']),
-        ('\uff33', &['\x53']), ('\uff34', &['\x54']), ('\uff35', &['\x55']), ('\uff36', &['\x56']),
-        ('\uff37', &['\x57']), ('\uff38', &['\x58']), ('\uff39', &['\x59']), ('\uff3a', &['\x5a']),
-        ('\uff3b', &['\x5b']), ('\uff3c', &['\x5c']), ('\uff3d', &['\x5d']), ('\uff3e', &['\x5e']),
-        ('\uff3f', &['\x5f']), ('\uff40', &['\x60']), ('\uff41', &['\x61']), ('\uff42', &['\x62']),
-        ('\uff43', &['\x63']), ('\uff44', &['\x64']), ('\uff45', &['\x65']), ('\uff46', &['\x66']),
-        ('\uff47', &['\x67']), ('\uff48', &['\x68']), ('\uff49', &['\x69']), ('\uff4a', &['\x6a']),
-        ('\uff4b', &['\x6b']), ('\uff4c', &['\x6c']), ('\uff4d', &['\x6d']), ('\uff4e', &['\x6e']),
-        ('\uff4f', &['\x6f']), ('\uff50', &['\x70']), ('\uff51', &['\x71']), ('\uff52', &['\x72']),
-        ('\uff53', &['\x73']), ('\uff54', &['\x74']), ('\uff55', &['\x75']), ('\uff56', &['\x76']),
-        ('\uff57', &['\x77']), ('\uff58', &['\x78']), ('\uff59', &['\x79']), ('\uff5a', &['\x7a']),
-        ('\uff5b', &['\x7b']), ('\uff5c', &['\x7c']), ('\uff5d', &['\x7d']), ('\uff5e', &['\x7e']),
-        ('\uff5f', &['\u2985']), ('\uff60', &['\u2986']), ('\uff61', &['\u3002']), ('\uff62',
-        &['\u300c']), ('\uff63', &['\u300d']), ('\uff64', &['\u3001']), ('\uff65', &['\u30fb']),
-        ('\uff66', &['\u30f2']), ('\uff67', &['\u30a1']), ('\uff68', &['\u30a3']), ('\uff69',
-        &['\u30a5']), ('\uff6a', &['\u30a7']), ('\uff6b', &['\u30a9']), ('\uff6c', &['\u30e3']),
-        ('\uff6d', &['\u30e5']), ('\uff6e', &['\u30e7']), ('\uff6f', &['\u30c3']), ('\uff70',
-        &['\u30fc']), ('\uff71', &['\u30a2']), ('\uff72', &['\u30a4']), ('\uff73', &['\u30a6']),
-        ('\uff74', &['\u30a8']), ('\uff75', &['\u30aa']), ('\uff76', &['\u30ab']), ('\uff77',
-        &['\u30ad']), ('\uff78', &['\u30af']), ('\uff79', &['\u30b1']), ('\uff7a', &['\u30b3']),
-        ('\uff7b', &['\u30b5']), ('\uff7c', &['\u30b7']), ('\uff7d', &['\u30b9']), ('\uff7e',
-        &['\u30bb']), ('\uff7f', &['\u30bd']), ('\uff80', &['\u30bf']), ('\uff81', &['\u30c1']),
-        ('\uff82', &['\u30c4']), ('\uff83', &['\u30c6']), ('\uff84', &['\u30c8']), ('\uff85',
-        &['\u30ca']), ('\uff86', &['\u30cb']), ('\uff87', &['\u30cc']), ('\uff88', &['\u30cd']),
-        ('\uff89', &['\u30ce']), ('\uff8a', &['\u30cf']), ('\uff8b', &['\u30d2']), ('\uff8c',
-        &['\u30d5']), ('\uff8d', &['\u30d8']), ('\uff8e', &['\u30db']), ('\uff8f', &['\u30de']),
-        ('\uff90', &['\u30df']), ('\uff91', &['\u30e0']), ('\uff92', &['\u30e1']), ('\uff93',
-        &['\u30e2']), ('\uff94', &['\u30e4']), ('\uff95', &['\u30e6']), ('\uff96', &['\u30e8']),
-        ('\uff97', &['\u30e9']), ('\uff98', &['\u30ea']), ('\uff99', &['\u30eb']), ('\uff9a',
-        &['\u30ec']), ('\uff9b', &['\u30ed']), ('\uff9c', &['\u30ef']), ('\uff9d', &['\u30f3']),
-        ('\uff9e', &['\u3099']), ('\uff9f', &['\u309a']), ('\uffa0', &['\u3164']), ('\uffa1',
-        &['\u3131']), ('\uffa2', &['\u3132']), ('\uffa3', &['\u3133']), ('\uffa4', &['\u3134']),
-        ('\uffa5', &['\u3135']), ('\uffa6', &['\u3136']), ('\uffa7', &['\u3137']), ('\uffa8',
-        &['\u3138']), ('\uffa9', &['\u3139']), ('\uffaa', &['\u313a']), ('\uffab', &['\u313b']),
-        ('\uffac', &['\u313c']), ('\uffad', &['\u313d']), ('\uffae', &['\u313e']), ('\uffaf',
-        &['\u313f']), ('\uffb0', &['\u3140']), ('\uffb1', &['\u3141']), ('\uffb2', &['\u3142']),
-        ('\uffb3', &['\u3143']), ('\uffb4', &['\u3144']), ('\uffb5', &['\u3145']), ('\uffb6',
-        &['\u3146']), ('\uffb7', &['\u3147']), ('\uffb8', &['\u3148']), ('\uffb9', &['\u3149']),
-        ('\uffba', &['\u314a']), ('\uffbb', &['\u314b']), ('\uffbc', &['\u314c']), ('\uffbd',
-        &['\u314d']), ('\uffbe', &['\u314e']), ('\uffc2', &['\u314f']), ('\uffc3', &['\u3150']),
-        ('\uffc4', &['\u3151']), ('\uffc5', &['\u3152']), ('\uffc6', &['\u3153']), ('\uffc7',
-        &['\u3154']), ('\uffca', &['\u3155']), ('\uffcb', &['\u3156']), ('\uffcc', &['\u3157']),
-        ('\uffcd', &['\u3158']), ('\uffce', &['\u3159']), ('\uffcf', &['\u315a']), ('\uffd2',
-        &['\u315b']), ('\uffd3', &['\u315c']), ('\uffd4', &['\u315d']), ('\uffd5', &['\u315e']),
-        ('\uffd6', &['\u315f']), ('\uffd7', &['\u3160']), ('\uffda', &['\u3161']), ('\uffdb',
-        &['\u3162']), ('\uffdc', &['\u3163']), ('\uffe0', &['\xa2']), ('\uffe1', &['\xa3']),
-        ('\uffe2', &['\xac']), ('\uffe3', &['\xaf']), ('\uffe4', &['\xa6']), ('\uffe5', &['\xa5']),
-        ('\uffe6', &['\u20a9']), ('\uffe8', &['\u2502']), ('\uffe9', &['\u2190']), ('\uffea',
-        &['\u2191']), ('\uffeb', &['\u2192']), ('\uffec', &['\u2193']), ('\uffed', &['\u25a0']),
-        ('\uffee', &['\u25cb']), ('\U0001d400', &['\x41']), ('\U0001d401', &['\x42']),
-        ('\U0001d402', &['\x43']), ('\U0001d403', &['\x44']), ('\U0001d404', &['\x45']),
-        ('\U0001d405', &['\x46']), ('\U0001d406', &['\x47']), ('\U0001d407', &['\x48']),
-        ('\U0001d408', &['\x49']), ('\U0001d409', &['\x4a']), ('\U0001d40a', &['\x4b']),
-        ('\U0001d40b', &['\x4c']), ('\U0001d40c', &['\x4d']), ('\U0001d40d', &['\x4e']),
-        ('\U0001d40e', &['\x4f']), ('\U0001d40f', &['\x50']), ('\U0001d410', &['\x51']),
-        ('\U0001d411', &['\x52']), ('\U0001d412', &['\x53']), ('\U0001d413', &['\x54']),
-        ('\U0001d414', &['\x55']), ('\U0001d415', &['\x56']), ('\U0001d416', &['\x57']),
-        ('\U0001d417', &['\x58']), ('\U0001d418', &['\x59']), ('\U0001d419', &['\x5a']),
-        ('\U0001d41a', &['\x61']), ('\U0001d41b', &['\x62']), ('\U0001d41c', &['\x63']),
-        ('\U0001d41d', &['\x64']), ('\U0001d41e', &['\x65']), ('\U0001d41f', &['\x66']),
-        ('\U0001d420', &['\x67']), ('\U0001d421', &['\x68']), ('\U0001d422', &['\x69']),
-        ('\U0001d423', &['\x6a']), ('\U0001d424', &['\x6b']), ('\U0001d425', &['\x6c']),
-        ('\U0001d426', &['\x6d']), ('\U0001d427', &['\x6e']), ('\U0001d428', &['\x6f']),
-        ('\U0001d429', &['\x70']), ('\U0001d42a', &['\x71']), ('\U0001d42b', &['\x72']),
-        ('\U0001d42c', &['\x73']), ('\U0001d42d', &['\x74']), ('\U0001d42e', &['\x75']),
-        ('\U0001d42f', &['\x76']), ('\U0001d430', &['\x77']), ('\U0001d431', &['\x78']),
-        ('\U0001d432', &['\x79']), ('\U0001d433', &['\x7a']), ('\U0001d434', &['\x41']),
-        ('\U0001d435', &['\x42']), ('\U0001d436', &['\x43']), ('\U0001d437', &['\x44']),
-        ('\U0001d438', &['\x45']), ('\U0001d439', &['\x46']), ('\U0001d43a', &['\x47']),
-        ('\U0001d43b', &['\x48']), ('\U0001d43c', &['\x49']), ('\U0001d43d', &['\x4a']),
-        ('\U0001d43e', &['\x4b']), ('\U0001d43f', &['\x4c']), ('\U0001d440', &['\x4d']),
-        ('\U0001d441', &['\x4e']), ('\U0001d442', &['\x4f']), ('\U0001d443', &['\x50']),
-        ('\U0001d444', &['\x51']), ('\U0001d445', &['\x52']), ('\U0001d446', &['\x53']),
-        ('\U0001d447', &['\x54']), ('\U0001d448', &['\x55']), ('\U0001d449', &['\x56']),
-        ('\U0001d44a', &['\x57']), ('\U0001d44b', &['\x58']), ('\U0001d44c', &['\x59']),
-        ('\U0001d44d', &['\x5a']), ('\U0001d44e', &['\x61']), ('\U0001d44f', &['\x62']),
-        ('\U0001d450', &['\x63']), ('\U0001d451', &['\x64']), ('\U0001d452', &['\x65']),
-        ('\U0001d453', &['\x66']), ('\U0001d454', &['\x67']), ('\U0001d456', &['\x69']),
-        ('\U0001d457', &['\x6a']), ('\U0001d458', &['\x6b']), ('\U0001d459', &['\x6c']),
-        ('\U0001d45a', &['\x6d']), ('\U0001d45b', &['\x6e']), ('\U0001d45c', &['\x6f']),
-        ('\U0001d45d', &['\x70']), ('\U0001d45e', &['\x71']), ('\U0001d45f', &['\x72']),
-        ('\U0001d460', &['\x73']), ('\U0001d461', &['\x74']), ('\U0001d462', &['\x75']),
-        ('\U0001d463', &['\x76']), ('\U0001d464', &['\x77']), ('\U0001d465', &['\x78']),
-        ('\U0001d466', &['\x79']), ('\U0001d467', &['\x7a']), ('\U0001d468', &['\x41']),
-        ('\U0001d469', &['\x42']), ('\U0001d46a', &['\x43']), ('\U0001d46b', &['\x44']),
-        ('\U0001d46c', &['\x45']), ('\U0001d46d', &['\x46']), ('\U0001d46e', &['\x47']),
-        ('\U0001d46f', &['\x48']), ('\U0001d470', &['\x49']), ('\U0001d471', &['\x4a']),
-        ('\U0001d472', &['\x4b']), ('\U0001d473', &['\x4c']), ('\U0001d474', &['\x4d']),
-        ('\U0001d475', &['\x4e']), ('\U0001d476', &['\x4f']), ('\U0001d477', &['\x50']),
-        ('\U0001d478', &['\x51']), ('\U0001d479', &['\x52']), ('\U0001d47a', &['\x53']),
-        ('\U0001d47b', &['\x54']), ('\U0001d47c', &['\x55']), ('\U0001d47d', &['\x56']),
-        ('\U0001d47e', &['\x57']), ('\U0001d47f', &['\x58']), ('\U0001d480', &['\x59']),
-        ('\U0001d481', &['\x5a']), ('\U0001d482', &['\x61']), ('\U0001d483', &['\x62']),
-        ('\U0001d484', &['\x63']), ('\U0001d485', &['\x64']), ('\U0001d486', &['\x65']),
-        ('\U0001d487', &['\x66']), ('\U0001d488', &['\x67']), ('\U0001d489', &['\x68']),
-        ('\U0001d48a', &['\x69']), ('\U0001d48b', &['\x6a']), ('\U0001d48c', &['\x6b']),
-        ('\U0001d48d', &['\x6c']), ('\U0001d48e', &['\x6d']), ('\U0001d48f', &['\x6e']),
-        ('\U0001d490', &['\x6f']), ('\U0001d491', &['\x70']), ('\U0001d492', &['\x71']),
-        ('\U0001d493', &['\x72']), ('\U0001d494', &['\x73']), ('\U0001d495', &['\x74']),
-        ('\U0001d496', &['\x75']), ('\U0001d497', &['\x76']), ('\U0001d498', &['\x77']),
-        ('\U0001d499', &['\x78']), ('\U0001d49a', &['\x79']), ('\U0001d49b', &['\x7a']),
-        ('\U0001d49c', &['\x41']), ('\U0001d49e', &['\x43']), ('\U0001d49f', &['\x44']),
-        ('\U0001d4a2', &['\x47']), ('\U0001d4a5', &['\x4a']), ('\U0001d4a6', &['\x4b']),
-        ('\U0001d4a9', &['\x4e']), ('\U0001d4aa', &['\x4f']), ('\U0001d4ab', &['\x50']),
-        ('\U0001d4ac', &['\x51']), ('\U0001d4ae', &['\x53']), ('\U0001d4af', &['\x54']),
-        ('\U0001d4b0', &['\x55']), ('\U0001d4b1', &['\x56']), ('\U0001d4b2', &['\x57']),
-        ('\U0001d4b3', &['\x58']), ('\U0001d4b4', &['\x59']), ('\U0001d4b5', &['\x5a']),
-        ('\U0001d4b6', &['\x61']), ('\U0001d4b7', &['\x62']), ('\U0001d4b8', &['\x63']),
-        ('\U0001d4b9', &['\x64']), ('\U0001d4bb', &['\x66']), ('\U0001d4bd', &['\x68']),
-        ('\U0001d4be', &['\x69']), ('\U0001d4bf', &['\x6a']), ('\U0001d4c0', &['\x6b']),
-        ('\U0001d4c1', &['\x6c']), ('\U0001d4c2', &['\x6d']), ('\U0001d4c3', &['\x6e']),
-        ('\U0001d4c5', &['\x70']), ('\U0001d4c6', &['\x71']), ('\U0001d4c7', &['\x72']),
-        ('\U0001d4c8', &['\x73']), ('\U0001d4c9', &['\x74']), ('\U0001d4ca', &['\x75']),
-        ('\U0001d4cb', &['\x76']), ('\U0001d4cc', &['\x77']), ('\U0001d4cd', &['\x78']),
-        ('\U0001d4ce', &['\x79']), ('\U0001d4cf', &['\x7a']), ('\U0001d4d0', &['\x41']),
-        ('\U0001d4d1', &['\x42']), ('\U0001d4d2', &['\x43']), ('\U0001d4d3', &['\x44']),
-        ('\U0001d4d4', &['\x45']), ('\U0001d4d5', &['\x46']), ('\U0001d4d6', &['\x47']),
-        ('\U0001d4d7', &['\x48']), ('\U0001d4d8', &['\x49']), ('\U0001d4d9', &['\x4a']),
-        ('\U0001d4da', &['\x4b']), ('\U0001d4db', &['\x4c']), ('\U0001d4dc', &['\x4d']),
-        ('\U0001d4dd', &['\x4e']), ('\U0001d4de', &['\x4f']), ('\U0001d4df', &['\x50']),
-        ('\U0001d4e0', &['\x51']), ('\U0001d4e1', &['\x52']), ('\U0001d4e2', &['\x53']),
-        ('\U0001d4e3', &['\x54']), ('\U0001d4e4', &['\x55']), ('\U0001d4e5', &['\x56']),
-        ('\U0001d4e6', &['\x57']), ('\U0001d4e7', &['\x58']), ('\U0001d4e8', &['\x59']),
-        ('\U0001d4e9', &['\x5a']), ('\U0001d4ea', &['\x61']), ('\U0001d4eb', &['\x62']),
-        ('\U0001d4ec', &['\x63']), ('\U0001d4ed', &['\x64']), ('\U0001d4ee', &['\x65']),
-        ('\U0001d4ef', &['\x66']), ('\U0001d4f0', &['\x67']), ('\U0001d4f1', &['\x68']),
-        ('\U0001d4f2', &['\x69']), ('\U0001d4f3', &['\x6a']), ('\U0001d4f4', &['\x6b']),
-        ('\U0001d4f5', &['\x6c']), ('\U0001d4f6', &['\x6d']), ('\U0001d4f7', &['\x6e']),
-        ('\U0001d4f8', &['\x6f']), ('\U0001d4f9', &['\x70']), ('\U0001d4fa', &['\x71']),
-        ('\U0001d4fb', &['\x72']), ('\U0001d4fc', &['\x73']), ('\U0001d4fd', &['\x74']),
-        ('\U0001d4fe', &['\x75']), ('\U0001d4ff', &['\x76']), ('\U0001d500', &['\x77']),
-        ('\U0001d501', &['\x78']), ('\U0001d502', &['\x79']), ('\U0001d503', &['\x7a']),
-        ('\U0001d504', &['\x41']), ('\U0001d505', &['\x42']), ('\U0001d507', &['\x44']),
-        ('\U0001d508', &['\x45']), ('\U0001d509', &['\x46']), ('\U0001d50a', &['\x47']),
-        ('\U0001d50d', &['\x4a']), ('\U0001d50e', &['\x4b']), ('\U0001d50f', &['\x4c']),
-        ('\U0001d510', &['\x4d']), ('\U0001d511', &['\x4e']), ('\U0001d512', &['\x4f']),
-        ('\U0001d513', &['\x50']), ('\U0001d514', &['\x51']), ('\U0001d516', &['\x53']),
-        ('\U0001d517', &['\x54']), ('\U0001d518', &['\x55']), ('\U0001d519', &['\x56']),
-        ('\U0001d51a', &['\x57']), ('\U0001d51b', &['\x58']), ('\U0001d51c', &['\x59']),
-        ('\U0001d51e', &['\x61']), ('\U0001d51f', &['\x62']), ('\U0001d520', &['\x63']),
-        ('\U0001d521', &['\x64']), ('\U0001d522', &['\x65']), ('\U0001d523', &['\x66']),
-        ('\U0001d524', &['\x67']), ('\U0001d525', &['\x68']), ('\U0001d526', &['\x69']),
-        ('\U0001d527', &['\x6a']), ('\U0001d528', &['\x6b']), ('\U0001d529', &['\x6c']),
-        ('\U0001d52a', &['\x6d']), ('\U0001d52b', &['\x6e']), ('\U0001d52c', &['\x6f']),
-        ('\U0001d52d', &['\x70']), ('\U0001d52e', &['\x71']), ('\U0001d52f', &['\x72']),
-        ('\U0001d530', &['\x73']), ('\U0001d531', &['\x74']), ('\U0001d532', &['\x75']),
-        ('\U0001d533', &['\x76']), ('\U0001d534', &['\x77']), ('\U0001d535', &['\x78']),
-        ('\U0001d536', &['\x79']), ('\U0001d537', &['\x7a']), ('\U0001d538', &['\x41']),
-        ('\U0001d539', &['\x42']), ('\U0001d53b', &['\x44']), ('\U0001d53c', &['\x45']),
-        ('\U0001d53d', &['\x46']), ('\U0001d53e', &['\x47']), ('\U0001d540', &['\x49']),
-        ('\U0001d541', &['\x4a']), ('\U0001d542', &['\x4b']), ('\U0001d543', &['\x4c']),
-        ('\U0001d544', &['\x4d']), ('\U0001d546', &['\x4f']), ('\U0001d54a', &['\x53']),
-        ('\U0001d54b', &['\x54']), ('\U0001d54c', &['\x55']), ('\U0001d54d', &['\x56']),
-        ('\U0001d54e', &['\x57']), ('\U0001d54f', &['\x58']), ('\U0001d550', &['\x59']),
-        ('\U0001d552', &['\x61']), ('\U0001d553', &['\x62']), ('\U0001d554', &['\x63']),
-        ('\U0001d555', &['\x64']), ('\U0001d556', &['\x65']), ('\U0001d557', &['\x66']),
-        ('\U0001d558', &['\x67']), ('\U0001d559', &['\x68']), ('\U0001d55a', &['\x69']),
-        ('\U0001d55b', &['\x6a']), ('\U0001d55c', &['\x6b']), ('\U0001d55d', &['\x6c']),
-        ('\U0001d55e', &['\x6d']), ('\U0001d55f', &['\x6e']), ('\U0001d560', &['\x6f']),
-        ('\U0001d561', &['\x70']), ('\U0001d562', &['\x71']), ('\U0001d563', &['\x72']),
-        ('\U0001d564', &['\x73']), ('\U0001d565', &['\x74']), ('\U0001d566', &['\x75']),
-        ('\U0001d567', &['\x76']), ('\U0001d568', &['\x77']), ('\U0001d569', &['\x78']),
-        ('\U0001d56a', &['\x79']), ('\U0001d56b', &['\x7a']), ('\U0001d56c', &['\x41']),
-        ('\U0001d56d', &['\x42']), ('\U0001d56e', &['\x43']), ('\U0001d56f', &['\x44']),
-        ('\U0001d570', &['\x45']), ('\U0001d571', &['\x46']), ('\U0001d572', &['\x47']),
-        ('\U0001d573', &['\x48']), ('\U0001d574', &['\x49']), ('\U0001d575', &['\x4a']),
-        ('\U0001d576', &['\x4b']), ('\U0001d577', &['\x4c']), ('\U0001d578', &['\x4d']),
-        ('\U0001d579', &['\x4e']), ('\U0001d57a', &['\x4f']), ('\U0001d57b', &['\x50']),
-        ('\U0001d57c', &['\x51']), ('\U0001d57d', &['\x52']), ('\U0001d57e', &['\x53']),
-        ('\U0001d57f', &['\x54']), ('\U0001d580', &['\x55']), ('\U0001d581', &['\x56']),
-        ('\U0001d582', &['\x57']), ('\U0001d583', &['\x58']), ('\U0001d584', &['\x59']),
-        ('\U0001d585', &['\x5a']), ('\U0001d586', &['\x61']), ('\U0001d587', &['\x62']),
-        ('\U0001d588', &['\x63']), ('\U0001d589', &['\x64']), ('\U0001d58a', &['\x65']),
-        ('\U0001d58b', &['\x66']), ('\U0001d58c', &['\x67']), ('\U0001d58d', &['\x68']),
-        ('\U0001d58e', &['\x69']), ('\U0001d58f', &['\x6a']), ('\U0001d590', &['\x6b']),
-        ('\U0001d591', &['\x6c']), ('\U0001d592', &['\x6d']), ('\U0001d593', &['\x6e']),
-        ('\U0001d594', &['\x6f']), ('\U0001d595', &['\x70']), ('\U0001d596', &['\x71']),
-        ('\U0001d597', &['\x72']), ('\U0001d598', &['\x73']), ('\U0001d599', &['\x74']),
-        ('\U0001d59a', &['\x75']), ('\U0001d59b', &['\x76']), ('\U0001d59c', &['\x77']),
-        ('\U0001d59d', &['\x78']), ('\U0001d59e', &['\x79']), ('\U0001d59f', &['\x7a']),
-        ('\U0001d5a0', &['\x41']), ('\U0001d5a1', &['\x42']), ('\U0001d5a2', &['\x43']),
-        ('\U0001d5a3', &['\x44']), ('\U0001d5a4', &['\x45']), ('\U0001d5a5', &['\x46']),
-        ('\U0001d5a6', &['\x47']), ('\U0001d5a7', &['\x48']), ('\U0001d5a8', &['\x49']),
-        ('\U0001d5a9', &['\x4a']), ('\U0001d5aa', &['\x4b']), ('\U0001d5ab', &['\x4c']),
-        ('\U0001d5ac', &['\x4d']), ('\U0001d5ad', &['\x4e']), ('\U0001d5ae', &['\x4f']),
-        ('\U0001d5af', &['\x50']), ('\U0001d5b0', &['\x51']), ('\U0001d5b1', &['\x52']),
-        ('\U0001d5b2', &['\x53']), ('\U0001d5b3', &['\x54']), ('\U0001d5b4', &['\x55']),
-        ('\U0001d5b5', &['\x56']), ('\U0001d5b6', &['\x57']), ('\U0001d5b7', &['\x58']),
-        ('\U0001d5b8', &['\x59']), ('\U0001d5b9', &['\x5a']), ('\U0001d5ba', &['\x61']),
-        ('\U0001d5bb', &['\x62']), ('\U0001d5bc', &['\x63']), ('\U0001d5bd', &['\x64']),
-        ('\U0001d5be', &['\x65']), ('\U0001d5bf', &['\x66']), ('\U0001d5c0', &['\x67']),
-        ('\U0001d5c1', &['\x68']), ('\U0001d5c2', &['\x69']), ('\U0001d5c3', &['\x6a']),
-        ('\U0001d5c4', &['\x6b']), ('\U0001d5c5', &['\x6c']), ('\U0001d5c6', &['\x6d']),
-        ('\U0001d5c7', &['\x6e']), ('\U0001d5c8', &['\x6f']), ('\U0001d5c9', &['\x70']),
-        ('\U0001d5ca', &['\x71']), ('\U0001d5cb', &['\x72']), ('\U0001d5cc', &['\x73']),
-        ('\U0001d5cd', &['\x74']), ('\U0001d5ce', &['\x75']), ('\U0001d5cf', &['\x76']),
-        ('\U0001d5d0', &['\x77']), ('\U0001d5d1', &['\x78']), ('\U0001d5d2', &['\x79']),
-        ('\U0001d5d3', &['\x7a']), ('\U0001d5d4', &['\x41']), ('\U0001d5d5', &['\x42']),
-        ('\U0001d5d6', &['\x43']), ('\U0001d5d7', &['\x44']), ('\U0001d5d8', &['\x45']),
-        ('\U0001d5d9', &['\x46']), ('\U0001d5da', &['\x47']), ('\U0001d5db', &['\x48']),
-        ('\U0001d5dc', &['\x49']), ('\U0001d5dd', &['\x4a']), ('\U0001d5de', &['\x4b']),
-        ('\U0001d5df', &['\x4c']), ('\U0001d5e0', &['\x4d']), ('\U0001d5e1', &['\x4e']),
-        ('\U0001d5e2', &['\x4f']), ('\U0001d5e3', &['\x50']), ('\U0001d5e4', &['\x51']),
-        ('\U0001d5e5', &['\x52']), ('\U0001d5e6', &['\x53']), ('\U0001d5e7', &['\x54']),
-        ('\U0001d5e8', &['\x55']), ('\U0001d5e9', &['\x56']), ('\U0001d5ea', &['\x57']),
-        ('\U0001d5eb', &['\x58']), ('\U0001d5ec', &['\x59']), ('\U0001d5ed', &['\x5a']),
-        ('\U0001d5ee', &['\x61']), ('\U0001d5ef', &['\x62']), ('\U0001d5f0', &['\x63']),
-        ('\U0001d5f1', &['\x64']), ('\U0001d5f2', &['\x65']), ('\U0001d5f3', &['\x66']),
-        ('\U0001d5f4', &['\x67']), ('\U0001d5f5', &['\x68']), ('\U0001d5f6', &['\x69']),
-        ('\U0001d5f7', &['\x6a']), ('\U0001d5f8', &['\x6b']), ('\U0001d5f9', &['\x6c']),
-        ('\U0001d5fa', &['\x6d']), ('\U0001d5fb', &['\x6e']), ('\U0001d5fc', &['\x6f']),
-        ('\U0001d5fd', &['\x70']), ('\U0001d5fe', &['\x71']), ('\U0001d5ff', &['\x72']),
-        ('\U0001d600', &['\x73']), ('\U0001d601', &['\x74']), ('\U0001d602', &['\x75']),
-        ('\U0001d603', &['\x76']), ('\U0001d604', &['\x77']), ('\U0001d605', &['\x78']),
-        ('\U0001d606', &['\x79']), ('\U0001d607', &['\x7a']), ('\U0001d608', &['\x41']),
-        ('\U0001d609', &['\x42']), ('\U0001d60a', &['\x43']), ('\U0001d60b', &['\x44']),
-        ('\U0001d60c', &['\x45']), ('\U0001d60d', &['\x46']), ('\U0001d60e', &['\x47']),
-        ('\U0001d60f', &['\x48']), ('\U0001d610', &['\x49']), ('\U0001d611', &['\x4a']),
-        ('\U0001d612', &['\x4b']), ('\U0001d613', &['\x4c']), ('\U0001d614', &['\x4d']),
-        ('\U0001d615', &['\x4e']), ('\U0001d616', &['\x4f']), ('\U0001d617', &['\x50']),
-        ('\U0001d618', &['\x51']), ('\U0001d619', &['\x52']), ('\U0001d61a', &['\x53']),
-        ('\U0001d61b', &['\x54']), ('\U0001d61c', &['\x55']), ('\U0001d61d', &['\x56']),
-        ('\U0001d61e', &['\x57']), ('\U0001d61f', &['\x58']), ('\U0001d620', &['\x59']),
-        ('\U0001d621', &['\x5a']), ('\U0001d622', &['\x61']), ('\U0001d623', &['\x62']),
-        ('\U0001d624', &['\x63']), ('\U0001d625', &['\x64']), ('\U0001d626', &['\x65']),
-        ('\U0001d627', &['\x66']), ('\U0001d628', &['\x67']), ('\U0001d629', &['\x68']),
-        ('\U0001d62a', &['\x69']), ('\U0001d62b', &['\x6a']), ('\U0001d62c', &['\x6b']),
-        ('\U0001d62d', &['\x6c']), ('\U0001d62e', &['\x6d']), ('\U0001d62f', &['\x6e']),
-        ('\U0001d630', &['\x6f']), ('\U0001d631', &['\x70']), ('\U0001d632', &['\x71']),
-        ('\U0001d633', &['\x72']), ('\U0001d634', &['\x73']), ('\U0001d635', &['\x74']),
-        ('\U0001d636', &['\x75']), ('\U0001d637', &['\x76']), ('\U0001d638', &['\x77']),
-        ('\U0001d639', &['\x78']), ('\U0001d63a', &['\x79']), ('\U0001d63b', &['\x7a']),
-        ('\U0001d63c', &['\x41']), ('\U0001d63d', &['\x42']), ('\U0001d63e', &['\x43']),
-        ('\U0001d63f', &['\x44']), ('\U0001d640', &['\x45']), ('\U0001d641', &['\x46']),
-        ('\U0001d642', &['\x47']), ('\U0001d643', &['\x48']), ('\U0001d644', &['\x49']),
-        ('\U0001d645', &['\x4a']), ('\U0001d646', &['\x4b']), ('\U0001d647', &['\x4c']),
-        ('\U0001d648', &['\x4d']), ('\U0001d649', &['\x4e']), ('\U0001d64a', &['\x4f']),
-        ('\U0001d64b', &['\x50']), ('\U0001d64c', &['\x51']), ('\U0001d64d', &['\x52']),
-        ('\U0001d64e', &['\x53']), ('\U0001d64f', &['\x54']), ('\U0001d650', &['\x55']),
-        ('\U0001d651', &['\x56']), ('\U0001d652', &['\x57']), ('\U0001d653', &['\x58']),
-        ('\U0001d654', &['\x59']), ('\U0001d655', &['\x5a']), ('\U0001d656', &['\x61']),
-        ('\U0001d657', &['\x62']), ('\U0001d658', &['\x63']), ('\U0001d659', &['\x64']),
-        ('\U0001d65a', &['\x65']), ('\U0001d65b', &['\x66']), ('\U0001d65c', &['\x67']),
-        ('\U0001d65d', &['\x68']), ('\U0001d65e', &['\x69']), ('\U0001d65f', &['\x6a']),
-        ('\U0001d660', &['\x6b']), ('\U0001d661', &['\x6c']), ('\U0001d662', &['\x6d']),
-        ('\U0001d663', &['\x6e']), ('\U0001d664', &['\x6f']), ('\U0001d665', &['\x70']),
-        ('\U0001d666', &['\x71']), ('\U0001d667', &['\x72']), ('\U0001d668', &['\x73']),
-        ('\U0001d669', &['\x74']), ('\U0001d66a', &['\x75']), ('\U0001d66b', &['\x76']),
-        ('\U0001d66c', &['\x77']), ('\U0001d66d', &['\x78']), ('\U0001d66e', &['\x79']),
-        ('\U0001d66f', &['\x7a']), ('\U0001d670', &['\x41']), ('\U0001d671', &['\x42']),
-        ('\U0001d672', &['\x43']), ('\U0001d673', &['\x44']), ('\U0001d674', &['\x45']),
-        ('\U0001d675', &['\x46']), ('\U0001d676', &['\x47']), ('\U0001d677', &['\x48']),
-        ('\U0001d678', &['\x49']), ('\U0001d679', &['\x4a']), ('\U0001d67a', &['\x4b']),
-        ('\U0001d67b', &['\x4c']), ('\U0001d67c', &['\x4d']), ('\U0001d67d', &['\x4e']),
-        ('\U0001d67e', &['\x4f']), ('\U0001d67f', &['\x50']), ('\U0001d680', &['\x51']),
-        ('\U0001d681', &['\x52']), ('\U0001d682', &['\x53']), ('\U0001d683', &['\x54']),
-        ('\U0001d684', &['\x55']), ('\U0001d685', &['\x56']), ('\U0001d686', &['\x57']),
-        ('\U0001d687', &['\x58']), ('\U0001d688', &['\x59']), ('\U0001d689', &['\x5a']),
-        ('\U0001d68a', &['\x61']), ('\U0001d68b', &['\x62']), ('\U0001d68c', &['\x63']),
-        ('\U0001d68d', &['\x64']), ('\U0001d68e', &['\x65']), ('\U0001d68f', &['\x66']),
-        ('\U0001d690', &['\x67']), ('\U0001d691', &['\x68']), ('\U0001d692', &['\x69']),
-        ('\U0001d693', &['\x6a']), ('\U0001d694', &['\x6b']), ('\U0001d695', &['\x6c']),
-        ('\U0001d696', &['\x6d']), ('\U0001d697', &['\x6e']), ('\U0001d698', &['\x6f']),
-        ('\U0001d699', &['\x70']), ('\U0001d69a', &['\x71']), ('\U0001d69b', &['\x72']),
-        ('\U0001d69c', &['\x73']), ('\U0001d69d', &['\x74']), ('\U0001d69e', &['\x75']),
-        ('\U0001d69f', &['\x76']), ('\U0001d6a0', &['\x77']), ('\U0001d6a1', &['\x78']),
-        ('\U0001d6a2', &['\x79']), ('\U0001d6a3', &['\x7a']), ('\U0001d6a4', &['\u0131']),
-        ('\U0001d6a5', &['\u0237']), ('\U0001d6a8', &['\u0391']), ('\U0001d6a9', &['\u0392']),
-        ('\U0001d6aa', &['\u0393']), ('\U0001d6ab', &['\u0394']), ('\U0001d6ac', &['\u0395']),
-        ('\U0001d6ad', &['\u0396']), ('\U0001d6ae', &['\u0397']), ('\U0001d6af', &['\u0398']),
-        ('\U0001d6b0', &['\u0399']), ('\U0001d6b1', &['\u039a']), ('\U0001d6b2', &['\u039b']),
-        ('\U0001d6b3', &['\u039c']), ('\U0001d6b4', &['\u039d']), ('\U0001d6b5', &['\u039e']),
-        ('\U0001d6b6', &['\u039f']), ('\U0001d6b7', &['\u03a0']), ('\U0001d6b8', &['\u03a1']),
-        ('\U0001d6b9', &['\u03f4']), ('\U0001d6ba', &['\u03a3']), ('\U0001d6bb', &['\u03a4']),
-        ('\U0001d6bc', &['\u03a5']), ('\U0001d6bd', &['\u03a6']), ('\U0001d6be', &['\u03a7']),
-        ('\U0001d6bf', &['\u03a8']), ('\U0001d6c0', &['\u03a9']), ('\U0001d6c1', &['\u2207']),
-        ('\U0001d6c2', &['\u03b1']), ('\U0001d6c3', &['\u03b2']), ('\U0001d6c4', &['\u03b3']),
-        ('\U0001d6c5', &['\u03b4']), ('\U0001d6c6', &['\u03b5']), ('\U0001d6c7', &['\u03b6']),
-        ('\U0001d6c8', &['\u03b7']), ('\U0001d6c9', &['\u03b8']), ('\U0001d6ca', &['\u03b9']),
-        ('\U0001d6cb', &['\u03ba']), ('\U0001d6cc', &['\u03bb']), ('\U0001d6cd', &['\u03bc']),
-        ('\U0001d6ce', &['\u03bd']), ('\U0001d6cf', &['\u03be']), ('\U0001d6d0', &['\u03bf']),
-        ('\U0001d6d1', &['\u03c0']), ('\U0001d6d2', &['\u03c1']), ('\U0001d6d3', &['\u03c2']),
-        ('\U0001d6d4', &['\u03c3']), ('\U0001d6d5', &['\u03c4']), ('\U0001d6d6', &['\u03c5']),
-        ('\U0001d6d7', &['\u03c6']), ('\U0001d6d8', &['\u03c7']), ('\U0001d6d9', &['\u03c8']),
-        ('\U0001d6da', &['\u03c9']), ('\U0001d6db', &['\u2202']), ('\U0001d6dc', &['\u03f5']),
-        ('\U0001d6dd', &['\u03d1']), ('\U0001d6de', &['\u03f0']), ('\U0001d6df', &['\u03d5']),
-        ('\U0001d6e0', &['\u03f1']), ('\U0001d6e1', &['\u03d6']), ('\U0001d6e2', &['\u0391']),
-        ('\U0001d6e3', &['\u0392']), ('\U0001d6e4', &['\u0393']), ('\U0001d6e5', &['\u0394']),
-        ('\U0001d6e6', &['\u0395']), ('\U0001d6e7', &['\u0396']), ('\U0001d6e8', &['\u0397']),
-        ('\U0001d6e9', &['\u0398']), ('\U0001d6ea', &['\u0399']), ('\U0001d6eb', &['\u039a']),
-        ('\U0001d6ec', &['\u039b']), ('\U0001d6ed', &['\u039c']), ('\U0001d6ee', &['\u039d']),
-        ('\U0001d6ef', &['\u039e']), ('\U0001d6f0', &['\u039f']), ('\U0001d6f1', &['\u03a0']),
-        ('\U0001d6f2', &['\u03a1']), ('\U0001d6f3', &['\u03f4']), ('\U0001d6f4', &['\u03a3']),
-        ('\U0001d6f5', &['\u03a4']), ('\U0001d6f6', &['\u03a5']), ('\U0001d6f7', &['\u03a6']),
-        ('\U0001d6f8', &['\u03a7']), ('\U0001d6f9', &['\u03a8']), ('\U0001d6fa', &['\u03a9']),
-        ('\U0001d6fb', &['\u2207']), ('\U0001d6fc', &['\u03b1']), ('\U0001d6fd', &['\u03b2']),
-        ('\U0001d6fe', &['\u03b3']), ('\U0001d6ff', &['\u03b4']), ('\U0001d700', &['\u03b5']),
-        ('\U0001d701', &['\u03b6']), ('\U0001d702', &['\u03b7']), ('\U0001d703', &['\u03b8']),
-        ('\U0001d704', &['\u03b9']), ('\U0001d705', &['\u03ba']), ('\U0001d706', &['\u03bb']),
-        ('\U0001d707', &['\u03bc']), ('\U0001d708', &['\u03bd']), ('\U0001d709', &['\u03be']),
-        ('\U0001d70a', &['\u03bf']), ('\U0001d70b', &['\u03c0']), ('\U0001d70c', &['\u03c1']),
-        ('\U0001d70d', &['\u03c2']), ('\U0001d70e', &['\u03c3']), ('\U0001d70f', &['\u03c4']),
-        ('\U0001d710', &['\u03c5']), ('\U0001d711', &['\u03c6']), ('\U0001d712', &['\u03c7']),
-        ('\U0001d713', &['\u03c8']), ('\U0001d714', &['\u03c9']), ('\U0001d715', &['\u2202']),
-        ('\U0001d716', &['\u03f5']), ('\U0001d717', &['\u03d1']), ('\U0001d718', &['\u03f0']),
-        ('\U0001d719', &['\u03d5']), ('\U0001d71a', &['\u03f1']), ('\U0001d71b', &['\u03d6']),
-        ('\U0001d71c', &['\u0391']), ('\U0001d71d', &['\u0392']), ('\U0001d71e', &['\u0393']),
-        ('\U0001d71f', &['\u0394']), ('\U0001d720', &['\u0395']), ('\U0001d721', &['\u0396']),
-        ('\U0001d722', &['\u0397']), ('\U0001d723', &['\u0398']), ('\U0001d724', &['\u0399']),
-        ('\U0001d725', &['\u039a']), ('\U0001d726', &['\u039b']), ('\U0001d727', &['\u039c']),
-        ('\U0001d728', &['\u039d']), ('\U0001d729', &['\u039e']), ('\U0001d72a', &['\u039f']),
-        ('\U0001d72b', &['\u03a0']), ('\U0001d72c', &['\u03a1']), ('\U0001d72d', &['\u03f4']),
-        ('\U0001d72e', &['\u03a3']), ('\U0001d72f', &['\u03a4']), ('\U0001d730', &['\u03a5']),
-        ('\U0001d731', &['\u03a6']), ('\U0001d732', &['\u03a7']), ('\U0001d733', &['\u03a8']),
-        ('\U0001d734', &['\u03a9']), ('\U0001d735', &['\u2207']), ('\U0001d736', &['\u03b1']),
-        ('\U0001d737', &['\u03b2']), ('\U0001d738', &['\u03b3']), ('\U0001d739', &['\u03b4']),
-        ('\U0001d73a', &['\u03b5']), ('\U0001d73b', &['\u03b6']), ('\U0001d73c', &['\u03b7']),
-        ('\U0001d73d', &['\u03b8']), ('\U0001d73e', &['\u03b9']), ('\U0001d73f', &['\u03ba']),
-        ('\U0001d740', &['\u03bb']), ('\U0001d741', &['\u03bc']), ('\U0001d742', &['\u03bd']),
-        ('\U0001d743', &['\u03be']), ('\U0001d744', &['\u03bf']), ('\U0001d745', &['\u03c0']),
-        ('\U0001d746', &['\u03c1']), ('\U0001d747', &['\u03c2']), ('\U0001d748', &['\u03c3']),
-        ('\U0001d749', &['\u03c4']), ('\U0001d74a', &['\u03c5']), ('\U0001d74b', &['\u03c6']),
-        ('\U0001d74c', &['\u03c7']), ('\U0001d74d', &['\u03c8']), ('\U0001d74e', &['\u03c9']),
-        ('\U0001d74f', &['\u2202']), ('\U0001d750', &['\u03f5']), ('\U0001d751', &['\u03d1']),
-        ('\U0001d752', &['\u03f0']), ('\U0001d753', &['\u03d5']), ('\U0001d754', &['\u03f1']),
-        ('\U0001d755', &['\u03d6']), ('\U0001d756', &['\u0391']), ('\U0001d757', &['\u0392']),
-        ('\U0001d758', &['\u0393']), ('\U0001d759', &['\u0394']), ('\U0001d75a', &['\u0395']),
-        ('\U0001d75b', &['\u0396']), ('\U0001d75c', &['\u0397']), ('\U0001d75d', &['\u0398']),
-        ('\U0001d75e', &['\u0399']), ('\U0001d75f', &['\u039a']), ('\U0001d760', &['\u039b']),
-        ('\U0001d761', &['\u039c']), ('\U0001d762', &['\u039d']), ('\U0001d763', &['\u039e']),
-        ('\U0001d764', &['\u039f']), ('\U0001d765', &['\u03a0']), ('\U0001d766', &['\u03a1']),
-        ('\U0001d767', &['\u03f4']), ('\U0001d768', &['\u03a3']), ('\U0001d769', &['\u03a4']),
-        ('\U0001d76a', &['\u03a5']), ('\U0001d76b', &['\u03a6']), ('\U0001d76c', &['\u03a7']),
-        ('\U0001d76d', &['\u03a8']), ('\U0001d76e', &['\u03a9']), ('\U0001d76f', &['\u2207']),
-        ('\U0001d770', &['\u03b1']), ('\U0001d771', &['\u03b2']), ('\U0001d772', &['\u03b3']),
-        ('\U0001d773', &['\u03b4']), ('\U0001d774', &['\u03b5']), ('\U0001d775', &['\u03b6']),
-        ('\U0001d776', &['\u03b7']), ('\U0001d777', &['\u03b8']), ('\U0001d778', &['\u03b9']),
-        ('\U0001d779', &['\u03ba']), ('\U0001d77a', &['\u03bb']), ('\U0001d77b', &['\u03bc']),
-        ('\U0001d77c', &['\u03bd']), ('\U0001d77d', &['\u03be']), ('\U0001d77e', &['\u03bf']),
-        ('\U0001d77f', &['\u03c0']), ('\U0001d780', &['\u03c1']), ('\U0001d781', &['\u03c2']),
-        ('\U0001d782', &['\u03c3']), ('\U0001d783', &['\u03c4']), ('\U0001d784', &['\u03c5']),
-        ('\U0001d785', &['\u03c6']), ('\U0001d786', &['\u03c7']), ('\U0001d787', &['\u03c8']),
-        ('\U0001d788', &['\u03c9']), ('\U0001d789', &['\u2202']), ('\U0001d78a', &['\u03f5']),
-        ('\U0001d78b', &['\u03d1']), ('\U0001d78c', &['\u03f0']), ('\U0001d78d', &['\u03d5']),
-        ('\U0001d78e', &['\u03f1']), ('\U0001d78f', &['\u03d6']), ('\U0001d790', &['\u0391']),
-        ('\U0001d791', &['\u0392']), ('\U0001d792', &['\u0393']), ('\U0001d793', &['\u0394']),
-        ('\U0001d794', &['\u0395']), ('\U0001d795', &['\u0396']), ('\U0001d796', &['\u0397']),
-        ('\U0001d797', &['\u0398']), ('\U0001d798', &['\u0399']), ('\U0001d799', &['\u039a']),
-        ('\U0001d79a', &['\u039b']), ('\U0001d79b', &['\u039c']), ('\U0001d79c', &['\u039d']),
-        ('\U0001d79d', &['\u039e']), ('\U0001d79e', &['\u039f']), ('\U0001d79f', &['\u03a0']),
-        ('\U0001d7a0', &['\u03a1']), ('\U0001d7a1', &['\u03f4']), ('\U0001d7a2', &['\u03a3']),
-        ('\U0001d7a3', &['\u03a4']), ('\U0001d7a4', &['\u03a5']), ('\U0001d7a5', &['\u03a6']),
-        ('\U0001d7a6', &['\u03a7']), ('\U0001d7a7', &['\u03a8']), ('\U0001d7a8', &['\u03a9']),
-        ('\U0001d7a9', &['\u2207']), ('\U0001d7aa', &['\u03b1']), ('\U0001d7ab', &['\u03b2']),
-        ('\U0001d7ac', &['\u03b3']), ('\U0001d7ad', &['\u03b4']), ('\U0001d7ae', &['\u03b5']),
-        ('\U0001d7af', &['\u03b6']), ('\U0001d7b0', &['\u03b7']), ('\U0001d7b1', &['\u03b8']),
-        ('\U0001d7b2', &['\u03b9']), ('\U0001d7b3', &['\u03ba']), ('\U0001d7b4', &['\u03bb']),
-        ('\U0001d7b5', &['\u03bc']), ('\U0001d7b6', &['\u03bd']), ('\U0001d7b7', &['\u03be']),
-        ('\U0001d7b8', &['\u03bf']), ('\U0001d7b9', &['\u03c0']), ('\U0001d7ba', &['\u03c1']),
-        ('\U0001d7bb', &['\u03c2']), ('\U0001d7bc', &['\u03c3']), ('\U0001d7bd', &['\u03c4']),
-        ('\U0001d7be', &['\u03c5']), ('\U0001d7bf', &['\u03c6']), ('\U0001d7c0', &['\u03c7']),
-        ('\U0001d7c1', &['\u03c8']), ('\U0001d7c2', &['\u03c9']), ('\U0001d7c3', &['\u2202']),
-        ('\U0001d7c4', &['\u03f5']), ('\U0001d7c5', &['\u03d1']), ('\U0001d7c6', &['\u03f0']),
-        ('\U0001d7c7', &['\u03d5']), ('\U0001d7c8', &['\u03f1']), ('\U0001d7c9', &['\u03d6']),
-        ('\U0001d7ca', &['\u03dc']), ('\U0001d7cb', &['\u03dd']), ('\U0001d7ce', &['\x30']),
-        ('\U0001d7cf', &['\x31']), ('\U0001d7d0', &['\x32']), ('\U0001d7d1', &['\x33']),
-        ('\U0001d7d2', &['\x34']), ('\U0001d7d3', &['\x35']), ('\U0001d7d4', &['\x36']),
-        ('\U0001d7d5', &['\x37']), ('\U0001d7d6', &['\x38']), ('\U0001d7d7', &['\x39']),
-        ('\U0001d7d8', &['\x30']), ('\U0001d7d9', &['\x31']), ('\U0001d7da', &['\x32']),
-        ('\U0001d7db', &['\x33']), ('\U0001d7dc', &['\x34']), ('\U0001d7dd', &['\x35']),
-        ('\U0001d7de', &['\x36']), ('\U0001d7df', &['\x37']), ('\U0001d7e0', &['\x38']),
-        ('\U0001d7e1', &['\x39']), ('\U0001d7e2', &['\x30']), ('\U0001d7e3', &['\x31']),
-        ('\U0001d7e4', &['\x32']), ('\U0001d7e5', &['\x33']), ('\U0001d7e6', &['\x34']),
-        ('\U0001d7e7', &['\x35']), ('\U0001d7e8', &['\x36']), ('\U0001d7e9', &['\x37']),
-        ('\U0001d7ea', &['\x38']), ('\U0001d7eb', &['\x39']), ('\U0001d7ec', &['\x30']),
-        ('\U0001d7ed', &['\x31']), ('\U0001d7ee', &['\x32']), ('\U0001d7ef', &['\x33']),
-        ('\U0001d7f0', &['\x34']), ('\U0001d7f1', &['\x35']), ('\U0001d7f2', &['\x36']),
-        ('\U0001d7f3', &['\x37']), ('\U0001d7f4', &['\x38']), ('\U0001d7f5', &['\x39']),
-        ('\U0001d7f6', &['\x30']), ('\U0001d7f7', &['\x31']), ('\U0001d7f8', &['\x32']),
-        ('\U0001d7f9', &['\x33']), ('\U0001d7fa', &['\x34']), ('\U0001d7fb', &['\x35']),
-        ('\U0001d7fc', &['\x36']), ('\U0001d7fd', &['\x37']), ('\U0001d7fe', &['\x38']),
-        ('\U0001d7ff', &['\x39']), ('\U0001ee00', &['\u0627']), ('\U0001ee01', &['\u0628']),
-        ('\U0001ee02', &['\u062c']), ('\U0001ee03', &['\u062f']), ('\U0001ee05', &['\u0648']),
-        ('\U0001ee06', &['\u0632']), ('\U0001ee07', &['\u062d']), ('\U0001ee08', &['\u0637']),
-        ('\U0001ee09', &['\u064a']), ('\U0001ee0a', &['\u0643']), ('\U0001ee0b', &['\u0644']),
-        ('\U0001ee0c', &['\u0645']), ('\U0001ee0d', &['\u0646']), ('\U0001ee0e', &['\u0633']),
-        ('\U0001ee0f', &['\u0639']), ('\U0001ee10', &['\u0641']), ('\U0001ee11', &['\u0635']),
-        ('\U0001ee12', &['\u0642']), ('\U0001ee13', &['\u0631']), ('\U0001ee14', &['\u0634']),
-        ('\U0001ee15', &['\u062a']), ('\U0001ee16', &['\u062b']), ('\U0001ee17', &['\u062e']),
-        ('\U0001ee18', &['\u0630']), ('\U0001ee19', &['\u0636']), ('\U0001ee1a', &['\u0638']),
-        ('\U0001ee1b', &['\u063a']), ('\U0001ee1c', &['\u066e']), ('\U0001ee1d', &['\u06ba']),
-        ('\U0001ee1e', &['\u06a1']), ('\U0001ee1f', &['\u066f']), ('\U0001ee21', &['\u0628']),
-        ('\U0001ee22', &['\u062c']), ('\U0001ee24', &['\u0647']), ('\U0001ee27', &['\u062d']),
-        ('\U0001ee29', &['\u064a']), ('\U0001ee2a', &['\u0643']), ('\U0001ee2b', &['\u0644']),
-        ('\U0001ee2c', &['\u0645']), ('\U0001ee2d', &['\u0646']), ('\U0001ee2e', &['\u0633']),
-        ('\U0001ee2f', &['\u0639']), ('\U0001ee30', &['\u0641']), ('\U0001ee31', &['\u0635']),
-        ('\U0001ee32', &['\u0642']), ('\U0001ee34', &['\u0634']), ('\U0001ee35', &['\u062a']),
-        ('\U0001ee36', &['\u062b']), ('\U0001ee37', &['\u062e']), ('\U0001ee39', &['\u0636']),
-        ('\U0001ee3b', &['\u063a']), ('\U0001ee42', &['\u062c']), ('\U0001ee47', &['\u062d']),
-        ('\U0001ee49', &['\u064a']), ('\U0001ee4b', &['\u0644']), ('\U0001ee4d', &['\u0646']),
-        ('\U0001ee4e', &['\u0633']), ('\U0001ee4f', &['\u0639']), ('\U0001ee51', &['\u0635']),
-        ('\U0001ee52', &['\u0642']), ('\U0001ee54', &['\u0634']), ('\U0001ee57', &['\u062e']),
-        ('\U0001ee59', &['\u0636']), ('\U0001ee5b', &['\u063a']), ('\U0001ee5d', &['\u06ba']),
-        ('\U0001ee5f', &['\u066f']), ('\U0001ee61', &['\u0628']), ('\U0001ee62', &['\u062c']),
-        ('\U0001ee64', &['\u0647']), ('\U0001ee67', &['\u062d']), ('\U0001ee68', &['\u0637']),
-        ('\U0001ee69', &['\u064a']), ('\U0001ee6a', &['\u0643']), ('\U0001ee6c', &['\u0645']),
-        ('\U0001ee6d', &['\u0646']), ('\U0001ee6e', &['\u0633']), ('\U0001ee6f', &['\u0639']),
-        ('\U0001ee70', &['\u0641']), ('\U0001ee71', &['\u0635']), ('\U0001ee72', &['\u0642']),
-        ('\U0001ee74', &['\u0634']), ('\U0001ee75', &['\u062a']), ('\U0001ee76', &['\u062b']),
-        ('\U0001ee77', &['\u062e']), ('\U0001ee79', &['\u0636']), ('\U0001ee7a', &['\u0638']),
-        ('\U0001ee7b', &['\u063a']), ('\U0001ee7c', &['\u066e']), ('\U0001ee7e', &['\u06a1']),
-        ('\U0001ee80', &['\u0627']), ('\U0001ee81', &['\u0628']), ('\U0001ee82', &['\u062c']),
-        ('\U0001ee83', &['\u062f']), ('\U0001ee84', &['\u0647']), ('\U0001ee85', &['\u0648']),
-        ('\U0001ee86', &['\u0632']), ('\U0001ee87', &['\u062d']), ('\U0001ee88', &['\u0637']),
-        ('\U0001ee89', &['\u064a']), ('\U0001ee8b', &['\u0644']), ('\U0001ee8c', &['\u0645']),
-        ('\U0001ee8d', &['\u0646']), ('\U0001ee8e', &['\u0633']), ('\U0001ee8f', &['\u0639']),
-        ('\U0001ee90', &['\u0641']), ('\U0001ee91', &['\u0635']), ('\U0001ee92', &['\u0642']),
-        ('\U0001ee93', &['\u0631']), ('\U0001ee94', &['\u0634']), ('\U0001ee95', &['\u062a']),
-        ('\U0001ee96', &['\u062b']), ('\U0001ee97', &['\u062e']), ('\U0001ee98', &['\u0630']),
-        ('\U0001ee99', &['\u0636']), ('\U0001ee9a', &['\u0638']), ('\U0001ee9b', &['\u063a']),
-        ('\U0001eea1', &['\u0628']), ('\U0001eea2', &['\u062c']), ('\U0001eea3', &['\u062f']),
-        ('\U0001eea5', &['\u0648']), ('\U0001eea6', &['\u0632']), ('\U0001eea7', &['\u062d']),
-        ('\U0001eea8', &['\u0637']), ('\U0001eea9', &['\u064a']), ('\U0001eeab', &['\u0644']),
-        ('\U0001eeac', &['\u0645']), ('\U0001eead', &['\u0646']), ('\U0001eeae', &['\u0633']),
-        ('\U0001eeaf', &['\u0639']), ('\U0001eeb0', &['\u0641']), ('\U0001eeb1', &['\u0635']),
-        ('\U0001eeb2', &['\u0642']), ('\U0001eeb3', &['\u0631']), ('\U0001eeb4', &['\u0634']),
-        ('\U0001eeb5', &['\u062a']), ('\U0001eeb6', &['\u062b']), ('\U0001eeb7', &['\u062e']),
-        ('\U0001eeb8', &['\u0630']), ('\U0001eeb9', &['\u0636']), ('\U0001eeba', &['\u0638']),
-        ('\U0001eebb', &['\u063a']), ('\U0001f100', &['\x30', '\x2e']), ('\U0001f101', &['\x30',
-        '\x2c']), ('\U0001f102', &['\x31', '\x2c']), ('\U0001f103', &['\x32', '\x2c']),
-        ('\U0001f104', &['\x33', '\x2c']), ('\U0001f105', &['\x34', '\x2c']), ('\U0001f106',
-        &['\x35', '\x2c']), ('\U0001f107', &['\x36', '\x2c']), ('\U0001f108', &['\x37', '\x2c']),
-        ('\U0001f109', &['\x38', '\x2c']), ('\U0001f10a', &['\x39', '\x2c']), ('\U0001f110',
-        &['\x28', '\x41', '\x29']), ('\U0001f111', &['\x28', '\x42', '\x29']), ('\U0001f112',
-        &['\x28', '\x43', '\x29']), ('\U0001f113', &['\x28', '\x44', '\x29']), ('\U0001f114',
-        &['\x28', '\x45', '\x29']), ('\U0001f115', &['\x28', '\x46', '\x29']), ('\U0001f116',
-        &['\x28', '\x47', '\x29']), ('\U0001f117', &['\x28', '\x48', '\x29']), ('\U0001f118',
-        &['\x28', '\x49', '\x29']), ('\U0001f119', &['\x28', '\x4a', '\x29']), ('\U0001f11a',
-        &['\x28', '\x4b', '\x29']), ('\U0001f11b', &['\x28', '\x4c', '\x29']), ('\U0001f11c',
-        &['\x28', '\x4d', '\x29']), ('\U0001f11d', &['\x28', '\x4e', '\x29']), ('\U0001f11e',
-        &['\x28', '\x4f', '\x29']), ('\U0001f11f', &['\x28', '\x50', '\x29']), ('\U0001f120',
-        &['\x28', '\x51', '\x29']), ('\U0001f121', &['\x28', '\x52', '\x29']), ('\U0001f122',
-        &['\x28', '\x53', '\x29']), ('\U0001f123', &['\x28', '\x54', '\x29']), ('\U0001f124',
-        &['\x28', '\x55', '\x29']), ('\U0001f125', &['\x28', '\x56', '\x29']), ('\U0001f126',
-        &['\x28', '\x57', '\x29']), ('\U0001f127', &['\x28', '\x58', '\x29']), ('\U0001f128',
-        &['\x28', '\x59', '\x29']), ('\U0001f129', &['\x28', '\x5a', '\x29']), ('\U0001f12a',
-        &['\u3014', '\x53', '\u3015']), ('\U0001f12b', &['\x43']), ('\U0001f12c', &['\x52']),
-        ('\U0001f12d', &['\x43', '\x44']), ('\U0001f12e', &['\x57', '\x5a']), ('\U0001f130',
-        &['\x41']), ('\U0001f131', &['\x42']), ('\U0001f132', &['\x43']), ('\U0001f133', &['\x44']),
-        ('\U0001f134', &['\x45']), ('\U0001f135', &['\x46']), ('\U0001f136', &['\x47']),
-        ('\U0001f137', &['\x48']), ('\U0001f138', &['\x49']), ('\U0001f139', &['\x4a']),
-        ('\U0001f13a', &['\x4b']), ('\U0001f13b', &['\x4c']), ('\U0001f13c', &['\x4d']),
-        ('\U0001f13d', &['\x4e']), ('\U0001f13e', &['\x4f']), ('\U0001f13f', &['\x50']),
-        ('\U0001f140', &['\x51']), ('\U0001f141', &['\x52']), ('\U0001f142', &['\x53']),
-        ('\U0001f143', &['\x54']), ('\U0001f144', &['\x55']), ('\U0001f145', &['\x56']),
-        ('\U0001f146', &['\x57']), ('\U0001f147', &['\x58']), ('\U0001f148', &['\x59']),
-        ('\U0001f149', &['\x5a']), ('\U0001f14a', &['\x48', '\x56']), ('\U0001f14b', &['\x4d',
-        '\x56']), ('\U0001f14c', &['\x53', '\x44']), ('\U0001f14d', &['\x53', '\x53']),
-        ('\U0001f14e', &['\x50', '\x50', '\x56']), ('\U0001f14f', &['\x57', '\x43']), ('\U0001f16a',
-        &['\x4d', '\x43']), ('\U0001f16b', &['\x4d', '\x44']), ('\U0001f190', &['\x44', '\x4a']),
-        ('\U0001f200', &['\u307b', '\u304b']), ('\U0001f201', &['\u30b3', '\u30b3']), ('\U0001f202',
-        &['\u30b5']), ('\U0001f210', &['\u624b']), ('\U0001f211', &['\u5b57']), ('\U0001f212',
-        &['\u53cc']), ('\U0001f213', &['\u30c7']), ('\U0001f214', &['\u4e8c']), ('\U0001f215',
-        &['\u591a']), ('\U0001f216', &['\u89e3']), ('\U0001f217', &['\u5929']), ('\U0001f218',
-        &['\u4ea4']), ('\U0001f219', &['\u6620']), ('\U0001f21a', &['\u7121']), ('\U0001f21b',
-        &['\u6599']), ('\U0001f21c', &['\u524d']), ('\U0001f21d', &['\u5f8c']), ('\U0001f21e',
-        &['\u518d']), ('\U0001f21f', &['\u65b0']), ('\U0001f220', &['\u521d']), ('\U0001f221',
-        &['\u7d42']), ('\U0001f222', &['\u751f']), ('\U0001f223', &['\u8ca9']), ('\U0001f224',
-        &['\u58f0']), ('\U0001f225', &['\u5439']), ('\U0001f226', &['\u6f14']), ('\U0001f227',
-        &['\u6295']), ('\U0001f228', &['\u6355']), ('\U0001f229', &['\u4e00']), ('\U0001f22a',
-        &['\u4e09']), ('\U0001f22b', &['\u904a']), ('\U0001f22c', &['\u5de6']), ('\U0001f22d',
-        &['\u4e2d']), ('\U0001f22e', &['\u53f3']), ('\U0001f22f', &['\u6307']), ('\U0001f230',
-        &['\u8d70']), ('\U0001f231', &['\u6253']), ('\U0001f232', &['\u7981']), ('\U0001f233',
-        &['\u7a7a']), ('\U0001f234', &['\u5408']), ('\U0001f235', &['\u6e80']), ('\U0001f236',
-        &['\u6709']), ('\U0001f237', &['\u6708']), ('\U0001f238', &['\u7533']), ('\U0001f239',
-        &['\u5272']), ('\U0001f23a', &['\u55b6']), ('\U0001f240', &['\u3014', '\u672c', '\u3015']),
-        ('\U0001f241', &['\u3014', '\u4e09', '\u3015']), ('\U0001f242', &['\u3014', '\u4e8c',
-        '\u3015']), ('\U0001f243', &['\u3014', '\u5b89', '\u3015']), ('\U0001f244', &['\u3014',
-        '\u70b9', '\u3015']), ('\U0001f245', &['\u3014', '\u6253', '\u3015']), ('\U0001f246',
-        &['\u3014', '\u76d7', '\u3015']), ('\U0001f247', &['\u3014', '\u52dd', '\u3015']),
-        ('\U0001f248', &['\u3014', '\u6557', '\u3015']), ('\U0001f250', &['\u5f97']), ('\U0001f251',
-        &['\u53ef'])
-    ];
-
-
-    pub fn decompose_canonical(c: char, i: |char|) { d(c, i, false); }
-
-    pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
-
-    fn d(c: char, i: |char|, k: bool) {
-        use iter::Iterator;
-
-        // 7-bit ASCII never decomposes
-        if c <= '\x7f' { i(c); return; }
-
-        // Perform decomposition for Hangul
-        if (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) {
-            decompose_hangul(c, i);
-            return;
-        }
-
-        // First check the canonical decompositions
-        match bsearch_table(c, canonical_table) {
-            Some(canon) => {
-                for x in canon.iter() {
-                    d(*x, |b| i(b), k);
-                }
-                return;
-            }
-            None => ()
-        }
-
-        // Bottom out if we're not doing compat.
-        if !k { i(c); return; }
-
-        // Then check the compatibility decompositions
-        match bsearch_table(c, compatibility_table) {
-            Some(compat) => {
-                for x in compat.iter() {
-                    d(*x, |b| i(b), k);
-                }
-                return;
-            }
-            None => ()
-        }
-
-        // Finally bottom out.
-        i(c);
-    }
-
-    // Constants from Unicode 6.2.0 Section 3.12 Conjoining Jamo Behavior
-    static S_BASE: u32 = 0xAC00;
-    static L_BASE: u32 = 0x1100;
-    static V_BASE: u32 = 0x1161;
-    static T_BASE: u32 = 0x11A7;
-    static L_COUNT: u32 = 19;
-    static V_COUNT: u32 = 21;
-    static T_COUNT: u32 = 28;
-    static N_COUNT: u32 = (V_COUNT * T_COUNT);
-    static S_COUNT: u32 = (L_COUNT * N_COUNT);
-
-    // Decompose a precomposed Hangul syllable
-    fn decompose_hangul(s: char, f: |char|) {
-        use mem::transmute;
-
-        let si = s as u32 - S_BASE;
-
-        let li = si / N_COUNT;
-        unsafe {
-            f(transmute(L_BASE + li));
-
-            let vi = (si % N_COUNT) / T_COUNT;
-            f(transmute(V_BASE + vi));
-
-            let ti = si % T_COUNT;
-            if ti > 0 {
-                f(transmute(T_BASE + ti));
-            }
-        }
-    }
-}
-
-pub mod derived_property {
-    static Alphabetic_table : &'static [(char,char)] = &[
-        ('\x41', '\x5a'), ('\x61', '\x7a'),
-        ('\xaa', '\xaa'), ('\xb5', '\xb5'),
-        ('\xba', '\xba'), ('\xc0', '\xd6'),
-        ('\xd8', '\xf6'), ('\xf8', '\u01ba'),
-        ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'),
-        ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'),
-        ('\u0294', '\u0294'), ('\u0295', '\u02af'),
-        ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'),
-        ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'),
-        ('\u02ee', '\u02ee'), ('\u0345', '\u0345'),
-        ('\u0370', '\u0373'), ('\u0374', '\u0374'),
-        ('\u0376', '\u0377'), ('\u037a', '\u037a'),
-        ('\u037b', '\u037d'), ('\u0386', '\u0386'),
-        ('\u0388', '\u038a'), ('\u038c', '\u038c'),
-        ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'),
-        ('\u03f7', '\u0481'), ('\u048a', '\u0527'),
-        ('\u0531', '\u0556'), ('\u0559', '\u0559'),
-        ('\u0561', '\u0587'), ('\u05b0', '\u05bd'),
-        ('\u05bf', '\u05bf'), ('\u05c1', '\u05c2'),
-        ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'),
-        ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'),
-        ('\u0610', '\u061a'), ('\u0620', '\u063f'),
-        ('\u0640', '\u0640'), ('\u0641', '\u064a'),
-        ('\u064b', '\u0657'), ('\u0659', '\u065f'),
-        ('\u066e', '\u066f'), ('\u0670', '\u0670'),
-        ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'),
-        ('\u06d6', '\u06dc'), ('\u06e1', '\u06e4'),
-        ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'),
-        ('\u06ed', '\u06ed'), ('\u06ee', '\u06ef'),
-        ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'),
-        ('\u0710', '\u0710'), ('\u0711', '\u0711'),
-        ('\u0712', '\u072f'), ('\u0730', '\u073f'),
-        ('\u074d', '\u07a5'), ('\u07a6', '\u07b0'),
-        ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'),
-        ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
-        ('\u0800', '\u0815'), ('\u0816', '\u0817'),
-        ('\u081a', '\u081a'), ('\u081b', '\u0823'),
-        ('\u0824', '\u0824'), ('\u0825', '\u0827'),
-        ('\u0828', '\u0828'), ('\u0829', '\u082c'),
-        ('\u0840', '\u0858'), ('\u08a0', '\u08a0'),
-        ('\u08a2', '\u08ac'), ('\u08e4', '\u08e9'),
-        ('\u08f0', '\u08fe'), ('\u0900', '\u0902'),
-        ('\u0903', '\u0903'), ('\u0904', '\u0939'),
-        ('\u093a', '\u093a'), ('\u093b', '\u093b'),
-        ('\u093d', '\u093d'), ('\u093e', '\u0940'),
-        ('\u0941', '\u0948'), ('\u0949', '\u094c'),
-        ('\u094e', '\u094f'), ('\u0950', '\u0950'),
-        ('\u0955', '\u0957'), ('\u0958', '\u0961'),
-        ('\u0962', '\u0963'), ('\u0971', '\u0971'),
-        ('\u0972', '\u0977'), ('\u0979', '\u097f'),
-        ('\u0981', '\u0981'), ('\u0982', '\u0983'),
-        ('\u0985', '\u098c'), ('\u098f', '\u0990'),
-        ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
-        ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
-        ('\u09bd', '\u09bd'), ('\u09be', '\u09c0'),
-        ('\u09c1', '\u09c4'), ('\u09c7', '\u09c8'),
-        ('\u09cb', '\u09cc'), ('\u09ce', '\u09ce'),
-        ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'),
-        ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'),
-        ('\u09f0', '\u09f1'), ('\u0a01', '\u0a02'),
-        ('\u0a03', '\u0a03'), ('\u0a05', '\u0a0a'),
-        ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'),
-        ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'),
-        ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'),
-        ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
-        ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4c'),
-        ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
-        ('\u0a5e', '\u0a5e'), ('\u0a70', '\u0a71'),
-        ('\u0a72', '\u0a74'), ('\u0a75', '\u0a75'),
-        ('\u0a81', '\u0a82'), ('\u0a83', '\u0a83'),
-        ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'),
-        ('\u0a93', '\u0aa8'), ('\u0aaa', '\u0ab0'),
-        ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'),
-        ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'),
-        ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'),
-        ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
-        ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'),
-        ('\u0ae2', '\u0ae3'), ('\u0b01', '\u0b01'),
-        ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'),
-        ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'),
-        ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'),
-        ('\u0b35', '\u0b39'), ('\u0b3d', '\u0b3d'),
-        ('\u0b3e', '\u0b3e'), ('\u0b3f', '\u0b3f'),
-        ('\u0b40', '\u0b40'), ('\u0b41', '\u0b44'),
-        ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4c'),
-        ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'),
-        ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'),
-        ('\u0b62', '\u0b63'), ('\u0b71', '\u0b71'),
-        ('\u0b82', '\u0b82'), ('\u0b83', '\u0b83'),
-        ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'),
-        ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'),
-        ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'),
-        ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'),
-        ('\u0bae', '\u0bb9'), ('\u0bbe', '\u0bbf'),
-        ('\u0bc0', '\u0bc0'), ('\u0bc1', '\u0bc2'),
-        ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcc'),
-        ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'),
-        ('\u0c01', '\u0c03'), ('\u0c05', '\u0c0c'),
-        ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'),
-        ('\u0c2a', '\u0c33'), ('\u0c35', '\u0c39'),
-        ('\u0c3d', '\u0c3d'), ('\u0c3e', '\u0c40'),
-        ('\u0c41', '\u0c44'), ('\u0c46', '\u0c48'),
-        ('\u0c4a', '\u0c4c'), ('\u0c55', '\u0c56'),
-        ('\u0c58', '\u0c59'), ('\u0c60', '\u0c61'),
-        ('\u0c62', '\u0c63'), ('\u0c82', '\u0c83'),
-        ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'),
-        ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'),
-        ('\u0cb5', '\u0cb9'), ('\u0cbd', '\u0cbd'),
-        ('\u0cbe', '\u0cbe'), ('\u0cbf', '\u0cbf'),
-        ('\u0cc0', '\u0cc4'), ('\u0cc6', '\u0cc6'),
-        ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'),
-        ('\u0ccc', '\u0ccc'), ('\u0cd5', '\u0cd6'),
-        ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'),
-        ('\u0ce2', '\u0ce3'), ('\u0cf1', '\u0cf2'),
-        ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'),
-        ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'),
-        ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'),
-        ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'),
-        ('\u0d4a', '\u0d4c'), ('\u0d4e', '\u0d4e'),
-        ('\u0d57', '\u0d57'), ('\u0d60', '\u0d61'),
-        ('\u0d62', '\u0d63'), ('\u0d7a', '\u0d7f'),
-        ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'),
-        ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
-        ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'),
-        ('\u0dcf', '\u0dd1'), ('\u0dd2', '\u0dd4'),
-        ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'),
-        ('\u0df2', '\u0df3'), ('\u0e01', '\u0e30'),
-        ('\u0e31', '\u0e31'), ('\u0e32', '\u0e33'),
-        ('\u0e34', '\u0e3a'), ('\u0e40', '\u0e45'),
-        ('\u0e46', '\u0e46'), ('\u0e4d', '\u0e4d'),
-        ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'),
-        ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
-        ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'),
-        ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
-        ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'),
-        ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
-        ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'),
-        ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
-        ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'),
-        ('\u0ec6', '\u0ec6'), ('\u0ecd', '\u0ecd'),
-        ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'),
-        ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'),
-        ('\u0f71', '\u0f7e'), ('\u0f7f', '\u0f7f'),
-        ('\u0f80', '\u0f81'), ('\u0f88', '\u0f8c'),
-        ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'),
-        ('\u1000', '\u102a'), ('\u102b', '\u102c'),
-        ('\u102d', '\u1030'), ('\u1031', '\u1031'),
-        ('\u1032', '\u1036'), ('\u1038', '\u1038'),
-        ('\u103b', '\u103c'), ('\u103d', '\u103e'),
-        ('\u103f', '\u103f'), ('\u1050', '\u1055'),
-        ('\u1056', '\u1057'), ('\u1058', '\u1059'),
-        ('\u105a', '\u105d'), ('\u105e', '\u1060'),
-        ('\u1061', '\u1061'), ('\u1062', '\u1062'),
-        ('\u1065', '\u1066'), ('\u1067', '\u1068'),
-        ('\u106e', '\u1070'), ('\u1071', '\u1074'),
-        ('\u1075', '\u1081'), ('\u1082', '\u1082'),
-        ('\u1083', '\u1084'), ('\u1085', '\u1086'),
-        ('\u108e', '\u108e'), ('\u109c', '\u109c'),
-        ('\u109d', '\u109d'), ('\u10a0', '\u10c5'),
-        ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
-        ('\u10d0', '\u10fa'), ('\u10fc', '\u10fc'),
-        ('\u10fd', '\u1248'), ('\u124a', '\u124d'),
-        ('\u1250', '\u1256'), ('\u1258', '\u1258'),
-        ('\u125a', '\u125d'), ('\u1260', '\u1288'),
-        ('\u128a', '\u128d'), ('\u1290', '\u12b0'),
-        ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'),
-        ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'),
-        ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'),
-        ('\u1312', '\u1315'), ('\u1318', '\u135a'),
-        ('\u135f', '\u135f'), ('\u1380', '\u138f'),
-        ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
-        ('\u166f', '\u167f'), ('\u1681', '\u169a'),
-        ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'),
-        ('\u1700', '\u170c'), ('\u170e', '\u1711'),
-        ('\u1712', '\u1713'), ('\u1720', '\u1731'),
-        ('\u1732', '\u1733'), ('\u1740', '\u1751'),
-        ('\u1752', '\u1753'), ('\u1760', '\u176c'),
-        ('\u176e', '\u1770'), ('\u1772', '\u1773'),
-        ('\u1780', '\u17b3'), ('\u17b6', '\u17b6'),
-        ('\u17b7', '\u17bd'), ('\u17be', '\u17c5'),
-        ('\u17c6', '\u17c6'), ('\u17c7', '\u17c8'),
-        ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'),
-        ('\u1820', '\u1842'), ('\u1843', '\u1843'),
-        ('\u1844', '\u1877'), ('\u1880', '\u18a8'),
-        ('\u18a9', '\u18a9'), ('\u18aa', '\u18aa'),
-        ('\u18b0', '\u18f5'), ('\u1900', '\u191c'),
-        ('\u1920', '\u1922'), ('\u1923', '\u1926'),
-        ('\u1927', '\u1928'), ('\u1929', '\u192b'),
-        ('\u1930', '\u1931'), ('\u1932', '\u1932'),
-        ('\u1933', '\u1938'), ('\u1950', '\u196d'),
-        ('\u1970', '\u1974'), ('\u1980', '\u19ab'),
-        ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'),
-        ('\u19c8', '\u19c9'), ('\u1a00', '\u1a16'),
-        ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'),
-        ('\u1a1b', '\u1a1b'), ('\u1a20', '\u1a54'),
-        ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'),
-        ('\u1a57', '\u1a57'), ('\u1a58', '\u1a5e'),
-        ('\u1a61', '\u1a61'), ('\u1a62', '\u1a62'),
-        ('\u1a63', '\u1a64'), ('\u1a65', '\u1a6c'),
-        ('\u1a6d', '\u1a72'), ('\u1a73', '\u1a74'),
-        ('\u1aa7', '\u1aa7'), ('\u1b00', '\u1b03'),
-        ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'),
-        ('\u1b35', '\u1b35'), ('\u1b36', '\u1b3a'),
-        ('\u1b3b', '\u1b3b'), ('\u1b3c', '\u1b3c'),
-        ('\u1b3d', '\u1b41'), ('\u1b42', '\u1b42'),
-        ('\u1b43', '\u1b43'), ('\u1b45', '\u1b4b'),
-        ('\u1b80', '\u1b81'), ('\u1b82', '\u1b82'),
-        ('\u1b83', '\u1ba0'), ('\u1ba1', '\u1ba1'),
-        ('\u1ba2', '\u1ba5'), ('\u1ba6', '\u1ba7'),
-        ('\u1ba8', '\u1ba9'), ('\u1bac', '\u1bad'),
-        ('\u1bae', '\u1baf'), ('\u1bba', '\u1be5'),
-        ('\u1be7', '\u1be7'), ('\u1be8', '\u1be9'),
-        ('\u1bea', '\u1bec'), ('\u1bed', '\u1bed'),
-        ('\u1bee', '\u1bee'), ('\u1bef', '\u1bf1'),
-        ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'),
-        ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
-        ('\u1c4d', '\u1c4f'), ('\u1c5a', '\u1c77'),
-        ('\u1c78', '\u1c7d'), ('\u1ce9', '\u1cec'),
-        ('\u1cee', '\u1cf1'), ('\u1cf2', '\u1cf3'),
-        ('\u1cf5', '\u1cf6'), ('\u1d00', '\u1d2b'),
-        ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
-        ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'),
-        ('\u1d9b', '\u1dbf'), ('\u1e00', '\u1f15'),
-        ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
-        ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
-        ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
-        ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
-        ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
-        ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
-        ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
-        ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'),
-        ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
-        ('\u2071', '\u2071'), ('\u207f', '\u207f'),
-        ('\u2090', '\u209c'), ('\u2102', '\u2102'),
-        ('\u2107', '\u2107'), ('\u210a', '\u2113'),
-        ('\u2115', '\u2115'), ('\u2119', '\u211d'),
-        ('\u2124', '\u2124'), ('\u2126', '\u2126'),
-        ('\u2128', '\u2128'), ('\u212a', '\u212d'),
-        ('\u212f', '\u2134'), ('\u2135', '\u2138'),
-        ('\u2139', '\u2139'), ('\u213c', '\u213f'),
-        ('\u2145', '\u2149'), ('\u214e', '\u214e'),
-        ('\u2160', '\u2182'), ('\u2183', '\u2184'),
-        ('\u2185', '\u2188'), ('\u24b6', '\u24e9'),
-        ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'),
-        ('\u2c60', '\u2c7b'), ('\u2c7c', '\u2c7d'),
-        ('\u2c7e', '\u2ce4'), ('\u2ceb', '\u2cee'),
-        ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'),
-        ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'),
-        ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'),
-        ('\u2d80', '\u2d96'), ('\u2da0', '\u2da6'),
-        ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'),
-        ('\u2db8', '\u2dbe'), ('\u2dc0', '\u2dc6'),
-        ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'),
-        ('\u2dd8', '\u2dde'), ('\u2de0', '\u2dff'),
-        ('\u2e2f', '\u2e2f'), ('\u3005', '\u3005'),
-        ('\u3006', '\u3006'), ('\u3007', '\u3007'),
-        ('\u3021', '\u3029'), ('\u3031', '\u3035'),
-        ('\u3038', '\u303a'), ('\u303b', '\u303b'),
-        ('\u303c', '\u303c'), ('\u3041', '\u3096'),
-        ('\u309d', '\u309e'), ('\u309f', '\u309f'),
-        ('\u30a1', '\u30fa'), ('\u30fc', '\u30fe'),
-        ('\u30ff', '\u30ff'), ('\u3105', '\u312d'),
-        ('\u3131', '\u318e'), ('\u31a0', '\u31ba'),
-        ('\u31f0', '\u31ff'), ('\u3400', '\u4db5'),
-        ('\u4e00', '\u9fcc'), ('\ua000', '\ua014'),
-        ('\ua015', '\ua015'), ('\ua016', '\ua48c'),
-        ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'),
-        ('\ua500', '\ua60b'), ('\ua60c', '\ua60c'),
-        ('\ua610', '\ua61f'), ('\ua62a', '\ua62b'),
-        ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'),
-        ('\ua674', '\ua67b'), ('\ua67f', '\ua67f'),
-        ('\ua680', '\ua697'), ('\ua69f', '\ua69f'),
-        ('\ua6a0', '\ua6e5'), ('\ua6e6', '\ua6ef'),
-        ('\ua717', '\ua71f'), ('\ua722', '\ua76f'),
-        ('\ua770', '\ua770'), ('\ua771', '\ua787'),
-        ('\ua788', '\ua788'), ('\ua78b', '\ua78e'),
-        ('\ua790', '\ua793'), ('\ua7a0', '\ua7aa'),
-        ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'),
-        ('\ua7fb', '\ua801'), ('\ua803', '\ua805'),
-        ('\ua807', '\ua80a'), ('\ua80c', '\ua822'),
-        ('\ua823', '\ua824'), ('\ua825', '\ua826'),
-        ('\ua827', '\ua827'), ('\ua840', '\ua873'),
-        ('\ua880', '\ua881'), ('\ua882', '\ua8b3'),
-        ('\ua8b4', '\ua8c3'), ('\ua8f2', '\ua8f7'),
-        ('\ua8fb', '\ua8fb'), ('\ua90a', '\ua925'),
-        ('\ua926', '\ua92a'), ('\ua930', '\ua946'),
-        ('\ua947', '\ua951'), ('\ua952', '\ua952'),
-        ('\ua960', '\ua97c'), ('\ua980', '\ua982'),
-        ('\ua983', '\ua983'), ('\ua984', '\ua9b2'),
-        ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'),
-        ('\ua9ba', '\ua9bb'), ('\ua9bc', '\ua9bc'),
-        ('\ua9bd', '\ua9bf'), ('\ua9cf', '\ua9cf'),
-        ('\uaa00', '\uaa28'), ('\uaa29', '\uaa2e'),
-        ('\uaa2f', '\uaa30'), ('\uaa31', '\uaa32'),
-        ('\uaa33', '\uaa34'), ('\uaa35', '\uaa36'),
-        ('\uaa40', '\uaa42'), ('\uaa43', '\uaa43'),
-        ('\uaa44', '\uaa4b'), ('\uaa4c', '\uaa4c'),
-        ('\uaa4d', '\uaa4d'), ('\uaa60', '\uaa6f'),
-        ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
-        ('\uaa7a', '\uaa7a'), ('\uaa80', '\uaaaf'),
-        ('\uaab0', '\uaab0'), ('\uaab1', '\uaab1'),
-        ('\uaab2', '\uaab4'), ('\uaab5', '\uaab6'),
-        ('\uaab7', '\uaab8'), ('\uaab9', '\uaabd'),
-        ('\uaabe', '\uaabe'), ('\uaac0', '\uaac0'),
-        ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
-        ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'),
-        ('\uaaeb', '\uaaeb'), ('\uaaec', '\uaaed'),
-        ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'),
-        ('\uaaf3', '\uaaf4'), ('\uaaf5', '\uaaf5'),
-        ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
-        ('\uab11', '\uab16'), ('\uab20', '\uab26'),
-        ('\uab28', '\uab2e'), ('\uabc0', '\uabe2'),
-        ('\uabe3', '\uabe4'), ('\uabe5', '\uabe5'),
-        ('\uabe6', '\uabe7'), ('\uabe8', '\uabe8'),
-        ('\uabe9', '\uabea'), ('\uac00', '\ud7a3'),
-        ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'),
-        ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
-        ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'),
-        ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'),
-        ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'),
-        ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
-        ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'),
-        ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufd3d'),
-        ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'),
-        ('\ufdf0', '\ufdfb'), ('\ufe70', '\ufe74'),
-        ('\ufe76', '\ufefc'), ('\uff21', '\uff3a'),
-        ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
-        ('\uff70', '\uff70'), ('\uff71', '\uff9d'),
-        ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'),
-        ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
-        ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'),
-        ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'),
-        ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'),
-        ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
-        ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'),
-        ('\U00010280', '\U0001029c'), ('\U000102a0', '\U000102d0'),
-        ('\U00010300', '\U0001031e'), ('\U00010330', '\U00010340'),
-        ('\U00010341', '\U00010341'), ('\U00010342', '\U00010349'),
-        ('\U0001034a', '\U0001034a'), ('\U00010380', '\U0001039d'),
-        ('\U000103a0', '\U000103c3'), ('\U000103c8', '\U000103cf'),
-        ('\U000103d1', '\U000103d5'), ('\U00010400', '\U0001044f'),
-        ('\U00010450', '\U0001049d'), ('\U00010800', '\U00010805'),
-        ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
-        ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
-        ('\U0001083f', '\U00010855'), ('\U00010900', '\U00010915'),
-        ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
-        ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'),
-        ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'),
-        ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'),
-        ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'),
-        ('\U00010a60', '\U00010a7c'), ('\U00010b00', '\U00010b35'),
-        ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
-        ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'),
-        ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'),
-        ('\U00011003', '\U00011037'), ('\U00011038', '\U00011045'),
-        ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'),
-        ('\U000110b0', '\U000110b2'), ('\U000110b3', '\U000110b6'),
-        ('\U000110b7', '\U000110b8'), ('\U000110d0', '\U000110e8'),
-        ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'),
-        ('\U00011127', '\U0001112b'), ('\U0001112c', '\U0001112c'),
-        ('\U0001112d', '\U00011132'), ('\U00011180', '\U00011181'),
-        ('\U00011182', '\U00011182'), ('\U00011183', '\U000111b2'),
-        ('\U000111b3', '\U000111b5'), ('\U000111b6', '\U000111be'),
-        ('\U000111bf', '\U000111bf'), ('\U000111c1', '\U000111c4'),
-        ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'),
-        ('\U000116ac', '\U000116ac'), ('\U000116ad', '\U000116ad'),
-        ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
-        ('\U00012000', '\U0001236e'), ('\U00012400', '\U00012462'),
-        ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
-        ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'),
-        ('\U00016f51', '\U00016f7e'), ('\U00016f93', '\U00016f9f'),
-        ('\U0001b000', '\U0001b001'), ('\U0001d400', '\U0001d454'),
-        ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
-        ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'),
-        ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'),
-        ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'),
-        ('\U0001d4c5', '\U0001d505'), ('\U0001d507', '\U0001d50a'),
-        ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'),
-        ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'),
-        ('\U0001d540', '\U0001d544'), ('\U0001d546', '\U0001d546'),
-        ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'),
-        ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'),
-        ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fc', '\U0001d714'),
-        ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'),
-        ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'),
-        ('\U0001d78a', '\U0001d7a8'), ('\U0001d7aa', '\U0001d7c2'),
-        ('\U0001d7c4', '\U0001d7cb'), ('\U0001ee00', '\U0001ee03'),
-        ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
-        ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'),
-        ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'),
-        ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
-        ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'),
-        ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'),
-        ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
-        ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'),
-        ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'),
-        ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
-        ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'),
-        ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'),
-        ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
-        ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'),
-        ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'),
-        ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
-        ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'),
-        ('\U0002b740', '\U0002b81d'), ('\U0002f800', '\U0002fa1d')
-    ];
-
-    pub fn Alphabetic(c: char) -> bool {
-        super::bsearch_range_table(c, Alphabetic_table)
-    }
-
-    static Lowercase_table : &'static [(char,char)] = &[
-        ('\x61', '\x7a'), ('\xaa', '\xaa'),
-        ('\xb5', '\xb5'), ('\xba', '\xba'),
-        ('\xdf', '\xf6'), ('\xf8', '\xff'),
-        ('\u0101', '\u0101'), ('\u0103', '\u0103'),
-        ('\u0105', '\u0105'), ('\u0107', '\u0107'),
-        ('\u0109', '\u0109'), ('\u010b', '\u010b'),
-        ('\u010d', '\u010d'), ('\u010f', '\u010f'),
-        ('\u0111', '\u0111'), ('\u0113', '\u0113'),
-        ('\u0115', '\u0115'), ('\u0117', '\u0117'),
-        ('\u0119', '\u0119'), ('\u011b', '\u011b'),
-        ('\u011d', '\u011d'), ('\u011f', '\u011f'),
-        ('\u0121', '\u0121'), ('\u0123', '\u0123'),
-        ('\u0125', '\u0125'), ('\u0127', '\u0127'),
-        ('\u0129', '\u0129'), ('\u012b', '\u012b'),
-        ('\u012d', '\u012d'), ('\u012f', '\u012f'),
-        ('\u0131', '\u0131'), ('\u0133', '\u0133'),
-        ('\u0135', '\u0135'), ('\u0137', '\u0138'),
-        ('\u013a', '\u013a'), ('\u013c', '\u013c'),
-        ('\u013e', '\u013e'), ('\u0140', '\u0140'),
-        ('\u0142', '\u0142'), ('\u0144', '\u0144'),
-        ('\u0146', '\u0146'), ('\u0148', '\u0149'),
-        ('\u014b', '\u014b'), ('\u014d', '\u014d'),
-        ('\u014f', '\u014f'), ('\u0151', '\u0151'),
-        ('\u0153', '\u0153'), ('\u0155', '\u0155'),
-        ('\u0157', '\u0157'), ('\u0159', '\u0159'),
-        ('\u015b', '\u015b'), ('\u015d', '\u015d'),
-        ('\u015f', '\u015f'), ('\u0161', '\u0161'),
-        ('\u0163', '\u0163'), ('\u0165', '\u0165'),
-        ('\u0167', '\u0167'), ('\u0169', '\u0169'),
-        ('\u016b', '\u016b'), ('\u016d', '\u016d'),
-        ('\u016f', '\u016f'), ('\u0171', '\u0171'),
-        ('\u0173', '\u0173'), ('\u0175', '\u0175'),
-        ('\u0177', '\u0177'), ('\u017a', '\u017a'),
-        ('\u017c', '\u017c'), ('\u017e', '\u0180'),
-        ('\u0183', '\u0183'), ('\u0185', '\u0185'),
-        ('\u0188', '\u0188'), ('\u018c', '\u018d'),
-        ('\u0192', '\u0192'), ('\u0195', '\u0195'),
-        ('\u0199', '\u019b'), ('\u019e', '\u019e'),
-        ('\u01a1', '\u01a1'), ('\u01a3', '\u01a3'),
-        ('\u01a5', '\u01a5'), ('\u01a8', '\u01a8'),
-        ('\u01aa', '\u01ab'), ('\u01ad', '\u01ad'),
-        ('\u01b0', '\u01b0'), ('\u01b4', '\u01b4'),
-        ('\u01b6', '\u01b6'), ('\u01b9', '\u01ba'),
-        ('\u01bd', '\u01bf'), ('\u01c6', '\u01c6'),
-        ('\u01c9', '\u01c9'), ('\u01cc', '\u01cc'),
-        ('\u01ce', '\u01ce'), ('\u01d0', '\u01d0'),
-        ('\u01d2', '\u01d2'), ('\u01d4', '\u01d4'),
-        ('\u01d6', '\u01d6'), ('\u01d8', '\u01d8'),
-        ('\u01da', '\u01da'), ('\u01dc', '\u01dd'),
-        ('\u01df', '\u01df'), ('\u01e1', '\u01e1'),
-        ('\u01e3', '\u01e3'), ('\u01e5', '\u01e5'),
-        ('\u01e7', '\u01e7'), ('\u01e9', '\u01e9'),
-        ('\u01eb', '\u01eb'), ('\u01ed', '\u01ed'),
-        ('\u01ef', '\u01f0'), ('\u01f3', '\u01f3'),
-        ('\u01f5', '\u01f5'), ('\u01f9', '\u01f9'),
-        ('\u01fb', '\u01fb'), ('\u01fd', '\u01fd'),
-        ('\u01ff', '\u01ff'), ('\u0201', '\u0201'),
-        ('\u0203', '\u0203'), ('\u0205', '\u0205'),
-        ('\u0207', '\u0207'), ('\u0209', '\u0209'),
-        ('\u020b', '\u020b'), ('\u020d', '\u020d'),
-        ('\u020f', '\u020f'), ('\u0211', '\u0211'),
-        ('\u0213', '\u0213'), ('\u0215', '\u0215'),
-        ('\u0217', '\u0217'), ('\u0219', '\u0219'),
-        ('\u021b', '\u021b'), ('\u021d', '\u021d'),
-        ('\u021f', '\u021f'), ('\u0221', '\u0221'),
-        ('\u0223', '\u0223'), ('\u0225', '\u0225'),
-        ('\u0227', '\u0227'), ('\u0229', '\u0229'),
-        ('\u022b', '\u022b'), ('\u022d', '\u022d'),
-        ('\u022f', '\u022f'), ('\u0231', '\u0231'),
-        ('\u0233', '\u0239'), ('\u023c', '\u023c'),
-        ('\u023f', '\u0240'), ('\u0242', '\u0242'),
-        ('\u0247', '\u0247'), ('\u0249', '\u0249'),
-        ('\u024b', '\u024b'), ('\u024d', '\u024d'),
-        ('\u024f', '\u0293'), ('\u0295', '\u02af'),
-        ('\u02b0', '\u02b8'), ('\u02c0', '\u02c1'),
-        ('\u02e0', '\u02e4'), ('\u0345', '\u0345'),
-        ('\u0371', '\u0371'), ('\u0373', '\u0373'),
-        ('\u0377', '\u0377'), ('\u037a', '\u037a'),
-        ('\u037b', '\u037d'), ('\u0390', '\u0390'),
-        ('\u03ac', '\u03ce'), ('\u03d0', '\u03d1'),
-        ('\u03d5', '\u03d7'), ('\u03d9', '\u03d9'),
-        ('\u03db', '\u03db'), ('\u03dd', '\u03dd'),
-        ('\u03df', '\u03df'), ('\u03e1', '\u03e1'),
-        ('\u03e3', '\u03e3'), ('\u03e5', '\u03e5'),
-        ('\u03e7', '\u03e7'), ('\u03e9', '\u03e9'),
-        ('\u03eb', '\u03eb'), ('\u03ed', '\u03ed'),
-        ('\u03ef', '\u03f3'), ('\u03f5', '\u03f5'),
-        ('\u03f8', '\u03f8'), ('\u03fb', '\u03fc'),
-        ('\u0430', '\u045f'), ('\u0461', '\u0461'),
-        ('\u0463', '\u0463'), ('\u0465', '\u0465'),
-        ('\u0467', '\u0467'), ('\u0469', '\u0469'),
-        ('\u046b', '\u046b'), ('\u046d', '\u046d'),
-        ('\u046f', '\u046f'), ('\u0471', '\u0471'),
-        ('\u0473', '\u0473'), ('\u0475', '\u0475'),
-        ('\u0477', '\u0477'), ('\u0479', '\u0479'),
-        ('\u047b', '\u047b'), ('\u047d', '\u047d'),
-        ('\u047f', '\u047f'), ('\u0481', '\u0481'),
-        ('\u048b', '\u048b'), ('\u048d', '\u048d'),
-        ('\u048f', '\u048f'), ('\u0491', '\u0491'),
-        ('\u0493', '\u0493'), ('\u0495', '\u0495'),
-        ('\u0497', '\u0497'), ('\u0499', '\u0499'),
-        ('\u049b', '\u049b'), ('\u049d', '\u049d'),
-        ('\u049f', '\u049f'), ('\u04a1', '\u04a1'),
-        ('\u04a3', '\u04a3'), ('\u04a5', '\u04a5'),
-        ('\u04a7', '\u04a7'), ('\u04a9', '\u04a9'),
-        ('\u04ab', '\u04ab'), ('\u04ad', '\u04ad'),
-        ('\u04af', '\u04af'), ('\u04b1', '\u04b1'),
-        ('\u04b3', '\u04b3'), ('\u04b5', '\u04b5'),
-        ('\u04b7', '\u04b7'), ('\u04b9', '\u04b9'),
-        ('\u04bb', '\u04bb'), ('\u04bd', '\u04bd'),
-        ('\u04bf', '\u04bf'), ('\u04c2', '\u04c2'),
-        ('\u04c4', '\u04c4'), ('\u04c6', '\u04c6'),
-        ('\u04c8', '\u04c8'), ('\u04ca', '\u04ca'),
-        ('\u04cc', '\u04cc'), ('\u04ce', '\u04cf'),
-        ('\u04d1', '\u04d1'), ('\u04d3', '\u04d3'),
-        ('\u04d5', '\u04d5'), ('\u04d7', '\u04d7'),
-        ('\u04d9', '\u04d9'), ('\u04db', '\u04db'),
-        ('\u04dd', '\u04dd'), ('\u04df', '\u04df'),
-        ('\u04e1', '\u04e1'), ('\u04e3', '\u04e3'),
-        ('\u04e5', '\u04e5'), ('\u04e7', '\u04e7'),
-        ('\u04e9', '\u04e9'), ('\u04eb', '\u04eb'),
-        ('\u04ed', '\u04ed'), ('\u04ef', '\u04ef'),
-        ('\u04f1', '\u04f1'), ('\u04f3', '\u04f3'),
-        ('\u04f5', '\u04f5'), ('\u04f7', '\u04f7'),
-        ('\u04f9', '\u04f9'), ('\u04fb', '\u04fb'),
-        ('\u04fd', '\u04fd'), ('\u04ff', '\u04ff'),
-        ('\u0501', '\u0501'), ('\u0503', '\u0503'),
-        ('\u0505', '\u0505'), ('\u0507', '\u0507'),
-        ('\u0509', '\u0509'), ('\u050b', '\u050b'),
-        ('\u050d', '\u050d'), ('\u050f', '\u050f'),
-        ('\u0511', '\u0511'), ('\u0513', '\u0513'),
-        ('\u0515', '\u0515'), ('\u0517', '\u0517'),
-        ('\u0519', '\u0519'), ('\u051b', '\u051b'),
-        ('\u051d', '\u051d'), ('\u051f', '\u051f'),
-        ('\u0521', '\u0521'), ('\u0523', '\u0523'),
-        ('\u0525', '\u0525'), ('\u0527', '\u0527'),
-        ('\u0561', '\u0587'), ('\u1d00', '\u1d2b'),
-        ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
-        ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'),
-        ('\u1d9b', '\u1dbf'), ('\u1e01', '\u1e01'),
-        ('\u1e03', '\u1e03'), ('\u1e05', '\u1e05'),
-        ('\u1e07', '\u1e07'), ('\u1e09', '\u1e09'),
-        ('\u1e0b', '\u1e0b'), ('\u1e0d', '\u1e0d'),
-        ('\u1e0f', '\u1e0f'), ('\u1e11', '\u1e11'),
-        ('\u1e13', '\u1e13'), ('\u1e15', '\u1e15'),
-        ('\u1e17', '\u1e17'), ('\u1e19', '\u1e19'),
-        ('\u1e1b', '\u1e1b'), ('\u1e1d', '\u1e1d'),
-        ('\u1e1f', '\u1e1f'), ('\u1e21', '\u1e21'),
-        ('\u1e23', '\u1e23'), ('\u1e25', '\u1e25'),
-        ('\u1e27', '\u1e27'), ('\u1e29', '\u1e29'),
-        ('\u1e2b', '\u1e2b'), ('\u1e2d', '\u1e2d'),
-        ('\u1e2f', '\u1e2f'), ('\u1e31', '\u1e31'),
-        ('\u1e33', '\u1e33'), ('\u1e35', '\u1e35'),
-        ('\u1e37', '\u1e37'), ('\u1e39', '\u1e39'),
-        ('\u1e3b', '\u1e3b'), ('\u1e3d', '\u1e3d'),
-        ('\u1e3f', '\u1e3f'), ('\u1e41', '\u1e41'),
-        ('\u1e43', '\u1e43'), ('\u1e45', '\u1e45'),
-        ('\u1e47', '\u1e47'), ('\u1e49', '\u1e49'),
-        ('\u1e4b', '\u1e4b'), ('\u1e4d', '\u1e4d'),
-        ('\u1e4f', '\u1e4f'), ('\u1e51', '\u1e51'),
-        ('\u1e53', '\u1e53'), ('\u1e55', '\u1e55'),
-        ('\u1e57', '\u1e57'), ('\u1e59', '\u1e59'),
-        ('\u1e5b', '\u1e5b'), ('\u1e5d', '\u1e5d'),
-        ('\u1e5f', '\u1e5f'), ('\u1e61', '\u1e61'),
-        ('\u1e63', '\u1e63'), ('\u1e65', '\u1e65'),
-        ('\u1e67', '\u1e67'), ('\u1e69', '\u1e69'),
-        ('\u1e6b', '\u1e6b'), ('\u1e6d', '\u1e6d'),
-        ('\u1e6f', '\u1e6f'), ('\u1e71', '\u1e71'),
-        ('\u1e73', '\u1e73'), ('\u1e75', '\u1e75'),
-        ('\u1e77', '\u1e77'), ('\u1e79', '\u1e79'),
-        ('\u1e7b', '\u1e7b'), ('\u1e7d', '\u1e7d'),
-        ('\u1e7f', '\u1e7f'), ('\u1e81', '\u1e81'),
-        ('\u1e83', '\u1e83'), ('\u1e85', '\u1e85'),
-        ('\u1e87', '\u1e87'), ('\u1e89', '\u1e89'),
-        ('\u1e8b', '\u1e8b'), ('\u1e8d', '\u1e8d'),
-        ('\u1e8f', '\u1e8f'), ('\u1e91', '\u1e91'),
-        ('\u1e93', '\u1e93'), ('\u1e95', '\u1e9d'),
-        ('\u1e9f', '\u1e9f'), ('\u1ea1', '\u1ea1'),
-        ('\u1ea3', '\u1ea3'), ('\u1ea5', '\u1ea5'),
-        ('\u1ea7', '\u1ea7'), ('\u1ea9', '\u1ea9'),
-        ('\u1eab', '\u1eab'), ('\u1ead', '\u1ead'),
-        ('\u1eaf', '\u1eaf'), ('\u1eb1', '\u1eb1'),
-        ('\u1eb3', '\u1eb3'), ('\u1eb5', '\u1eb5'),
-        ('\u1eb7', '\u1eb7'), ('\u1eb9', '\u1eb9'),
-        ('\u1ebb', '\u1ebb'), ('\u1ebd', '\u1ebd'),
-        ('\u1ebf', '\u1ebf'), ('\u1ec1', '\u1ec1'),
-        ('\u1ec3', '\u1ec3'), ('\u1ec5', '\u1ec5'),
-        ('\u1ec7', '\u1ec7'), ('\u1ec9', '\u1ec9'),
-        ('\u1ecb', '\u1ecb'), ('\u1ecd', '\u1ecd'),
-        ('\u1ecf', '\u1ecf'), ('\u1ed1', '\u1ed1'),
-        ('\u1ed3', '\u1ed3'), ('\u1ed5', '\u1ed5'),
-        ('\u1ed7', '\u1ed7'), ('\u1ed9', '\u1ed9'),
-        ('\u1edb', '\u1edb'), ('\u1edd', '\u1edd'),
-        ('\u1edf', '\u1edf'), ('\u1ee1', '\u1ee1'),
-        ('\u1ee3', '\u1ee3'), ('\u1ee5', '\u1ee5'),
-        ('\u1ee7', '\u1ee7'), ('\u1ee9', '\u1ee9'),
-        ('\u1eeb', '\u1eeb'), ('\u1eed', '\u1eed'),
-        ('\u1eef', '\u1eef'), ('\u1ef1', '\u1ef1'),
-        ('\u1ef3', '\u1ef3'), ('\u1ef5', '\u1ef5'),
-        ('\u1ef7', '\u1ef7'), ('\u1ef9', '\u1ef9'),
-        ('\u1efb', '\u1efb'), ('\u1efd', '\u1efd'),
-        ('\u1eff', '\u1f07'), ('\u1f10', '\u1f15'),
-        ('\u1f20', '\u1f27'), ('\u1f30', '\u1f37'),
-        ('\u1f40', '\u1f45'), ('\u1f50', '\u1f57'),
-        ('\u1f60', '\u1f67'), ('\u1f70', '\u1f7d'),
-        ('\u1f80', '\u1f87'), ('\u1f90', '\u1f97'),
-        ('\u1fa0', '\u1fa7'), ('\u1fb0', '\u1fb4'),
-        ('\u1fb6', '\u1fb7'), ('\u1fbe', '\u1fbe'),
-        ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fc7'),
-        ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fd7'),
-        ('\u1fe0', '\u1fe7'), ('\u1ff2', '\u1ff4'),
-        ('\u1ff6', '\u1ff7'), ('\u2071', '\u2071'),
-        ('\u207f', '\u207f'), ('\u2090', '\u209c'),
-        ('\u210a', '\u210a'), ('\u210e', '\u210f'),
-        ('\u2113', '\u2113'), ('\u212f', '\u212f'),
-        ('\u2134', '\u2134'), ('\u2139', '\u2139'),
-        ('\u213c', '\u213d'), ('\u2146', '\u2149'),
-        ('\u214e', '\u214e'), ('\u2170', '\u217f'),
-        ('\u2184', '\u2184'), ('\u24d0', '\u24e9'),
-        ('\u2c30', '\u2c5e'), ('\u2c61', '\u2c61'),
-        ('\u2c65', '\u2c66'), ('\u2c68', '\u2c68'),
-        ('\u2c6a', '\u2c6a'), ('\u2c6c', '\u2c6c'),
-        ('\u2c71', '\u2c71'), ('\u2c73', '\u2c74'),
-        ('\u2c76', '\u2c7b'), ('\u2c7c', '\u2c7d'),
-        ('\u2c81', '\u2c81'), ('\u2c83', '\u2c83'),
-        ('\u2c85', '\u2c85'), ('\u2c87', '\u2c87'),
-        ('\u2c89', '\u2c89'), ('\u2c8b', '\u2c8b'),
-        ('\u2c8d', '\u2c8d'), ('\u2c8f', '\u2c8f'),
-        ('\u2c91', '\u2c91'), ('\u2c93', '\u2c93'),
-        ('\u2c95', '\u2c95'), ('\u2c97', '\u2c97'),
-        ('\u2c99', '\u2c99'), ('\u2c9b', '\u2c9b'),
-        ('\u2c9d', '\u2c9d'), ('\u2c9f', '\u2c9f'),
-        ('\u2ca1', '\u2ca1'), ('\u2ca3', '\u2ca3'),
-        ('\u2ca5', '\u2ca5'), ('\u2ca7', '\u2ca7'),
-        ('\u2ca9', '\u2ca9'), ('\u2cab', '\u2cab'),
-        ('\u2cad', '\u2cad'), ('\u2caf', '\u2caf'),
-        ('\u2cb1', '\u2cb1'), ('\u2cb3', '\u2cb3'),
-        ('\u2cb5', '\u2cb5'), ('\u2cb7', '\u2cb7'),
-        ('\u2cb9', '\u2cb9'), ('\u2cbb', '\u2cbb'),
-        ('\u2cbd', '\u2cbd'), ('\u2cbf', '\u2cbf'),
-        ('\u2cc1', '\u2cc1'), ('\u2cc3', '\u2cc3'),
-        ('\u2cc5', '\u2cc5'), ('\u2cc7', '\u2cc7'),
-        ('\u2cc9', '\u2cc9'), ('\u2ccb', '\u2ccb'),
-        ('\u2ccd', '\u2ccd'), ('\u2ccf', '\u2ccf'),
-        ('\u2cd1', '\u2cd1'), ('\u2cd3', '\u2cd3'),
-        ('\u2cd5', '\u2cd5'), ('\u2cd7', '\u2cd7'),
-        ('\u2cd9', '\u2cd9'), ('\u2cdb', '\u2cdb'),
-        ('\u2cdd', '\u2cdd'), ('\u2cdf', '\u2cdf'),
-        ('\u2ce1', '\u2ce1'), ('\u2ce3', '\u2ce4'),
-        ('\u2cec', '\u2cec'), ('\u2cee', '\u2cee'),
-        ('\u2cf3', '\u2cf3'), ('\u2d00', '\u2d25'),
-        ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'),
-        ('\ua641', '\ua641'), ('\ua643', '\ua643'),
-        ('\ua645', '\ua645'), ('\ua647', '\ua647'),
-        ('\ua649', '\ua649'), ('\ua64b', '\ua64b'),
-        ('\ua64d', '\ua64d'), ('\ua64f', '\ua64f'),
-        ('\ua651', '\ua651'), ('\ua653', '\ua653'),
-        ('\ua655', '\ua655'), ('\ua657', '\ua657'),
-        ('\ua659', '\ua659'), ('\ua65b', '\ua65b'),
-        ('\ua65d', '\ua65d'), ('\ua65f', '\ua65f'),
-        ('\ua661', '\ua661'), ('\ua663', '\ua663'),
-        ('\ua665', '\ua665'), ('\ua667', '\ua667'),
-        ('\ua669', '\ua669'), ('\ua66b', '\ua66b'),
-        ('\ua66d', '\ua66d'), ('\ua681', '\ua681'),
-        ('\ua683', '\ua683'), ('\ua685', '\ua685'),
-        ('\ua687', '\ua687'), ('\ua689', '\ua689'),
-        ('\ua68b', '\ua68b'), ('\ua68d', '\ua68d'),
-        ('\ua68f', '\ua68f'), ('\ua691', '\ua691'),
-        ('\ua693', '\ua693'), ('\ua695', '\ua695'),
-        ('\ua697', '\ua697'), ('\ua723', '\ua723'),
-        ('\ua725', '\ua725'), ('\ua727', '\ua727'),
-        ('\ua729', '\ua729'), ('\ua72b', '\ua72b'),
-        ('\ua72d', '\ua72d'), ('\ua72f', '\ua731'),
-        ('\ua733', '\ua733'), ('\ua735', '\ua735'),
-        ('\ua737', '\ua737'), ('\ua739', '\ua739'),
-        ('\ua73b', '\ua73b'), ('\ua73d', '\ua73d'),
-        ('\ua73f', '\ua73f'), ('\ua741', '\ua741'),
-        ('\ua743', '\ua743'), ('\ua745', '\ua745'),
-        ('\ua747', '\ua747'), ('\ua749', '\ua749'),
-        ('\ua74b', '\ua74b'), ('\ua74d', '\ua74d'),
-        ('\ua74f', '\ua74f'), ('\ua751', '\ua751'),
-        ('\ua753', '\ua753'), ('\ua755', '\ua755'),
-        ('\ua757', '\ua757'), ('\ua759', '\ua759'),
-        ('\ua75b', '\ua75b'), ('\ua75d', '\ua75d'),
-        ('\ua75f', '\ua75f'), ('\ua761', '\ua761'),
-        ('\ua763', '\ua763'), ('\ua765', '\ua765'),
-        ('\ua767', '\ua767'), ('\ua769', '\ua769'),
-        ('\ua76b', '\ua76b'), ('\ua76d', '\ua76d'),
-        ('\ua76f', '\ua76f'), ('\ua770', '\ua770'),
-        ('\ua771', '\ua778'), ('\ua77a', '\ua77a'),
-        ('\ua77c', '\ua77c'), ('\ua77f', '\ua77f'),
-        ('\ua781', '\ua781'), ('\ua783', '\ua783'),
-        ('\ua785', '\ua785'), ('\ua787', '\ua787'),
-        ('\ua78c', '\ua78c'), ('\ua78e', '\ua78e'),
-        ('\ua791', '\ua791'), ('\ua793', '\ua793'),
-        ('\ua7a1', '\ua7a1'), ('\ua7a3', '\ua7a3'),
-        ('\ua7a5', '\ua7a5'), ('\ua7a7', '\ua7a7'),
-        ('\ua7a9', '\ua7a9'), ('\ua7f8', '\ua7f9'),
-        ('\ua7fa', '\ua7fa'), ('\ufb00', '\ufb06'),
-        ('\ufb13', '\ufb17'), ('\uff41', '\uff5a'),
-        ('\U00010428', '\U0001044f'), ('\U0001d41a', '\U0001d433'),
-        ('\U0001d44e', '\U0001d454'), ('\U0001d456', '\U0001d467'),
-        ('\U0001d482', '\U0001d49b'), ('\U0001d4b6', '\U0001d4b9'),
-        ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'),
-        ('\U0001d4c5', '\U0001d4cf'), ('\U0001d4ea', '\U0001d503'),
-        ('\U0001d51e', '\U0001d537'), ('\U0001d552', '\U0001d56b'),
-        ('\U0001d586', '\U0001d59f'), ('\U0001d5ba', '\U0001d5d3'),
-        ('\U0001d5ee', '\U0001d607'), ('\U0001d622', '\U0001d63b'),
-        ('\U0001d656', '\U0001d66f'), ('\U0001d68a', '\U0001d6a5'),
-        ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6e1'),
-        ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d71b'),
-        ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d755'),
-        ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d78f'),
-        ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7c9'),
-        ('\U0001d7cb', '\U0001d7cb')
-    ];
-
-    pub fn Lowercase(c: char) -> bool {
-        super::bsearch_range_table(c, Lowercase_table)
-    }
-
-    static Uppercase_table : &'static [(char,char)] = &[
-        ('\x41', '\x5a'), ('\xc0', '\xd6'),
-        ('\xd8', '\xde'), ('\u0100', '\u0100'),
-        ('\u0102', '\u0102'), ('\u0104', '\u0104'),
-        ('\u0106', '\u0106'), ('\u0108', '\u0108'),
-        ('\u010a', '\u010a'), ('\u010c', '\u010c'),
-        ('\u010e', '\u010e'), ('\u0110', '\u0110'),
-        ('\u0112', '\u0112'), ('\u0114', '\u0114'),
-        ('\u0116', '\u0116'), ('\u0118', '\u0118'),
-        ('\u011a', '\u011a'), ('\u011c', '\u011c'),
-        ('\u011e', '\u011e'), ('\u0120', '\u0120'),
-        ('\u0122', '\u0122'), ('\u0124', '\u0124'),
-        ('\u0126', '\u0126'), ('\u0128', '\u0128'),
-        ('\u012a', '\u012a'), ('\u012c', '\u012c'),
-        ('\u012e', '\u012e'), ('\u0130', '\u0130'),
-        ('\u0132', '\u0132'), ('\u0134', '\u0134'),
-        ('\u0136', '\u0136'), ('\u0139', '\u0139'),
-        ('\u013b', '\u013b'), ('\u013d', '\u013d'),
-        ('\u013f', '\u013f'), ('\u0141', '\u0141'),
-        ('\u0143', '\u0143'), ('\u0145', '\u0145'),
-        ('\u0147', '\u0147'), ('\u014a', '\u014a'),
-        ('\u014c', '\u014c'), ('\u014e', '\u014e'),
-        ('\u0150', '\u0150'), ('\u0152', '\u0152'),
-        ('\u0154', '\u0154'), ('\u0156', '\u0156'),
-        ('\u0158', '\u0158'), ('\u015a', '\u015a'),
-        ('\u015c', '\u015c'), ('\u015e', '\u015e'),
-        ('\u0160', '\u0160'), ('\u0162', '\u0162'),
-        ('\u0164', '\u0164'), ('\u0166', '\u0166'),
-        ('\u0168', '\u0168'), ('\u016a', '\u016a'),
-        ('\u016c', '\u016c'), ('\u016e', '\u016e'),
-        ('\u0170', '\u0170'), ('\u0172', '\u0172'),
-        ('\u0174', '\u0174'), ('\u0176', '\u0176'),
-        ('\u0178', '\u0179'), ('\u017b', '\u017b'),
-        ('\u017d', '\u017d'), ('\u0181', '\u0182'),
-        ('\u0184', '\u0184'), ('\u0186', '\u0187'),
-        ('\u0189', '\u018b'), ('\u018e', '\u0191'),
-        ('\u0193', '\u0194'), ('\u0196', '\u0198'),
-        ('\u019c', '\u019d'), ('\u019f', '\u01a0'),
-        ('\u01a2', '\u01a2'), ('\u01a4', '\u01a4'),
-        ('\u01a6', '\u01a7'), ('\u01a9', '\u01a9'),
-        ('\u01ac', '\u01ac'), ('\u01ae', '\u01af'),
-        ('\u01b1', '\u01b3'), ('\u01b5', '\u01b5'),
-        ('\u01b7', '\u01b8'), ('\u01bc', '\u01bc'),
-        ('\u01c4', '\u01c4'), ('\u01c7', '\u01c7'),
-        ('\u01ca', '\u01ca'), ('\u01cd', '\u01cd'),
-        ('\u01cf', '\u01cf'), ('\u01d1', '\u01d1'),
-        ('\u01d3', '\u01d3'), ('\u01d5', '\u01d5'),
-        ('\u01d7', '\u01d7'), ('\u01d9', '\u01d9'),
-        ('\u01db', '\u01db'), ('\u01de', '\u01de'),
-        ('\u01e0', '\u01e0'), ('\u01e2', '\u01e2'),
-        ('\u01e4', '\u01e4'), ('\u01e6', '\u01e6'),
-        ('\u01e8', '\u01e8'), ('\u01ea', '\u01ea'),
-        ('\u01ec', '\u01ec'), ('\u01ee', '\u01ee'),
-        ('\u01f1', '\u01f1'), ('\u01f4', '\u01f4'),
-        ('\u01f6', '\u01f8'), ('\u01fa', '\u01fa'),
-        ('\u01fc', '\u01fc'), ('\u01fe', '\u01fe'),
-        ('\u0200', '\u0200'), ('\u0202', '\u0202'),
-        ('\u0204', '\u0204'), ('\u0206', '\u0206'),
-        ('\u0208', '\u0208'), ('\u020a', '\u020a'),
-        ('\u020c', '\u020c'), ('\u020e', '\u020e'),
-        ('\u0210', '\u0210'), ('\u0212', '\u0212'),
-        ('\u0214', '\u0214'), ('\u0216', '\u0216'),
-        ('\u0218', '\u0218'), ('\u021a', '\u021a'),
-        ('\u021c', '\u021c'), ('\u021e', '\u021e'),
-        ('\u0220', '\u0220'), ('\u0222', '\u0222'),
-        ('\u0224', '\u0224'), ('\u0226', '\u0226'),
-        ('\u0228', '\u0228'), ('\u022a', '\u022a'),
-        ('\u022c', '\u022c'), ('\u022e', '\u022e'),
-        ('\u0230', '\u0230'), ('\u0232', '\u0232'),
-        ('\u023a', '\u023b'), ('\u023d', '\u023e'),
-        ('\u0241', '\u0241'), ('\u0243', '\u0246'),
-        ('\u0248', '\u0248'), ('\u024a', '\u024a'),
-        ('\u024c', '\u024c'), ('\u024e', '\u024e'),
-        ('\u0370', '\u0370'), ('\u0372', '\u0372'),
-        ('\u0376', '\u0376'), ('\u0386', '\u0386'),
-        ('\u0388', '\u038a'), ('\u038c', '\u038c'),
-        ('\u038e', '\u038f'), ('\u0391', '\u03a1'),
-        ('\u03a3', '\u03ab'), ('\u03cf', '\u03cf'),
-        ('\u03d2', '\u03d4'), ('\u03d8', '\u03d8'),
-        ('\u03da', '\u03da'), ('\u03dc', '\u03dc'),
-        ('\u03de', '\u03de'), ('\u03e0', '\u03e0'),
-        ('\u03e2', '\u03e2'), ('\u03e4', '\u03e4'),
-        ('\u03e6', '\u03e6'), ('\u03e8', '\u03e8'),
-        ('\u03ea', '\u03ea'), ('\u03ec', '\u03ec'),
-        ('\u03ee', '\u03ee'), ('\u03f4', '\u03f4'),
-        ('\u03f7', '\u03f7'), ('\u03f9', '\u03fa'),
-        ('\u03fd', '\u042f'), ('\u0460', '\u0460'),
-        ('\u0462', '\u0462'), ('\u0464', '\u0464'),
-        ('\u0466', '\u0466'), ('\u0468', '\u0468'),
-        ('\u046a', '\u046a'), ('\u046c', '\u046c'),
-        ('\u046e', '\u046e'), ('\u0470', '\u0470'),
-        ('\u0472', '\u0472'), ('\u0474', '\u0474'),
-        ('\u0476', '\u0476'), ('\u0478', '\u0478'),
-        ('\u047a', '\u047a'), ('\u047c', '\u047c'),
-        ('\u047e', '\u047e'), ('\u0480', '\u0480'),
-        ('\u048a', '\u048a'), ('\u048c', '\u048c'),
-        ('\u048e', '\u048e'), ('\u0490', '\u0490'),
-        ('\u0492', '\u0492'), ('\u0494', '\u0494'),
-        ('\u0496', '\u0496'), ('\u0498', '\u0498'),
-        ('\u049a', '\u049a'), ('\u049c', '\u049c'),
-        ('\u049e', '\u049e'), ('\u04a0', '\u04a0'),
-        ('\u04a2', '\u04a2'), ('\u04a4', '\u04a4'),
-        ('\u04a6', '\u04a6'), ('\u04a8', '\u04a8'),
-        ('\u04aa', '\u04aa'), ('\u04ac', '\u04ac'),
-        ('\u04ae', '\u04ae'), ('\u04b0', '\u04b0'),
-        ('\u04b2', '\u04b2'), ('\u04b4', '\u04b4'),
-        ('\u04b6', '\u04b6'), ('\u04b8', '\u04b8'),
-        ('\u04ba', '\u04ba'), ('\u04bc', '\u04bc'),
-        ('\u04be', '\u04be'), ('\u04c0', '\u04c1'),
-        ('\u04c3', '\u04c3'), ('\u04c5', '\u04c5'),
-        ('\u04c7', '\u04c7'), ('\u04c9', '\u04c9'),
-        ('\u04cb', '\u04cb'), ('\u04cd', '\u04cd'),
-        ('\u04d0', '\u04d0'), ('\u04d2', '\u04d2'),
-        ('\u04d4', '\u04d4'), ('\u04d6', '\u04d6'),
-        ('\u04d8', '\u04d8'), ('\u04da', '\u04da'),
-        ('\u04dc', '\u04dc'), ('\u04de', '\u04de'),
-        ('\u04e0', '\u04e0'), ('\u04e2', '\u04e2'),
-        ('\u04e4', '\u04e4'), ('\u04e6', '\u04e6'),
-        ('\u04e8', '\u04e8'), ('\u04ea', '\u04ea'),
-        ('\u04ec', '\u04ec'), ('\u04ee', '\u04ee'),
-        ('\u04f0', '\u04f0'), ('\u04f2', '\u04f2'),
-        ('\u04f4', '\u04f4'), ('\u04f6', '\u04f6'),
-        ('\u04f8', '\u04f8'), ('\u04fa', '\u04fa'),
-        ('\u04fc', '\u04fc'), ('\u04fe', '\u04fe'),
-        ('\u0500', '\u0500'), ('\u0502', '\u0502'),
-        ('\u0504', '\u0504'), ('\u0506', '\u0506'),
-        ('\u0508', '\u0508'), ('\u050a', '\u050a'),
-        ('\u050c', '\u050c'), ('\u050e', '\u050e'),
-        ('\u0510', '\u0510'), ('\u0512', '\u0512'),
-        ('\u0514', '\u0514'), ('\u0516', '\u0516'),
-        ('\u0518', '\u0518'), ('\u051a', '\u051a'),
-        ('\u051c', '\u051c'), ('\u051e', '\u051e'),
-        ('\u0520', '\u0520'), ('\u0522', '\u0522'),
-        ('\u0524', '\u0524'), ('\u0526', '\u0526'),
-        ('\u0531', '\u0556'), ('\u10a0', '\u10c5'),
-        ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
-        ('\u1e00', '\u1e00'), ('\u1e02', '\u1e02'),
-        ('\u1e04', '\u1e04'), ('\u1e06', '\u1e06'),
-        ('\u1e08', '\u1e08'), ('\u1e0a', '\u1e0a'),
-        ('\u1e0c', '\u1e0c'), ('\u1e0e', '\u1e0e'),
-        ('\u1e10', '\u1e10'), ('\u1e12', '\u1e12'),
-        ('\u1e14', '\u1e14'), ('\u1e16', '\u1e16'),
-        ('\u1e18', '\u1e18'), ('\u1e1a', '\u1e1a'),
-        ('\u1e1c', '\u1e1c'), ('\u1e1e', '\u1e1e'),
-        ('\u1e20', '\u1e20'), ('\u1e22', '\u1e22'),
-        ('\u1e24', '\u1e24'), ('\u1e26', '\u1e26'),
-        ('\u1e28', '\u1e28'), ('\u1e2a', '\u1e2a'),
-        ('\u1e2c', '\u1e2c'), ('\u1e2e', '\u1e2e'),
-        ('\u1e30', '\u1e30'), ('\u1e32', '\u1e32'),
-        ('\u1e34', '\u1e34'), ('\u1e36', '\u1e36'),
-        ('\u1e38', '\u1e38'), ('\u1e3a', '\u1e3a'),
-        ('\u1e3c', '\u1e3c'), ('\u1e3e', '\u1e3e'),
-        ('\u1e40', '\u1e40'), ('\u1e42', '\u1e42'),
-        ('\u1e44', '\u1e44'), ('\u1e46', '\u1e46'),
-        ('\u1e48', '\u1e48'), ('\u1e4a', '\u1e4a'),
-        ('\u1e4c', '\u1e4c'), ('\u1e4e', '\u1e4e'),
-        ('\u1e50', '\u1e50'), ('\u1e52', '\u1e52'),
-        ('\u1e54', '\u1e54'), ('\u1e56', '\u1e56'),
-        ('\u1e58', '\u1e58'), ('\u1e5a', '\u1e5a'),
-        ('\u1e5c', '\u1e5c'), ('\u1e5e', '\u1e5e'),
-        ('\u1e60', '\u1e60'), ('\u1e62', '\u1e62'),
-        ('\u1e64', '\u1e64'), ('\u1e66', '\u1e66'),
-        ('\u1e68', '\u1e68'), ('\u1e6a', '\u1e6a'),
-        ('\u1e6c', '\u1e6c'), ('\u1e6e', '\u1e6e'),
-        ('\u1e70', '\u1e70'), ('\u1e72', '\u1e72'),
-        ('\u1e74', '\u1e74'), ('\u1e76', '\u1e76'),
-        ('\u1e78', '\u1e78'), ('\u1e7a', '\u1e7a'),
-        ('\u1e7c', '\u1e7c'), ('\u1e7e', '\u1e7e'),
-        ('\u1e80', '\u1e80'), ('\u1e82', '\u1e82'),
-        ('\u1e84', '\u1e84'), ('\u1e86', '\u1e86'),
-        ('\u1e88', '\u1e88'), ('\u1e8a', '\u1e8a'),
-        ('\u1e8c', '\u1e8c'), ('\u1e8e', '\u1e8e'),
-        ('\u1e90', '\u1e90'), ('\u1e92', '\u1e92'),
-        ('\u1e94', '\u1e94'), ('\u1e9e', '\u1e9e'),
-        ('\u1ea0', '\u1ea0'), ('\u1ea2', '\u1ea2'),
-        ('\u1ea4', '\u1ea4'), ('\u1ea6', '\u1ea6'),
-        ('\u1ea8', '\u1ea8'), ('\u1eaa', '\u1eaa'),
-        ('\u1eac', '\u1eac'), ('\u1eae', '\u1eae'),
-        ('\u1eb0', '\u1eb0'), ('\u1eb2', '\u1eb2'),
-        ('\u1eb4', '\u1eb4'), ('\u1eb6', '\u1eb6'),
-        ('\u1eb8', '\u1eb8'), ('\u1eba', '\u1eba'),
-        ('\u1ebc', '\u1ebc'), ('\u1ebe', '\u1ebe'),
-        ('\u1ec0', '\u1ec0'), ('\u1ec2', '\u1ec2'),
-        ('\u1ec4', '\u1ec4'), ('\u1ec6', '\u1ec6'),
-        ('\u1ec8', '\u1ec8'), ('\u1eca', '\u1eca'),
-        ('\u1ecc', '\u1ecc'), ('\u1ece', '\u1ece'),
-        ('\u1ed0', '\u1ed0'), ('\u1ed2', '\u1ed2'),
-        ('\u1ed4', '\u1ed4'), ('\u1ed6', '\u1ed6'),
-        ('\u1ed8', '\u1ed8'), ('\u1eda', '\u1eda'),
-        ('\u1edc', '\u1edc'), ('\u1ede', '\u1ede'),
-        ('\u1ee0', '\u1ee0'), ('\u1ee2', '\u1ee2'),
-        ('\u1ee4', '\u1ee4'), ('\u1ee6', '\u1ee6'),
-        ('\u1ee8', '\u1ee8'), ('\u1eea', '\u1eea'),
-        ('\u1eec', '\u1eec'), ('\u1eee', '\u1eee'),
-        ('\u1ef0', '\u1ef0'), ('\u1ef2', '\u1ef2'),
-        ('\u1ef4', '\u1ef4'), ('\u1ef6', '\u1ef6'),
-        ('\u1ef8', '\u1ef8'), ('\u1efa', '\u1efa'),
-        ('\u1efc', '\u1efc'), ('\u1efe', '\u1efe'),
-        ('\u1f08', '\u1f0f'), ('\u1f18', '\u1f1d'),
-        ('\u1f28', '\u1f2f'), ('\u1f38', '\u1f3f'),
-        ('\u1f48', '\u1f4d'), ('\u1f59', '\u1f59'),
-        ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'),
-        ('\u1f5f', '\u1f5f'), ('\u1f68', '\u1f6f'),
-        ('\u1fb8', '\u1fbb'), ('\u1fc8', '\u1fcb'),
-        ('\u1fd8', '\u1fdb'), ('\u1fe8', '\u1fec'),
-        ('\u1ff8', '\u1ffb'), ('\u2102', '\u2102'),
-        ('\u2107', '\u2107'), ('\u210b', '\u210d'),
-        ('\u2110', '\u2112'), ('\u2115', '\u2115'),
-        ('\u2119', '\u211d'), ('\u2124', '\u2124'),
-        ('\u2126', '\u2126'), ('\u2128', '\u2128'),
-        ('\u212a', '\u212d'), ('\u2130', '\u2133'),
-        ('\u213e', '\u213f'), ('\u2145', '\u2145'),
-        ('\u2160', '\u216f'), ('\u2183', '\u2183'),
-        ('\u24b6', '\u24cf'), ('\u2c00', '\u2c2e'),
-        ('\u2c60', '\u2c60'), ('\u2c62', '\u2c64'),
-        ('\u2c67', '\u2c67'), ('\u2c69', '\u2c69'),
-        ('\u2c6b', '\u2c6b'), ('\u2c6d', '\u2c70'),
-        ('\u2c72', '\u2c72'), ('\u2c75', '\u2c75'),
-        ('\u2c7e', '\u2c80'), ('\u2c82', '\u2c82'),
-        ('\u2c84', '\u2c84'), ('\u2c86', '\u2c86'),
-        ('\u2c88', '\u2c88'), ('\u2c8a', '\u2c8a'),
-        ('\u2c8c', '\u2c8c'), ('\u2c8e', '\u2c8e'),
-        ('\u2c90', '\u2c90'), ('\u2c92', '\u2c92'),
-        ('\u2c94', '\u2c94'), ('\u2c96', '\u2c96'),
-        ('\u2c98', '\u2c98'), ('\u2c9a', '\u2c9a'),
-        ('\u2c9c', '\u2c9c'), ('\u2c9e', '\u2c9e'),
-        ('\u2ca0', '\u2ca0'), ('\u2ca2', '\u2ca2'),
-        ('\u2ca4', '\u2ca4'), ('\u2ca6', '\u2ca6'),
-        ('\u2ca8', '\u2ca8'), ('\u2caa', '\u2caa'),
-        ('\u2cac', '\u2cac'), ('\u2cae', '\u2cae'),
-        ('\u2cb0', '\u2cb0'), ('\u2cb2', '\u2cb2'),
-        ('\u2cb4', '\u2cb4'), ('\u2cb6', '\u2cb6'),
-        ('\u2cb8', '\u2cb8'), ('\u2cba', '\u2cba'),
-        ('\u2cbc', '\u2cbc'), ('\u2cbe', '\u2cbe'),
-        ('\u2cc0', '\u2cc0'), ('\u2cc2', '\u2cc2'),
-        ('\u2cc4', '\u2cc4'), ('\u2cc6', '\u2cc6'),
-        ('\u2cc8', '\u2cc8'), ('\u2cca', '\u2cca'),
-        ('\u2ccc', '\u2ccc'), ('\u2cce', '\u2cce'),
-        ('\u2cd0', '\u2cd0'), ('\u2cd2', '\u2cd2'),
-        ('\u2cd4', '\u2cd4'), ('\u2cd6', '\u2cd6'),
-        ('\u2cd8', '\u2cd8'), ('\u2cda', '\u2cda'),
-        ('\u2cdc', '\u2cdc'), ('\u2cde', '\u2cde'),
-        ('\u2ce0', '\u2ce0'), ('\u2ce2', '\u2ce2'),
-        ('\u2ceb', '\u2ceb'), ('\u2ced', '\u2ced'),
-        ('\u2cf2', '\u2cf2'), ('\ua640', '\ua640'),
-        ('\ua642', '\ua642'), ('\ua644', '\ua644'),
-        ('\ua646', '\ua646'), ('\ua648', '\ua648'),
-        ('\ua64a', '\ua64a'), ('\ua64c', '\ua64c'),
-        ('\ua64e', '\ua64e'), ('\ua650', '\ua650'),
-        ('\ua652', '\ua652'), ('\ua654', '\ua654'),
-        ('\ua656', '\ua656'), ('\ua658', '\ua658'),
-        ('\ua65a', '\ua65a'), ('\ua65c', '\ua65c'),
-        ('\ua65e', '\ua65e'), ('\ua660', '\ua660'),
-        ('\ua662', '\ua662'), ('\ua664', '\ua664'),
-        ('\ua666', '\ua666'), ('\ua668', '\ua668'),
-        ('\ua66a', '\ua66a'), ('\ua66c', '\ua66c'),
-        ('\ua680', '\ua680'), ('\ua682', '\ua682'),
-        ('\ua684', '\ua684'), ('\ua686', '\ua686'),
-        ('\ua688', '\ua688'), ('\ua68a', '\ua68a'),
-        ('\ua68c', '\ua68c'), ('\ua68e', '\ua68e'),
-        ('\ua690', '\ua690'), ('\ua692', '\ua692'),
-        ('\ua694', '\ua694'), ('\ua696', '\ua696'),
-        ('\ua722', '\ua722'), ('\ua724', '\ua724'),
-        ('\ua726', '\ua726'), ('\ua728', '\ua728'),
-        ('\ua72a', '\ua72a'), ('\ua72c', '\ua72c'),
-        ('\ua72e', '\ua72e'), ('\ua732', '\ua732'),
-        ('\ua734', '\ua734'), ('\ua736', '\ua736'),
-        ('\ua738', '\ua738'), ('\ua73a', '\ua73a'),
-        ('\ua73c', '\ua73c'), ('\ua73e', '\ua73e'),
-        ('\ua740', '\ua740'), ('\ua742', '\ua742'),
-        ('\ua744', '\ua744'), ('\ua746', '\ua746'),
-        ('\ua748', '\ua748'), ('\ua74a', '\ua74a'),
-        ('\ua74c', '\ua74c'), ('\ua74e', '\ua74e'),
-        ('\ua750', '\ua750'), ('\ua752', '\ua752'),
-        ('\ua754', '\ua754'), ('\ua756', '\ua756'),
-        ('\ua758', '\ua758'), ('\ua75a', '\ua75a'),
-        ('\ua75c', '\ua75c'), ('\ua75e', '\ua75e'),
-        ('\ua760', '\ua760'), ('\ua762', '\ua762'),
-        ('\ua764', '\ua764'), ('\ua766', '\ua766'),
-        ('\ua768', '\ua768'), ('\ua76a', '\ua76a'),
-        ('\ua76c', '\ua76c'), ('\ua76e', '\ua76e'),
-        ('\ua779', '\ua779'), ('\ua77b', '\ua77b'),
-        ('\ua77d', '\ua77e'), ('\ua780', '\ua780'),
-        ('\ua782', '\ua782'), ('\ua784', '\ua784'),
-        ('\ua786', '\ua786'), ('\ua78b', '\ua78b'),
-        ('\ua78d', '\ua78d'), ('\ua790', '\ua790'),
-        ('\ua792', '\ua792'), ('\ua7a0', '\ua7a0'),
-        ('\ua7a2', '\ua7a2'), ('\ua7a4', '\ua7a4'),
-        ('\ua7a6', '\ua7a6'), ('\ua7a8', '\ua7a8'),
-        ('\ua7aa', '\ua7aa'), ('\uff21', '\uff3a'),
-        ('\U00010400', '\U00010427'), ('\U0001d400', '\U0001d419'),
-        ('\U0001d434', '\U0001d44d'), ('\U0001d468', '\U0001d481'),
-        ('\U0001d49c', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
-        ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'),
-        ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b5'),
-        ('\U0001d4d0', '\U0001d4e9'), ('\U0001d504', '\U0001d505'),
-        ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
-        ('\U0001d516', '\U0001d51c'), ('\U0001d538', '\U0001d539'),
-        ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
-        ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
-        ('\U0001d56c', '\U0001d585'), ('\U0001d5a0', '\U0001d5b9'),
-        ('\U0001d5d4', '\U0001d5ed'), ('\U0001d608', '\U0001d621'),
-        ('\U0001d63c', '\U0001d655'), ('\U0001d670', '\U0001d689'),
-        ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6e2', '\U0001d6fa'),
-        ('\U0001d71c', '\U0001d734'), ('\U0001d756', '\U0001d76e'),
-        ('\U0001d790', '\U0001d7a8'), ('\U0001d7ca', '\U0001d7ca')
-    ];
-
-    pub fn Uppercase(c: char) -> bool {
-        super::bsearch_range_table(c, Uppercase_table)
-    }
-
-    static XID_Continue_table : &'static [(char,char)] = &[
-        ('\x30', '\x39'), ('\x41', '\x5a'),
-        ('\x5f', '\x5f'), ('\x61', '\x7a'),
-        ('\xaa', '\xaa'), ('\xb5', '\xb5'),
-        ('\xb7', '\xb7'), ('\xba', '\xba'),
-        ('\xc0', '\xd6'), ('\xd8', '\xf6'),
-        ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'),
-        ('\u01bc', '\u01bf'), ('\u01c0', '\u01c3'),
-        ('\u01c4', '\u0293'), ('\u0294', '\u0294'),
-        ('\u0295', '\u02af'), ('\u02b0', '\u02c1'),
-        ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'),
-        ('\u02ec', '\u02ec'), ('\u02ee', '\u02ee'),
-        ('\u0300', '\u036f'), ('\u0370', '\u0373'),
-        ('\u0374', '\u0374'), ('\u0376', '\u0377'),
-        ('\u037b', '\u037d'), ('\u0386', '\u0386'),
-        ('\u0387', '\u0387'), ('\u0388', '\u038a'),
-        ('\u038c', '\u038c'), ('\u038e', '\u03a1'),
-        ('\u03a3', '\u03f5'), ('\u03f7', '\u0481'),
-        ('\u0483', '\u0487'), ('\u048a', '\u0527'),
-        ('\u0531', '\u0556'), ('\u0559', '\u0559'),
-        ('\u0561', '\u0587'), ('\u0591', '\u05bd'),
-        ('\u05bf', '\u05bf'), ('\u05c1', '\u05c2'),
-        ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'),
-        ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'),
-        ('\u0610', '\u061a'), ('\u0620', '\u063f'),
-        ('\u0640', '\u0640'), ('\u0641', '\u064a'),
-        ('\u064b', '\u065f'), ('\u0660', '\u0669'),
-        ('\u066e', '\u066f'), ('\u0670', '\u0670'),
-        ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'),
-        ('\u06d6', '\u06dc'), ('\u06df', '\u06e4'),
-        ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'),
-        ('\u06ea', '\u06ed'), ('\u06ee', '\u06ef'),
-        ('\u06f0', '\u06f9'), ('\u06fa', '\u06fc'),
-        ('\u06ff', '\u06ff'), ('\u0710', '\u0710'),
-        ('\u0711', '\u0711'), ('\u0712', '\u072f'),
-        ('\u0730', '\u074a'), ('\u074d', '\u07a5'),
-        ('\u07a6', '\u07b0'), ('\u07b1', '\u07b1'),
-        ('\u07c0', '\u07c9'), ('\u07ca', '\u07ea'),
-        ('\u07eb', '\u07f3'), ('\u07f4', '\u07f5'),
-        ('\u07fa', '\u07fa'), ('\u0800', '\u0815'),
-        ('\u0816', '\u0819'), ('\u081a', '\u081a'),
-        ('\u081b', '\u0823'), ('\u0824', '\u0824'),
-        ('\u0825', '\u0827'), ('\u0828', '\u0828'),
-        ('\u0829', '\u082d'), ('\u0840', '\u0858'),
-        ('\u0859', '\u085b'), ('\u08a0', '\u08a0'),
-        ('\u08a2', '\u08ac'), ('\u08e4', '\u08fe'),
-        ('\u0900', '\u0902'), ('\u0903', '\u0903'),
-        ('\u0904', '\u0939'), ('\u093a', '\u093a'),
-        ('\u093b', '\u093b'), ('\u093c', '\u093c'),
-        ('\u093d', '\u093d'), ('\u093e', '\u0940'),
-        ('\u0941', '\u0948'), ('\u0949', '\u094c'),
-        ('\u094d', '\u094d'), ('\u094e', '\u094f'),
-        ('\u0950', '\u0950'), ('\u0951', '\u0957'),
-        ('\u0958', '\u0961'), ('\u0962', '\u0963'),
-        ('\u0966', '\u096f'), ('\u0971', '\u0971'),
-        ('\u0972', '\u0977'), ('\u0979', '\u097f'),
-        ('\u0981', '\u0981'), ('\u0982', '\u0983'),
-        ('\u0985', '\u098c'), ('\u098f', '\u0990'),
-        ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
-        ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
-        ('\u09bc', '\u09bc'), ('\u09bd', '\u09bd'),
-        ('\u09be', '\u09c0'), ('\u09c1', '\u09c4'),
-        ('\u09c7', '\u09c8'), ('\u09cb', '\u09cc'),
-        ('\u09cd', '\u09cd'), ('\u09ce', '\u09ce'),
-        ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'),
-        ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'),
-        ('\u09e6', '\u09ef'), ('\u09f0', '\u09f1'),
-        ('\u0a01', '\u0a02'), ('\u0a03', '\u0a03'),
-        ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'),
-        ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'),
-        ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'),
-        ('\u0a38', '\u0a39'), ('\u0a3c', '\u0a3c'),
-        ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
-        ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'),
-        ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
-        ('\u0a5e', '\u0a5e'), ('\u0a66', '\u0a6f'),
-        ('\u0a70', '\u0a71'), ('\u0a72', '\u0a74'),
-        ('\u0a75', '\u0a75'), ('\u0a81', '\u0a82'),
-        ('\u0a83', '\u0a83'), ('\u0a85', '\u0a8d'),
-        ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'),
-        ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'),
-        ('\u0ab5', '\u0ab9'), ('\u0abc', '\u0abc'),
-        ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'),
-        ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'),
-        ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
-        ('\u0acd', '\u0acd'), ('\u0ad0', '\u0ad0'),
-        ('\u0ae0', '\u0ae1'), ('\u0ae2', '\u0ae3'),
-        ('\u0ae6', '\u0aef'), ('\u0b01', '\u0b01'),
-        ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'),
-        ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'),
-        ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'),
-        ('\u0b35', '\u0b39'), ('\u0b3c', '\u0b3c'),
-        ('\u0b3d', '\u0b3d'), ('\u0b3e', '\u0b3e'),
-        ('\u0b3f', '\u0b3f'), ('\u0b40', '\u0b40'),
-        ('\u0b41', '\u0b44'), ('\u0b47', '\u0b48'),
-        ('\u0b4b', '\u0b4c'), ('\u0b4d', '\u0b4d'),
-        ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'),
-        ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'),
-        ('\u0b62', '\u0b63'), ('\u0b66', '\u0b6f'),
-        ('\u0b71', '\u0b71'), ('\u0b82', '\u0b82'),
-        ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'),
-        ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'),
-        ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'),
-        ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'),
-        ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'),
-        ('\u0bbe', '\u0bbf'), ('\u0bc0', '\u0bc0'),
-        ('\u0bc1', '\u0bc2'), ('\u0bc6', '\u0bc8'),
-        ('\u0bca', '\u0bcc'), ('\u0bcd', '\u0bcd'),
-        ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'),
-        ('\u0be6', '\u0bef'), ('\u0c01', '\u0c03'),
-        ('\u0c05', '\u0c0c'), ('\u0c0e', '\u0c10'),
-        ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c33'),
-        ('\u0c35', '\u0c39'), ('\u0c3d', '\u0c3d'),
-        ('\u0c3e', '\u0c40'), ('\u0c41', '\u0c44'),
-        ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'),
-        ('\u0c55', '\u0c56'), ('\u0c58', '\u0c59'),
-        ('\u0c60', '\u0c61'), ('\u0c62', '\u0c63'),
-        ('\u0c66', '\u0c6f'), ('\u0c82', '\u0c83'),
-        ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'),
-        ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'),
-        ('\u0cb5', '\u0cb9'), ('\u0cbc', '\u0cbc'),
-        ('\u0cbd', '\u0cbd'), ('\u0cbe', '\u0cbe'),
-        ('\u0cbf', '\u0cbf'), ('\u0cc0', '\u0cc4'),
-        ('\u0cc6', '\u0cc6'), ('\u0cc7', '\u0cc8'),
-        ('\u0cca', '\u0ccb'), ('\u0ccc', '\u0ccd'),
-        ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'),
-        ('\u0ce0', '\u0ce1'), ('\u0ce2', '\u0ce3'),
-        ('\u0ce6', '\u0cef'), ('\u0cf1', '\u0cf2'),
-        ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'),
-        ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'),
-        ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'),
-        ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'),
-        ('\u0d4a', '\u0d4c'), ('\u0d4d', '\u0d4d'),
-        ('\u0d4e', '\u0d4e'), ('\u0d57', '\u0d57'),
-        ('\u0d60', '\u0d61'), ('\u0d62', '\u0d63'),
-        ('\u0d66', '\u0d6f'), ('\u0d7a', '\u0d7f'),
-        ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'),
-        ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
-        ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'),
-        ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd1'),
-        ('\u0dd2', '\u0dd4'), ('\u0dd6', '\u0dd6'),
-        ('\u0dd8', '\u0ddf'), ('\u0df2', '\u0df3'),
-        ('\u0e01', '\u0e30'), ('\u0e31', '\u0e31'),
-        ('\u0e32', '\u0e33'), ('\u0e34', '\u0e3a'),
-        ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'),
-        ('\u0e47', '\u0e4e'), ('\u0e50', '\u0e59'),
-        ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'),
-        ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
-        ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'),
-        ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
-        ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'),
-        ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
-        ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'),
-        ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
-        ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'),
-        ('\u0ec6', '\u0ec6'), ('\u0ec8', '\u0ecd'),
-        ('\u0ed0', '\u0ed9'), ('\u0edc', '\u0edf'),
-        ('\u0f00', '\u0f00'), ('\u0f18', '\u0f19'),
-        ('\u0f20', '\u0f29'), ('\u0f35', '\u0f35'),
-        ('\u0f37', '\u0f37'), ('\u0f39', '\u0f39'),
-        ('\u0f3e', '\u0f3f'), ('\u0f40', '\u0f47'),
-        ('\u0f49', '\u0f6c'), ('\u0f71', '\u0f7e'),
-        ('\u0f7f', '\u0f7f'), ('\u0f80', '\u0f84'),
-        ('\u0f86', '\u0f87'), ('\u0f88', '\u0f8c'),
-        ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'),
-        ('\u0fc6', '\u0fc6'), ('\u1000', '\u102a'),
-        ('\u102b', '\u102c'), ('\u102d', '\u1030'),
-        ('\u1031', '\u1031'), ('\u1032', '\u1037'),
-        ('\u1038', '\u1038'), ('\u1039', '\u103a'),
-        ('\u103b', '\u103c'), ('\u103d', '\u103e'),
-        ('\u103f', '\u103f'), ('\u1040', '\u1049'),
-        ('\u1050', '\u1055'), ('\u1056', '\u1057'),
-        ('\u1058', '\u1059'), ('\u105a', '\u105d'),
-        ('\u105e', '\u1060'), ('\u1061', '\u1061'),
-        ('\u1062', '\u1064'), ('\u1065', '\u1066'),
-        ('\u1067', '\u106d'), ('\u106e', '\u1070'),
-        ('\u1071', '\u1074'), ('\u1075', '\u1081'),
-        ('\u1082', '\u1082'), ('\u1083', '\u1084'),
-        ('\u1085', '\u1086'), ('\u1087', '\u108c'),
-        ('\u108d', '\u108d'), ('\u108e', '\u108e'),
-        ('\u108f', '\u108f'), ('\u1090', '\u1099'),
-        ('\u109a', '\u109c'), ('\u109d', '\u109d'),
-        ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'),
-        ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'),
-        ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'),
-        ('\u124a', '\u124d'), ('\u1250', '\u1256'),
-        ('\u1258', '\u1258'), ('\u125a', '\u125d'),
-        ('\u1260', '\u1288'), ('\u128a', '\u128d'),
-        ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'),
-        ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'),
-        ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'),
-        ('\u12d8', '\u1310'), ('\u1312', '\u1315'),
-        ('\u1318', '\u135a'), ('\u135d', '\u135f'),
-        ('\u1369', '\u1371'), ('\u1380', '\u138f'),
-        ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
-        ('\u166f', '\u167f'), ('\u1681', '\u169a'),
-        ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'),
-        ('\u1700', '\u170c'), ('\u170e', '\u1711'),
-        ('\u1712', '\u1714'), ('\u1720', '\u1731'),
-        ('\u1732', '\u1734'), ('\u1740', '\u1751'),
-        ('\u1752', '\u1753'), ('\u1760', '\u176c'),
-        ('\u176e', '\u1770'), ('\u1772', '\u1773'),
-        ('\u1780', '\u17b3'), ('\u17b4', '\u17b5'),
-        ('\u17b6', '\u17b6'), ('\u17b7', '\u17bd'),
-        ('\u17be', '\u17c5'), ('\u17c6', '\u17c6'),
-        ('\u17c7', '\u17c8'), ('\u17c9', '\u17d3'),
-        ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'),
-        ('\u17dd', '\u17dd'), ('\u17e0', '\u17e9'),
-        ('\u180b', '\u180d'), ('\u1810', '\u1819'),
-        ('\u1820', '\u1842'), ('\u1843', '\u1843'),
-        ('\u1844', '\u1877'), ('\u1880', '\u18a8'),
-        ('\u18a9', '\u18a9'), ('\u18aa', '\u18aa'),
-        ('\u18b0', '\u18f5'), ('\u1900', '\u191c'),
-        ('\u1920', '\u1922'), ('\u1923', '\u1926'),
-        ('\u1927', '\u1928'), ('\u1929', '\u192b'),
-        ('\u1930', '\u1931'), ('\u1932', '\u1932'),
-        ('\u1933', '\u1938'), ('\u1939', '\u193b'),
-        ('\u1946', '\u194f'), ('\u1950', '\u196d'),
-        ('\u1970', '\u1974'), ('\u1980', '\u19ab'),
-        ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'),
-        ('\u19c8', '\u19c9'), ('\u19d0', '\u19d9'),
-        ('\u19da', '\u19da'), ('\u1a00', '\u1a16'),
-        ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'),
-        ('\u1a1b', '\u1a1b'), ('\u1a20', '\u1a54'),
-        ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'),
-        ('\u1a57', '\u1a57'), ('\u1a58', '\u1a5e'),
-        ('\u1a60', '\u1a60'), ('\u1a61', '\u1a61'),
-        ('\u1a62', '\u1a62'), ('\u1a63', '\u1a64'),
-        ('\u1a65', '\u1a6c'), ('\u1a6d', '\u1a72'),
-        ('\u1a73', '\u1a7c'), ('\u1a7f', '\u1a7f'),
-        ('\u1a80', '\u1a89'), ('\u1a90', '\u1a99'),
-        ('\u1aa7', '\u1aa7'), ('\u1b00', '\u1b03'),
-        ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'),
-        ('\u1b34', '\u1b34'), ('\u1b35', '\u1b35'),
-        ('\u1b36', '\u1b3a'), ('\u1b3b', '\u1b3b'),
-        ('\u1b3c', '\u1b3c'), ('\u1b3d', '\u1b41'),
-        ('\u1b42', '\u1b42'), ('\u1b43', '\u1b44'),
-        ('\u1b45', '\u1b4b'), ('\u1b50', '\u1b59'),
-        ('\u1b6b', '\u1b73'), ('\u1b80', '\u1b81'),
-        ('\u1b82', '\u1b82'), ('\u1b83', '\u1ba0'),
-        ('\u1ba1', '\u1ba1'), ('\u1ba2', '\u1ba5'),
-        ('\u1ba6', '\u1ba7'), ('\u1ba8', '\u1ba9'),
-        ('\u1baa', '\u1baa'), ('\u1bab', '\u1bab'),
-        ('\u1bac', '\u1bad'), ('\u1bae', '\u1baf'),
-        ('\u1bb0', '\u1bb9'), ('\u1bba', '\u1be5'),
-        ('\u1be6', '\u1be6'), ('\u1be7', '\u1be7'),
-        ('\u1be8', '\u1be9'), ('\u1bea', '\u1bec'),
-        ('\u1bed', '\u1bed'), ('\u1bee', '\u1bee'),
-        ('\u1bef', '\u1bf1'), ('\u1bf2', '\u1bf3'),
-        ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'),
-        ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
-        ('\u1c36', '\u1c37'), ('\u1c40', '\u1c49'),
-        ('\u1c4d', '\u1c4f'), ('\u1c50', '\u1c59'),
-        ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'),
-        ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1ce0'),
-        ('\u1ce1', '\u1ce1'), ('\u1ce2', '\u1ce8'),
-        ('\u1ce9', '\u1cec'), ('\u1ced', '\u1ced'),
-        ('\u1cee', '\u1cf1'), ('\u1cf2', '\u1cf3'),
-        ('\u1cf4', '\u1cf4'), ('\u1cf5', '\u1cf6'),
-        ('\u1d00', '\u1d2b'), ('\u1d2c', '\u1d6a'),
-        ('\u1d6b', '\u1d77'), ('\u1d78', '\u1d78'),
-        ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbf'),
-        ('\u1dc0', '\u1de6'), ('\u1dfc', '\u1dff'),
-        ('\u1e00', '\u1f15'), ('\u1f18', '\u1f1d'),
-        ('\u1f20', '\u1f45'), ('\u1f48', '\u1f4d'),
-        ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'),
-        ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'),
-        ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'),
-        ('\u1fb6', '\u1fbc'), ('\u1fbe', '\u1fbe'),
-        ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'),
-        ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fdb'),
-        ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'),
-        ('\u1ff6', '\u1ffc'), ('\u203f', '\u2040'),
-        ('\u2054', '\u2054'), ('\u2071', '\u2071'),
-        ('\u207f', '\u207f'), ('\u2090', '\u209c'),
-        ('\u20d0', '\u20dc'), ('\u20e1', '\u20e1'),
-        ('\u20e5', '\u20f0'), ('\u2102', '\u2102'),
-        ('\u2107', '\u2107'), ('\u210a', '\u2113'),
-        ('\u2115', '\u2115'), ('\u2118', '\u2118'),
-        ('\u2119', '\u211d'), ('\u2124', '\u2124'),
-        ('\u2126', '\u2126'), ('\u2128', '\u2128'),
-        ('\u212a', '\u212d'), ('\u212e', '\u212e'),
-        ('\u212f', '\u2134'), ('\u2135', '\u2138'),
-        ('\u2139', '\u2139'), ('\u213c', '\u213f'),
-        ('\u2145', '\u2149'), ('\u214e', '\u214e'),
-        ('\u2160', '\u2182'), ('\u2183', '\u2184'),
-        ('\u2185', '\u2188'), ('\u2c00', '\u2c2e'),
-        ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'),
-        ('\u2c7c', '\u2c7d'), ('\u2c7e', '\u2ce4'),
-        ('\u2ceb', '\u2cee'), ('\u2cef', '\u2cf1'),
-        ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'),
-        ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'),
-        ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'),
-        ('\u2d7f', '\u2d7f'), ('\u2d80', '\u2d96'),
-        ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'),
-        ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'),
-        ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'),
-        ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'),
-        ('\u2de0', '\u2dff'), ('\u3005', '\u3005'),
-        ('\u3006', '\u3006'), ('\u3007', '\u3007'),
-        ('\u3021', '\u3029'), ('\u302a', '\u302d'),
-        ('\u302e', '\u302f'), ('\u3031', '\u3035'),
-        ('\u3038', '\u303a'), ('\u303b', '\u303b'),
-        ('\u303c', '\u303c'), ('\u3041', '\u3096'),
-        ('\u3099', '\u309a'), ('\u309d', '\u309e'),
-        ('\u309f', '\u309f'), ('\u30a1', '\u30fa'),
-        ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'),
-        ('\u3105', '\u312d'), ('\u3131', '\u318e'),
-        ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'),
-        ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'),
-        ('\ua000', '\ua014'), ('\ua015', '\ua015'),
-        ('\ua016', '\ua48c'), ('\ua4d0', '\ua4f7'),
-        ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'),
-        ('\ua60c', '\ua60c'), ('\ua610', '\ua61f'),
-        ('\ua620', '\ua629'), ('\ua62a', '\ua62b'),
-        ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'),
-        ('\ua66f', '\ua66f'), ('\ua674', '\ua67d'),
-        ('\ua67f', '\ua67f'), ('\ua680', '\ua697'),
-        ('\ua69f', '\ua69f'), ('\ua6a0', '\ua6e5'),
-        ('\ua6e6', '\ua6ef'), ('\ua6f0', '\ua6f1'),
-        ('\ua717', '\ua71f'), ('\ua722', '\ua76f'),
-        ('\ua770', '\ua770'), ('\ua771', '\ua787'),
-        ('\ua788', '\ua788'), ('\ua78b', '\ua78e'),
-        ('\ua790', '\ua793'), ('\ua7a0', '\ua7aa'),
-        ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'),
-        ('\ua7fb', '\ua801'), ('\ua802', '\ua802'),
-        ('\ua803', '\ua805'), ('\ua806', '\ua806'),
-        ('\ua807', '\ua80a'), ('\ua80b', '\ua80b'),
-        ('\ua80c', '\ua822'), ('\ua823', '\ua824'),
-        ('\ua825', '\ua826'), ('\ua827', '\ua827'),
-        ('\ua840', '\ua873'), ('\ua880', '\ua881'),
-        ('\ua882', '\ua8b3'), ('\ua8b4', '\ua8c3'),
-        ('\ua8c4', '\ua8c4'), ('\ua8d0', '\ua8d9'),
-        ('\ua8e0', '\ua8f1'), ('\ua8f2', '\ua8f7'),
-        ('\ua8fb', '\ua8fb'), ('\ua900', '\ua909'),
-        ('\ua90a', '\ua925'), ('\ua926', '\ua92d'),
-        ('\ua930', '\ua946'), ('\ua947', '\ua951'),
-        ('\ua952', '\ua953'), ('\ua960', '\ua97c'),
-        ('\ua980', '\ua982'), ('\ua983', '\ua983'),
-        ('\ua984', '\ua9b2'), ('\ua9b3', '\ua9b3'),
-        ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'),
-        ('\ua9ba', '\ua9bb'), ('\ua9bc', '\ua9bc'),
-        ('\ua9bd', '\ua9c0'), ('\ua9cf', '\ua9cf'),
-        ('\ua9d0', '\ua9d9'), ('\uaa00', '\uaa28'),
-        ('\uaa29', '\uaa2e'), ('\uaa2f', '\uaa30'),
-        ('\uaa31', '\uaa32'), ('\uaa33', '\uaa34'),
-        ('\uaa35', '\uaa36'), ('\uaa40', '\uaa42'),
-        ('\uaa43', '\uaa43'), ('\uaa44', '\uaa4b'),
-        ('\uaa4c', '\uaa4c'), ('\uaa4d', '\uaa4d'),
-        ('\uaa50', '\uaa59'), ('\uaa60', '\uaa6f'),
-        ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
-        ('\uaa7a', '\uaa7a'), ('\uaa7b', '\uaa7b'),
-        ('\uaa80', '\uaaaf'), ('\uaab0', '\uaab0'),
-        ('\uaab1', '\uaab1'), ('\uaab2', '\uaab4'),
-        ('\uaab5', '\uaab6'), ('\uaab7', '\uaab8'),
-        ('\uaab9', '\uaabd'), ('\uaabe', '\uaabf'),
-        ('\uaac0', '\uaac0'), ('\uaac1', '\uaac1'),
-        ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
-        ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'),
-        ('\uaaeb', '\uaaeb'), ('\uaaec', '\uaaed'),
-        ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'),
-        ('\uaaf3', '\uaaf4'), ('\uaaf5', '\uaaf5'),
-        ('\uaaf6', '\uaaf6'), ('\uab01', '\uab06'),
-        ('\uab09', '\uab0e'), ('\uab11', '\uab16'),
-        ('\uab20', '\uab26'), ('\uab28', '\uab2e'),
-        ('\uabc0', '\uabe2'), ('\uabe3', '\uabe4'),
-        ('\uabe5', '\uabe5'), ('\uabe6', '\uabe7'),
-        ('\uabe8', '\uabe8'), ('\uabe9', '\uabea'),
-        ('\uabec', '\uabec'), ('\uabed', '\uabed'),
-        ('\uabf0', '\uabf9'), ('\uac00', '\ud7a3'),
-        ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'),
-        ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
-        ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'),
-        ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'),
-        ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'),
-        ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
-        ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'),
-        ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufc5d'),
-        ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'),
-        ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdf9'),
-        ('\ufe00', '\ufe0f'), ('\ufe20', '\ufe26'),
-        ('\ufe33', '\ufe34'), ('\ufe4d', '\ufe4f'),
-        ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'),
-        ('\ufe77', '\ufe77'), ('\ufe79', '\ufe79'),
-        ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'),
-        ('\ufe7f', '\ufefc'), ('\uff10', '\uff19'),
-        ('\uff21', '\uff3a'), ('\uff3f', '\uff3f'),
-        ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
-        ('\uff70', '\uff70'), ('\uff71', '\uff9d'),
-        ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'),
-        ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
-        ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'),
-        ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'),
-        ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'),
-        ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
-        ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'),
-        ('\U000101fd', '\U000101fd'), ('\U00010280', '\U0001029c'),
-        ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031e'),
-        ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'),
-        ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'),
-        ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'),
-        ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'),
-        ('\U00010400', '\U0001044f'), ('\U00010450', '\U0001049d'),
-        ('\U000104a0', '\U000104a9'), ('\U00010800', '\U00010805'),
-        ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
-        ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
-        ('\U0001083f', '\U00010855'), ('\U00010900', '\U00010915'),
-        ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
-        ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'),
-        ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'),
-        ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'),
-        ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'),
-        ('\U00010a38', '\U00010a3a'), ('\U00010a3f', '\U00010a3f'),
-        ('\U00010a60', '\U00010a7c'), ('\U00010b00', '\U00010b35'),
-        ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
-        ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'),
-        ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'),
-        ('\U00011003', '\U00011037'), ('\U00011038', '\U00011046'),
-        ('\U00011066', '\U0001106f'), ('\U00011080', '\U00011081'),
-        ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'),
-        ('\U000110b0', '\U000110b2'), ('\U000110b3', '\U000110b6'),
-        ('\U000110b7', '\U000110b8'), ('\U000110b9', '\U000110ba'),
-        ('\U000110d0', '\U000110e8'), ('\U000110f0', '\U000110f9'),
-        ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'),
-        ('\U00011127', '\U0001112b'), ('\U0001112c', '\U0001112c'),
-        ('\U0001112d', '\U00011134'), ('\U00011136', '\U0001113f'),
-        ('\U00011180', '\U00011181'), ('\U00011182', '\U00011182'),
-        ('\U00011183', '\U000111b2'), ('\U000111b3', '\U000111b5'),
-        ('\U000111b6', '\U000111be'), ('\U000111bf', '\U000111c0'),
-        ('\U000111c1', '\U000111c4'), ('\U000111d0', '\U000111d9'),
-        ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'),
-        ('\U000116ac', '\U000116ac'), ('\U000116ad', '\U000116ad'),
-        ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
-        ('\U000116b6', '\U000116b6'), ('\U000116b7', '\U000116b7'),
-        ('\U000116c0', '\U000116c9'), ('\U00012000', '\U0001236e'),
-        ('\U00012400', '\U00012462'), ('\U00013000', '\U0001342e'),
-        ('\U00016800', '\U00016a38'), ('\U00016f00', '\U00016f44'),
-        ('\U00016f50', '\U00016f50'), ('\U00016f51', '\U00016f7e'),
-        ('\U00016f8f', '\U00016f92'), ('\U00016f93', '\U00016f9f'),
-        ('\U0001b000', '\U0001b001'), ('\U0001d165', '\U0001d166'),
-        ('\U0001d167', '\U0001d169'), ('\U0001d16d', '\U0001d172'),
-        ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'),
-        ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'),
-        ('\U0001d400', '\U0001d454'), ('\U0001d456', '\U0001d49c'),
-        ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
-        ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
-        ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'),
-        ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
-        ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
-        ('\U0001d516', '\U0001d51c'), ('\U0001d51e', '\U0001d539'),
-        ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
-        ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
-        ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'),
-        ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
-        ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'),
-        ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d76e'),
-        ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
-        ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'),
-        ('\U0001d7ce', '\U0001d7ff'), ('\U0001ee00', '\U0001ee03'),
-        ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
-        ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'),
-        ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'),
-        ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
-        ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'),
-        ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'),
-        ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
-        ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'),
-        ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'),
-        ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
-        ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'),
-        ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'),
-        ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
-        ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'),
-        ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'),
-        ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
-        ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'),
-        ('\U0002b740', '\U0002b81d'), ('\U0002f800', '\U0002fa1d'),
-        ('\U000e0100', '\U000e01ef')
-    ];
-
-    pub fn XID_Continue(c: char) -> bool {
-        super::bsearch_range_table(c, XID_Continue_table)
-    }
-
-    static XID_Start_table : &'static [(char,char)] = &[
-        ('\x41', '\x5a'), ('\x61', '\x7a'),
-        ('\xaa', '\xaa'), ('\xb5', '\xb5'),
-        ('\xba', '\xba'), ('\xc0', '\xd6'),
-        ('\xd8', '\xf6'), ('\xf8', '\u01ba'),
-        ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'),
-        ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'),
-        ('\u0294', '\u0294'), ('\u0295', '\u02af'),
-        ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'),
-        ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'),
-        ('\u02ee', '\u02ee'), ('\u0370', '\u0373'),
-        ('\u0374', '\u0374'), ('\u0376', '\u0377'),
-        ('\u037b', '\u037d'), ('\u0386', '\u0386'),
-        ('\u0388', '\u038a'), ('\u038c', '\u038c'),
-        ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'),
-        ('\u03f7', '\u0481'), ('\u048a', '\u0527'),
-        ('\u0531', '\u0556'), ('\u0559', '\u0559'),
-        ('\u0561', '\u0587'), ('\u05d0', '\u05ea'),
-        ('\u05f0', '\u05f2'), ('\u0620', '\u063f'),
-        ('\u0640', '\u0640'), ('\u0641', '\u064a'),
-        ('\u066e', '\u066f'), ('\u0671', '\u06d3'),
-        ('\u06d5', '\u06d5'), ('\u06e5', '\u06e6'),
-        ('\u06ee', '\u06ef'), ('\u06fa', '\u06fc'),
-        ('\u06ff', '\u06ff'), ('\u0710', '\u0710'),
-        ('\u0712', '\u072f'), ('\u074d', '\u07a5'),
-        ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'),
-        ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
-        ('\u0800', '\u0815'), ('\u081a', '\u081a'),
-        ('\u0824', '\u0824'), ('\u0828', '\u0828'),
-        ('\u0840', '\u0858'), ('\u08a0', '\u08a0'),
-        ('\u08a2', '\u08ac'), ('\u0904', '\u0939'),
-        ('\u093d', '\u093d'), ('\u0950', '\u0950'),
-        ('\u0958', '\u0961'), ('\u0971', '\u0971'),
-        ('\u0972', '\u0977'), ('\u0979', '\u097f'),
-        ('\u0985', '\u098c'), ('\u098f', '\u0990'),
-        ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
-        ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
-        ('\u09bd', '\u09bd'), ('\u09ce', '\u09ce'),
-        ('\u09dc', '\u09dd'), ('\u09df', '\u09e1'),
-        ('\u09f0', '\u09f1'), ('\u0a05', '\u0a0a'),
-        ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'),
-        ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'),
-        ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'),
-        ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'),
-        ('\u0a72', '\u0a74'), ('\u0a85', '\u0a8d'),
-        ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'),
-        ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'),
-        ('\u0ab5', '\u0ab9'), ('\u0abd', '\u0abd'),
-        ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'),
-        ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'),
-        ('\u0b13', '\u0b28'), ('\u0b2a', '\u0b30'),
-        ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'),
-        ('\u0b3d', '\u0b3d'), ('\u0b5c', '\u0b5d'),
-        ('\u0b5f', '\u0b61'), ('\u0b71', '\u0b71'),
-        ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'),
-        ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'),
-        ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'),
-        ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'),
-        ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'),
-        ('\u0bd0', '\u0bd0'), ('\u0c05', '\u0c0c'),
-        ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'),
-        ('\u0c2a', '\u0c33'), ('\u0c35', '\u0c39'),
-        ('\u0c3d', '\u0c3d'), ('\u0c58', '\u0c59'),
-        ('\u0c60', '\u0c61'), ('\u0c85', '\u0c8c'),
-        ('\u0c8e', '\u0c90'), ('\u0c92', '\u0ca8'),
-        ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'),
-        ('\u0cbd', '\u0cbd'), ('\u0cde', '\u0cde'),
-        ('\u0ce0', '\u0ce1'), ('\u0cf1', '\u0cf2'),
-        ('\u0d05', '\u0d0c'), ('\u0d0e', '\u0d10'),
-        ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'),
-        ('\u0d4e', '\u0d4e'), ('\u0d60', '\u0d61'),
-        ('\u0d7a', '\u0d7f'), ('\u0d85', '\u0d96'),
-        ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
-        ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'),
-        ('\u0e01', '\u0e30'), ('\u0e32', '\u0e32'),
-        ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'),
-        ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'),
-        ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
-        ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'),
-        ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
-        ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'),
-        ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
-        ('\u0eb2', '\u0eb2'), ('\u0ebd', '\u0ebd'),
-        ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'),
-        ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'),
-        ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'),
-        ('\u0f88', '\u0f8c'), ('\u1000', '\u102a'),
-        ('\u103f', '\u103f'), ('\u1050', '\u1055'),
-        ('\u105a', '\u105d'), ('\u1061', '\u1061'),
-        ('\u1065', '\u1066'), ('\u106e', '\u1070'),
-        ('\u1075', '\u1081'), ('\u108e', '\u108e'),
-        ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'),
-        ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'),
-        ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'),
-        ('\u124a', '\u124d'), ('\u1250', '\u1256'),
-        ('\u1258', '\u1258'), ('\u125a', '\u125d'),
-        ('\u1260', '\u1288'), ('\u128a', '\u128d'),
-        ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'),
-        ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'),
-        ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'),
-        ('\u12d8', '\u1310'), ('\u1312', '\u1315'),
-        ('\u1318', '\u135a'), ('\u1380', '\u138f'),
-        ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
-        ('\u166f', '\u167f'), ('\u1681', '\u169a'),
-        ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'),
-        ('\u1700', '\u170c'), ('\u170e', '\u1711'),
-        ('\u1720', '\u1731'), ('\u1740', '\u1751'),
-        ('\u1760', '\u176c'), ('\u176e', '\u1770'),
-        ('\u1780', '\u17b3'), ('\u17d7', '\u17d7'),
-        ('\u17dc', '\u17dc'), ('\u1820', '\u1842'),
-        ('\u1843', '\u1843'), ('\u1844', '\u1877'),
-        ('\u1880', '\u18a8'), ('\u18aa', '\u18aa'),
-        ('\u18b0', '\u18f5'), ('\u1900', '\u191c'),
-        ('\u1950', '\u196d'), ('\u1970', '\u1974'),
-        ('\u1980', '\u19ab'), ('\u19c1', '\u19c7'),
-        ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'),
-        ('\u1aa7', '\u1aa7'), ('\u1b05', '\u1b33'),
-        ('\u1b45', '\u1b4b'), ('\u1b83', '\u1ba0'),
-        ('\u1bae', '\u1baf'), ('\u1bba', '\u1be5'),
-        ('\u1c00', '\u1c23'), ('\u1c4d', '\u1c4f'),
-        ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'),
-        ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'),
-        ('\u1cf5', '\u1cf6'), ('\u1d00', '\u1d2b'),
-        ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
-        ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'),
-        ('\u1d9b', '\u1dbf'), ('\u1e00', '\u1f15'),
-        ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
-        ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
-        ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
-        ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
-        ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
-        ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
-        ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
-        ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'),
-        ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
-        ('\u2071', '\u2071'), ('\u207f', '\u207f'),
-        ('\u2090', '\u209c'), ('\u2102', '\u2102'),
-        ('\u2107', '\u2107'), ('\u210a', '\u2113'),
-        ('\u2115', '\u2115'), ('\u2118', '\u2118'),
-        ('\u2119', '\u211d'), ('\u2124', '\u2124'),
-        ('\u2126', '\u2126'), ('\u2128', '\u2128'),
-        ('\u212a', '\u212d'), ('\u212e', '\u212e'),
-        ('\u212f', '\u2134'), ('\u2135', '\u2138'),
-        ('\u2139', '\u2139'), ('\u213c', '\u213f'),
-        ('\u2145', '\u2149'), ('\u214e', '\u214e'),
-        ('\u2160', '\u2182'), ('\u2183', '\u2184'),
-        ('\u2185', '\u2188'), ('\u2c00', '\u2c2e'),
-        ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'),
-        ('\u2c7c', '\u2c7d'), ('\u2c7e', '\u2ce4'),
-        ('\u2ceb', '\u2cee'), ('\u2cf2', '\u2cf3'),
-        ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'),
-        ('\u2d2d', '\u2d2d'), ('\u2d30', '\u2d67'),
-        ('\u2d6f', '\u2d6f'), ('\u2d80', '\u2d96'),
-        ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'),
-        ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'),
-        ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'),
-        ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'),
-        ('\u3005', '\u3005'), ('\u3006', '\u3006'),
-        ('\u3007', '\u3007'), ('\u3021', '\u3029'),
-        ('\u3031', '\u3035'), ('\u3038', '\u303a'),
-        ('\u303b', '\u303b'), ('\u303c', '\u303c'),
-        ('\u3041', '\u3096'), ('\u309d', '\u309e'),
-        ('\u309f', '\u309f'), ('\u30a1', '\u30fa'),
-        ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'),
-        ('\u3105', '\u312d'), ('\u3131', '\u318e'),
-        ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'),
-        ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'),
-        ('\ua000', '\ua014'), ('\ua015', '\ua015'),
-        ('\ua016', '\ua48c'), ('\ua4d0', '\ua4f7'),
-        ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'),
-        ('\ua60c', '\ua60c'), ('\ua610', '\ua61f'),
-        ('\ua62a', '\ua62b'), ('\ua640', '\ua66d'),
-        ('\ua66e', '\ua66e'), ('\ua67f', '\ua67f'),
-        ('\ua680', '\ua697'), ('\ua6a0', '\ua6e5'),
-        ('\ua6e6', '\ua6ef'), ('\ua717', '\ua71f'),
-        ('\ua722', '\ua76f'), ('\ua770', '\ua770'),
-        ('\ua771', '\ua787'), ('\ua788', '\ua788'),
-        ('\ua78b', '\ua78e'), ('\ua790', '\ua793'),
-        ('\ua7a0', '\ua7aa'), ('\ua7f8', '\ua7f9'),
-        ('\ua7fa', '\ua7fa'), ('\ua7fb', '\ua801'),
-        ('\ua803', '\ua805'), ('\ua807', '\ua80a'),
-        ('\ua80c', '\ua822'), ('\ua840', '\ua873'),
-        ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'),
-        ('\ua8fb', '\ua8fb'), ('\ua90a', '\ua925'),
-        ('\ua930', '\ua946'), ('\ua960', '\ua97c'),
-        ('\ua984', '\ua9b2'), ('\ua9cf', '\ua9cf'),
-        ('\uaa00', '\uaa28'), ('\uaa40', '\uaa42'),
-        ('\uaa44', '\uaa4b'), ('\uaa60', '\uaa6f'),
-        ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
-        ('\uaa7a', '\uaa7a'), ('\uaa80', '\uaaaf'),
-        ('\uaab1', '\uaab1'), ('\uaab5', '\uaab6'),
-        ('\uaab9', '\uaabd'), ('\uaac0', '\uaac0'),
-        ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
-        ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'),
-        ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'),
-        ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
-        ('\uab11', '\uab16'), ('\uab20', '\uab26'),
-        ('\uab28', '\uab2e'), ('\uabc0', '\uabe2'),
-        ('\uac00', '\ud7a3'), ('\ud7b0', '\ud7c6'),
-        ('\ud7cb', '\ud7fb'), ('\uf900', '\ufa6d'),
-        ('\ufa70', '\ufad9'), ('\ufb00', '\ufb06'),
-        ('\ufb13', '\ufb17'), ('\ufb1d', '\ufb1d'),
-        ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'),
-        ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
-        ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'),
-        ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufc5d'),
-        ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'),
-        ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdf9'),
-        ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'),
-        ('\ufe77', '\ufe77'), ('\ufe79', '\ufe79'),
-        ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'),
-        ('\ufe7f', '\ufefc'), ('\uff21', '\uff3a'),
-        ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
-        ('\uff70', '\uff70'), ('\uff71', '\uff9d'),
-        ('\uffa0', '\uffbe'), ('\uffc2', '\uffc7'),
-        ('\uffca', '\uffcf'), ('\uffd2', '\uffd7'),
-        ('\uffda', '\uffdc'), ('\U00010000', '\U0001000b'),
-        ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'),
-        ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'),
-        ('\U00010050', '\U0001005d'), ('\U00010080', '\U000100fa'),
-        ('\U00010140', '\U00010174'), ('\U00010280', '\U0001029c'),
-        ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031e'),
-        ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'),
-        ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'),
-        ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'),
-        ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'),
-        ('\U00010400', '\U0001044f'), ('\U00010450', '\U0001049d'),
-        ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'),
-        ('\U0001080a', '\U00010835'), ('\U00010837', '\U00010838'),
-        ('\U0001083c', '\U0001083c'), ('\U0001083f', '\U00010855'),
-        ('\U00010900', '\U00010915'), ('\U00010920', '\U00010939'),
-        ('\U00010980', '\U000109b7'), ('\U000109be', '\U000109bf'),
-        ('\U00010a00', '\U00010a00'), ('\U00010a10', '\U00010a13'),
-        ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'),
-        ('\U00010a60', '\U00010a7c'), ('\U00010b00', '\U00010b35'),
-        ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
-        ('\U00010c00', '\U00010c48'), ('\U00011003', '\U00011037'),
-        ('\U00011083', '\U000110af'), ('\U000110d0', '\U000110e8'),
-        ('\U00011103', '\U00011126'), ('\U00011183', '\U000111b2'),
-        ('\U000111c1', '\U000111c4'), ('\U00011680', '\U000116aa'),
-        ('\U00012000', '\U0001236e'), ('\U00012400', '\U00012462'),
-        ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
-        ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'),
-        ('\U00016f93', '\U00016f9f'), ('\U0001b000', '\U0001b001'),
-        ('\U0001d400', '\U0001d454'), ('\U0001d456', '\U0001d49c'),
-        ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
-        ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
-        ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'),
-        ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
-        ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
-        ('\U0001d516', '\U0001d51c'), ('\U0001d51e', '\U0001d539'),
-        ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
-        ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
-        ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'),
-        ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
-        ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'),
-        ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d76e'),
-        ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
-        ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'),
-        ('\U0001ee00', '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'),
-        ('\U0001ee21', '\U0001ee22'), ('\U0001ee24', '\U0001ee24'),
-        ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'),
-        ('\U0001ee34', '\U0001ee37'), ('\U0001ee39', '\U0001ee39'),
-        ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42', '\U0001ee42'),
-        ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'),
-        ('\U0001ee4b', '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'),
-        ('\U0001ee51', '\U0001ee52'), ('\U0001ee54', '\U0001ee54'),
-        ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'),
-        ('\U0001ee5b', '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'),
-        ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61', '\U0001ee62'),
-        ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'),
-        ('\U0001ee6c', '\U0001ee72'), ('\U0001ee74', '\U0001ee77'),
-        ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e', '\U0001ee7e'),
-        ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'),
-        ('\U0001eea1', '\U0001eea3'), ('\U0001eea5', '\U0001eea9'),
-        ('\U0001eeab', '\U0001eebb'), ('\U00020000', '\U0002a6d6'),
-        ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'),
-        ('\U0002f800', '\U0002fa1d')
-    ];
-
-    pub fn XID_Start(c: char) -> bool {
-        super::bsearch_range_table(c, XID_Start_table)
-    }
-
-}
-
-pub mod property {
-    static White_Space_table : &'static [(char,char)] = &[
-        ('\x09', '\x0d'), ('\x20', '\x20'),
-        ('\x85', '\x85'), ('\xa0', '\xa0'),
-        ('\u1680', '\u1680'), ('\u2000', '\u200a'),
-        ('\u2028', '\u2028'), ('\u2029', '\u2029'),
-        ('\u202f', '\u202f'), ('\u205f', '\u205f'),
-        ('\u3000', '\u3000')
-    ];
-
-    pub fn White_Space(c: char) -> bool {
-        super::bsearch_range_table(c, White_Space_table)
-    }
-
-}
-
-pub mod conversions {
-    use cmp::{Equal, Less, Greater};
-    use slice::ImmutableVector;
-    use tuple::Tuple2;
-    use option::{Option, Some, None};
-
-    pub fn to_lower(c: char) -> char {
-        match bsearch_case_table(c, LuLl_table) {
-          None        => c,
-          Some(index) => LuLl_table[index].val1()
-        }
-    }
-
-    pub fn to_upper(c: char) -> char {
-        match bsearch_case_table(c, LlLu_table) {
-            None        => c,
-            Some(index) => LlLu_table[index].val1()
-        }
-    }
-
-    fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<uint> {
-        table.bsearch(|&(key, _)| {
-            if c == key { Equal }
-            else if key < c { Less }
-            else { Greater }
-        })
-    }
-
-    static LuLl_table : &'static [(char, char)] = &[
-        ('\x41', '\x61'), ('\x42', '\x62'),
-        ('\x43', '\x63'), ('\x44', '\x64'),
-        ('\x45', '\x65'), ('\x46', '\x66'),
-        ('\x47', '\x67'), ('\x48', '\x68'),
-        ('\x49', '\x69'), ('\x4a', '\x6a'),
-        ('\x4b', '\x6b'), ('\x4c', '\x6c'),
-        ('\x4d', '\x6d'), ('\x4e', '\x6e'),
-        ('\x4f', '\x6f'), ('\x50', '\x70'),
-        ('\x51', '\x71'), ('\x52', '\x72'),
-        ('\x53', '\x73'), ('\x54', '\x74'),
-        ('\x55', '\x75'), ('\x56', '\x76'),
-        ('\x57', '\x77'), ('\x58', '\x78'),
-        ('\x59', '\x79'), ('\x5a', '\x7a'),
-        ('\xc0', '\xe0'), ('\xc1', '\xe1'),
-        ('\xc2', '\xe2'), ('\xc3', '\xe3'),
-        ('\xc4', '\xe4'), ('\xc5', '\xe5'),
-        ('\xc6', '\xe6'), ('\xc7', '\xe7'),
-        ('\xc8', '\xe8'), ('\xc9', '\xe9'),
-        ('\xca', '\xea'), ('\xcb', '\xeb'),
-        ('\xcc', '\xec'), ('\xcd', '\xed'),
-        ('\xce', '\xee'), ('\xcf', '\xef'),
-        ('\xd0', '\xf0'), ('\xd1', '\xf1'),
-        ('\xd2', '\xf2'), ('\xd3', '\xf3'),
-        ('\xd4', '\xf4'), ('\xd5', '\xf5'),
-        ('\xd6', '\xf6'), ('\xd8', '\xf8'),
-        ('\xd9', '\xf9'), ('\xda', '\xfa'),
-        ('\xdb', '\xfb'), ('\xdc', '\xfc'),
-        ('\xdd', '\xfd'), ('\xde', '\xfe'),
-        ('\u0100', '\u0101'), ('\u0102', '\u0103'),
-        ('\u0104', '\u0105'), ('\u0106', '\u0107'),
-        ('\u0108', '\u0109'), ('\u010a', '\u010b'),
-        ('\u010c', '\u010d'), ('\u010e', '\u010f'),
-        ('\u0110', '\u0111'), ('\u0112', '\u0113'),
-        ('\u0114', '\u0115'), ('\u0116', '\u0117'),
-        ('\u0118', '\u0119'), ('\u011a', '\u011b'),
-        ('\u011c', '\u011d'), ('\u011e', '\u011f'),
-        ('\u0120', '\u0121'), ('\u0122', '\u0123'),
-        ('\u0124', '\u0125'), ('\u0126', '\u0127'),
-        ('\u0128', '\u0129'), ('\u012a', '\u012b'),
-        ('\u012c', '\u012d'), ('\u012e', '\u012f'),
-        ('\u0130', '\x69'), ('\u0132', '\u0133'),
-        ('\u0134', '\u0135'), ('\u0136', '\u0137'),
-        ('\u0139', '\u013a'), ('\u013b', '\u013c'),
-        ('\u013d', '\u013e'), ('\u013f', '\u0140'),
-        ('\u0141', '\u0142'), ('\u0143', '\u0144'),
-        ('\u0145', '\u0146'), ('\u0147', '\u0148'),
-        ('\u014a', '\u014b'), ('\u014c', '\u014d'),
-        ('\u014e', '\u014f'), ('\u0150', '\u0151'),
-        ('\u0152', '\u0153'), ('\u0154', '\u0155'),
-        ('\u0156', '\u0157'), ('\u0158', '\u0159'),
-        ('\u015a', '\u015b'), ('\u015c', '\u015d'),
-        ('\u015e', '\u015f'), ('\u0160', '\u0161'),
-        ('\u0162', '\u0163'), ('\u0164', '\u0165'),
-        ('\u0166', '\u0167'), ('\u0168', '\u0169'),
-        ('\u016a', '\u016b'), ('\u016c', '\u016d'),
-        ('\u016e', '\u016f'), ('\u0170', '\u0171'),
-        ('\u0172', '\u0173'), ('\u0174', '\u0175'),
-        ('\u0176', '\u0177'), ('\u0178', '\xff'),
-        ('\u0179', '\u017a'), ('\u017b', '\u017c'),
-        ('\u017d', '\u017e'), ('\u0181', '\u0253'),
-        ('\u0182', '\u0183'), ('\u0184', '\u0185'),
-        ('\u0186', '\u0254'), ('\u0187', '\u0188'),
-        ('\u0189', '\u0256'), ('\u018a', '\u0257'),
-        ('\u018b', '\u018c'), ('\u018e', '\u01dd'),
-        ('\u018f', '\u0259'), ('\u0190', '\u025b'),
-        ('\u0191', '\u0192'), ('\u0193', '\u0260'),
-        ('\u0194', '\u0263'), ('\u0196', '\u0269'),
-        ('\u0197', '\u0268'), ('\u0198', '\u0199'),
-        ('\u019c', '\u026f'), ('\u019d', '\u0272'),
-        ('\u019f', '\u0275'), ('\u01a0', '\u01a1'),
-        ('\u01a2', '\u01a3'), ('\u01a4', '\u01a5'),
-        ('\u01a6', '\u0280'), ('\u01a7', '\u01a8'),
-        ('\u01a9', '\u0283'), ('\u01ac', '\u01ad'),
-        ('\u01ae', '\u0288'), ('\u01af', '\u01b0'),
-        ('\u01b1', '\u028a'), ('\u01b2', '\u028b'),
-        ('\u01b3', '\u01b4'), ('\u01b5', '\u01b6'),
-        ('\u01b7', '\u0292'), ('\u01b8', '\u01b9'),
-        ('\u01bc', '\u01bd'), ('\u01c4', '\u01c6'),
-        ('\u01c7', '\u01c9'), ('\u01ca', '\u01cc'),
-        ('\u01cd', '\u01ce'), ('\u01cf', '\u01d0'),
-        ('\u01d1', '\u01d2'), ('\u01d3', '\u01d4'),
-        ('\u01d5', '\u01d6'), ('\u01d7', '\u01d8'),
-        ('\u01d9', '\u01da'), ('\u01db', '\u01dc'),
-        ('\u01de', '\u01df'), ('\u01e0', '\u01e1'),
-        ('\u01e2', '\u01e3'), ('\u01e4', '\u01e5'),
-        ('\u01e6', '\u01e7'), ('\u01e8', '\u01e9'),
-        ('\u01ea', '\u01eb'), ('\u01ec', '\u01ed'),
-        ('\u01ee', '\u01ef'), ('\u01f1', '\u01f3'),
-        ('\u01f4', '\u01f5'), ('\u01f6', '\u0195'),
-        ('\u01f7', '\u01bf'), ('\u01f8', '\u01f9'),
-        ('\u01fa', '\u01fb'), ('\u01fc', '\u01fd'),
-        ('\u01fe', '\u01ff'), ('\u0200', '\u0201'),
-        ('\u0202', '\u0203'), ('\u0204', '\u0205'),
-        ('\u0206', '\u0207'), ('\u0208', '\u0209'),
-        ('\u020a', '\u020b'), ('\u020c', '\u020d'),
-        ('\u020e', '\u020f'), ('\u0210', '\u0211'),
-        ('\u0212', '\u0213'), ('\u0214', '\u0215'),
-        ('\u0216', '\u0217'), ('\u0218', '\u0219'),
-        ('\u021a', '\u021b'), ('\u021c', '\u021d'),
-        ('\u021e', '\u021f'), ('\u0220', '\u019e'),
-        ('\u0222', '\u0223'), ('\u0224', '\u0225'),
-        ('\u0226', '\u0227'), ('\u0228', '\u0229'),
-        ('\u022a', '\u022b'), ('\u022c', '\u022d'),
-        ('\u022e', '\u022f'), ('\u0230', '\u0231'),
-        ('\u0232', '\u0233'), ('\u023a', '\u2c65'),
-        ('\u023b', '\u023c'), ('\u023d', '\u019a'),
-        ('\u023e', '\u2c66'), ('\u0241', '\u0242'),
-        ('\u0243', '\u0180'), ('\u0244', '\u0289'),
-        ('\u0245', '\u028c'), ('\u0246', '\u0247'),
-        ('\u0248', '\u0249'), ('\u024a', '\u024b'),
-        ('\u024c', '\u024d'), ('\u024e', '\u024f'),
-        ('\u0370', '\u0371'), ('\u0372', '\u0373'),
-        ('\u0376', '\u0377'), ('\u0386', '\u03ac'),
-        ('\u0388', '\u03ad'), ('\u0389', '\u03ae'),
-        ('\u038a', '\u03af'), ('\u038c', '\u03cc'),
-        ('\u038e', '\u03cd'), ('\u038f', '\u03ce'),
-        ('\u0391', '\u03b1'), ('\u0392', '\u03b2'),
-        ('\u0393', '\u03b3'), ('\u0394', '\u03b4'),
-        ('\u0395', '\u03b5'), ('\u0396', '\u03b6'),
-        ('\u0397', '\u03b7'), ('\u0398', '\u03b8'),
-        ('\u0399', '\u03b9'), ('\u039a', '\u03ba'),
-        ('\u039b', '\u03bb'), ('\u039c', '\u03bc'),
-        ('\u039d', '\u03bd'), ('\u039e', '\u03be'),
-        ('\u039f', '\u03bf'), ('\u03a0', '\u03c0'),
-        ('\u03a1', '\u03c1'), ('\u03a3', '\u03c3'),
-        ('\u03a4', '\u03c4'), ('\u03a5', '\u03c5'),
-        ('\u03a6', '\u03c6'), ('\u03a7', '\u03c7'),
-        ('\u03a8', '\u03c8'), ('\u03a9', '\u03c9'),
-        ('\u03aa', '\u03ca'), ('\u03ab', '\u03cb'),
-        ('\u03cf', '\u03d7'), ('\u03d8', '\u03d9'),
-        ('\u03da', '\u03db'), ('\u03dc', '\u03dd'),
-        ('\u03de', '\u03df'), ('\u03e0', '\u03e1'),
-        ('\u03e2', '\u03e3'), ('\u03e4', '\u03e5'),
-        ('\u03e6', '\u03e7'), ('\u03e8', '\u03e9'),
-        ('\u03ea', '\u03eb'), ('\u03ec', '\u03ed'),
-        ('\u03ee', '\u03ef'), ('\u03f4', '\u03b8'),
-        ('\u03f7', '\u03f8'), ('\u03f9', '\u03f2'),
-        ('\u03fa', '\u03fb'), ('\u03fd', '\u037b'),
-        ('\u03fe', '\u037c'), ('\u03ff', '\u037d'),
-        ('\u0400', '\u0450'), ('\u0401', '\u0451'),
-        ('\u0402', '\u0452'), ('\u0403', '\u0453'),
-        ('\u0404', '\u0454'), ('\u0405', '\u0455'),
-        ('\u0406', '\u0456'), ('\u0407', '\u0457'),
-        ('\u0408', '\u0458'), ('\u0409', '\u0459'),
-        ('\u040a', '\u045a'), ('\u040b', '\u045b'),
-        ('\u040c', '\u045c'), ('\u040d', '\u045d'),
-        ('\u040e', '\u045e'), ('\u040f', '\u045f'),
-        ('\u0410', '\u0430'), ('\u0411', '\u0431'),
-        ('\u0412', '\u0432'), ('\u0413', '\u0433'),
-        ('\u0414', '\u0434'), ('\u0415', '\u0435'),
-        ('\u0416', '\u0436'), ('\u0417', '\u0437'),
-        ('\u0418', '\u0438'), ('\u0419', '\u0439'),
-        ('\u041a', '\u043a'), ('\u041b', '\u043b'),
-        ('\u041c', '\u043c'), ('\u041d', '\u043d'),
-        ('\u041e', '\u043e'), ('\u041f', '\u043f'),
-        ('\u0420', '\u0440'), ('\u0421', '\u0441'),
-        ('\u0422', '\u0442'), ('\u0423', '\u0443'),
-        ('\u0424', '\u0444'), ('\u0425', '\u0445'),
-        ('\u0426', '\u0446'), ('\u0427', '\u0447'),
-        ('\u0428', '\u0448'), ('\u0429', '\u0449'),
-        ('\u042a', '\u044a'), ('\u042b', '\u044b'),
-        ('\u042c', '\u044c'), ('\u042d', '\u044d'),
-        ('\u042e', '\u044e'), ('\u042f', '\u044f'),
-        ('\u0460', '\u0461'), ('\u0462', '\u0463'),
-        ('\u0464', '\u0465'), ('\u0466', '\u0467'),
-        ('\u0468', '\u0469'), ('\u046a', '\u046b'),
-        ('\u046c', '\u046d'), ('\u046e', '\u046f'),
-        ('\u0470', '\u0471'), ('\u0472', '\u0473'),
-        ('\u0474', '\u0475'), ('\u0476', '\u0477'),
-        ('\u0478', '\u0479'), ('\u047a', '\u047b'),
-        ('\u047c', '\u047d'), ('\u047e', '\u047f'),
-        ('\u0480', '\u0481'), ('\u048a', '\u048b'),
-        ('\u048c', '\u048d'), ('\u048e', '\u048f'),
-        ('\u0490', '\u0491'), ('\u0492', '\u0493'),
-        ('\u0494', '\u0495'), ('\u0496', '\u0497'),
-        ('\u0498', '\u0499'), ('\u049a', '\u049b'),
-        ('\u049c', '\u049d'), ('\u049e', '\u049f'),
-        ('\u04a0', '\u04a1'), ('\u04a2', '\u04a3'),
-        ('\u04a4', '\u04a5'), ('\u04a6', '\u04a7'),
-        ('\u04a8', '\u04a9'), ('\u04aa', '\u04ab'),
-        ('\u04ac', '\u04ad'), ('\u04ae', '\u04af'),
-        ('\u04b0', '\u04b1'), ('\u04b2', '\u04b3'),
-        ('\u04b4', '\u04b5'), ('\u04b6', '\u04b7'),
-        ('\u04b8', '\u04b9'), ('\u04ba', '\u04bb'),
-        ('\u04bc', '\u04bd'), ('\u04be', '\u04bf'),
-        ('\u04c0', '\u04cf'), ('\u04c1', '\u04c2'),
-        ('\u04c3', '\u04c4'), ('\u04c5', '\u04c6'),
-        ('\u04c7', '\u04c8'), ('\u04c9', '\u04ca'),
-        ('\u04cb', '\u04cc'), ('\u04cd', '\u04ce'),
-        ('\u04d0', '\u04d1'), ('\u04d2', '\u04d3'),
-        ('\u04d4', '\u04d5'), ('\u04d6', '\u04d7'),
-        ('\u04d8', '\u04d9'), ('\u04da', '\u04db'),
-        ('\u04dc', '\u04dd'), ('\u04de', '\u04df'),
-        ('\u04e0', '\u04e1'), ('\u04e2', '\u04e3'),
-        ('\u04e4', '\u04e5'), ('\u04e6', '\u04e7'),
-        ('\u04e8', '\u04e9'), ('\u04ea', '\u04eb'),
-        ('\u04ec', '\u04ed'), ('\u04ee', '\u04ef'),
-        ('\u04f0', '\u04f1'), ('\u04f2', '\u04f3'),
-        ('\u04f4', '\u04f5'), ('\u04f6', '\u04f7'),
-        ('\u04f8', '\u04f9'), ('\u04fa', '\u04fb'),
-        ('\u04fc', '\u04fd'), ('\u04fe', '\u04ff'),
-        ('\u0500', '\u0501'), ('\u0502', '\u0503'),
-        ('\u0504', '\u0505'), ('\u0506', '\u0507'),
-        ('\u0508', '\u0509'), ('\u050a', '\u050b'),
-        ('\u050c', '\u050d'), ('\u050e', '\u050f'),
-        ('\u0510', '\u0511'), ('\u0512', '\u0513'),
-        ('\u0514', '\u0515'), ('\u0516', '\u0517'),
-        ('\u0518', '\u0519'), ('\u051a', '\u051b'),
-        ('\u051c', '\u051d'), ('\u051e', '\u051f'),
-        ('\u0520', '\u0521'), ('\u0522', '\u0523'),
-        ('\u0524', '\u0525'), ('\u0526', '\u0527'),
-        ('\u0531', '\u0561'), ('\u0532', '\u0562'),
-        ('\u0533', '\u0563'), ('\u0534', '\u0564'),
-        ('\u0535', '\u0565'), ('\u0536', '\u0566'),
-        ('\u0537', '\u0567'), ('\u0538', '\u0568'),
-        ('\u0539', '\u0569'), ('\u053a', '\u056a'),
-        ('\u053b', '\u056b'), ('\u053c', '\u056c'),
-        ('\u053d', '\u056d'), ('\u053e', '\u056e'),
-        ('\u053f', '\u056f'), ('\u0540', '\u0570'),
-        ('\u0541', '\u0571'), ('\u0542', '\u0572'),
-        ('\u0543', '\u0573'), ('\u0544', '\u0574'),
-        ('\u0545', '\u0575'), ('\u0546', '\u0576'),
-        ('\u0547', '\u0577'), ('\u0548', '\u0578'),
-        ('\u0549', '\u0579'), ('\u054a', '\u057a'),
-        ('\u054b', '\u057b'), ('\u054c', '\u057c'),
-        ('\u054d', '\u057d'), ('\u054e', '\u057e'),
-        ('\u054f', '\u057f'), ('\u0550', '\u0580'),
-        ('\u0551', '\u0581'), ('\u0552', '\u0582'),
-        ('\u0553', '\u0583'), ('\u0554', '\u0584'),
-        ('\u0555', '\u0585'), ('\u0556', '\u0586'),
-        ('\u10a0', '\u2d00'), ('\u10a1', '\u2d01'),
-        ('\u10a2', '\u2d02'), ('\u10a3', '\u2d03'),
-        ('\u10a4', '\u2d04'), ('\u10a5', '\u2d05'),
-        ('\u10a6', '\u2d06'), ('\u10a7', '\u2d07'),
-        ('\u10a8', '\u2d08'), ('\u10a9', '\u2d09'),
-        ('\u10aa', '\u2d0a'), ('\u10ab', '\u2d0b'),
-        ('\u10ac', '\u2d0c'), ('\u10ad', '\u2d0d'),
-        ('\u10ae', '\u2d0e'), ('\u10af', '\u2d0f'),
-        ('\u10b0', '\u2d10'), ('\u10b1', '\u2d11'),
-        ('\u10b2', '\u2d12'), ('\u10b3', '\u2d13'),
-        ('\u10b4', '\u2d14'), ('\u10b5', '\u2d15'),
-        ('\u10b6', '\u2d16'), ('\u10b7', '\u2d17'),
-        ('\u10b8', '\u2d18'), ('\u10b9', '\u2d19'),
-        ('\u10ba', '\u2d1a'), ('\u10bb', '\u2d1b'),
-        ('\u10bc', '\u2d1c'), ('\u10bd', '\u2d1d'),
-        ('\u10be', '\u2d1e'), ('\u10bf', '\u2d1f'),
-        ('\u10c0', '\u2d20'), ('\u10c1', '\u2d21'),
-        ('\u10c2', '\u2d22'), ('\u10c3', '\u2d23'),
-        ('\u10c4', '\u2d24'), ('\u10c5', '\u2d25'),
-        ('\u10c7', '\u2d27'), ('\u10cd', '\u2d2d'),
-        ('\u1e00', '\u1e01'), ('\u1e02', '\u1e03'),
-        ('\u1e04', '\u1e05'), ('\u1e06', '\u1e07'),
-        ('\u1e08', '\u1e09'), ('\u1e0a', '\u1e0b'),
-        ('\u1e0c', '\u1e0d'), ('\u1e0e', '\u1e0f'),
-        ('\u1e10', '\u1e11'), ('\u1e12', '\u1e13'),
-        ('\u1e14', '\u1e15'), ('\u1e16', '\u1e17'),
-        ('\u1e18', '\u1e19'), ('\u1e1a', '\u1e1b'),
-        ('\u1e1c', '\u1e1d'), ('\u1e1e', '\u1e1f'),
-        ('\u1e20', '\u1e21'), ('\u1e22', '\u1e23'),
-        ('\u1e24', '\u1e25'), ('\u1e26', '\u1e27'),
-        ('\u1e28', '\u1e29'), ('\u1e2a', '\u1e2b'),
-        ('\u1e2c', '\u1e2d'), ('\u1e2e', '\u1e2f'),
-        ('\u1e30', '\u1e31'), ('\u1e32', '\u1e33'),
-        ('\u1e34', '\u1e35'), ('\u1e36', '\u1e37'),
-        ('\u1e38', '\u1e39'), ('\u1e3a', '\u1e3b'),
-        ('\u1e3c', '\u1e3d'), ('\u1e3e', '\u1e3f'),
-        ('\u1e40', '\u1e41'), ('\u1e42', '\u1e43'),
-        ('\u1e44', '\u1e45'), ('\u1e46', '\u1e47'),
-        ('\u1e48', '\u1e49'), ('\u1e4a', '\u1e4b'),
-        ('\u1e4c', '\u1e4d'), ('\u1e4e', '\u1e4f'),
-        ('\u1e50', '\u1e51'), ('\u1e52', '\u1e53'),
-        ('\u1e54', '\u1e55'), ('\u1e56', '\u1e57'),
-        ('\u1e58', '\u1e59'), ('\u1e5a', '\u1e5b'),
-        ('\u1e5c', '\u1e5d'), ('\u1e5e', '\u1e5f'),
-        ('\u1e60', '\u1e61'), ('\u1e62', '\u1e63'),
-        ('\u1e64', '\u1e65'), ('\u1e66', '\u1e67'),
-        ('\u1e68', '\u1e69'), ('\u1e6a', '\u1e6b'),
-        ('\u1e6c', '\u1e6d'), ('\u1e6e', '\u1e6f'),
-        ('\u1e70', '\u1e71'), ('\u1e72', '\u1e73'),
-        ('\u1e74', '\u1e75'), ('\u1e76', '\u1e77'),
-        ('\u1e78', '\u1e79'), ('\u1e7a', '\u1e7b'),
-        ('\u1e7c', '\u1e7d'), ('\u1e7e', '\u1e7f'),
-        ('\u1e80', '\u1e81'), ('\u1e82', '\u1e83'),
-        ('\u1e84', '\u1e85'), ('\u1e86', '\u1e87'),
-        ('\u1e88', '\u1e89'), ('\u1e8a', '\u1e8b'),
-        ('\u1e8c', '\u1e8d'), ('\u1e8e', '\u1e8f'),
-        ('\u1e90', '\u1e91'), ('\u1e92', '\u1e93'),
-        ('\u1e94', '\u1e95'), ('\u1e9e', '\xdf'),
-        ('\u1ea0', '\u1ea1'), ('\u1ea2', '\u1ea3'),
-        ('\u1ea4', '\u1ea5'), ('\u1ea6', '\u1ea7'),
-        ('\u1ea8', '\u1ea9'), ('\u1eaa', '\u1eab'),
-        ('\u1eac', '\u1ead'), ('\u1eae', '\u1eaf'),
-        ('\u1eb0', '\u1eb1'), ('\u1eb2', '\u1eb3'),
-        ('\u1eb4', '\u1eb5'), ('\u1eb6', '\u1eb7'),
-        ('\u1eb8', '\u1eb9'), ('\u1eba', '\u1ebb'),
-        ('\u1ebc', '\u1ebd'), ('\u1ebe', '\u1ebf'),
-        ('\u1ec0', '\u1ec1'), ('\u1ec2', '\u1ec3'),
-        ('\u1ec4', '\u1ec5'), ('\u1ec6', '\u1ec7'),
-        ('\u1ec8', '\u1ec9'), ('\u1eca', '\u1ecb'),
-        ('\u1ecc', '\u1ecd'), ('\u1ece', '\u1ecf'),
-        ('\u1ed0', '\u1ed1'), ('\u1ed2', '\u1ed3'),
-        ('\u1ed4', '\u1ed5'), ('\u1ed6', '\u1ed7'),
-        ('\u1ed8', '\u1ed9'), ('\u1eda', '\u1edb'),
-        ('\u1edc', '\u1edd'), ('\u1ede', '\u1edf'),
-        ('\u1ee0', '\u1ee1'), ('\u1ee2', '\u1ee3'),
-        ('\u1ee4', '\u1ee5'), ('\u1ee6', '\u1ee7'),
-        ('\u1ee8', '\u1ee9'), ('\u1eea', '\u1eeb'),
-        ('\u1eec', '\u1eed'), ('\u1eee', '\u1eef'),
-        ('\u1ef0', '\u1ef1'), ('\u1ef2', '\u1ef3'),
-        ('\u1ef4', '\u1ef5'), ('\u1ef6', '\u1ef7'),
-        ('\u1ef8', '\u1ef9'), ('\u1efa', '\u1efb'),
-        ('\u1efc', '\u1efd'), ('\u1efe', '\u1eff'),
-        ('\u1f08', '\u1f00'), ('\u1f09', '\u1f01'),
-        ('\u1f0a', '\u1f02'), ('\u1f0b', '\u1f03'),
-        ('\u1f0c', '\u1f04'), ('\u1f0d', '\u1f05'),
-        ('\u1f0e', '\u1f06'), ('\u1f0f', '\u1f07'),
-        ('\u1f18', '\u1f10'), ('\u1f19', '\u1f11'),
-        ('\u1f1a', '\u1f12'), ('\u1f1b', '\u1f13'),
-        ('\u1f1c', '\u1f14'), ('\u1f1d', '\u1f15'),
-        ('\u1f28', '\u1f20'), ('\u1f29', '\u1f21'),
-        ('\u1f2a', '\u1f22'), ('\u1f2b', '\u1f23'),
-        ('\u1f2c', '\u1f24'), ('\u1f2d', '\u1f25'),
-        ('\u1f2e', '\u1f26'), ('\u1f2f', '\u1f27'),
-        ('\u1f38', '\u1f30'), ('\u1f39', '\u1f31'),
-        ('\u1f3a', '\u1f32'), ('\u1f3b', '\u1f33'),
-        ('\u1f3c', '\u1f34'), ('\u1f3d', '\u1f35'),
-        ('\u1f3e', '\u1f36'), ('\u1f3f', '\u1f37'),
-        ('\u1f48', '\u1f40'), ('\u1f49', '\u1f41'),
-        ('\u1f4a', '\u1f42'), ('\u1f4b', '\u1f43'),
-        ('\u1f4c', '\u1f44'), ('\u1f4d', '\u1f45'),
-        ('\u1f59', '\u1f51'), ('\u1f5b', '\u1f53'),
-        ('\u1f5d', '\u1f55'), ('\u1f5f', '\u1f57'),
-        ('\u1f68', '\u1f60'), ('\u1f69', '\u1f61'),
-        ('\u1f6a', '\u1f62'), ('\u1f6b', '\u1f63'),
-        ('\u1f6c', '\u1f64'), ('\u1f6d', '\u1f65'),
-        ('\u1f6e', '\u1f66'), ('\u1f6f', '\u1f67'),
-        ('\u1fb8', '\u1fb0'), ('\u1fb9', '\u1fb1'),
-        ('\u1fba', '\u1f70'), ('\u1fbb', '\u1f71'),
-        ('\u1fc8', '\u1f72'), ('\u1fc9', '\u1f73'),
-        ('\u1fca', '\u1f74'), ('\u1fcb', '\u1f75'),
-        ('\u1fd8', '\u1fd0'), ('\u1fd9', '\u1fd1'),
-        ('\u1fda', '\u1f76'), ('\u1fdb', '\u1f77'),
-        ('\u1fe8', '\u1fe0'), ('\u1fe9', '\u1fe1'),
-        ('\u1fea', '\u1f7a'), ('\u1feb', '\u1f7b'),
-        ('\u1fec', '\u1fe5'), ('\u1ff8', '\u1f78'),
-        ('\u1ff9', '\u1f79'), ('\u1ffa', '\u1f7c'),
-        ('\u1ffb', '\u1f7d'), ('\u2126', '\u03c9'),
-        ('\u212a', '\x6b'), ('\u212b', '\xe5'),
-        ('\u2132', '\u214e'), ('\u2183', '\u2184'),
-        ('\u2c00', '\u2c30'), ('\u2c01', '\u2c31'),
-        ('\u2c02', '\u2c32'), ('\u2c03', '\u2c33'),
-        ('\u2c04', '\u2c34'), ('\u2c05', '\u2c35'),
-        ('\u2c06', '\u2c36'), ('\u2c07', '\u2c37'),
-        ('\u2c08', '\u2c38'), ('\u2c09', '\u2c39'),
-        ('\u2c0a', '\u2c3a'), ('\u2c0b', '\u2c3b'),
-        ('\u2c0c', '\u2c3c'), ('\u2c0d', '\u2c3d'),
-        ('\u2c0e', '\u2c3e'), ('\u2c0f', '\u2c3f'),
-        ('\u2c10', '\u2c40'), ('\u2c11', '\u2c41'),
-        ('\u2c12', '\u2c42'), ('\u2c13', '\u2c43'),
-        ('\u2c14', '\u2c44'), ('\u2c15', '\u2c45'),
-        ('\u2c16', '\u2c46'), ('\u2c17', '\u2c47'),
-        ('\u2c18', '\u2c48'), ('\u2c19', '\u2c49'),
-        ('\u2c1a', '\u2c4a'), ('\u2c1b', '\u2c4b'),
-        ('\u2c1c', '\u2c4c'), ('\u2c1d', '\u2c4d'),
-        ('\u2c1e', '\u2c4e'), ('\u2c1f', '\u2c4f'),
-        ('\u2c20', '\u2c50'), ('\u2c21', '\u2c51'),
-        ('\u2c22', '\u2c52'), ('\u2c23', '\u2c53'),
-        ('\u2c24', '\u2c54'), ('\u2c25', '\u2c55'),
-        ('\u2c26', '\u2c56'), ('\u2c27', '\u2c57'),
-        ('\u2c28', '\u2c58'), ('\u2c29', '\u2c59'),
-        ('\u2c2a', '\u2c5a'), ('\u2c2b', '\u2c5b'),
-        ('\u2c2c', '\u2c5c'), ('\u2c2d', '\u2c5d'),
-        ('\u2c2e', '\u2c5e'), ('\u2c60', '\u2c61'),
-        ('\u2c62', '\u026b'), ('\u2c63', '\u1d7d'),
-        ('\u2c64', '\u027d'), ('\u2c67', '\u2c68'),
-        ('\u2c69', '\u2c6a'), ('\u2c6b', '\u2c6c'),
-        ('\u2c6d', '\u0251'), ('\u2c6e', '\u0271'),
-        ('\u2c6f', '\u0250'), ('\u2c70', '\u0252'),
-        ('\u2c72', '\u2c73'), ('\u2c75', '\u2c76'),
-        ('\u2c7e', '\u023f'), ('\u2c7f', '\u0240'),
-        ('\u2c80', '\u2c81'), ('\u2c82', '\u2c83'),
-        ('\u2c84', '\u2c85'), ('\u2c86', '\u2c87'),
-        ('\u2c88', '\u2c89'), ('\u2c8a', '\u2c8b'),
-        ('\u2c8c', '\u2c8d'), ('\u2c8e', '\u2c8f'),
-        ('\u2c90', '\u2c91'), ('\u2c92', '\u2c93'),
-        ('\u2c94', '\u2c95'), ('\u2c96', '\u2c97'),
-        ('\u2c98', '\u2c99'), ('\u2c9a', '\u2c9b'),
-        ('\u2c9c', '\u2c9d'), ('\u2c9e', '\u2c9f'),
-        ('\u2ca0', '\u2ca1'), ('\u2ca2', '\u2ca3'),
-        ('\u2ca4', '\u2ca5'), ('\u2ca6', '\u2ca7'),
-        ('\u2ca8', '\u2ca9'), ('\u2caa', '\u2cab'),
-        ('\u2cac', '\u2cad'), ('\u2cae', '\u2caf'),
-        ('\u2cb0', '\u2cb1'), ('\u2cb2', '\u2cb3'),
-        ('\u2cb4', '\u2cb5'), ('\u2cb6', '\u2cb7'),
-        ('\u2cb8', '\u2cb9'), ('\u2cba', '\u2cbb'),
-        ('\u2cbc', '\u2cbd'), ('\u2cbe', '\u2cbf'),
-        ('\u2cc0', '\u2cc1'), ('\u2cc2', '\u2cc3'),
-        ('\u2cc4', '\u2cc5'), ('\u2cc6', '\u2cc7'),
-        ('\u2cc8', '\u2cc9'), ('\u2cca', '\u2ccb'),
-        ('\u2ccc', '\u2ccd'), ('\u2cce', '\u2ccf'),
-        ('\u2cd0', '\u2cd1'), ('\u2cd2', '\u2cd3'),
-        ('\u2cd4', '\u2cd5'), ('\u2cd6', '\u2cd7'),
-        ('\u2cd8', '\u2cd9'), ('\u2cda', '\u2cdb'),
-        ('\u2cdc', '\u2cdd'), ('\u2cde', '\u2cdf'),
-        ('\u2ce0', '\u2ce1'), ('\u2ce2', '\u2ce3'),
-        ('\u2ceb', '\u2cec'), ('\u2ced', '\u2cee'),
-        ('\u2cf2', '\u2cf3'), ('\ua640', '\ua641'),
-        ('\ua642', '\ua643'), ('\ua644', '\ua645'),
-        ('\ua646', '\ua647'), ('\ua648', '\ua649'),
-        ('\ua64a', '\ua64b'), ('\ua64c', '\ua64d'),
-        ('\ua64e', '\ua64f'), ('\ua650', '\ua651'),
-        ('\ua652', '\ua653'), ('\ua654', '\ua655'),
-        ('\ua656', '\ua657'), ('\ua658', '\ua659'),
-        ('\ua65a', '\ua65b'), ('\ua65c', '\ua65d'),
-        ('\ua65e', '\ua65f'), ('\ua660', '\ua661'),
-        ('\ua662', '\ua663'), ('\ua664', '\ua665'),
-        ('\ua666', '\ua667'), ('\ua668', '\ua669'),
-        ('\ua66a', '\ua66b'), ('\ua66c', '\ua66d'),
-        ('\ua680', '\ua681'), ('\ua682', '\ua683'),
-        ('\ua684', '\ua685'), ('\ua686', '\ua687'),
-        ('\ua688', '\ua689'), ('\ua68a', '\ua68b'),
-        ('\ua68c', '\ua68d'), ('\ua68e', '\ua68f'),
-        ('\ua690', '\ua691'), ('\ua692', '\ua693'),
-        ('\ua694', '\ua695'), ('\ua696', '\ua697'),
-        ('\ua722', '\ua723'), ('\ua724', '\ua725'),
-        ('\ua726', '\ua727'), ('\ua728', '\ua729'),
-        ('\ua72a', '\ua72b'), ('\ua72c', '\ua72d'),
-        ('\ua72e', '\ua72f'), ('\ua732', '\ua733'),
-        ('\ua734', '\ua735'), ('\ua736', '\ua737'),
-        ('\ua738', '\ua739'), ('\ua73a', '\ua73b'),
-        ('\ua73c', '\ua73d'), ('\ua73e', '\ua73f'),
-        ('\ua740', '\ua741'), ('\ua742', '\ua743'),
-        ('\ua744', '\ua745'), ('\ua746', '\ua747'),
-        ('\ua748', '\ua749'), ('\ua74a', '\ua74b'),
-        ('\ua74c', '\ua74d'), ('\ua74e', '\ua74f'),
-        ('\ua750', '\ua751'), ('\ua752', '\ua753'),
-        ('\ua754', '\ua755'), ('\ua756', '\ua757'),
-        ('\ua758', '\ua759'), ('\ua75a', '\ua75b'),
-        ('\ua75c', '\ua75d'), ('\ua75e', '\ua75f'),
-        ('\ua760', '\ua761'), ('\ua762', '\ua763'),
-        ('\ua764', '\ua765'), ('\ua766', '\ua767'),
-        ('\ua768', '\ua769'), ('\ua76a', '\ua76b'),
-        ('\ua76c', '\ua76d'), ('\ua76e', '\ua76f'),
-        ('\ua779', '\ua77a'), ('\ua77b', '\ua77c'),
-        ('\ua77d', '\u1d79'), ('\ua77e', '\ua77f'),
-        ('\ua780', '\ua781'), ('\ua782', '\ua783'),
-        ('\ua784', '\ua785'), ('\ua786', '\ua787'),
-        ('\ua78b', '\ua78c'), ('\ua78d', '\u0265'),
-        ('\ua790', '\ua791'), ('\ua792', '\ua793'),
-        ('\ua7a0', '\ua7a1'), ('\ua7a2', '\ua7a3'),
-        ('\ua7a4', '\ua7a5'), ('\ua7a6', '\ua7a7'),
-        ('\ua7a8', '\ua7a9'), ('\ua7aa', '\u0266'),
-        ('\uff21', '\uff41'), ('\uff22', '\uff42'),
-        ('\uff23', '\uff43'), ('\uff24', '\uff44'),
-        ('\uff25', '\uff45'), ('\uff26', '\uff46'),
-        ('\uff27', '\uff47'), ('\uff28', '\uff48'),
-        ('\uff29', '\uff49'), ('\uff2a', '\uff4a'),
-        ('\uff2b', '\uff4b'), ('\uff2c', '\uff4c'),
-        ('\uff2d', '\uff4d'), ('\uff2e', '\uff4e'),
-        ('\uff2f', '\uff4f'), ('\uff30', '\uff50'),
-        ('\uff31', '\uff51'), ('\uff32', '\uff52'),
-        ('\uff33', '\uff53'), ('\uff34', '\uff54'),
-        ('\uff35', '\uff55'), ('\uff36', '\uff56'),
-        ('\uff37', '\uff57'), ('\uff38', '\uff58'),
-        ('\uff39', '\uff59'), ('\uff3a', '\uff5a'),
-        ('\U00010400', '\U00010428'), ('\U00010401', '\U00010429'),
-        ('\U00010402', '\U0001042a'), ('\U00010403', '\U0001042b'),
-        ('\U00010404', '\U0001042c'), ('\U00010405', '\U0001042d'),
-        ('\U00010406', '\U0001042e'), ('\U00010407', '\U0001042f'),
-        ('\U00010408', '\U00010430'), ('\U00010409', '\U00010431'),
-        ('\U0001040a', '\U00010432'), ('\U0001040b', '\U00010433'),
-        ('\U0001040c', '\U00010434'), ('\U0001040d', '\U00010435'),
-        ('\U0001040e', '\U00010436'), ('\U0001040f', '\U00010437'),
-        ('\U00010410', '\U00010438'), ('\U00010411', '\U00010439'),
-        ('\U00010412', '\U0001043a'), ('\U00010413', '\U0001043b'),
-        ('\U00010414', '\U0001043c'), ('\U00010415', '\U0001043d'),
-        ('\U00010416', '\U0001043e'), ('\U00010417', '\U0001043f'),
-        ('\U00010418', '\U00010440'), ('\U00010419', '\U00010441'),
-        ('\U0001041a', '\U00010442'), ('\U0001041b', '\U00010443'),
-        ('\U0001041c', '\U00010444'), ('\U0001041d', '\U00010445'),
-        ('\U0001041e', '\U00010446'), ('\U0001041f', '\U00010447'),
-        ('\U00010420', '\U00010448'), ('\U00010421', '\U00010449'),
-        ('\U00010422', '\U0001044a'), ('\U00010423', '\U0001044b'),
-        ('\U00010424', '\U0001044c'), ('\U00010425', '\U0001044d'),
-        ('\U00010426', '\U0001044e'), ('\U00010427', '\U0001044f')
-    ];
-
-    static LlLu_table : &'static [(char, char)] = &[
-        ('\x61', '\x41'), ('\x62', '\x42'),
-        ('\x63', '\x43'), ('\x64', '\x44'),
-        ('\x65', '\x45'), ('\x66', '\x46'),
-        ('\x67', '\x47'), ('\x68', '\x48'),
-        ('\x69', '\x49'), ('\x6a', '\x4a'),
-        ('\x6b', '\x4b'), ('\x6c', '\x4c'),
-        ('\x6d', '\x4d'), ('\x6e', '\x4e'),
-        ('\x6f', '\x4f'), ('\x70', '\x50'),
-        ('\x71', '\x51'), ('\x72', '\x52'),
-        ('\x73', '\x53'), ('\x74', '\x54'),
-        ('\x75', '\x55'), ('\x76', '\x56'),
-        ('\x77', '\x57'), ('\x78', '\x58'),
-        ('\x79', '\x59'), ('\x7a', '\x5a'),
-        ('\xb5', '\u039c'), ('\xe0', '\xc0'),
-        ('\xe1', '\xc1'), ('\xe2', '\xc2'),
-        ('\xe3', '\xc3'), ('\xe4', '\xc4'),
-        ('\xe5', '\xc5'), ('\xe6', '\xc6'),
-        ('\xe7', '\xc7'), ('\xe8', '\xc8'),
-        ('\xe9', '\xc9'), ('\xea', '\xca'),
-        ('\xeb', '\xcb'), ('\xec', '\xcc'),
-        ('\xed', '\xcd'), ('\xee', '\xce'),
-        ('\xef', '\xcf'), ('\xf0', '\xd0'),
-        ('\xf1', '\xd1'), ('\xf2', '\xd2'),
-        ('\xf3', '\xd3'), ('\xf4', '\xd4'),
-        ('\xf5', '\xd5'), ('\xf6', '\xd6'),
-        ('\xf8', '\xd8'), ('\xf9', '\xd9'),
-        ('\xfa', '\xda'), ('\xfb', '\xdb'),
-        ('\xfc', '\xdc'), ('\xfd', '\xdd'),
-        ('\xfe', '\xde'), ('\xff', '\u0178'),
-        ('\u0101', '\u0100'), ('\u0103', '\u0102'),
-        ('\u0105', '\u0104'), ('\u0107', '\u0106'),
-        ('\u0109', '\u0108'), ('\u010b', '\u010a'),
-        ('\u010d', '\u010c'), ('\u010f', '\u010e'),
-        ('\u0111', '\u0110'), ('\u0113', '\u0112'),
-        ('\u0115', '\u0114'), ('\u0117', '\u0116'),
-        ('\u0119', '\u0118'), ('\u011b', '\u011a'),
-        ('\u011d', '\u011c'), ('\u011f', '\u011e'),
-        ('\u0121', '\u0120'), ('\u0123', '\u0122'),
-        ('\u0125', '\u0124'), ('\u0127', '\u0126'),
-        ('\u0129', '\u0128'), ('\u012b', '\u012a'),
-        ('\u012d', '\u012c'), ('\u012f', '\u012e'),
-        ('\u0131', '\x49'), ('\u0133', '\u0132'),
-        ('\u0135', '\u0134'), ('\u0137', '\u0136'),
-        ('\u013a', '\u0139'), ('\u013c', '\u013b'),
-        ('\u013e', '\u013d'), ('\u0140', '\u013f'),
-        ('\u0142', '\u0141'), ('\u0144', '\u0143'),
-        ('\u0146', '\u0145'), ('\u0148', '\u0147'),
-        ('\u014b', '\u014a'), ('\u014d', '\u014c'),
-        ('\u014f', '\u014e'), ('\u0151', '\u0150'),
-        ('\u0153', '\u0152'), ('\u0155', '\u0154'),
-        ('\u0157', '\u0156'), ('\u0159', '\u0158'),
-        ('\u015b', '\u015a'), ('\u015d', '\u015c'),
-        ('\u015f', '\u015e'), ('\u0161', '\u0160'),
-        ('\u0163', '\u0162'), ('\u0165', '\u0164'),
-        ('\u0167', '\u0166'), ('\u0169', '\u0168'),
-        ('\u016b', '\u016a'), ('\u016d', '\u016c'),
-        ('\u016f', '\u016e'), ('\u0171', '\u0170'),
-        ('\u0173', '\u0172'), ('\u0175', '\u0174'),
-        ('\u0177', '\u0176'), ('\u017a', '\u0179'),
-        ('\u017c', '\u017b'), ('\u017e', '\u017d'),
-        ('\u017f', '\x53'), ('\u0180', '\u0243'),
-        ('\u0183', '\u0182'), ('\u0185', '\u0184'),
-        ('\u0188', '\u0187'), ('\u018c', '\u018b'),
-        ('\u0192', '\u0191'), ('\u0195', '\u01f6'),
-        ('\u0199', '\u0198'), ('\u019a', '\u023d'),
-        ('\u019e', '\u0220'), ('\u01a1', '\u01a0'),
-        ('\u01a3', '\u01a2'), ('\u01a5', '\u01a4'),
-        ('\u01a8', '\u01a7'), ('\u01ad', '\u01ac'),
-        ('\u01b0', '\u01af'), ('\u01b4', '\u01b3'),
-        ('\u01b6', '\u01b5'), ('\u01b9', '\u01b8'),
-        ('\u01bd', '\u01bc'), ('\u01bf', '\u01f7'),
-        ('\u01c6', '\u01c4'), ('\u01c9', '\u01c7'),
-        ('\u01cc', '\u01ca'), ('\u01ce', '\u01cd'),
-        ('\u01d0', '\u01cf'), ('\u01d2', '\u01d1'),
-        ('\u01d4', '\u01d3'), ('\u01d6', '\u01d5'),
-        ('\u01d8', '\u01d7'), ('\u01da', '\u01d9'),
-        ('\u01dc', '\u01db'), ('\u01dd', '\u018e'),
-        ('\u01df', '\u01de'), ('\u01e1', '\u01e0'),
-        ('\u01e3', '\u01e2'), ('\u01e5', '\u01e4'),
-        ('\u01e7', '\u01e6'), ('\u01e9', '\u01e8'),
-        ('\u01eb', '\u01ea'), ('\u01ed', '\u01ec'),
-        ('\u01ef', '\u01ee'), ('\u01f3', '\u01f1'),
-        ('\u01f5', '\u01f4'), ('\u01f9', '\u01f8'),
-        ('\u01fb', '\u01fa'), ('\u01fd', '\u01fc'),
-        ('\u01ff', '\u01fe'), ('\u0201', '\u0200'),
-        ('\u0203', '\u0202'), ('\u0205', '\u0204'),
-        ('\u0207', '\u0206'), ('\u0209', '\u0208'),
-        ('\u020b', '\u020a'), ('\u020d', '\u020c'),
-        ('\u020f', '\u020e'), ('\u0211', '\u0210'),
-        ('\u0213', '\u0212'), ('\u0215', '\u0214'),
-        ('\u0217', '\u0216'), ('\u0219', '\u0218'),
-        ('\u021b', '\u021a'), ('\u021d', '\u021c'),
-        ('\u021f', '\u021e'), ('\u0223', '\u0222'),
-        ('\u0225', '\u0224'), ('\u0227', '\u0226'),
-        ('\u0229', '\u0228'), ('\u022b', '\u022a'),
-        ('\u022d', '\u022c'), ('\u022f', '\u022e'),
-        ('\u0231', '\u0230'), ('\u0233', '\u0232'),
-        ('\u023c', '\u023b'), ('\u023f', '\u2c7e'),
-        ('\u0240', '\u2c7f'), ('\u0242', '\u0241'),
-        ('\u0247', '\u0246'), ('\u0249', '\u0248'),
-        ('\u024b', '\u024a'), ('\u024d', '\u024c'),
-        ('\u024f', '\u024e'), ('\u0250', '\u2c6f'),
-        ('\u0251', '\u2c6d'), ('\u0252', '\u2c70'),
-        ('\u0253', '\u0181'), ('\u0254', '\u0186'),
-        ('\u0256', '\u0189'), ('\u0257', '\u018a'),
-        ('\u0259', '\u018f'), ('\u025b', '\u0190'),
-        ('\u0260', '\u0193'), ('\u0263', '\u0194'),
-        ('\u0265', '\ua78d'), ('\u0266', '\ua7aa'),
-        ('\u0268', '\u0197'), ('\u0269', '\u0196'),
-        ('\u026b', '\u2c62'), ('\u026f', '\u019c'),
-        ('\u0271', '\u2c6e'), ('\u0272', '\u019d'),
-        ('\u0275', '\u019f'), ('\u027d', '\u2c64'),
-        ('\u0280', '\u01a6'), ('\u0283', '\u01a9'),
-        ('\u0288', '\u01ae'), ('\u0289', '\u0244'),
-        ('\u028a', '\u01b1'), ('\u028b', '\u01b2'),
-        ('\u028c', '\u0245'), ('\u0292', '\u01b7'),
-        ('\u0371', '\u0370'), ('\u0373', '\u0372'),
-        ('\u0377', '\u0376'), ('\u037b', '\u03fd'),
-        ('\u037c', '\u03fe'), ('\u037d', '\u03ff'),
-        ('\u03ac', '\u0386'), ('\u03ad', '\u0388'),
-        ('\u03ae', '\u0389'), ('\u03af', '\u038a'),
-        ('\u03b1', '\u0391'), ('\u03b2', '\u0392'),
-        ('\u03b3', '\u0393'), ('\u03b4', '\u0394'),
-        ('\u03b5', '\u0395'), ('\u03b6', '\u0396'),
-        ('\u03b7', '\u0397'), ('\u03b8', '\u0398'),
-        ('\u03b9', '\u0399'), ('\u03ba', '\u039a'),
-        ('\u03bb', '\u039b'), ('\u03bc', '\u039c'),
-        ('\u03bd', '\u039d'), ('\u03be', '\u039e'),
-        ('\u03bf', '\u039f'), ('\u03c0', '\u03a0'),
-        ('\u03c1', '\u03a1'), ('\u03c2', '\u03a3'),
-        ('\u03c3', '\u03a3'), ('\u03c4', '\u03a4'),
-        ('\u03c5', '\u03a5'), ('\u03c6', '\u03a6'),
-        ('\u03c7', '\u03a7'), ('\u03c8', '\u03a8'),
-        ('\u03c9', '\u03a9'), ('\u03ca', '\u03aa'),
-        ('\u03cb', '\u03ab'), ('\u03cc', '\u038c'),
-        ('\u03cd', '\u038e'), ('\u03ce', '\u038f'),
-        ('\u03d0', '\u0392'), ('\u03d1', '\u0398'),
-        ('\u03d5', '\u03a6'), ('\u03d6', '\u03a0'),
-        ('\u03d7', '\u03cf'), ('\u03d9', '\u03d8'),
-        ('\u03db', '\u03da'), ('\u03dd', '\u03dc'),
-        ('\u03df', '\u03de'), ('\u03e1', '\u03e0'),
-        ('\u03e3', '\u03e2'), ('\u03e5', '\u03e4'),
-        ('\u03e7', '\u03e6'), ('\u03e9', '\u03e8'),
-        ('\u03eb', '\u03ea'), ('\u03ed', '\u03ec'),
-        ('\u03ef', '\u03ee'), ('\u03f0', '\u039a'),
-        ('\u03f1', '\u03a1'), ('\u03f2', '\u03f9'),
-        ('\u03f5', '\u0395'), ('\u03f8', '\u03f7'),
-        ('\u03fb', '\u03fa'), ('\u0430', '\u0410'),
-        ('\u0431', '\u0411'), ('\u0432', '\u0412'),
-        ('\u0433', '\u0413'), ('\u0434', '\u0414'),
-        ('\u0435', '\u0415'), ('\u0436', '\u0416'),
-        ('\u0437', '\u0417'), ('\u0438', '\u0418'),
-        ('\u0439', '\u0419'), ('\u043a', '\u041a'),
-        ('\u043b', '\u041b'), ('\u043c', '\u041c'),
-        ('\u043d', '\u041d'), ('\u043e', '\u041e'),
-        ('\u043f', '\u041f'), ('\u0440', '\u0420'),
-        ('\u0441', '\u0421'), ('\u0442', '\u0422'),
-        ('\u0443', '\u0423'), ('\u0444', '\u0424'),
-        ('\u0445', '\u0425'), ('\u0446', '\u0426'),
-        ('\u0447', '\u0427'), ('\u0448', '\u0428'),
-        ('\u0449', '\u0429'), ('\u044a', '\u042a'),
-        ('\u044b', '\u042b'), ('\u044c', '\u042c'),
-        ('\u044d', '\u042d'), ('\u044e', '\u042e'),
-        ('\u044f', '\u042f'), ('\u0450', '\u0400'),
-        ('\u0451', '\u0401'), ('\u0452', '\u0402'),
-        ('\u0453', '\u0403'), ('\u0454', '\u0404'),
-        ('\u0455', '\u0405'), ('\u0456', '\u0406'),
-        ('\u0457', '\u0407'), ('\u0458', '\u0408'),
-        ('\u0459', '\u0409'), ('\u045a', '\u040a'),
-        ('\u045b', '\u040b'), ('\u045c', '\u040c'),
-        ('\u045d', '\u040d'), ('\u045e', '\u040e'),
-        ('\u045f', '\u040f'), ('\u0461', '\u0460'),
-        ('\u0463', '\u0462'), ('\u0465', '\u0464'),
-        ('\u0467', '\u0466'), ('\u0469', '\u0468'),
-        ('\u046b', '\u046a'), ('\u046d', '\u046c'),
-        ('\u046f', '\u046e'), ('\u0471', '\u0470'),
-        ('\u0473', '\u0472'), ('\u0475', '\u0474'),
-        ('\u0477', '\u0476'), ('\u0479', '\u0478'),
-        ('\u047b', '\u047a'), ('\u047d', '\u047c'),
-        ('\u047f', '\u047e'), ('\u0481', '\u0480'),
-        ('\u048b', '\u048a'), ('\u048d', '\u048c'),
-        ('\u048f', '\u048e'), ('\u0491', '\u0490'),
-        ('\u0493', '\u0492'), ('\u0495', '\u0494'),
-        ('\u0497', '\u0496'), ('\u0499', '\u0498'),
-        ('\u049b', '\u049a'), ('\u049d', '\u049c'),
-        ('\u049f', '\u049e'), ('\u04a1', '\u04a0'),
-        ('\u04a3', '\u04a2'), ('\u04a5', '\u04a4'),
-        ('\u04a7', '\u04a6'), ('\u04a9', '\u04a8'),
-        ('\u04ab', '\u04aa'), ('\u04ad', '\u04ac'),
-        ('\u04af', '\u04ae'), ('\u04b1', '\u04b0'),
-        ('\u04b3', '\u04b2'), ('\u04b5', '\u04b4'),
-        ('\u04b7', '\u04b6'), ('\u04b9', '\u04b8'),
-        ('\u04bb', '\u04ba'), ('\u04bd', '\u04bc'),
-        ('\u04bf', '\u04be'), ('\u04c2', '\u04c1'),
-        ('\u04c4', '\u04c3'), ('\u04c6', '\u04c5'),
-        ('\u04c8', '\u04c7'), ('\u04ca', '\u04c9'),
-        ('\u04cc', '\u04cb'), ('\u04ce', '\u04cd'),
-        ('\u04cf', '\u04c0'), ('\u04d1', '\u04d0'),
-        ('\u04d3', '\u04d2'), ('\u04d5', '\u04d4'),
-        ('\u04d7', '\u04d6'), ('\u04d9', '\u04d8'),
-        ('\u04db', '\u04da'), ('\u04dd', '\u04dc'),
-        ('\u04df', '\u04de'), ('\u04e1', '\u04e0'),
-        ('\u04e3', '\u04e2'), ('\u04e5', '\u04e4'),
-        ('\u04e7', '\u04e6'), ('\u04e9', '\u04e8'),
-        ('\u04eb', '\u04ea'), ('\u04ed', '\u04ec'),
-        ('\u04ef', '\u04ee'), ('\u04f1', '\u04f0'),
-        ('\u04f3', '\u04f2'), ('\u04f5', '\u04f4'),
-        ('\u04f7', '\u04f6'), ('\u04f9', '\u04f8'),
-        ('\u04fb', '\u04fa'), ('\u04fd', '\u04fc'),
-        ('\u04ff', '\u04fe'), ('\u0501', '\u0500'),
-        ('\u0503', '\u0502'), ('\u0505', '\u0504'),
-        ('\u0507', '\u0506'), ('\u0509', '\u0508'),
-        ('\u050b', '\u050a'), ('\u050d', '\u050c'),
-        ('\u050f', '\u050e'), ('\u0511', '\u0510'),
-        ('\u0513', '\u0512'), ('\u0515', '\u0514'),
-        ('\u0517', '\u0516'), ('\u0519', '\u0518'),
-        ('\u051b', '\u051a'), ('\u051d', '\u051c'),
-        ('\u051f', '\u051e'), ('\u0521', '\u0520'),
-        ('\u0523', '\u0522'), ('\u0525', '\u0524'),
-        ('\u0527', '\u0526'), ('\u0561', '\u0531'),
-        ('\u0562', '\u0532'), ('\u0563', '\u0533'),
-        ('\u0564', '\u0534'), ('\u0565', '\u0535'),
-        ('\u0566', '\u0536'), ('\u0567', '\u0537'),
-        ('\u0568', '\u0538'), ('\u0569', '\u0539'),
-        ('\u056a', '\u053a'), ('\u056b', '\u053b'),
-        ('\u056c', '\u053c'), ('\u056d', '\u053d'),
-        ('\u056e', '\u053e'), ('\u056f', '\u053f'),
-        ('\u0570', '\u0540'), ('\u0571', '\u0541'),
-        ('\u0572', '\u0542'), ('\u0573', '\u0543'),
-        ('\u0574', '\u0544'), ('\u0575', '\u0545'),
-        ('\u0576', '\u0546'), ('\u0577', '\u0547'),
-        ('\u0578', '\u0548'), ('\u0579', '\u0549'),
-        ('\u057a', '\u054a'), ('\u057b', '\u054b'),
-        ('\u057c', '\u054c'), ('\u057d', '\u054d'),
-        ('\u057e', '\u054e'), ('\u057f', '\u054f'),
-        ('\u0580', '\u0550'), ('\u0581', '\u0551'),
-        ('\u0582', '\u0552'), ('\u0583', '\u0553'),
-        ('\u0584', '\u0554'), ('\u0585', '\u0555'),
-        ('\u0586', '\u0556'), ('\u1d79', '\ua77d'),
-        ('\u1d7d', '\u2c63'), ('\u1e01', '\u1e00'),
-        ('\u1e03', '\u1e02'), ('\u1e05', '\u1e04'),
-        ('\u1e07', '\u1e06'), ('\u1e09', '\u1e08'),
-        ('\u1e0b', '\u1e0a'), ('\u1e0d', '\u1e0c'),
-        ('\u1e0f', '\u1e0e'), ('\u1e11', '\u1e10'),
-        ('\u1e13', '\u1e12'), ('\u1e15', '\u1e14'),
-        ('\u1e17', '\u1e16'), ('\u1e19', '\u1e18'),
-        ('\u1e1b', '\u1e1a'), ('\u1e1d', '\u1e1c'),
-        ('\u1e1f', '\u1e1e'), ('\u1e21', '\u1e20'),
-        ('\u1e23', '\u1e22'), ('\u1e25', '\u1e24'),
-        ('\u1e27', '\u1e26'), ('\u1e29', '\u1e28'),
-        ('\u1e2b', '\u1e2a'), ('\u1e2d', '\u1e2c'),
-        ('\u1e2f', '\u1e2e'), ('\u1e31', '\u1e30'),
-        ('\u1e33', '\u1e32'), ('\u1e35', '\u1e34'),
-        ('\u1e37', '\u1e36'), ('\u1e39', '\u1e38'),
-        ('\u1e3b', '\u1e3a'), ('\u1e3d', '\u1e3c'),
-        ('\u1e3f', '\u1e3e'), ('\u1e41', '\u1e40'),
-        ('\u1e43', '\u1e42'), ('\u1e45', '\u1e44'),
-        ('\u1e47', '\u1e46'), ('\u1e49', '\u1e48'),
-        ('\u1e4b', '\u1e4a'), ('\u1e4d', '\u1e4c'),
-        ('\u1e4f', '\u1e4e'), ('\u1e51', '\u1e50'),
-        ('\u1e53', '\u1e52'), ('\u1e55', '\u1e54'),
-        ('\u1e57', '\u1e56'), ('\u1e59', '\u1e58'),
-        ('\u1e5b', '\u1e5a'), ('\u1e5d', '\u1e5c'),
-        ('\u1e5f', '\u1e5e'), ('\u1e61', '\u1e60'),
-        ('\u1e63', '\u1e62'), ('\u1e65', '\u1e64'),
-        ('\u1e67', '\u1e66'), ('\u1e69', '\u1e68'),
-        ('\u1e6b', '\u1e6a'), ('\u1e6d', '\u1e6c'),
-        ('\u1e6f', '\u1e6e'), ('\u1e71', '\u1e70'),
-        ('\u1e73', '\u1e72'), ('\u1e75', '\u1e74'),
-        ('\u1e77', '\u1e76'), ('\u1e79', '\u1e78'),
-        ('\u1e7b', '\u1e7a'), ('\u1e7d', '\u1e7c'),
-        ('\u1e7f', '\u1e7e'), ('\u1e81', '\u1e80'),
-        ('\u1e83', '\u1e82'), ('\u1e85', '\u1e84'),
-        ('\u1e87', '\u1e86'), ('\u1e89', '\u1e88'),
-        ('\u1e8b', '\u1e8a'), ('\u1e8d', '\u1e8c'),
-        ('\u1e8f', '\u1e8e'), ('\u1e91', '\u1e90'),
-        ('\u1e93', '\u1e92'), ('\u1e95', '\u1e94'),
-        ('\u1e9b', '\u1e60'), ('\u1ea1', '\u1ea0'),
-        ('\u1ea3', '\u1ea2'), ('\u1ea5', '\u1ea4'),
-        ('\u1ea7', '\u1ea6'), ('\u1ea9', '\u1ea8'),
-        ('\u1eab', '\u1eaa'), ('\u1ead', '\u1eac'),
-        ('\u1eaf', '\u1eae'), ('\u1eb1', '\u1eb0'),
-        ('\u1eb3', '\u1eb2'), ('\u1eb5', '\u1eb4'),
-        ('\u1eb7', '\u1eb6'), ('\u1eb9', '\u1eb8'),
-        ('\u1ebb', '\u1eba'), ('\u1ebd', '\u1ebc'),
-        ('\u1ebf', '\u1ebe'), ('\u1ec1', '\u1ec0'),
-        ('\u1ec3', '\u1ec2'), ('\u1ec5', '\u1ec4'),
-        ('\u1ec7', '\u1ec6'), ('\u1ec9', '\u1ec8'),
-        ('\u1ecb', '\u1eca'), ('\u1ecd', '\u1ecc'),
-        ('\u1ecf', '\u1ece'), ('\u1ed1', '\u1ed0'),
-        ('\u1ed3', '\u1ed2'), ('\u1ed5', '\u1ed4'),
-        ('\u1ed7', '\u1ed6'), ('\u1ed9', '\u1ed8'),
-        ('\u1edb', '\u1eda'), ('\u1edd', '\u1edc'),
-        ('\u1edf', '\u1ede'), ('\u1ee1', '\u1ee0'),
-        ('\u1ee3', '\u1ee2'), ('\u1ee5', '\u1ee4'),
-        ('\u1ee7', '\u1ee6'), ('\u1ee9', '\u1ee8'),
-        ('\u1eeb', '\u1eea'), ('\u1eed', '\u1eec'),
-        ('\u1eef', '\u1eee'), ('\u1ef1', '\u1ef0'),
-        ('\u1ef3', '\u1ef2'), ('\u1ef5', '\u1ef4'),
-        ('\u1ef7', '\u1ef6'), ('\u1ef9', '\u1ef8'),
-        ('\u1efb', '\u1efa'), ('\u1efd', '\u1efc'),
-        ('\u1eff', '\u1efe'), ('\u1f00', '\u1f08'),
-        ('\u1f01', '\u1f09'), ('\u1f02', '\u1f0a'),
-        ('\u1f03', '\u1f0b'), ('\u1f04', '\u1f0c'),
-        ('\u1f05', '\u1f0d'), ('\u1f06', '\u1f0e'),
-        ('\u1f07', '\u1f0f'), ('\u1f10', '\u1f18'),
-        ('\u1f11', '\u1f19'), ('\u1f12', '\u1f1a'),
-        ('\u1f13', '\u1f1b'), ('\u1f14', '\u1f1c'),
-        ('\u1f15', '\u1f1d'), ('\u1f20', '\u1f28'),
-        ('\u1f21', '\u1f29'), ('\u1f22', '\u1f2a'),
-        ('\u1f23', '\u1f2b'), ('\u1f24', '\u1f2c'),
-        ('\u1f25', '\u1f2d'), ('\u1f26', '\u1f2e'),
-        ('\u1f27', '\u1f2f'), ('\u1f30', '\u1f38'),
-        ('\u1f31', '\u1f39'), ('\u1f32', '\u1f3a'),
-        ('\u1f33', '\u1f3b'), ('\u1f34', '\u1f3c'),
-        ('\u1f35', '\u1f3d'), ('\u1f36', '\u1f3e'),
-        ('\u1f37', '\u1f3f'), ('\u1f40', '\u1f48'),
-        ('\u1f41', '\u1f49'), ('\u1f42', '\u1f4a'),
-        ('\u1f43', '\u1f4b'), ('\u1f44', '\u1f4c'),
-        ('\u1f45', '\u1f4d'), ('\u1f51', '\u1f59'),
-        ('\u1f53', '\u1f5b'), ('\u1f55', '\u1f5d'),
-        ('\u1f57', '\u1f5f'), ('\u1f60', '\u1f68'),
-        ('\u1f61', '\u1f69'), ('\u1f62', '\u1f6a'),
-        ('\u1f63', '\u1f6b'), ('\u1f64', '\u1f6c'),
-        ('\u1f65', '\u1f6d'), ('\u1f66', '\u1f6e'),
-        ('\u1f67', '\u1f6f'), ('\u1f70', '\u1fba'),
-        ('\u1f71', '\u1fbb'), ('\u1f72', '\u1fc8'),
-        ('\u1f73', '\u1fc9'), ('\u1f74', '\u1fca'),
-        ('\u1f75', '\u1fcb'), ('\u1f76', '\u1fda'),
-        ('\u1f77', '\u1fdb'), ('\u1f78', '\u1ff8'),
-        ('\u1f79', '\u1ff9'), ('\u1f7a', '\u1fea'),
-        ('\u1f7b', '\u1feb'), ('\u1f7c', '\u1ffa'),
-        ('\u1f7d', '\u1ffb'), ('\u1f80', '\u1f88'),
-        ('\u1f81', '\u1f89'), ('\u1f82', '\u1f8a'),
-        ('\u1f83', '\u1f8b'), ('\u1f84', '\u1f8c'),
-        ('\u1f85', '\u1f8d'), ('\u1f86', '\u1f8e'),
-        ('\u1f87', '\u1f8f'), ('\u1f90', '\u1f98'),
-        ('\u1f91', '\u1f99'), ('\u1f92', '\u1f9a'),
-        ('\u1f93', '\u1f9b'), ('\u1f94', '\u1f9c'),
-        ('\u1f95', '\u1f9d'), ('\u1f96', '\u1f9e'),
-        ('\u1f97', '\u1f9f'), ('\u1fa0', '\u1fa8'),
-        ('\u1fa1', '\u1fa9'), ('\u1fa2', '\u1faa'),
-        ('\u1fa3', '\u1fab'), ('\u1fa4', '\u1fac'),
-        ('\u1fa5', '\u1fad'), ('\u1fa6', '\u1fae'),
-        ('\u1fa7', '\u1faf'), ('\u1fb0', '\u1fb8'),
-        ('\u1fb1', '\u1fb9'), ('\u1fb3', '\u1fbc'),
-        ('\u1fbe', '\u0399'), ('\u1fc3', '\u1fcc'),
-        ('\u1fd0', '\u1fd8'), ('\u1fd1', '\u1fd9'),
-        ('\u1fe0', '\u1fe8'), ('\u1fe1', '\u1fe9'),
-        ('\u1fe5', '\u1fec'), ('\u1ff3', '\u1ffc'),
-        ('\u214e', '\u2132'), ('\u2184', '\u2183'),
-        ('\u2c30', '\u2c00'), ('\u2c31', '\u2c01'),
-        ('\u2c32', '\u2c02'), ('\u2c33', '\u2c03'),
-        ('\u2c34', '\u2c04'), ('\u2c35', '\u2c05'),
-        ('\u2c36', '\u2c06'), ('\u2c37', '\u2c07'),
-        ('\u2c38', '\u2c08'), ('\u2c39', '\u2c09'),
-        ('\u2c3a', '\u2c0a'), ('\u2c3b', '\u2c0b'),
-        ('\u2c3c', '\u2c0c'), ('\u2c3d', '\u2c0d'),
-        ('\u2c3e', '\u2c0e'), ('\u2c3f', '\u2c0f'),
-        ('\u2c40', '\u2c10'), ('\u2c41', '\u2c11'),
-        ('\u2c42', '\u2c12'), ('\u2c43', '\u2c13'),
-        ('\u2c44', '\u2c14'), ('\u2c45', '\u2c15'),
-        ('\u2c46', '\u2c16'), ('\u2c47', '\u2c17'),
-        ('\u2c48', '\u2c18'), ('\u2c49', '\u2c19'),
-        ('\u2c4a', '\u2c1a'), ('\u2c4b', '\u2c1b'),
-        ('\u2c4c', '\u2c1c'), ('\u2c4d', '\u2c1d'),
-        ('\u2c4e', '\u2c1e'), ('\u2c4f', '\u2c1f'),
-        ('\u2c50', '\u2c20'), ('\u2c51', '\u2c21'),
-        ('\u2c52', '\u2c22'), ('\u2c53', '\u2c23'),
-        ('\u2c54', '\u2c24'), ('\u2c55', '\u2c25'),
-        ('\u2c56', '\u2c26'), ('\u2c57', '\u2c27'),
-        ('\u2c58', '\u2c28'), ('\u2c59', '\u2c29'),
-        ('\u2c5a', '\u2c2a'), ('\u2c5b', '\u2c2b'),
-        ('\u2c5c', '\u2c2c'), ('\u2c5d', '\u2c2d'),
-        ('\u2c5e', '\u2c2e'), ('\u2c61', '\u2c60'),
-        ('\u2c65', '\u023a'), ('\u2c66', '\u023e'),
-        ('\u2c68', '\u2c67'), ('\u2c6a', '\u2c69'),
-        ('\u2c6c', '\u2c6b'), ('\u2c73', '\u2c72'),
-        ('\u2c76', '\u2c75'), ('\u2c81', '\u2c80'),
-        ('\u2c83', '\u2c82'), ('\u2c85', '\u2c84'),
-        ('\u2c87', '\u2c86'), ('\u2c89', '\u2c88'),
-        ('\u2c8b', '\u2c8a'), ('\u2c8d', '\u2c8c'),
-        ('\u2c8f', '\u2c8e'), ('\u2c91', '\u2c90'),
-        ('\u2c93', '\u2c92'), ('\u2c95', '\u2c94'),
-        ('\u2c97', '\u2c96'), ('\u2c99', '\u2c98'),
-        ('\u2c9b', '\u2c9a'), ('\u2c9d', '\u2c9c'),
-        ('\u2c9f', '\u2c9e'), ('\u2ca1', '\u2ca0'),
-        ('\u2ca3', '\u2ca2'), ('\u2ca5', '\u2ca4'),
-        ('\u2ca7', '\u2ca6'), ('\u2ca9', '\u2ca8'),
-        ('\u2cab', '\u2caa'), ('\u2cad', '\u2cac'),
-        ('\u2caf', '\u2cae'), ('\u2cb1', '\u2cb0'),
-        ('\u2cb3', '\u2cb2'), ('\u2cb5', '\u2cb4'),
-        ('\u2cb7', '\u2cb6'), ('\u2cb9', '\u2cb8'),
-        ('\u2cbb', '\u2cba'), ('\u2cbd', '\u2cbc'),
-        ('\u2cbf', '\u2cbe'), ('\u2cc1', '\u2cc0'),
-        ('\u2cc3', '\u2cc2'), ('\u2cc5', '\u2cc4'),
-        ('\u2cc7', '\u2cc6'), ('\u2cc9', '\u2cc8'),
-        ('\u2ccb', '\u2cca'), ('\u2ccd', '\u2ccc'),
-        ('\u2ccf', '\u2cce'), ('\u2cd1', '\u2cd0'),
-        ('\u2cd3', '\u2cd2'), ('\u2cd5', '\u2cd4'),
-        ('\u2cd7', '\u2cd6'), ('\u2cd9', '\u2cd8'),
-        ('\u2cdb', '\u2cda'), ('\u2cdd', '\u2cdc'),
-        ('\u2cdf', '\u2cde'), ('\u2ce1', '\u2ce0'),
-        ('\u2ce3', '\u2ce2'), ('\u2cec', '\u2ceb'),
-        ('\u2cee', '\u2ced'), ('\u2cf3', '\u2cf2'),
-        ('\u2d00', '\u10a0'), ('\u2d01', '\u10a1'),
-        ('\u2d02', '\u10a2'), ('\u2d03', '\u10a3'),
-        ('\u2d04', '\u10a4'), ('\u2d05', '\u10a5'),
-        ('\u2d06', '\u10a6'), ('\u2d07', '\u10a7'),
-        ('\u2d08', '\u10a8'), ('\u2d09', '\u10a9'),
-        ('\u2d0a', '\u10aa'), ('\u2d0b', '\u10ab'),
-        ('\u2d0c', '\u10ac'), ('\u2d0d', '\u10ad'),
-        ('\u2d0e', '\u10ae'), ('\u2d0f', '\u10af'),
-        ('\u2d10', '\u10b0'), ('\u2d11', '\u10b1'),
-        ('\u2d12', '\u10b2'), ('\u2d13', '\u10b3'),
-        ('\u2d14', '\u10b4'), ('\u2d15', '\u10b5'),
-        ('\u2d16', '\u10b6'), ('\u2d17', '\u10b7'),
-        ('\u2d18', '\u10b8'), ('\u2d19', '\u10b9'),
-        ('\u2d1a', '\u10ba'), ('\u2d1b', '\u10bb'),
-        ('\u2d1c', '\u10bc'), ('\u2d1d', '\u10bd'),
-        ('\u2d1e', '\u10be'), ('\u2d1f', '\u10bf'),
-        ('\u2d20', '\u10c0'), ('\u2d21', '\u10c1'),
-        ('\u2d22', '\u10c2'), ('\u2d23', '\u10c3'),
-        ('\u2d24', '\u10c4'), ('\u2d25', '\u10c5'),
-        ('\u2d27', '\u10c7'), ('\u2d2d', '\u10cd'),
-        ('\ua641', '\ua640'), ('\ua643', '\ua642'),
-        ('\ua645', '\ua644'), ('\ua647', '\ua646'),
-        ('\ua649', '\ua648'), ('\ua64b', '\ua64a'),
-        ('\ua64d', '\ua64c'), ('\ua64f', '\ua64e'),
-        ('\ua651', '\ua650'), ('\ua653', '\ua652'),
-        ('\ua655', '\ua654'), ('\ua657', '\ua656'),
-        ('\ua659', '\ua658'), ('\ua65b', '\ua65a'),
-        ('\ua65d', '\ua65c'), ('\ua65f', '\ua65e'),
-        ('\ua661', '\ua660'), ('\ua663', '\ua662'),
-        ('\ua665', '\ua664'), ('\ua667', '\ua666'),
-        ('\ua669', '\ua668'), ('\ua66b', '\ua66a'),
-        ('\ua66d', '\ua66c'), ('\ua681', '\ua680'),
-        ('\ua683', '\ua682'), ('\ua685', '\ua684'),
-        ('\ua687', '\ua686'), ('\ua689', '\ua688'),
-        ('\ua68b', '\ua68a'), ('\ua68d', '\ua68c'),
-        ('\ua68f', '\ua68e'), ('\ua691', '\ua690'),
-        ('\ua693', '\ua692'), ('\ua695', '\ua694'),
-        ('\ua697', '\ua696'), ('\ua723', '\ua722'),
-        ('\ua725', '\ua724'), ('\ua727', '\ua726'),
-        ('\ua729', '\ua728'), ('\ua72b', '\ua72a'),
-        ('\ua72d', '\ua72c'), ('\ua72f', '\ua72e'),
-        ('\ua733', '\ua732'), ('\ua735', '\ua734'),
-        ('\ua737', '\ua736'), ('\ua739', '\ua738'),
-        ('\ua73b', '\ua73a'), ('\ua73d', '\ua73c'),
-        ('\ua73f', '\ua73e'), ('\ua741', '\ua740'),
-        ('\ua743', '\ua742'), ('\ua745', '\ua744'),
-        ('\ua747', '\ua746'), ('\ua749', '\ua748'),
-        ('\ua74b', '\ua74a'), ('\ua74d', '\ua74c'),
-        ('\ua74f', '\ua74e'), ('\ua751', '\ua750'),
-        ('\ua753', '\ua752'), ('\ua755', '\ua754'),
-        ('\ua757', '\ua756'), ('\ua759', '\ua758'),
-        ('\ua75b', '\ua75a'), ('\ua75d', '\ua75c'),
-        ('\ua75f', '\ua75e'), ('\ua761', '\ua760'),
-        ('\ua763', '\ua762'), ('\ua765', '\ua764'),
-        ('\ua767', '\ua766'), ('\ua769', '\ua768'),
-        ('\ua76b', '\ua76a'), ('\ua76d', '\ua76c'),
-        ('\ua76f', '\ua76e'), ('\ua77a', '\ua779'),
-        ('\ua77c', '\ua77b'), ('\ua77f', '\ua77e'),
-        ('\ua781', '\ua780'), ('\ua783', '\ua782'),
-        ('\ua785', '\ua784'), ('\ua787', '\ua786'),
-        ('\ua78c', '\ua78b'), ('\ua791', '\ua790'),
-        ('\ua793', '\ua792'), ('\ua7a1', '\ua7a0'),
-        ('\ua7a3', '\ua7a2'), ('\ua7a5', '\ua7a4'),
-        ('\ua7a7', '\ua7a6'), ('\ua7a9', '\ua7a8'),
-        ('\uff41', '\uff21'), ('\uff42', '\uff22'),
-        ('\uff43', '\uff23'), ('\uff44', '\uff24'),
-        ('\uff45', '\uff25'), ('\uff46', '\uff26'),
-        ('\uff47', '\uff27'), ('\uff48', '\uff28'),
-        ('\uff49', '\uff29'), ('\uff4a', '\uff2a'),
-        ('\uff4b', '\uff2b'), ('\uff4c', '\uff2c'),
-        ('\uff4d', '\uff2d'), ('\uff4e', '\uff2e'),
-        ('\uff4f', '\uff2f'), ('\uff50', '\uff30'),
-        ('\uff51', '\uff31'), ('\uff52', '\uff32'),
-        ('\uff53', '\uff33'), ('\uff54', '\uff34'),
-        ('\uff55', '\uff35'), ('\uff56', '\uff36'),
-        ('\uff57', '\uff37'), ('\uff58', '\uff38'),
-        ('\uff59', '\uff39'), ('\uff5a', '\uff3a'),
-        ('\U00010428', '\U00010400'), ('\U00010429', '\U00010401'),
-        ('\U0001042a', '\U00010402'), ('\U0001042b', '\U00010403'),
-        ('\U0001042c', '\U00010404'), ('\U0001042d', '\U00010405'),
-        ('\U0001042e', '\U00010406'), ('\U0001042f', '\U00010407'),
-        ('\U00010430', '\U00010408'), ('\U00010431', '\U00010409'),
-        ('\U00010432', '\U0001040a'), ('\U00010433', '\U0001040b'),
-        ('\U00010434', '\U0001040c'), ('\U00010435', '\U0001040d'),
-        ('\U00010436', '\U0001040e'), ('\U00010437', '\U0001040f'),
-        ('\U00010438', '\U00010410'), ('\U00010439', '\U00010411'),
-        ('\U0001043a', '\U00010412'), ('\U0001043b', '\U00010413'),
-        ('\U0001043c', '\U00010414'), ('\U0001043d', '\U00010415'),
-        ('\U0001043e', '\U00010416'), ('\U0001043f', '\U00010417'),
-        ('\U00010440', '\U00010418'), ('\U00010441', '\U00010419'),
-        ('\U00010442', '\U0001041a'), ('\U00010443', '\U0001041b'),
-        ('\U00010444', '\U0001041c'), ('\U00010445', '\U0001041d'),
-        ('\U00010446', '\U0001041e'), ('\U00010447', '\U0001041f'),
-        ('\U00010448', '\U00010420'), ('\U00010449', '\U00010421'),
-        ('\U0001044a', '\U00010422'), ('\U0001044b', '\U00010423'),
-        ('\U0001044c', '\U00010424'), ('\U0001044d', '\U00010425'),
-        ('\U0001044e', '\U00010426'), ('\U0001044f', '\U00010427')
-    ];
-
-}
index 852edd90b0f3fb28ecb6ad4b574dce7fe2079d50..51d13535caf303758b34fca2df3212f62714cace 100644 (file)
@@ -167,12 +167,6 @@ fn string(c: char) -> String {
     assert_eq!(s.as_slice(), "\\U0001d4b6");
 }
 
-#[test]
-fn test_to_str() {
-    let s = 't'.to_str();
-    assert_eq!(s.as_slice(), "t");
-}
-
 #[test]
 fn test_encode_utf8() {
     fn check(input: char, expect: &[u8]) {
@@ -200,3 +194,30 @@ fn check(input: char, expect: &[u16]) {
     check('\ua66e', [0xa66e]);
     check('\U0001f4a9', [0xd83d, 0xdca9]);
 }
+
+#[test]
+fn test_width() {
+    assert_eq!('\x00'.width(false),Some(0));
+    assert_eq!('\x00'.width(true),Some(0));
+
+    assert_eq!('\x0A'.width(false),None);
+    assert_eq!('\x0A'.width(true),None);
+
+    assert_eq!('w'.width(false),Some(1));
+    assert_eq!('w'.width(true),Some(1));
+
+    assert_eq!('h'.width(false),Some(2));
+    assert_eq!('h'.width(true),Some(2));
+
+    assert_eq!('\xAD'.width(false),Some(1));
+    assert_eq!('\xAD'.width(true),Some(1));
+
+    assert_eq!('\u1160'.width(false),Some(0));
+    assert_eq!('\u1160'.width(true),Some(0));
+
+    assert_eq!('\u00a1'.width(false),Some(1));
+    assert_eq!('\u00a1'.width(true),Some(2));
+
+    assert_eq!('\u0300'.width(false),Some(0));
+    assert_eq!('\u0300'.width(true),Some(0));
+}
index 86b5ffece41033c7a8b851a637b2490c4b2ccee9..64c336093996d6b44c079a7344d9ebb6b75c6b43 100644 (file)
@@ -833,3 +833,12 @@ fn test_min_max_result() {
     let r = MinMax(1i,2);
     assert_eq!(r.into_option(), Some((1,2)));
 }
+
+#[test]
+fn test_iterate() {
+    let mut it = iterate(|x| x * 2, 1u);
+    assert_eq!(it.next(), Some(1u));
+    assert_eq!(it.next(), Some(2u));
+    assert_eq!(it.next(), Some(4u));
+    assert_eq!(it.next(), Some(8u));
+}
index 4087cb952716831fa3a55215e8a3538024b0392e..0b04a07ea888af5a667fa1ad61015c0382141c5d 100644 (file)
@@ -45,7 +45,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             // If we have a specified width for formatting, then we have to make
             // this allocation of a new string
             _ => {
-                let s = repr::repr_to_str(self);
+                let s = repr::repr_to_string(self);
                 f.pad(s.as_slice())
             }
         }
index 850002b595e91a0031981e494e4be42cc9cef124..6341a38056359bf495d21bd1798c3f241643d23e 100644 (file)
 //! Additionally, it is not guaranteed that functionality such as reflection
 //! will persist into the future.
 
-#![crate_id = "debug#0.11.0"]
+#![crate_name = "debug"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 #![experimental]
 #![feature(managed_boxes, macro_rules)]
 #![allow(experimental)]
index 133353ec3d717a09a9225a332d77ae0e5b61f55a..3e541929dbf0883957cd74cd4f5046d1a52882f8 100644 (file)
@@ -73,7 +73,7 @@ fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
 
 macro_rules! num_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
     fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
-        let s = self.to_str();
+        let s = self.to_string();
         writer.write(s.as_bytes()).and_then(|()| {
             writer.write($suffix)
         })
@@ -564,7 +564,7 @@ pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> {
     }
 }
 
-pub fn repr_to_str<T>(t: &T) -> String {
+pub fn repr_to_string<T>(t: &T) -> String {
     let mut result = io::MemWriter::new();
     write_repr(&mut result as &mut io::Writer, t).unwrap();
     String::from_utf8(result.unwrap()).unwrap()
index d944818abc56ad3a4054aa87590448e4d4c1a9b5..4226ac14118a40a232c2b0c92d01aa30b82f5083 100644 (file)
 
 */
 
-#![crate_id = "flate#0.11.0"]
+#![crate_name = "flate"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 #![feature(phase)]
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
index b9c0fcce52da7c3e162412c0292392d358c59a24..62547b6669f7acfec1ca168b356eca821b1962e2 100644 (file)
@@ -14,7 +14,7 @@
 //! Parsing does not happen at runtime: structures of `std::fmt::rt` are
 //! generated instead.
 
-#![crate_id = "fmt_macros#0.11.0"]
+#![crate_name = "fmt_macros"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
index e854cd3069c8a78d0ff031cfe203a4bd9977eae5..aa8d84bec1711010c25973642ad12c24a5ff8708 100644 (file)
@@ -39,14 +39,14 @@ fn main() {
 
 */
 
-#![crate_id = "fourcc#0.11.0"]
+#![crate_name = "fourcc"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 
 #![feature(plugin_registrar, managed_boxes)]
 
index 00e6df9ffbbb2eab49343ac77ca144970fe07e07..eaec31a45f42180fab1f4cb3ae95ac19a0d00bcd 100644 (file)
@@ -59,7 +59,7 @@
 //!     ];
 //!     let matches = match getopts(args.tail(), opts) {
 //!         Ok(m) => { m }
-//!         Err(f) => { fail!(f.to_str()) }
+//!         Err(f) => { fail!(f.to_string()) }
 //!     };
 //!     if matches.opt_present("h") {
 //!         print_usage(program.as_slice(), opts);
 //! }
 //! ~~~
 
-#![crate_id = "getopts#0.11.0"]
+#![crate_name = "getopts"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(globs, phase)]
 #![deny(missing_doc)]
@@ -220,9 +220,9 @@ fn from_str(nm: &str) -> Name {
         }
     }
 
-    fn to_str(&self) -> String {
+    fn to_string(&self) -> String {
         match *self {
-            Short(ch) => ch.to_str(),
+            Short(ch) => ch.to_string(),
             Long(ref s) => s.to_string()
         }
     }
@@ -499,7 +499,7 @@ impl Fail_ {
     /// Convert a `Fail_` enum into an error string.
     #[deprecated="use `Show` (`{}` format specifier)"]
     pub fn to_err_msg(self) -> String {
-        self.to_str()
+        self.to_string()
     }
 }
 
@@ -607,12 +607,12 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                 name_pos += 1;
                 let optid = match find_opt(opts.as_slice(), (*nm).clone()) {
                   Some(id) => id,
-                  None => return Err(UnrecognizedOption(nm.to_str()))
+                  None => return Err(UnrecognizedOption(nm.to_string()))
                 };
                 match opts.get(optid).hasarg {
                   No => {
                     if !i_arg.is_none() {
-                        return Err(UnexpectedArgument(nm.to_str()));
+                        return Err(UnexpectedArgument(nm.to_string()));
                     }
                     vals.get_mut(optid).push(Given);
                   }
@@ -633,7 +633,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                     if !i_arg.is_none() {
                         vals.get_mut(optid).push(Val(i_arg.clone().unwrap()));
                     } else if i + 1 == l {
-                        return Err(ArgumentMissing(nm.to_str()));
+                        return Err(ArgumentMissing(nm.to_string()));
                     } else {
                         i += 1;
                         vals.get_mut(optid).push(Val(args[i].clone()));
@@ -650,12 +650,12 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
         let occ = opts.get(i).occur;
         if occ == Req {
             if n == 0 {
-                return Err(OptionMissing(opts.get(i).name.to_str()));
+                return Err(OptionMissing(opts.get(i).name.to_string()));
             }
         }
         if occ != Multi {
             if n > 1 {
-                return Err(OptionDuplicated(opts.get(i).name.to_str()));
+                return Err(OptionDuplicated(opts.get(i).name.to_string()));
             }
         }
         i += 1;
@@ -894,7 +894,7 @@ enum LengthLimit {
         *cont
     };
 
-    ss.char_indices().advance(|x| machine(&mut cont, x));
+    ss.char_indices().all(|x| machine(&mut cont, x));
 
     // Let the automaton 'run out' by supplying trailing whitespace
     while cont && match state { B | C => true, A => false } {
index 3cb21601e331d8f2f9d73022ecd076c4fde92bae..c28eb51d59d442d42acfa5962886e50a5fd0bf7c 100644 (file)
  * `glob`/`fnmatch` functions.
  */
 
-#![crate_id = "glob#0.11.0"]
+#![crate_name = "glob"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 use std::cell::Cell;
@@ -601,13 +601,13 @@ pub struct MatchOptions {
      * currently only considers upper/lower case relationships between ASCII characters,
      * but in future this might be extended to work with Unicode.
      */
-    case_sensitive: bool,
+    pub case_sensitive: bool,
 
     /**
      * If this is true then path-component separator characters (e.g. `/` on Posix)
      * must be matched by a literal `/`, rather than by `*` or `?` or `[...]`
      */
-    require_literal_separator: bool,
+    pub require_literal_separator: bool,
 
     /**
      * If this is true then paths that contain components that start with a `.` will
@@ -615,7 +615,7 @@ pub struct MatchOptions {
      * will not match. This is useful because such files are conventionally considered
      * hidden on Unix systems and it might be desirable to skip them when listing files.
      */
-    require_literal_leading_dot: bool
+    pub require_literal_leading_dot: bool
 }
 
 impl MatchOptions {
@@ -701,11 +701,11 @@ fn test_range_pattern() {
         for &p in pats.iter() {
             let pat = Pattern::new(p);
             for c in "abcdefghijklmnopqrstuvwxyz".chars() {
-                assert!(pat.matches(c.to_str().as_slice()));
+                assert!(pat.matches(c.to_string().as_slice()));
             }
             for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars() {
                 let options = MatchOptions {case_sensitive: false, .. MatchOptions::new()};
-                assert!(pat.matches_with(c.to_str().as_slice(), options));
+                assert!(pat.matches_with(c.to_string().as_slice(), options));
             }
             assert!(pat.matches("1"));
             assert!(pat.matches("2"));
index 16298f51ea96b283a562537069a5ae98476f483b..a3653fa9735901353a3cf331b895fc614e296e0f 100644 (file)
@@ -266,16 +266,14 @@ pub fn main() {
 
 */
 
-#![crate_id = "graphviz#0.11.0"]
+#![crate_name = "graphviz"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
-
-#![experimental]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 
 use std::io;
 use std::str;
@@ -436,10 +434,37 @@ fn escape_str(s: &str) -> String {
     /// Renders text as string suitable for a label in a .dot file.
     pub fn escape(&self) -> String {
         match self {
-            &LabelStr(ref s) => s.as_slice().escape_default().to_string(),
-            &EscStr(ref s) => LabelText::escape_str(s.as_slice()).to_string(),
+            &LabelStr(ref s) => s.as_slice().escape_default(),
+            &EscStr(ref s) => LabelText::escape_str(s.as_slice()),
+        }
+    }
+
+    /// Decomposes content into string suitable for making EscStr that
+    /// yields same content as self.  The result obeys the law
+    /// render(`lt`) == render(`EscStr(lt.pre_escaped_content())`) for
+    /// all `lt: LabelText`.
+    fn pre_escaped_content(self) -> str::MaybeOwned<'a> {
+        match self {
+            EscStr(s) => s,
+            LabelStr(s) => if s.as_slice().contains_char('\\') {
+                str::Owned(s.as_slice().escape_default())
+            } else {
+                s
+            },
         }
     }
+
+    /// Puts `prefix` on a line above this label, with a blank line separator.
+    pub fn prefix_line(self, prefix: LabelText) -> LabelText {
+        prefix.suffix_line(self)
+    }
+
+    /// Puts `suffix` on a line below this label, with a blank line separator.
+    pub fn suffix_line(self, suffix: LabelText) -> LabelText {
+        let prefix = self.pre_escaped_content().into_string();
+        let suffix = suffix.pre_escaped_content();
+        EscStr(str::Owned(prefix.append(r"\n\n").append(suffix.as_slice())))
+    }
 }
 
 pub type Nodes<'a,N> = MaybeOwnedVector<'a,N>;
@@ -666,10 +691,7 @@ fn test_input(g: LabelledGraph) -> IoResult<String> {
         let mut writer = MemWriter::new();
         render(&g, &mut writer).unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        match r.read_to_str() {
-            Ok(string) => Ok(string.to_string()),
-            Err(err) => Err(err),
-        }
+        r.read_to_string()
     }
 
     // All of the tests use raw-strings as the format for the expected outputs,
@@ -768,7 +790,7 @@ fn left_aligned_text() {
 
         render(&g, &mut writer).unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        let r = r.read_to_str();
+        let r = r.read_to_string();
 
         assert_eq!(r.unwrap().as_slice(),
 r#"digraph syntax_tree {
index 1b34679b0a18a67a0857d39ee3ce5aaf68c23f0c..6e4e2ac0feee39999fa78548913f7c8ad7861f6e 100644 (file)
 //! possibly pinned to a particular scheduler thread:
 //!
 //! ```rust
+//! extern crate green;
+//! extern crate rustuv;
+//!
+//! # fn main() {
 //! use std::task::TaskBuilder;
 //! use green::{SchedPool, PoolConfig, GreenTaskBuilder};
 //!
-//! let config = PoolConfig::new();
+//! let mut config = PoolConfig::new();
+//!
+//! // Optional: Set the event loop to be rustuv's to allow I/O to work
+//! config.event_loop_factory = rustuv::event_loop;
+//!
 //! let mut pool = SchedPool::new(config);
 //!
 //! // Spawn tasks into the pool of schedulers
 //! // Required to shut down this scheduler pool.
 //! // The task will fail if `shutdown` is not called.
 //! pool.shutdown();
+//! # }
 //! ```
 
-#![crate_id = "green#0.11.0"]
+#![crate_name = "green"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 // NB this does *not* include globs, please keep it that way.
-#![feature(macro_rules, phase)]
-#![allow(visible_private_types)]
-#![allow(deprecated)]
-#![feature(default_type_params)]
+#![feature(macro_rules, phase, default_type_params)]
+#![allow(visible_private_types, deprecated)]
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 #[cfg(test)] extern crate rustuv;
index 5faa9cfe6f6a2bd0cbbb0c7d80cf95754de2331f..633bd3c041a3d586f2d35ee3e440587ef53bc17e 100644 (file)
@@ -8,14 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::ptr;
 use std::sync::atomics;
 use std::os::{errno, page_size, MemoryMap, MapReadable, MapWritable,
-              MapNonStandardFlags, MapVirtual, getenv};
+              MapNonStandardFlags, getenv};
 use libc;
 
 /// A task's stack. The name "Stack" is a vestige of segmented stacks.
 pub struct Stack {
-    buf: MemoryMap,
+    buf: Option<MemoryMap>,
     min_size: uint,
     valgrind_id: libc::c_uint,
 }
@@ -52,11 +53,11 @@ pub fn new(size: uint) -> Stack {
         // guaranteed to be aligned properly.
         if !protect_last_page(&stack) {
             fail!("Could not memory-protect guard page. stack={}, errno={}",
-                  stack.data, errno());
+                  stack.data(), errno());
         }
 
         let mut stk = Stack {
-            buf: stack,
+            buf: Some(stack),
             min_size: size,
             valgrind_id: 0
         };
@@ -71,7 +72,7 @@ pub fn new(size: uint) -> Stack {
     /// Create a 0-length stack which starts (and ends) at 0.
     pub unsafe fn dummy_stack() -> Stack {
         Stack {
-            buf: MemoryMap { data: 0 as *mut u8, len: 0, kind: MapVirtual },
+            buf: None,
             min_size: 0,
             valgrind_id: 0
         }
@@ -79,14 +80,15 @@ pub unsafe fn dummy_stack() -> Stack {
 
     /// Point to the low end of the allocated stack
     pub fn start(&self) -> *const uint {
-        self.buf.data as *const uint
+        self.buf.as_ref().map(|m| m.data() as *const uint)
+            .unwrap_or(ptr::null())
     }
 
     /// Point one uint beyond the high end of the allocated stack
     pub fn end(&self) -> *const uint {
-        unsafe {
-            self.buf.data.offset(self.buf.len as int) as *const uint
-        }
+        self.buf.as_ref().map(|buf| unsafe {
+            buf.data().offset(buf.len() as int) as *const uint
+        }).unwrap_or(ptr::null())
     }
 }
 
@@ -96,7 +98,7 @@ fn protect_last_page(stack: &MemoryMap) -> bool {
         // This may seem backwards: the start of the segment is the last page?
         // Yes! The stack grows from higher addresses (the end of the allocated
         // block) to lower addresses (the start of the allocated block).
-        let last_page = stack.data as *mut libc::c_void;
+        let last_page = stack.data() as *mut libc::c_void;
         libc::mprotect(last_page, page_size() as libc::size_t,
                        libc::PROT_NONE) != -1
     }
@@ -106,7 +108,7 @@ fn protect_last_page(stack: &MemoryMap) -> bool {
 fn protect_last_page(stack: &MemoryMap) -> bool {
     unsafe {
         // see above
-        let last_page = stack.data as *mut libc::c_void;
+        let last_page = stack.data() as *mut libc::c_void;
         let mut old_prot: libc::DWORD = 0;
         libc::VirtualProtect(last_page, page_size() as libc::SIZE_T,
                              libc::PAGE_NOACCESS,
index 64538bd2212a47e8d7562c7faa619036927172de..2859e1c985f5e5beb96666faeb8d916150e054ba 100644 (file)
@@ -36,14 +36,14 @@ fn main() {
 
 */
 
-#![crate_id = "hexfloat#0.11.0"]
+#![crate_name = "hexfloat"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 #![feature(plugin_registrar, managed_boxes)]
 
 extern crate syntax;
index 81e50889952ec2671e931604c50654d03e2dd996..fc4144a2868638c2f7598aaf0aabb6ba4347bed5 100644 (file)
@@ -9,14 +9,14 @@
 // except according to those terms.
 
 #![feature(globs)]
-#![crate_id = "libc#0.11.0"]
+#![crate_name = "libc"]
 #![experimental]
 #![no_std] // we don't need std, and we can't have std, since it doesn't exist
            // yet. std depends on us.
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 /*!
@@ -2008,6 +2008,7 @@ pub mod c99 {
         pub mod posix88 {
             use types::os::arch::c95::c_int;
             use types::common::c95::c_void;
+            use types::os::arch::posix88::mode_t;
 
             pub static O_RDONLY : c_int = 0;
             pub static O_WRONLY : c_int = 1;
@@ -2016,20 +2017,20 @@ pub mod posix88 {
             pub static O_CREAT : c_int = 64;
             pub static O_EXCL : c_int = 128;
             pub static O_TRUNC : c_int = 512;
-            pub static S_IFIFO : c_int = 4096;
-            pub static S_IFCHR : c_int = 8192;
-            pub static S_IFBLK : c_int = 24576;
-            pub static S_IFDIR : c_int = 16384;
-            pub static S_IFREG : c_int = 32768;
-            pub static S_IFLNK : c_int = 40960;
-            pub static S_IFMT : c_int = 61440;
-            pub static S_IEXEC : c_int = 64;
-            pub static S_IWRITE : c_int = 128;
-            pub static S_IREAD : c_int = 256;
-            pub static S_IRWXU : c_int = 448;
-            pub static S_IXUSR : c_int = 64;
-            pub static S_IWUSR : c_int = 128;
-            pub static S_IRUSR : c_int = 256;
+            pub static S_IFIFO : mode_t = 4096;
+            pub static S_IFCHR : mode_t = 8192;
+            pub static S_IFBLK : mode_t = 24576;
+            pub static S_IFDIR : mode_t = 16384;
+            pub static S_IFREG : mode_t = 32768;
+            pub static S_IFLNK : mode_t = 40960;
+            pub static S_IFMT : mode_t = 61440;
+            pub static S_IEXEC : mode_t = 64;
+            pub static S_IWRITE : mode_t = 128;
+            pub static S_IREAD : mode_t = 256;
+            pub static S_IRWXU : mode_t = 448;
+            pub static S_IXUSR : mode_t = 64;
+            pub static S_IWUSR : mode_t = 128;
+            pub static S_IRUSR : mode_t = 256;
             pub static F_OK : c_int = 0;
             pub static R_OK : c_int = 4;
             pub static W_OK : c_int = 2;
@@ -2220,6 +2221,7 @@ pub mod posix88 {
         pub mod posix88 {
             use types::os::arch::c95::c_int;
             use types::common::c95::c_void;
+            use types::os::arch::posix88::mode_t;
 
             pub static O_RDONLY : c_int = 0;
             pub static O_WRONLY : c_int = 1;
@@ -2228,20 +2230,20 @@ pub mod posix88 {
             pub static O_CREAT : c_int = 256;
             pub static O_EXCL : c_int = 1024;
             pub static O_TRUNC : c_int = 512;
-            pub static S_IFIFO : c_int = 4096;
-            pub static S_IFCHR : c_int = 8192;
-            pub static S_IFBLK : c_int = 24576;
-            pub static S_IFDIR : c_int = 16384;
-            pub static S_IFREG : c_int = 32768;
-            pub static S_IFLNK : c_int = 40960;
-            pub static S_IFMT : c_int = 61440;
-            pub static S_IEXEC : c_int = 64;
-            pub static S_IWRITE : c_int = 128;
-            pub static S_IREAD : c_int = 256;
-            pub static S_IRWXU : c_int = 448;
-            pub static S_IXUSR : c_int = 64;
-            pub static S_IWUSR : c_int = 128;
-            pub static S_IRUSR : c_int = 256;
+            pub static S_IFIFO : mode_t = 4096;
+            pub static S_IFCHR : mode_t = 8192;
+            pub static S_IFBLK : mode_t = 24576;
+            pub static S_IFDIR : mode_t = 16384;
+            pub static S_IFREG : mode_t = 32768;
+            pub static S_IFLNK : mode_t = 40960;
+            pub static S_IFMT : mode_t = 61440;
+            pub static S_IEXEC : mode_t = 64;
+            pub static S_IWRITE : mode_t = 128;
+            pub static S_IREAD : mode_t = 256;
+            pub static S_IRWXU : mode_t = 448;
+            pub static S_IXUSR : mode_t = 64;
+            pub static S_IWUSR : mode_t = 128;
+            pub static S_IRUSR : mode_t = 256;
             pub static F_OK : c_int = 0;
             pub static R_OK : c_int = 4;
             pub static W_OK : c_int = 2;
@@ -2759,6 +2761,7 @@ pub mod c99 {
         pub mod posix88 {
             use types::common::c95::c_void;
             use types::os::arch::c95::c_int;
+            use types::os::arch::posix88::mode_t;
 
             pub static O_RDONLY : c_int = 0;
             pub static O_WRONLY : c_int = 1;
@@ -2767,20 +2770,20 @@ pub mod posix88 {
             pub static O_CREAT : c_int = 512;
             pub static O_EXCL : c_int = 2048;
             pub static O_TRUNC : c_int = 1024;
-            pub static S_IFIFO : c_int = 4096;
-            pub static S_IFCHR : c_int = 8192;
-            pub static S_IFBLK : c_int = 24576;
-            pub static S_IFDIR : c_int = 16384;
-            pub static S_IFREG : c_int = 32768;
-            pub static S_IFLNK : c_int = 40960;
-            pub static S_IFMT : c_int = 61440;
-            pub static S_IEXEC : c_int = 64;
-            pub static S_IWRITE : c_int = 128;
-            pub static S_IREAD : c_int = 256;
-            pub static S_IRWXU : c_int = 448;
-            pub static S_IXUSR : c_int = 64;
-            pub static S_IWUSR : c_int = 128;
-            pub static S_IRUSR : c_int = 256;
+            pub static S_IFIFO : mode_t = 4096;
+            pub static S_IFCHR : mode_t = 8192;
+            pub static S_IFBLK : mode_t = 24576;
+            pub static S_IFDIR : mode_t = 16384;
+            pub static S_IFREG : mode_t = 32768;
+            pub static S_IFLNK : mode_t = 40960;
+            pub static S_IFMT : mode_t = 61440;
+            pub static S_IEXEC : mode_t = 64;
+            pub static S_IWRITE : mode_t = 128;
+            pub static S_IREAD : mode_t = 256;
+            pub static S_IRWXU : mode_t = 448;
+            pub static S_IXUSR : mode_t = 64;
+            pub static S_IWUSR : mode_t = 128;
+            pub static S_IRUSR : mode_t = 256;
             pub static F_OK : c_int = 0;
             pub static R_OK : c_int = 4;
             pub static W_OK : c_int = 2;
@@ -3148,6 +3151,7 @@ pub mod c99 {
         pub mod posix88 {
             use types::common::c95::c_void;
             use types::os::arch::c95::c_int;
+            use types::os::arch::posix88::mode_t;
 
             pub static O_RDONLY : c_int = 0;
             pub static O_WRONLY : c_int = 1;
@@ -3156,20 +3160,20 @@ pub mod posix88 {
             pub static O_CREAT : c_int = 512;
             pub static O_EXCL : c_int = 2048;
             pub static O_TRUNC : c_int = 1024;
-            pub static S_IFIFO : c_int = 4096;
-            pub static S_IFCHR : c_int = 8192;
-            pub static S_IFBLK : c_int = 24576;
-            pub static S_IFDIR : c_int = 16384;
-            pub static S_IFREG : c_int = 32768;
-            pub static S_IFLNK : c_int = 40960;
-            pub static S_IFMT : c_int = 61440;
-            pub static S_IEXEC : c_int = 64;
-            pub static S_IWRITE : c_int = 128;
-            pub static S_IREAD : c_int = 256;
-            pub static S_IRWXU : c_int = 448;
-            pub static S_IXUSR : c_int = 64;
-            pub static S_IWUSR : c_int = 128;
-            pub static S_IRUSR : c_int = 256;
+            pub static S_IFIFO : mode_t = 4096;
+            pub static S_IFCHR : mode_t = 8192;
+            pub static S_IFBLK : mode_t = 24576;
+            pub static S_IFDIR : mode_t = 16384;
+            pub static S_IFREG : mode_t = 32768;
+            pub static S_IFLNK : mode_t = 40960;
+            pub static S_IFMT : mode_t = 61440;
+            pub static S_IEXEC : mode_t = 64;
+            pub static S_IWRITE : mode_t = 128;
+            pub static S_IREAD : mode_t = 256;
+            pub static S_IRWXU : mode_t = 448;
+            pub static S_IXUSR : mode_t = 64;
+            pub static S_IWUSR : mode_t = 128;
+            pub static S_IRUSR : mode_t = 256;
             pub static F_OK : c_int = 0;
             pub static R_OK : c_int = 4;
             pub static W_OK : c_int = 2;
@@ -3858,7 +3862,7 @@ pub mod fcntl {
             use types::os::arch::posix88::mode_t;
 
             extern {
-                pub fn open(path: *const c_char, oflag: c_int, mode: c_int)
+                pub fn open(path: *const c_char, oflag: c_int, mode: mode_t)
                             -> c_int;
                 pub fn creat(path: *const c_char, mode: mode_t) -> c_int;
                 pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int;
index 6216e79fe841878f0ae73347f98c29609dcb8e1e..554f27b881b7269700937bdac03eb50f7fae7b69 100644 (file)
@@ -105,16 +105,15 @@ fn main() {
 
 */
 
-#![crate_id = "log#0.11.0"]
+#![crate_name = "log"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
-
 #![feature(macro_rules)]
 #![deny(missing_doc)]
 
index 98553603313404382aafa07a63d726c28ef9b1a6..dbca4ff7ff719a9575a8dafe09c2b5adb629afc1 100644 (file)
@@ -259,7 +259,7 @@ pub fn to_utf16(s: &CString) -> IoResult<Vec<u16>> {
         None => Err(IoError {
             code: libc::ERROR_INVALID_NAME as uint,
             extra: 0,
-            detail: Some("valid unicode input required".to_str()),
+            detail: Some("valid unicode input required".to_string()),
         })
     }
 }
index b5b2065f996ed29d079807a1454c3f86f2763269..0e019fa7e8fbdadf7b04ea38dd5e09a22ba5edc1 100644 (file)
@@ -43,7 +43,7 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
         return Err(IoError {
             code: ERROR as uint,
             extra: 0,
-            detail: Some("path must be smaller than SUN_LEN".to_str()),
+            detail: Some("path must be smaller than SUN_LEN".to_string()),
         })
     }
     s.sun_family = libc::AF_UNIX as libc::sa_family_t;
index e5e8cdeffd7e4c2249b44d5a7f1db0fa2fee47f7..ec40ff89bd2cdb9fdf6d46576c80c8005d5abfc1 100644 (file)
@@ -479,7 +479,7 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
                             Err(IoError {
                                 code: libc::ERROR_OPERATION_ABORTED as uint,
                                 extra: amt,
-                                detail: Some("short write during write".to_str()),
+                                detail: Some("short write during write".to_string()),
                             })
                         } else {
                             Err(util::timeout("write timed out"))
index 6fab73115cf9a5e2dcd1ddf7847f2796b4f44e4d..e3e6ae425266e586265c3e2866390bd8c83c4420 100644 (file)
@@ -170,7 +170,7 @@ fn kill(&mut self, signum: int) -> IoResult<()> {
             Some(..) => return Err(IoError {
                 code: ERROR as uint,
                 extra: 0,
-                detail: Some("can't kill an exited process".to_str()),
+                detail: Some("can't kill an exited process".to_string()),
             }),
             None => {}
         }
@@ -301,10 +301,29 @@ fn spawn_process_os(cfg: ProcessConfig,
         return Err(IoError {
             code: libc::ERROR_CALL_NOT_IMPLEMENTED as uint,
             extra: 0,
-            detail: Some("unsupported gid/uid requested on windows".to_str()),
+            detail: Some("unsupported gid/uid requested on windows".to_string()),
         })
     }
 
+    // To have the spawning semantics of unix/windows stay the same, we need to
+    // read the *child's* PATH if one is provided. See #15149 for more details.
+    let program = cfg.env.and_then(|env| {
+        for &(ref key, ref v) in env.iter() {
+            if b"PATH" != key.as_bytes_no_nul() { continue }
+
+            // Split the value and test each path to see if the program exists.
+            for path in os::split_paths(v.as_bytes_no_nul()).move_iter() {
+                let path = path.join(cfg.program.as_bytes_no_nul())
+                               .with_extension(os::consts::EXE_EXTENSION);
+                if path.exists() {
+                    return Some(path.to_c_str())
+                }
+            }
+            break
+        }
+        None
+    });
+
     unsafe {
         let mut si = zeroed_startupinfo();
         si.cb = mem::size_of::<STARTUPINFO>() as DWORD;
@@ -362,7 +381,8 @@ fn spawn_process_os(cfg: ProcessConfig,
         try!(set_fd(&out_fd, &mut si.hStdOutput, false));
         try!(set_fd(&err_fd, &mut si.hStdError, false));
 
-        let cmd_str = make_command_line(cfg.program, cfg.args);
+        let cmd_str = make_command_line(program.as_ref().unwrap_or(cfg.program),
+                                        cfg.args);
         let mut pi = zeroed_process_information();
         let mut create_err = None;
 
@@ -729,7 +749,7 @@ fn with_argv<T>(prog: &CString, args: &[CString],
 }
 
 #[cfg(unix)]
-fn with_envp<T>(env: Option<&[(CString, CString)]>,
+fn with_envp<T>(env: Option<&[(&CString, &CString)]>,
                 cb: proc(*const c_void) -> T) -> T {
     // On posixy systems we can pass a char** for envp, which is a
     // null-terminated array of "k=v\0" strings. Since we must create
@@ -762,7 +782,7 @@ fn with_envp<T>(env: Option<&[(CString, CString)]>,
 }
 
 #[cfg(windows)]
-fn with_envp<T>(env: Option<&[(CString, CString)]>, cb: |*mut c_void| -> T) -> T {
+fn with_envp<T>(env: Option<&[(&CString, &CString)]>, cb: |*mut c_void| -> T) -> T {
     // On win32 we pass an "environment block" which is not a char**, but
     // rather a concatenation of null-terminated k=v\0 sequences, with a final
     // \0 to terminate.
index 31ba2223082d554325d66814aa8869500c566324..06046cc74cfd85d7828d92b2f0688756764bf57a 100644 (file)
@@ -30,7 +30,7 @@ pub fn timeout(desc: &'static str) -> IoError {
     IoError {
         code: ERROR as uint,
         extra: 0,
-        detail: Some(desc.to_str()),
+        detail: Some(desc.to_string()),
     }
 }
 
@@ -40,7 +40,7 @@ pub fn short_write(n: uint, desc: &'static str) -> IoError {
     IoError {
         code: ERROR as uint,
         extra: n,
-        detail: Some(desc.to_str()),
+        detail: Some(desc.to_string()),
     }
 }
 
index 2e43ddba6449ce08bb956b2c14711911472775b5..d358aa6b6453ebf2981ee3def9fe9e3044d5b666 100644 (file)
 //! }
 //! ```
 
-#![crate_id = "native#0.11.0"]
+#![crate_name = "native"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 
 #![deny(unused_result, unused_must_use)]
 #![allow(non_camel_case_types, deprecated)]
index cc3753def59f4cc2a6ed98d1080f4a36fc33ae28..046ba96f45a38185e28770381c58094ca4713e77 100644 (file)
@@ -2737,7 +2737,7 @@ fn check(s: &str, ans: Option<int>) {
         // attempt to allocate a vector of size (-1u) == huge.
         let x: BigInt =
             from_str(format!("1{}", "0".repeat(36)).as_slice()).unwrap();
-        let _y = x.to_str();
+        let _y = x.to_string();
     }
 
     #[test]
@@ -2842,14 +2842,14 @@ fn fib_100(b: &mut Bencher) {
     }
 
     #[bench]
-    fn to_str(b: &mut Bencher) {
+    fn to_string(b: &mut Bencher) {
         let fac = factorial(100);
         let fib = fib(100);
         b.iter(|| {
-            fac.to_str();
+            fac.to_string();
         });
         b.iter(|| {
-            fib.to_str();
+            fib.to_string();
         });
     }
 
index 9ee80d283cf924621ac20309c075ea29d8fcf371..f4a3ac97a4ef762bca048dee50bab92cea967fc7 100644 (file)
@@ -347,9 +347,9 @@ fn test_neg() {
     }
 
     #[test]
-    fn test_to_str() {
+    fn test_to_string() {
         fn test(c : Complex64, s: String) {
-            assert_eq!(c.to_str(), s);
+            assert_eq!(c.to_string(), s);
         }
         test(_0_0i, "0+0i".to_string());
         test(_1_0i, "1+0i".to_string());
index db0cd7f2567243b006d36a0508bdd8cb55b601e0..5cc2eee7da75c2743695c41c1f414621f661e8b4 100644 (file)
 
 #![feature(macro_rules)]
 
-#![crate_id = "num#0.11.0"]
+#![crate_name = "num"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
-
 #![allow(deprecated)] // from_str_radix
 
 extern crate rand;
index c35b2976b407f19aef7f9614c48d2f3fc19e4bd7..a279ede6fa5347d68b85d7251fb3ad20a4b43752 100644 (file)
@@ -15,7 +15,9 @@
 use std::cmp;
 use std::fmt;
 use std::from_str::FromStr;
+use std::num;
 use std::num::{Zero, One, ToStrRadix, FromStrRadix};
+
 use bigint::{BigInt, BigUint, Sign, Plus, Minus};
 
 /// Represents the ratio between 2 numbers.
@@ -273,6 +275,36 @@ fn one() -> Ratio<T> {
 impl<T: Clone + Integer + PartialOrd>
     Num for Ratio<T> {}
 
+impl<T: Clone + Integer + PartialOrd>
+    num::Signed for Ratio<T> {
+    #[inline]
+    fn abs(&self) -> Ratio<T> {
+        if self.is_negative() { -self.clone() } else { self.clone() }
+    }
+
+    #[inline]
+    fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> {
+        if *self <= *other { Zero::zero() } else { *self - *other }
+    }
+
+    #[inline]
+    fn signum(&self) -> Ratio<T> {
+        if *self > Zero::zero() {
+            num::one()
+        } else if self.is_zero() {
+            num::zero()
+        } else {
+            - num::one::<Ratio<T>>()
+        }
+    }
+
+    #[inline]
+    fn is_positive(&self) -> bool { *self > Zero::zero() }
+
+    #[inline]
+    fn is_negative(&self) -> bool { *self < Zero::zero() }
+}
+
 /* String conversions */
 impl<T: fmt::Show + Eq + One> fmt::Show for Ratio<T> {
     /// Renders as `numer/denom`. If denom=1, renders as numer.
@@ -338,6 +370,7 @@ mod test {
     use super::{Ratio, Rational, BigRational};
     use std::num::{Zero, One, FromStrRadix, FromPrimitive, ToStrRadix};
     use std::from_str::FromStr;
+    use std::num;
 
     pub static _0 : Rational = Ratio { numer: 0, denom: 1};
     pub static _1 : Rational = Ratio { numer: 1, denom: 1};
@@ -571,7 +604,7 @@ fn test_recip() {
     fn test_to_from_str() {
         fn test(r: Rational, s: String) {
             assert_eq!(FromStr::from_str(s.as_slice()), Some(r));
-            assert_eq!(r.to_str(), s);
+            assert_eq!(r.to_string(), s);
         }
         test(_1, "1".to_string());
         test(_0, "0".to_string());
@@ -672,4 +705,16 @@ fn test_from_float_fail() {
         assert_eq!(Ratio::from_float(f64::INFINITY), None);
         assert_eq!(Ratio::from_float(f64::NEG_INFINITY), None);
     }
+
+    #[test]
+    fn test_signed() {
+        assert_eq!(_neg1_2.abs(), _1_2);
+        assert_eq!(_3_2.abs_sub(&_1_2), _1);
+        assert_eq!(_1_2.abs_sub(&_3_2), Zero::zero());
+        assert_eq!(_1_2.signum(), One::one());
+        assert_eq!(_neg1_2.signum(), - num::one::<Ratio<int>>());
+        assert!(_neg1_2.is_negative());
+        assert!(! _neg1_2.is_positive());
+        assert!(! _1_2.is_negative());
+    }
 }
index 593b9785d475abb3f65ae9d3b49982ea7e8c5299..9c33b713e4a6b1f8b3d7853b2d9bcbd512f5714d 100644 (file)
 //! is not recommended to use this library directly, but rather the official
 //! interface through `std::rand`.
 
-#![crate_id = "rand#0.11.0"]
+#![crate_name = "rand"]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, phase, globs)]
index b69c4471267bb6cefdf80f1d940966eb32b941b9..1bb7f605e5474878d8a4837e4f18eb2d1fecebbd 100644 (file)
 //!
 //! ## Perl character classes (Unicode friendly)
 //!
+//! These classes are based on the definitions provided in
+//! [UTS#18](http://www.unicode.org/reports/tr18/#Compatibility_Properties):
+//!
 //! <pre class="rust">
-//! \d     digit ([0-9] + \p{Nd})
+//! \d     digit (\p{Nd})
 //! \D     not digit
-//! \s     whitespace ([\t\n\f\r ] + \p{Z})
+//! \s     whitespace (\p{White_Space})
 //! \S     not whitespace
-//! \w     word character ([0-9A-Za-z_] + \p{L})
+//! \w     word character (\p{Alphabetic} + \p{M} + \d + \p{Pc} + \p{Join_Control})
 //! \W     not word character
 //! </pre>
 //!
 //! characters in the search text and `m` is the number of instructions in a
 //! compiled expression.
 
-#![crate_id = "regex#0.11.0"]
+#![crate_name = "regex"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, phase)]
 #[cfg(test)]
 extern crate regex;
 
+// unicode tables for character classes are defined in libunicode
+extern crate unicode;
+
 pub use parse::Error;
 pub use re::{Regex, Captures, SubCaptures, SubCapturesPos};
 pub use re::{FindCaptures, FindMatches};
diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs
new file mode 100644 (file)
index 0000000..a274752
--- /dev/null
@@ -0,0 +1,1062 @@
+// 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 std::char;
+use std::cmp;
+use std::fmt;
+use std::iter;
+use std::num;
+use std::str;
+
+/// Static data containing Unicode ranges for general categories and scripts.
+use unicode::regex::{UNICODE_CLASSES, PERLD, PERLS, PERLW};
+
+/// The maximum number of repetitions allowed with the `{n,m}` syntax.
+static MAX_REPEAT: uint = 1000;
+
+/// Error corresponds to something that can go wrong while parsing
+/// a regular expression.
+///
+/// (Once an expression is compiled, it is not possible to produce an error
+/// via searching, splitting or replacing.)
+pub struct Error {
+    /// The *approximate* character index of where the error occurred.
+    pub pos: uint,
+    /// A message describing the error.
+    pub msg: String,
+}
+
+impl fmt::Show for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Regex syntax error near position {}: {}",
+               self.pos, self.msg)
+    }
+}
+
+/// Represents the abstract syntax of a regular expression.
+/// It is showable so that error messages resulting from a bug can provide
+/// useful information.
+/// It is cloneable so that expressions can be repeated for the counted
+/// repetition feature. (No other copying is done.)
+///
+/// Note that this representation prevents one from reproducing the regex as
+/// it was typed. (But it could be used to reproduce an equivalent regex.)
+#[deriving(Show, Clone)]
+pub enum Ast {
+    Nothing,
+    Literal(char, Flags),
+    Dot(Flags),
+    Class(Vec<(char, char)>, Flags),
+    Begin(Flags),
+    End(Flags),
+    WordBoundary(Flags),
+    Capture(uint, Option<String>, Box<Ast>),
+    // Represent concatenation as a flat vector to avoid blowing the
+    // stack in the compiler.
+    Cat(Vec<Ast>),
+    Alt(Box<Ast>, Box<Ast>),
+    Rep(Box<Ast>, Repeater, Greed),
+}
+
+#[deriving(Show, PartialEq, Clone)]
+pub enum Repeater {
+    ZeroOne,
+    ZeroMore,
+    OneMore,
+}
+
+#[deriving(Show, Clone)]
+pub enum Greed {
+    Greedy,
+    Ungreedy,
+}
+
+impl Greed {
+    pub fn is_greedy(&self) -> bool {
+        match *self {
+            Greedy => true,
+            _ => false,
+        }
+    }
+
+    fn swap(self, swapped: bool) -> Greed {
+        if !swapped { return self }
+        match self {
+            Greedy => Ungreedy,
+            Ungreedy => Greedy,
+        }
+    }
+}
+
+/// BuildAst is a regrettable type that represents intermediate state for
+/// constructing an abstract syntax tree. Its central purpose is to facilitate
+/// parsing groups and alternations while also maintaining a stack of flag
+/// state.
+#[deriving(Show)]
+enum BuildAst {
+    Ast(Ast),
+    Paren(Flags, uint, String), // '('
+    Bar, // '|'
+}
+
+impl BuildAst {
+    fn paren(&self) -> bool {
+        match *self {
+            Paren(_, _, _) => true,
+            _ => false,
+        }
+    }
+
+    fn flags(&self) -> Flags {
+        match *self {
+            Paren(flags, _, _) => flags,
+            _ => fail!("Cannot get flags from {}", self),
+        }
+    }
+
+    fn capture(&self) -> Option<uint> {
+        match *self {
+            Paren(_, 0, _) => None,
+            Paren(_, c, _) => Some(c),
+            _ => fail!("Cannot get capture group from {}", self),
+        }
+    }
+
+    fn capture_name(&self) -> Option<String> {
+        match *self {
+            Paren(_, 0, _) => None,
+            Paren(_, _, ref name) => {
+                if name.len() == 0 {
+                    None
+                } else {
+                    Some(name.clone())
+                }
+            }
+            _ => fail!("Cannot get capture name from {}", self),
+        }
+    }
+
+    fn bar(&self) -> bool {
+        match *self {
+            Bar => true,
+            _ => false,
+        }
+    }
+
+    fn unwrap(self) -> Result<Ast, Error> {
+        match self {
+            Ast(x) => Ok(x),
+            _ => fail!("Tried to unwrap non-AST item: {}", self),
+        }
+    }
+}
+
+/// Flags represents all options that can be twiddled by a user in an
+/// expression.
+pub type Flags = u8;
+
+pub static FLAG_EMPTY:      u8 = 0;
+pub static FLAG_NOCASE:     u8 = 1 << 0; // i
+pub static FLAG_MULTI:      u8 = 1 << 1; // m
+pub static FLAG_DOTNL:      u8 = 1 << 2; // s
+pub static FLAG_SWAP_GREED: u8 = 1 << 3; // U
+pub static FLAG_NEGATED:    u8 = 1 << 4; // char class or not word boundary
+
+struct Parser<'a> {
+    // The input, parsed only as a sequence of UTF8 code points.
+    chars: Vec<char>,
+    // The index of the current character in the input.
+    chari: uint,
+    // The intermediate state representing the AST.
+    stack: Vec<BuildAst>,
+    // The current set of flags.
+    flags: Flags,
+    // The total number of capture groups.
+    // Incremented each time an opening left paren is seen (assuming it is
+    // opening a capture group).
+    caps: uint,
+    // A set of all capture group names used only to detect duplicates.
+    names: Vec<String>,
+}
+
+pub fn parse(s: &str) -> Result<Ast, Error> {
+    Parser {
+        chars: s.chars().collect(),
+        chari: 0,
+        stack: vec!(),
+        flags: FLAG_EMPTY,
+        caps: 0,
+        names: vec!(),
+    }.parse()
+}
+
+impl<'a> Parser<'a> {
+    fn parse(&mut self) -> Result<Ast, Error> {
+        if self.chars.len() == 0 {
+            return Ok(Nothing);
+        }
+        loop {
+            let c = self.cur();
+            match c {
+                '?' | '*' | '+' => try!(self.push_repeater(c)),
+                '\\' => {
+                    let ast = try!(self.parse_escape());
+                    self.push(ast)
+                }
+                '{' => try!(self.parse_counted()),
+                '[' => match self.try_parse_ascii() {
+                    None => try!(self.parse_class()),
+                    Some(class) => self.push(class),
+                },
+                '(' => {
+                    if self.peek_is(1, '?') {
+                        try!(self.expect('?'))
+                        try!(self.parse_group_opts())
+                    } else {
+                        self.caps += 1;
+                        self.stack.push(Paren(self.flags,
+                                              self.caps,
+                                              "".to_string()))
+                    }
+                }
+                ')' => {
+                    let catfrom = try!(
+                        self.pos_last(false, |x| x.paren() || x.bar()));
+                    try!(self.concat(catfrom));
+
+                    let altfrom = try!(self.pos_last(false, |x| x.paren()));
+                    // Before we smush the alternates together and pop off the
+                    // left paren, let's grab the old flags and see if we
+                    // need a capture.
+                    let (cap, cap_name, oldflags) = {
+                        let paren = self.stack.get(altfrom-1);
+                        (paren.capture(), paren.capture_name(), paren.flags())
+                    };
+                    try!(self.alternate(altfrom));
+                    self.flags = oldflags;
+
+                    // If this was a capture, pop what we just pushed in
+                    // alternate and make it a capture.
+                    if cap.is_some() {
+                        let ast = try!(self.pop_ast());
+                        self.push(Capture(cap.unwrap(), cap_name, box ast));
+                    }
+                }
+                '|' => {
+                    let catfrom = try!(
+                        self.pos_last(true, |x| x.paren() || x.bar()));
+                    try!(self.concat(catfrom));
+
+                    self.stack.push(Bar);
+                }
+                _ => try!(self.push_literal(c)),
+            }
+            if !self.next_char() {
+                break
+            }
+        }
+
+        // Try to improve error handling. At this point, there should be
+        // no remaining open parens.
+        if self.stack.iter().any(|x| x.paren()) {
+            return self.err("Unclosed parenthesis.")
+        }
+        let catfrom = try!(self.pos_last(true, |x| x.bar()));
+        try!(self.concat(catfrom));
+        try!(self.alternate(0));
+
+        assert!(self.stack.len() == 1);
+        self.pop_ast()
+    }
+
+    fn noteof(&mut self, expected: &str) -> Result<(), Error> {
+        match self.next_char() {
+            true => Ok(()),
+            false => {
+                self.err(format!("Expected {} but got EOF.",
+                                 expected).as_slice())
+            }
+        }
+    }
+
+    fn expect(&mut self, expected: char) -> Result<(), Error> {
+        match self.next_char() {
+            true if self.cur() == expected => Ok(()),
+            true => self.err(format!("Expected '{}' but got '{}'.",
+                                     expected, self.cur()).as_slice()),
+            false => {
+                self.err(format!("Expected '{}' but got EOF.",
+                                 expected).as_slice())
+            }
+        }
+    }
+
+    fn next_char(&mut self) -> bool {
+        self.chari += 1;
+        self.chari < self.chars.len()
+    }
+
+    fn pop_ast(&mut self) -> Result<Ast, Error> {
+        match self.stack.pop().unwrap().unwrap() {
+            Err(e) => Err(e),
+            Ok(ast) => Ok(ast),
+        }
+    }
+
+    fn push(&mut self, ast: Ast) {
+        self.stack.push(Ast(ast))
+    }
+
+    fn push_repeater(&mut self, c: char) -> Result<(), Error> {
+        if self.stack.len() == 0 {
+            return self.err(
+                "A repeat operator must be preceded by a valid expression.")
+        }
+        let rep: Repeater = match c {
+            '?' => ZeroOne, '*' => ZeroMore, '+' => OneMore,
+            _ => fail!("Not a valid repeater operator."),
+        };
+
+        match self.peek(1) {
+            Some('*') | Some('+') =>
+                return self.err(
+                    "Double repeat operators are not supported."),
+            _ => {},
+        }
+        let ast = try!(self.pop_ast());
+        match ast {
+            Begin(_) | End(_) | WordBoundary(_) =>
+                return self.err(
+                    "Repeat arguments cannot be empty width assertions."),
+            _ => {}
+        }
+        let greed = try!(self.get_next_greedy());
+        self.push(Rep(box ast, rep, greed));
+        Ok(())
+    }
+
+    fn push_literal(&mut self, c: char) -> Result<(), Error> {
+        let flags = self.flags;
+        match c {
+            '.' => {
+                self.push(Dot(flags))
+            }
+            '^' => {
+                self.push(Begin(flags))
+            }
+            '$' => {
+                self.push(End(flags))
+            }
+            _ => {
+                self.push(Literal(c, flags))
+            }
+        }
+        Ok(())
+    }
+
+    // Parses all forms of character classes.
+    // Assumes that '[' is the current character.
+    fn parse_class(&mut self) -> Result<(), Error> {
+        let negated =
+            if self.peek_is(1, '^') {
+                try!(self.expect('^'))
+                FLAG_NEGATED
+            } else {
+                FLAG_EMPTY
+            };
+        let mut ranges: Vec<(char, char)> = vec!();
+        let mut alts: Vec<Ast> = vec!();
+
+        if self.peek_is(1, ']') {
+            try!(self.expect(']'))
+            ranges.push((']', ']'))
+        }
+        while self.peek_is(1, '-') {
+            try!(self.expect('-'))
+            ranges.push(('-', '-'))
+        }
+        loop {
+            try!(self.noteof("a closing ']' or a non-empty character class)"))
+            let mut c = self.cur();
+            match c {
+                '[' =>
+                    match self.try_parse_ascii() {
+                        Some(Class(asciis, flags)) => {
+                            alts.push(Class(asciis, flags ^ negated));
+                            continue
+                        }
+                        Some(ast) =>
+                            fail!("Expected Class AST but got '{}'", ast),
+                        // Just drop down and try to add as a regular character.
+                        None => {},
+                    },
+                '\\' => {
+                    match try!(self.parse_escape()) {
+                        Class(asciis, flags) => {
+                            alts.push(Class(asciis, flags ^ negated));
+                            continue
+                        }
+                        Literal(c2, _) => c = c2, // process below
+                        Begin(_) | End(_) | WordBoundary(_) =>
+                            return self.err(
+                                "\\A, \\z, \\b and \\B are not valid escape \
+                                 sequences inside a character class."),
+                        ast => fail!("Unexpected AST item '{}'", ast),
+                    }
+                }
+                _ => {},
+            }
+            match c {
+                ']' => {
+                    if ranges.len() > 0 {
+                        let flags = negated | (self.flags & FLAG_NOCASE);
+                        let mut ast = Class(combine_ranges(ranges), flags);
+                        for alt in alts.move_iter() {
+                            ast = Alt(box alt, box ast)
+                        }
+                        self.push(ast);
+                    } else if alts.len() > 0 {
+                        let mut ast = alts.pop().unwrap();
+                        for alt in alts.move_iter() {
+                            ast = Alt(box alt, box ast)
+                        }
+                        self.push(ast);
+                    }
+                    return Ok(())
+                }
+                c => {
+                    if self.peek_is(1, '-') && !self.peek_is(2, ']') {
+                        try!(self.expect('-'))
+                        try!(self.noteof("not a ']'"))
+                        let c2 = self.cur();
+                        if c2 < c {
+                            return self.err(format!("Invalid character class \
+                                                     range '{}-{}'",
+                                                    c,
+                                                    c2).as_slice())
+                        }
+                        ranges.push((c, self.cur()))
+                    } else {
+                        ranges.push((c, c))
+                    }
+                }
+            }
+        }
+    }
+
+    // Tries to parse an ASCII character class of the form [:name:].
+    // If successful, returns an AST character class corresponding to name
+    // and moves the parser to the final ']' character.
+    // If unsuccessful, no state is changed and None is returned.
+    // Assumes that '[' is the current character.
+    fn try_parse_ascii(&mut self) -> Option<Ast> {
+        if !self.peek_is(1, ':') {
+            return None
+        }
+        let closer =
+            match self.pos(']') {
+                Some(i) => i,
+                None => return None,
+            };
+        if *self.chars.get(closer-1) != ':' {
+            return None
+        }
+        if closer - self.chari <= 3 {
+            return None
+        }
+        let mut name_start = self.chari + 2;
+        let negated =
+            if self.peek_is(2, '^') {
+                name_start += 1;
+                FLAG_NEGATED
+            } else {
+                FLAG_EMPTY
+            };
+        let name = self.slice(name_start, closer - 1);
+        match find_class(ASCII_CLASSES, name.as_slice()) {
+            None => None,
+            Some(ranges) => {
+                self.chari = closer;
+                let flags = negated | (self.flags & FLAG_NOCASE);
+                Some(Class(combine_ranges(ranges), flags))
+            }
+        }
+    }
+
+    // Parses counted repetition. Supports:
+    // {n}, {n,}, {n,m}, {n}?, {n,}? and {n,m}?
+    // Assumes that '{' is the current character.
+    // Returns either an error or moves the parser to the final '}' character.
+    // (Or the '?' character if not greedy.)
+    fn parse_counted(&mut self) -> Result<(), Error> {
+        // Scan until the closing '}' and grab the stuff in {}.
+        let start = self.chari;
+        let closer =
+            match self.pos('}') {
+                Some(i) => i,
+                None => {
+                    return self.err(format!("No closing brace for counted \
+                                             repetition starting at position \
+                                             {}.",
+                                            start).as_slice())
+                }
+            };
+        self.chari = closer;
+        let greed = try!(self.get_next_greedy());
+        let inner = str::from_chars(
+            self.chars.as_slice().slice(start + 1, closer));
+
+        // Parse the min and max values from the regex.
+        let (mut min, mut max): (uint, Option<uint>);
+        if !inner.as_slice().contains(",") {
+            min = try!(self.parse_uint(inner.as_slice()));
+            max = Some(min);
+        } else {
+            let pieces: Vec<&str> = inner.as_slice().splitn(',', 1).collect();
+            let (smin, smax) = (*pieces.get(0), *pieces.get(1));
+            if smin.len() == 0 {
+                return self.err("Max repetitions cannot be specified \
+                                    without min repetitions.")
+            }
+            min = try!(self.parse_uint(smin));
+            max =
+                if smax.len() == 0 {
+                    None
+                } else {
+                    Some(try!(self.parse_uint(smax)))
+                };
+        }
+
+        // Do some bounds checking and make sure max >= min.
+        if min > MAX_REPEAT {
+            return self.err(format!(
+                "{} exceeds maximum allowed repetitions ({})",
+                min, MAX_REPEAT).as_slice());
+        }
+        if max.is_some() {
+            let m = max.unwrap();
+            if m > MAX_REPEAT {
+                return self.err(format!(
+                    "{} exceeds maximum allowed repetitions ({})",
+                    m, MAX_REPEAT).as_slice());
+            }
+            if m < min {
+                return self.err(format!(
+                    "Max repetitions ({}) cannot be smaller than min \
+                     repetitions ({}).", m, min).as_slice());
+            }
+        }
+
+        // Now manipulate the AST be repeating elements.
+        if max.is_none() {
+            // Require N copies of what's on the stack and then repeat it.
+            let ast = try!(self.pop_ast());
+            for _ in iter::range(0, min) {
+                self.push(ast.clone())
+            }
+            self.push(Rep(box ast, ZeroMore, greed));
+        } else {
+            // Require N copies of what's on the stack and then repeat it
+            // up to M times optionally.
+            let ast = try!(self.pop_ast());
+            for _ in iter::range(0, min) {
+                self.push(ast.clone())
+            }
+            if max.is_some() {
+                for _ in iter::range(min, max.unwrap()) {
+                    self.push(Rep(box ast.clone(), ZeroOne, greed))
+                }
+            }
+            // It's possible that we popped something off the stack but
+            // never put anything back on it. To keep things simple, add
+            // a no-op expression.
+            if min == 0 && (max.is_none() || max == Some(0)) {
+                self.push(Nothing)
+            }
+        }
+        Ok(())
+    }
+
+    // Parses all escape sequences.
+    // Assumes that '\' is the current character.
+    fn parse_escape(&mut self) -> Result<Ast, Error> {
+        try!(self.noteof("an escape sequence following a '\\'"))
+
+        let c = self.cur();
+        if is_punct(c) {
+            return Ok(Literal(c, FLAG_EMPTY))
+        }
+        match c {
+            'a' => Ok(Literal('\x07', FLAG_EMPTY)),
+            'f' => Ok(Literal('\x0C', FLAG_EMPTY)),
+            't' => Ok(Literal('\t', FLAG_EMPTY)),
+            'n' => Ok(Literal('\n', FLAG_EMPTY)),
+            'r' => Ok(Literal('\r', FLAG_EMPTY)),
+            'v' => Ok(Literal('\x0B', FLAG_EMPTY)),
+            'A' => Ok(Begin(FLAG_EMPTY)),
+            'z' => Ok(End(FLAG_EMPTY)),
+            'b' => Ok(WordBoundary(FLAG_EMPTY)),
+            'B' => Ok(WordBoundary(FLAG_NEGATED)),
+            '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7' => Ok(try!(self.parse_octal())),
+            'x' => Ok(try!(self.parse_hex())),
+            'p' | 'P' => Ok(try!(self.parse_unicode_name())),
+            'd' | 'D' | 's' | 'S' | 'w' | 'W' => {
+                let ranges = perl_unicode_class(c);
+                let mut flags = self.flags & FLAG_NOCASE;
+                if c.is_uppercase() { flags |= FLAG_NEGATED }
+                Ok(Class(ranges, flags))
+            }
+            _ => {
+                self.err(format!("Invalid escape sequence '\\\\{}'",
+                                 c).as_slice())
+            }
+        }
+    }
+
+    // Parses a unicode character class name, either of the form \pF where
+    // F is a one letter unicode class name or of the form \p{name} where
+    // name is the unicode class name.
+    // Assumes that \p or \P has been read (and 'p' or 'P' is the current
+    // character).
+    fn parse_unicode_name(&mut self) -> Result<Ast, Error> {
+        let negated = if self.cur() == 'P' { FLAG_NEGATED } else { FLAG_EMPTY };
+        let mut name: String;
+        if self.peek_is(1, '{') {
+            try!(self.expect('{'))
+            let closer =
+                match self.pos('}') {
+                    Some(i) => i,
+                    None => return self.err(format!(
+                        "Missing '}}' for unclosed '{{' at position {}",
+                        self.chari).as_slice()),
+                };
+            if closer - self.chari + 1 == 0 {
+                return self.err("No Unicode class name found.")
+            }
+            name = self.slice(self.chari + 1, closer);
+            self.chari = closer;
+        } else {
+            if self.chari + 1 >= self.chars.len() {
+                return self.err("No single letter Unicode class name found.")
+            }
+            name = self.slice(self.chari + 1, self.chari + 2);
+            self.chari += 1;
+        }
+        match find_class(UNICODE_CLASSES, name.as_slice()) {
+            None => {
+                return self.err(format!("Could not find Unicode class '{}'",
+                                        name).as_slice())
+            }
+            Some(ranges) => {
+                Ok(Class(ranges, negated | (self.flags & FLAG_NOCASE)))
+            }
+        }
+    }
+
+    // Parses an octal number, up to 3 digits.
+    // Assumes that \n has been read, where n is the first digit.
+    fn parse_octal(&mut self) -> Result<Ast, Error> {
+        let start = self.chari;
+        let mut end = start + 1;
+        let (d2, d3) = (self.peek(1), self.peek(2));
+        if d2 >= Some('0') && d2 <= Some('7') {
+            try!(self.noteof("expected octal character in [0-7]"))
+            end += 1;
+            if d3 >= Some('0') && d3 <= Some('7') {
+                try!(self.noteof("expected octal character in [0-7]"))
+                end += 1;
+            }
+        }
+        let s = self.slice(start, end);
+        match num::from_str_radix::<u32>(s.as_slice(), 8) {
+            Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
+            None => {
+                self.err(format!("Could not parse '{}' as octal number.",
+                                 s).as_slice())
+            }
+        }
+    }
+
+    // Parse a hex number. Either exactly two digits or anything in {}.
+    // Assumes that \x has been read.
+    fn parse_hex(&mut self) -> Result<Ast, Error> {
+        if !self.peek_is(1, '{') {
+            try!(self.expect('{'))
+            return self.parse_hex_two()
+        }
+        let start = self.chari + 2;
+        let closer =
+            match self.pos('}') {
+                None => {
+                    return self.err(format!("Missing '}}' for unclosed \
+                                             '{{' at position {}",
+                                            start).as_slice())
+                }
+                Some(i) => i,
+            };
+        self.chari = closer;
+        self.parse_hex_digits(self.slice(start, closer).as_slice())
+    }
+
+    // Parses a two-digit hex number.
+    // Assumes that \xn has been read, where n is the first digit and is the
+    // current character.
+    // After return, parser will point at the second digit.
+    fn parse_hex_two(&mut self) -> Result<Ast, Error> {
+        let (start, end) = (self.chari, self.chari + 2);
+        let bad = self.slice(start - 2, self.chars.len());
+        try!(self.noteof(format!("Invalid hex escape sequence '{}'",
+                                 bad).as_slice()))
+        self.parse_hex_digits(self.slice(start, end).as_slice())
+    }
+
+    // Parses `s` as a hexadecimal number.
+    fn parse_hex_digits(&self, s: &str) -> Result<Ast, Error> {
+        match num::from_str_radix::<u32>(s, 16) {
+            Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
+            None => {
+                self.err(format!("Could not parse '{}' as hex number.",
+                                 s).as_slice())
+            }
+        }
+    }
+
+    // Parses a named capture.
+    // Assumes that '(?P<' has been consumed and that the current character
+    // is '<'.
+    // When done, parser will be at the closing '>' character.
+    fn parse_named_capture(&mut self) -> Result<(), Error> {
+        try!(self.noteof("a capture name"))
+        let closer =
+            match self.pos('>') {
+                Some(i) => i,
+                None => return self.err("Capture name must end with '>'."),
+            };
+        if closer - self.chari == 0 {
+            return self.err("Capture names must have at least 1 character.")
+        }
+        let name = self.slice(self.chari, closer);
+        if !name.as_slice().chars().all(is_valid_cap) {
+            return self.err(
+                "Capture names can only have underscores, letters and digits.")
+        }
+        if self.names.contains(&name) {
+            return self.err(format!("Duplicate capture group name '{}'.",
+                                    name).as_slice())
+        }
+        self.names.push(name.clone());
+        self.chari = closer;
+        self.caps += 1;
+        self.stack.push(Paren(self.flags, self.caps, name));
+        Ok(())
+    }
+
+    // Parses non-capture groups and options.
+    // Assumes that '(?' has already been consumed and '?' is the current
+    // character.
+    fn parse_group_opts(&mut self) -> Result<(), Error> {
+        if self.peek_is(1, 'P') && self.peek_is(2, '<') {
+            try!(self.expect('P')) try!(self.expect('<'))
+            return self.parse_named_capture()
+        }
+        let start = self.chari;
+        let mut flags = self.flags;
+        let mut sign = 1i;
+        let mut saw_flag = false;
+        loop {
+            try!(self.noteof("expected non-empty set of flags or closing ')'"))
+            match self.cur() {
+                'i' => { flags = flags | FLAG_NOCASE;     saw_flag = true},
+                'm' => { flags = flags | FLAG_MULTI;      saw_flag = true},
+                's' => { flags = flags | FLAG_DOTNL;      saw_flag = true},
+                'U' => { flags = flags | FLAG_SWAP_GREED; saw_flag = true},
+                '-' => {
+                    if sign < 0 {
+                        return self.err(format!(
+                            "Cannot negate flags twice in '{}'.",
+                            self.slice(start, self.chari + 1)).as_slice())
+                    }
+                    sign = -1;
+                    saw_flag = false;
+                    flags = flags ^ flags;
+                }
+                ':' | ')' => {
+                    if sign < 0 {
+                        if !saw_flag {
+                            return self.err(format!(
+                                "A valid flag does not follow negation in '{}'",
+                                self.slice(start, self.chari + 1)).as_slice())
+                        }
+                        flags = flags ^ flags;
+                    }
+                    if self.cur() == ':' {
+                        // Save the old flags with the opening paren.
+                        self.stack.push(Paren(self.flags, 0, "".to_string()));
+                    }
+                    self.flags = flags;
+                    return Ok(())
+                }
+                _ => return self.err(format!(
+                    "Unrecognized flag '{}'.", self.cur()).as_slice()),
+            }
+        }
+    }
+
+    // Peeks at the next character and returns whether it's ungreedy or not.
+    // If it is, then the next character is consumed.
+    fn get_next_greedy(&mut self) -> Result<Greed, Error> {
+        Ok(if self.peek_is(1, '?') {
+            try!(self.expect('?'))
+            Ungreedy
+        } else {
+            Greedy
+        }.swap(self.flags & FLAG_SWAP_GREED > 0))
+    }
+
+    // Searches the stack (starting at the top) until it finds an expression
+    // for which `pred` returns true. The index of that expression in the
+    // stack is returned.
+    // If there's no match, then one of two things happens depending on the
+    // values of `allow_start`. When it's true, then `0` will be returned.
+    // Otherwise, an error will be returned.
+    // Generally, `allow_start` is only true when you're *not* expecting an
+    // opening parenthesis.
+    fn pos_last(&self, allow_start: bool, pred: |&BuildAst| -> bool)
+               -> Result<uint, Error> {
+        let from = match self.stack.iter().rev().position(pred) {
+            Some(i) => i,
+            None => {
+                if allow_start {
+                    self.stack.len()
+                } else {
+                    return self.err("No matching opening parenthesis.")
+                }
+            }
+        };
+        // Adjust index since 'from' is for the reversed stack.
+        // Also, don't include the '(' or '|'.
+        Ok(self.stack.len() - from)
+    }
+
+    // concat starts at `from` in the parser's stack and concatenates all
+    // expressions up to the top of the stack. The resulting concatenation is
+    // then pushed on to the stack.
+    // Usually `from` corresponds to the position of an opening parenthesis,
+    // a '|' (alternation) or the start of the entire expression.
+    fn concat(&mut self, from: uint) -> Result<(), Error> {
+        let ast = try!(self.build_from(from, concat_flatten));
+        self.push(ast);
+        Ok(())
+    }
+
+    // concat starts at `from` in the parser's stack and alternates all
+    // expressions up to the top of the stack. The resulting alternation is
+    // then pushed on to the stack.
+    // Usually `from` corresponds to the position of an opening parenthesis
+    // or the start of the entire expression.
+    // This will also drop any opening parens or alternation bars found in
+    // the intermediate AST.
+    fn alternate(&mut self, mut from: uint) -> Result<(), Error> {
+        // Unlike in the concatenation case, we want 'build_from' to continue
+        // all the way to the opening left paren (so it will be popped off and
+        // thrown away). But be careful with overflow---we can't count on the
+        // open paren to be there.
+        if from > 0 { from = from - 1}
+        let ast = try!(self.build_from(from, |l,r| Alt(box l, box r)));
+        self.push(ast);
+        Ok(())
+    }
+
+    // build_from combines all AST elements starting at 'from' in the
+    // parser's stack using 'mk' to combine them. If any such element is not an
+    // AST then it is popped off the stack and ignored.
+    fn build_from(&mut self, from: uint, mk: |Ast, Ast| -> Ast)
+                 -> Result<Ast, Error> {
+        if from >= self.stack.len() {
+            return self.err("Empty group or alternate not allowed.")
+        }
+
+        let mut combined = try!(self.pop_ast());
+        let mut i = self.stack.len();
+        while i > from {
+            i = i - 1;
+            match self.stack.pop().unwrap() {
+                Ast(x) => combined = mk(x, combined),
+                _ => {},
+            }
+        }
+        Ok(combined)
+    }
+
+    fn parse_uint(&self, s: &str) -> Result<uint, Error> {
+        match from_str::<uint>(s) {
+            Some(i) => Ok(i),
+            None => {
+                self.err(format!("Expected an unsigned integer but got '{}'.",
+                                 s).as_slice())
+            }
+        }
+    }
+
+    fn char_from_u32(&self, n: u32) -> Result<char, Error> {
+        match char::from_u32(n) {
+            Some(c) => Ok(c),
+            None => {
+                self.err(format!("Could not decode '{}' to unicode \
+                                  character.",
+                                 n).as_slice())
+            }
+        }
+    }
+
+    fn pos(&self, c: char) -> Option<uint> {
+        self.chars.iter()
+            .skip(self.chari).position(|&c2| c2 == c).map(|i| self.chari + i)
+    }
+
+    fn err<T>(&self, msg: &str) -> Result<T, Error> {
+        Err(Error {
+            pos: self.chari,
+            msg: msg.to_string(),
+        })
+    }
+
+    fn peek(&self, offset: uint) -> Option<char> {
+        if self.chari + offset >= self.chars.len() {
+            return None
+        }
+        Some(*self.chars.get(self.chari + offset))
+    }
+
+    fn peek_is(&self, offset: uint, is: char) -> bool {
+        self.peek(offset) == Some(is)
+    }
+
+    fn cur(&self) -> char {
+        *self.chars.get(self.chari)
+    }
+
+    fn slice(&self, start: uint, end: uint) -> String {
+        str::from_chars(self.chars.as_slice().slice(start, end)).to_string()
+    }
+}
+
+// Given an unordered collection of character ranges, combine_ranges returns
+// an ordered sequence of character ranges where no two ranges overlap. They
+// are ordered from least to greatest (using start position).
+fn combine_ranges(unordered: Vec<(char, char)>) -> Vec<(char, char)> {
+    // Returns true iff the two character classes overlap or share a boundary.
+    // e.g., ('a', 'g') and ('h', 'm') would return true.
+    fn should_merge((a, b): (char, char), (x, y): (char, char)) -> bool {
+        cmp::max(a, x) as u32 <= cmp::min(b, y) as u32 + 1
+    }
+
+    // This is currently O(n^2), but I think with sufficient cleverness,
+    // it can be reduced to O(n) **if necessary**.
+    let mut ordered: Vec<(char, char)> = Vec::with_capacity(unordered.len());
+    for (us, ue) in unordered.move_iter() {
+        let (mut us, mut ue) = (us, ue);
+        assert!(us <= ue);
+        let mut which: Option<uint> = None;
+        for (i, &(os, oe)) in ordered.iter().enumerate() {
+            if should_merge((us, ue), (os, oe)) {
+                us = cmp::min(us, os);
+                ue = cmp::max(ue, oe);
+                which = Some(i);
+                break
+            }
+        }
+        match which {
+            None => ordered.push((us, ue)),
+            Some(i) => *ordered.get_mut(i) = (us, ue),
+        }
+    }
+    ordered.sort();
+    ordered
+}
+
+// Constructs a Unicode friendly Perl character class from \d, \s or \w
+// (or any of their negated forms). Note that this does not handle negation.
+fn perl_unicode_class(which: char) -> Vec<(char, char)> {
+    match which.to_lowercase() {
+        'd' => Vec::from_slice(PERLD),
+        's' => Vec::from_slice(PERLS),
+        'w' => Vec::from_slice(PERLW),
+        _ => unreachable!(),
+    }
+}
+
+// Returns a concatenation of two expressions. This also guarantees that a
+// `Cat` expression will never be a direct child of another `Cat` expression.
+fn concat_flatten(x: Ast, y: Ast) -> Ast {
+    match (x, y) {
+        (Cat(mut xs), Cat(ys)) => { xs.push_all_move(ys); Cat(xs) }
+        (Cat(mut xs), ast) => { xs.push(ast); Cat(xs) }
+        (ast, Cat(mut xs)) => { xs.unshift(ast); Cat(xs) }
+        (ast1, ast2) => Cat(vec!(ast1, ast2)),
+    }
+}
+
+pub fn is_punct(c: char) -> bool {
+    match c {
+        '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' |
+        '[' | ']' | '{' | '}' | '^' | '$' => true,
+        _ => false,
+    }
+}
+
+fn is_valid_cap(c: char) -> bool {
+    c == '_' || (c >= '0' && c <= '9')
+    || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+}
+
+fn find_class(classes: NamedClasses, name: &str) -> Option<Vec<(char, char)>> {
+    match classes.bsearch(|&(s, _)| s.cmp(&name)) {
+        Some(i) => Some(Vec::from_slice(classes[i].val1())),
+        None => None,
+    }
+}
+
+type Class = &'static [(char, char)];
+type NamedClasses = &'static [(&'static str, Class)];
+
+static ASCII_CLASSES: NamedClasses = &[
+    // Classes must be in alphabetical order so that bsearch works.
+    // [:alnum:]      alphanumeric (== [0-9A-Za-z])
+    // [:alpha:]      alphabetic (== [A-Za-z])
+    // [:ascii:]      ASCII (== [\x00-\x7F])
+    // [:blank:]      blank (== [\t ])
+    // [:cntrl:]      control (== [\x00-\x1F\x7F])
+    // [:digit:]      digits (== [0-9])
+    // [:graph:]      graphical (== [!-~])
+    // [:lower:]      lower case (== [a-z])
+    // [:print:]      printable (== [ -~] == [ [:graph:]])
+    // [:punct:]      punctuation (== [!-/:-@[-`{-~])
+    // [:space:]      whitespace (== [\t\n\v\f\r ])
+    // [:upper:]      upper case (== [A-Z])
+    // [:word:]       word characters (== [0-9A-Za-z_])
+    // [:xdigit:]     hex digit (== [0-9A-Fa-f])
+    // Taken from: http://golang.org/pkg/regex/syntax/
+    ("alnum", &[('0', '9'), ('A', 'Z'), ('a', 'z')]),
+    ("alpha", &[('A', 'Z'), ('a', 'z')]),
+    ("ascii", &[('\x00', '\x7F')]),
+    ("blank", &[(' ', ' '), ('\t', '\t')]),
+    ("cntrl", &[('\x00', '\x1F'), ('\x7F', '\x7F')]),
+    ("digit", &[('0', '9')]),
+    ("graph", &[('!', '~')]),
+    ("lower", &[('a', 'z')]),
+    ("print", &[(' ', '~')]),
+    ("punct", &[('!', '/'), (':', '@'), ('[', '`'), ('{', '~')]),
+    ("space", &[('\t', '\t'), ('\n', '\n'), ('\x0B', '\x0B'), ('\x0C', '\x0C'),
+                ('\r', '\r'), (' ', ' ')]),
+    ("upper", &[('A', 'Z')]),
+    ("word", &[('0', '9'), ('A', 'Z'), ('a', 'z'), ('_', '_')]),
+    ("xdigit", &[('0', '9'), ('A', 'F'), ('a', 'f')]),
+];
diff --git a/src/libregex/parse/mod.rs b/src/libregex/parse/mod.rs
deleted file mode 100644 (file)
index 9cde40c..0000000
+++ /dev/null
@@ -1,1064 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::char;
-use std::cmp;
-use std::fmt;
-use std::iter;
-use std::num;
-use std::str;
-
-/// Static data containing Unicode ranges for general categories and scripts.
-use self::unicode::{UNICODE_CLASSES, PERLD, PERLS, PERLW};
-#[allow(visible_private_types)]
-pub mod unicode;
-
-/// The maximum number of repetitions allowed with the `{n,m}` syntax.
-static MAX_REPEAT: uint = 1000;
-
-/// Error corresponds to something that can go wrong while parsing
-/// a regular expression.
-///
-/// (Once an expression is compiled, it is not possible to produce an error
-/// via searching, splitting or replacing.)
-pub struct Error {
-    /// The *approximate* character index of where the error occurred.
-    pub pos: uint,
-    /// A message describing the error.
-    pub msg: String,
-}
-
-impl fmt::Show for Error {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "Regex syntax error near position {}: {}",
-               self.pos, self.msg)
-    }
-}
-
-/// Represents the abstract syntax of a regular expression.
-/// It is showable so that error messages resulting from a bug can provide
-/// useful information.
-/// It is cloneable so that expressions can be repeated for the counted
-/// repetition feature. (No other copying is done.)
-///
-/// Note that this representation prevents one from reproducing the regex as
-/// it was typed. (But it could be used to reproduce an equivalent regex.)
-#[deriving(Show, Clone)]
-pub enum Ast {
-    Nothing,
-    Literal(char, Flags),
-    Dot(Flags),
-    Class(Vec<(char, char)>, Flags),
-    Begin(Flags),
-    End(Flags),
-    WordBoundary(Flags),
-    Capture(uint, Option<String>, Box<Ast>),
-    // Represent concatenation as a flat vector to avoid blowing the
-    // stack in the compiler.
-    Cat(Vec<Ast>),
-    Alt(Box<Ast>, Box<Ast>),
-    Rep(Box<Ast>, Repeater, Greed),
-}
-
-#[deriving(Show, PartialEq, Clone)]
-pub enum Repeater {
-    ZeroOne,
-    ZeroMore,
-    OneMore,
-}
-
-#[deriving(Show, Clone)]
-pub enum Greed {
-    Greedy,
-    Ungreedy,
-}
-
-impl Greed {
-    pub fn is_greedy(&self) -> bool {
-        match *self {
-            Greedy => true,
-            _ => false,
-        }
-    }
-
-    fn swap(self, swapped: bool) -> Greed {
-        if !swapped { return self }
-        match self {
-            Greedy => Ungreedy,
-            Ungreedy => Greedy,
-        }
-    }
-}
-
-/// BuildAst is a regrettable type that represents intermediate state for
-/// constructing an abstract syntax tree. Its central purpose is to facilitate
-/// parsing groups and alternations while also maintaining a stack of flag
-/// state.
-#[deriving(Show)]
-enum BuildAst {
-    Ast(Ast),
-    Paren(Flags, uint, String), // '('
-    Bar, // '|'
-}
-
-impl BuildAst {
-    fn paren(&self) -> bool {
-        match *self {
-            Paren(_, _, _) => true,
-            _ => false,
-        }
-    }
-
-    fn flags(&self) -> Flags {
-        match *self {
-            Paren(flags, _, _) => flags,
-            _ => fail!("Cannot get flags from {}", self),
-        }
-    }
-
-    fn capture(&self) -> Option<uint> {
-        match *self {
-            Paren(_, 0, _) => None,
-            Paren(_, c, _) => Some(c),
-            _ => fail!("Cannot get capture group from {}", self),
-        }
-    }
-
-    fn capture_name(&self) -> Option<String> {
-        match *self {
-            Paren(_, 0, _) => None,
-            Paren(_, _, ref name) => {
-                if name.len() == 0 {
-                    None
-                } else {
-                    Some(name.clone())
-                }
-            }
-            _ => fail!("Cannot get capture name from {}", self),
-        }
-    }
-
-    fn bar(&self) -> bool {
-        match *self {
-            Bar => true,
-            _ => false,
-        }
-    }
-
-    fn unwrap(self) -> Result<Ast, Error> {
-        match self {
-            Ast(x) => Ok(x),
-            _ => fail!("Tried to unwrap non-AST item: {}", self),
-        }
-    }
-}
-
-/// Flags represents all options that can be twiddled by a user in an
-/// expression.
-pub type Flags = u8;
-
-pub static FLAG_EMPTY:      u8 = 0;
-pub static FLAG_NOCASE:     u8 = 1 << 0; // i
-pub static FLAG_MULTI:      u8 = 1 << 1; // m
-pub static FLAG_DOTNL:      u8 = 1 << 2; // s
-pub static FLAG_SWAP_GREED: u8 = 1 << 3; // U
-pub static FLAG_NEGATED:    u8 = 1 << 4; // char class or not word boundary
-
-struct Parser<'a> {
-    // The input, parsed only as a sequence of UTF8 code points.
-    chars: Vec<char>,
-    // The index of the current character in the input.
-    chari: uint,
-    // The intermediate state representing the AST.
-    stack: Vec<BuildAst>,
-    // The current set of flags.
-    flags: Flags,
-    // The total number of capture groups.
-    // Incremented each time an opening left paren is seen (assuming it is
-    // opening a capture group).
-    caps: uint,
-    // A set of all capture group names used only to detect duplicates.
-    names: Vec<String>,
-}
-
-pub fn parse(s: &str) -> Result<Ast, Error> {
-    Parser {
-        chars: s.chars().collect(),
-        chari: 0,
-        stack: vec!(),
-        flags: FLAG_EMPTY,
-        caps: 0,
-        names: vec!(),
-    }.parse()
-}
-
-impl<'a> Parser<'a> {
-    fn parse(&mut self) -> Result<Ast, Error> {
-        if self.chars.len() == 0 {
-            return Ok(Nothing);
-        }
-        loop {
-            let c = self.cur();
-            match c {
-                '?' | '*' | '+' => try!(self.push_repeater(c)),
-                '\\' => {
-                    let ast = try!(self.parse_escape());
-                    self.push(ast)
-                }
-                '{' => try!(self.parse_counted()),
-                '[' => match self.try_parse_ascii() {
-                    None => try!(self.parse_class()),
-                    Some(class) => self.push(class),
-                },
-                '(' => {
-                    if self.peek_is(1, '?') {
-                        try!(self.expect('?'))
-                        try!(self.parse_group_opts())
-                    } else {
-                        self.caps += 1;
-                        self.stack.push(Paren(self.flags,
-                                              self.caps,
-                                              "".to_string()))
-                    }
-                }
-                ')' => {
-                    let catfrom = try!(
-                        self.pos_last(false, |x| x.paren() || x.bar()));
-                    try!(self.concat(catfrom));
-
-                    let altfrom = try!(self.pos_last(false, |x| x.paren()));
-                    // Before we smush the alternates together and pop off the
-                    // left paren, let's grab the old flags and see if we
-                    // need a capture.
-                    let (cap, cap_name, oldflags) = {
-                        let paren = self.stack.get(altfrom-1);
-                        (paren.capture(), paren.capture_name(), paren.flags())
-                    };
-                    try!(self.alternate(altfrom));
-                    self.flags = oldflags;
-
-                    // If this was a capture, pop what we just pushed in
-                    // alternate and make it a capture.
-                    if cap.is_some() {
-                        let ast = try!(self.pop_ast());
-                        self.push(Capture(cap.unwrap(), cap_name, box ast));
-                    }
-                }
-                '|' => {
-                    let catfrom = try!(
-                        self.pos_last(true, |x| x.paren() || x.bar()));
-                    try!(self.concat(catfrom));
-
-                    self.stack.push(Bar);
-                }
-                _ => try!(self.push_literal(c)),
-            }
-            if !self.next_char() {
-                break
-            }
-        }
-
-        // Try to improve error handling. At this point, there should be
-        // no remaining open parens.
-        if self.stack.iter().any(|x| x.paren()) {
-            return self.err("Unclosed parenthesis.")
-        }
-        let catfrom = try!(self.pos_last(true, |x| x.bar()));
-        try!(self.concat(catfrom));
-        try!(self.alternate(0));
-
-        assert!(self.stack.len() == 1);
-        self.pop_ast()
-    }
-
-    fn noteof(&mut self, expected: &str) -> Result<(), Error> {
-        match self.next_char() {
-            true => Ok(()),
-            false => {
-                self.err(format!("Expected {} but got EOF.",
-                                 expected).as_slice())
-            }
-        }
-    }
-
-    fn expect(&mut self, expected: char) -> Result<(), Error> {
-        match self.next_char() {
-            true if self.cur() == expected => Ok(()),
-            true => self.err(format!("Expected '{}' but got '{}'.",
-                                     expected, self.cur()).as_slice()),
-            false => {
-                self.err(format!("Expected '{}' but got EOF.",
-                                 expected).as_slice())
-            }
-        }
-    }
-
-    fn next_char(&mut self) -> bool {
-        self.chari += 1;
-        self.chari < self.chars.len()
-    }
-
-    fn pop_ast(&mut self) -> Result<Ast, Error> {
-        match self.stack.pop().unwrap().unwrap() {
-            Err(e) => Err(e),
-            Ok(ast) => Ok(ast),
-        }
-    }
-
-    fn push(&mut self, ast: Ast) {
-        self.stack.push(Ast(ast))
-    }
-
-    fn push_repeater(&mut self, c: char) -> Result<(), Error> {
-        if self.stack.len() == 0 {
-            return self.err(
-                "A repeat operator must be preceded by a valid expression.")
-        }
-        let rep: Repeater = match c {
-            '?' => ZeroOne, '*' => ZeroMore, '+' => OneMore,
-            _ => fail!("Not a valid repeater operator."),
-        };
-
-        match self.peek(1) {
-            Some('*') | Some('+') =>
-                return self.err(
-                    "Double repeat operators are not supported."),
-            _ => {},
-        }
-        let ast = try!(self.pop_ast());
-        match ast {
-            Begin(_) | End(_) | WordBoundary(_) =>
-                return self.err(
-                    "Repeat arguments cannot be empty width assertions."),
-            _ => {}
-        }
-        let greed = try!(self.get_next_greedy());
-        self.push(Rep(box ast, rep, greed));
-        Ok(())
-    }
-
-    fn push_literal(&mut self, c: char) -> Result<(), Error> {
-        let flags = self.flags;
-        match c {
-            '.' => {
-                self.push(Dot(flags))
-            }
-            '^' => {
-                self.push(Begin(flags))
-            }
-            '$' => {
-                self.push(End(flags))
-            }
-            _ => {
-                self.push(Literal(c, flags))
-            }
-        }
-        Ok(())
-    }
-
-    // Parses all forms of character classes.
-    // Assumes that '[' is the current character.
-    fn parse_class(&mut self) -> Result<(), Error> {
-        let negated =
-            if self.peek_is(1, '^') {
-                try!(self.expect('^'))
-                FLAG_NEGATED
-            } else {
-                FLAG_EMPTY
-            };
-        let mut ranges: Vec<(char, char)> = vec!();
-        let mut alts: Vec<Ast> = vec!();
-
-        if self.peek_is(1, ']') {
-            try!(self.expect(']'))
-            ranges.push((']', ']'))
-        }
-        while self.peek_is(1, '-') {
-            try!(self.expect('-'))
-            ranges.push(('-', '-'))
-        }
-        loop {
-            try!(self.noteof("a closing ']' or a non-empty character class)"))
-            let mut c = self.cur();
-            match c {
-                '[' =>
-                    match self.try_parse_ascii() {
-                        Some(Class(asciis, flags)) => {
-                            alts.push(Class(asciis, flags ^ negated));
-                            continue
-                        }
-                        Some(ast) =>
-                            fail!("Expected Class AST but got '{}'", ast),
-                        // Just drop down and try to add as a regular character.
-                        None => {},
-                    },
-                '\\' => {
-                    match try!(self.parse_escape()) {
-                        Class(asciis, flags) => {
-                            alts.push(Class(asciis, flags ^ negated));
-                            continue
-                        }
-                        Literal(c2, _) => c = c2, // process below
-                        Begin(_) | End(_) | WordBoundary(_) =>
-                            return self.err(
-                                "\\A, \\z, \\b and \\B are not valid escape \
-                                 sequences inside a character class."),
-                        ast => fail!("Unexpected AST item '{}'", ast),
-                    }
-                }
-                _ => {},
-            }
-            match c {
-                ']' => {
-                    if ranges.len() > 0 {
-                        let flags = negated | (self.flags & FLAG_NOCASE);
-                        let mut ast = Class(combine_ranges(ranges), flags);
-                        for alt in alts.move_iter() {
-                            ast = Alt(box alt, box ast)
-                        }
-                        self.push(ast);
-                    } else if alts.len() > 0 {
-                        let mut ast = alts.pop().unwrap();
-                        for alt in alts.move_iter() {
-                            ast = Alt(box alt, box ast)
-                        }
-                        self.push(ast);
-                    }
-                    return Ok(())
-                }
-                c => {
-                    if self.peek_is(1, '-') && !self.peek_is(2, ']') {
-                        try!(self.expect('-'))
-                        try!(self.noteof("not a ']'"))
-                        let c2 = self.cur();
-                        if c2 < c {
-                            return self.err(format!("Invalid character class \
-                                                     range '{}-{}'",
-                                                    c,
-                                                    c2).as_slice())
-                        }
-                        ranges.push((c, self.cur()))
-                    } else {
-                        ranges.push((c, c))
-                    }
-                }
-            }
-        }
-    }
-
-    // Tries to parse an ASCII character class of the form [:name:].
-    // If successful, returns an AST character class corresponding to name
-    // and moves the parser to the final ']' character.
-    // If unsuccessful, no state is changed and None is returned.
-    // Assumes that '[' is the current character.
-    fn try_parse_ascii(&mut self) -> Option<Ast> {
-        if !self.peek_is(1, ':') {
-            return None
-        }
-        let closer =
-            match self.pos(']') {
-                Some(i) => i,
-                None => return None,
-            };
-        if *self.chars.get(closer-1) != ':' {
-            return None
-        }
-        if closer - self.chari <= 3 {
-            return None
-        }
-        let mut name_start = self.chari + 2;
-        let negated =
-            if self.peek_is(2, '^') {
-                name_start += 1;
-                FLAG_NEGATED
-            } else {
-                FLAG_EMPTY
-            };
-        let name = self.slice(name_start, closer - 1);
-        match find_class(ASCII_CLASSES, name.as_slice()) {
-            None => None,
-            Some(ranges) => {
-                self.chari = closer;
-                let flags = negated | (self.flags & FLAG_NOCASE);
-                Some(Class(combine_ranges(ranges), flags))
-            }
-        }
-    }
-
-    // Parses counted repetition. Supports:
-    // {n}, {n,}, {n,m}, {n}?, {n,}? and {n,m}?
-    // Assumes that '{' is the current character.
-    // Returns either an error or moves the parser to the final '}' character.
-    // (Or the '?' character if not greedy.)
-    fn parse_counted(&mut self) -> Result<(), Error> {
-        // Scan until the closing '}' and grab the stuff in {}.
-        let start = self.chari;
-        let closer =
-            match self.pos('}') {
-                Some(i) => i,
-                None => {
-                    return self.err(format!("No closing brace for counted \
-                                             repetition starting at position \
-                                             {}.",
-                                            start).as_slice())
-                }
-            };
-        self.chari = closer;
-        let greed = try!(self.get_next_greedy());
-        let inner = str::from_chars(
-            self.chars.as_slice().slice(start + 1, closer));
-
-        // Parse the min and max values from the regex.
-        let (mut min, mut max): (uint, Option<uint>);
-        if !inner.as_slice().contains(",") {
-            min = try!(self.parse_uint(inner.as_slice()));
-            max = Some(min);
-        } else {
-            let pieces: Vec<&str> = inner.as_slice().splitn(',', 1).collect();
-            let (smin, smax) = (*pieces.get(0), *pieces.get(1));
-            if smin.len() == 0 {
-                return self.err("Max repetitions cannot be specified \
-                                    without min repetitions.")
-            }
-            min = try!(self.parse_uint(smin));
-            max =
-                if smax.len() == 0 {
-                    None
-                } else {
-                    Some(try!(self.parse_uint(smax)))
-                };
-        }
-
-        // Do some bounds checking and make sure max >= min.
-        if min > MAX_REPEAT {
-            return self.err(format!(
-                "{} exceeds maximum allowed repetitions ({})",
-                min, MAX_REPEAT).as_slice());
-        }
-        if max.is_some() {
-            let m = max.unwrap();
-            if m > MAX_REPEAT {
-                return self.err(format!(
-                    "{} exceeds maximum allowed repetitions ({})",
-                    m, MAX_REPEAT).as_slice());
-            }
-            if m < min {
-                return self.err(format!(
-                    "Max repetitions ({}) cannot be smaller than min \
-                     repetitions ({}).", m, min).as_slice());
-            }
-        }
-
-        // Now manipulate the AST be repeating elements.
-        if max.is_none() {
-            // Require N copies of what's on the stack and then repeat it.
-            let ast = try!(self.pop_ast());
-            for _ in iter::range(0, min) {
-                self.push(ast.clone())
-            }
-            self.push(Rep(box ast, ZeroMore, greed));
-        } else {
-            // Require N copies of what's on the stack and then repeat it
-            // up to M times optionally.
-            let ast = try!(self.pop_ast());
-            for _ in iter::range(0, min) {
-                self.push(ast.clone())
-            }
-            if max.is_some() {
-                for _ in iter::range(min, max.unwrap()) {
-                    self.push(Rep(box ast.clone(), ZeroOne, greed))
-                }
-            }
-            // It's possible that we popped something off the stack but
-            // never put anything back on it. To keep things simple, add
-            // a no-op expression.
-            if min == 0 && (max.is_none() || max == Some(0)) {
-                self.push(Nothing)
-            }
-        }
-        Ok(())
-    }
-
-    // Parses all escape sequences.
-    // Assumes that '\' is the current character.
-    fn parse_escape(&mut self) -> Result<Ast, Error> {
-        try!(self.noteof("an escape sequence following a '\\'"))
-
-        let c = self.cur();
-        if is_punct(c) {
-            return Ok(Literal(c, FLAG_EMPTY))
-        }
-        match c {
-            'a' => Ok(Literal('\x07', FLAG_EMPTY)),
-            'f' => Ok(Literal('\x0C', FLAG_EMPTY)),
-            't' => Ok(Literal('\t', FLAG_EMPTY)),
-            'n' => Ok(Literal('\n', FLAG_EMPTY)),
-            'r' => Ok(Literal('\r', FLAG_EMPTY)),
-            'v' => Ok(Literal('\x0B', FLAG_EMPTY)),
-            'A' => Ok(Begin(FLAG_EMPTY)),
-            'z' => Ok(End(FLAG_EMPTY)),
-            'b' => Ok(WordBoundary(FLAG_EMPTY)),
-            'B' => Ok(WordBoundary(FLAG_NEGATED)),
-            '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7' => Ok(try!(self.parse_octal())),
-            'x' => Ok(try!(self.parse_hex())),
-            'p' | 'P' => Ok(try!(self.parse_unicode_name())),
-            'd' | 'D' | 's' | 'S' | 'w' | 'W' => {
-                let ranges = perl_unicode_class(c);
-                let mut flags = self.flags & FLAG_NOCASE;
-                if c.is_uppercase() { flags |= FLAG_NEGATED }
-                Ok(Class(ranges, flags))
-            }
-            _ => {
-                self.err(format!("Invalid escape sequence '\\\\{}'",
-                                 c).as_slice())
-            }
-        }
-    }
-
-    // Parses a unicode character class name, either of the form \pF where
-    // F is a one letter unicode class name or of the form \p{name} where
-    // name is the unicode class name.
-    // Assumes that \p or \P has been read (and 'p' or 'P' is the current
-    // character).
-    fn parse_unicode_name(&mut self) -> Result<Ast, Error> {
-        let negated = if self.cur() == 'P' { FLAG_NEGATED } else { FLAG_EMPTY };
-        let mut name: String;
-        if self.peek_is(1, '{') {
-            try!(self.expect('{'))
-            let closer =
-                match self.pos('}') {
-                    Some(i) => i,
-                    None => return self.err(format!(
-                        "Missing '}}' for unclosed '{{' at position {}",
-                        self.chari).as_slice()),
-                };
-            if closer - self.chari + 1 == 0 {
-                return self.err("No Unicode class name found.")
-            }
-            name = self.slice(self.chari + 1, closer);
-            self.chari = closer;
-        } else {
-            if self.chari + 1 >= self.chars.len() {
-                return self.err("No single letter Unicode class name found.")
-            }
-            name = self.slice(self.chari + 1, self.chari + 2);
-            self.chari += 1;
-        }
-        match find_class(UNICODE_CLASSES, name.as_slice()) {
-            None => {
-                return self.err(format!("Could not find Unicode class '{}'",
-                                        name).as_slice())
-            }
-            Some(ranges) => {
-                Ok(Class(ranges, negated | (self.flags & FLAG_NOCASE)))
-            }
-        }
-    }
-
-    // Parses an octal number, up to 3 digits.
-    // Assumes that \n has been read, where n is the first digit.
-    fn parse_octal(&mut self) -> Result<Ast, Error> {
-        let start = self.chari;
-        let mut end = start + 1;
-        let (d2, d3) = (self.peek(1), self.peek(2));
-        if d2 >= Some('0') && d2 <= Some('7') {
-            try!(self.noteof("expected octal character in [0-7]"))
-            end += 1;
-            if d3 >= Some('0') && d3 <= Some('7') {
-                try!(self.noteof("expected octal character in [0-7]"))
-                end += 1;
-            }
-        }
-        let s = self.slice(start, end);
-        match num::from_str_radix::<u32>(s.as_slice(), 8) {
-            Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
-            None => {
-                self.err(format!("Could not parse '{}' as octal number.",
-                                 s).as_slice())
-            }
-        }
-    }
-
-    // Parse a hex number. Either exactly two digits or anything in {}.
-    // Assumes that \x has been read.
-    fn parse_hex(&mut self) -> Result<Ast, Error> {
-        if !self.peek_is(1, '{') {
-            try!(self.expect('{'))
-            return self.parse_hex_two()
-        }
-        let start = self.chari + 2;
-        let closer =
-            match self.pos('}') {
-                None => {
-                    return self.err(format!("Missing '}}' for unclosed \
-                                             '{{' at position {}",
-                                            start).as_slice())
-                }
-                Some(i) => i,
-            };
-        self.chari = closer;
-        self.parse_hex_digits(self.slice(start, closer).as_slice())
-    }
-
-    // Parses a two-digit hex number.
-    // Assumes that \xn has been read, where n is the first digit and is the
-    // current character.
-    // After return, parser will point at the second digit.
-    fn parse_hex_two(&mut self) -> Result<Ast, Error> {
-        let (start, end) = (self.chari, self.chari + 2);
-        let bad = self.slice(start - 2, self.chars.len());
-        try!(self.noteof(format!("Invalid hex escape sequence '{}'",
-                                 bad).as_slice()))
-        self.parse_hex_digits(self.slice(start, end).as_slice())
-    }
-
-    // Parses `s` as a hexadecimal number.
-    fn parse_hex_digits(&self, s: &str) -> Result<Ast, Error> {
-        match num::from_str_radix::<u32>(s, 16) {
-            Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
-            None => {
-                self.err(format!("Could not parse '{}' as hex number.",
-                                 s).as_slice())
-            }
-        }
-    }
-
-    // Parses a named capture.
-    // Assumes that '(?P<' has been consumed and that the current character
-    // is '<'.
-    // When done, parser will be at the closing '>' character.
-    fn parse_named_capture(&mut self) -> Result<(), Error> {
-        try!(self.noteof("a capture name"))
-        let closer =
-            match self.pos('>') {
-                Some(i) => i,
-                None => return self.err("Capture name must end with '>'."),
-            };
-        if closer - self.chari == 0 {
-            return self.err("Capture names must have at least 1 character.")
-        }
-        let name = self.slice(self.chari, closer);
-        if !name.as_slice().chars().all(is_valid_cap) {
-            return self.err(
-                "Capture names can only have underscores, letters and digits.")
-        }
-        if self.names.contains(&name) {
-            return self.err(format!("Duplicate capture group name '{}'.",
-                                    name).as_slice())
-        }
-        self.names.push(name.clone());
-        self.chari = closer;
-        self.caps += 1;
-        self.stack.push(Paren(self.flags, self.caps, name));
-        Ok(())
-    }
-
-    // Parses non-capture groups and options.
-    // Assumes that '(?' has already been consumed and '?' is the current
-    // character.
-    fn parse_group_opts(&mut self) -> Result<(), Error> {
-        if self.peek_is(1, 'P') && self.peek_is(2, '<') {
-            try!(self.expect('P')) try!(self.expect('<'))
-            return self.parse_named_capture()
-        }
-        let start = self.chari;
-        let mut flags = self.flags;
-        let mut sign = 1i;
-        let mut saw_flag = false;
-        loop {
-            try!(self.noteof("expected non-empty set of flags or closing ')'"))
-            match self.cur() {
-                'i' => { flags = flags | FLAG_NOCASE;     saw_flag = true},
-                'm' => { flags = flags | FLAG_MULTI;      saw_flag = true},
-                's' => { flags = flags | FLAG_DOTNL;      saw_flag = true},
-                'U' => { flags = flags | FLAG_SWAP_GREED; saw_flag = true},
-                '-' => {
-                    if sign < 0 {
-                        return self.err(format!(
-                            "Cannot negate flags twice in '{}'.",
-                            self.slice(start, self.chari + 1)).as_slice())
-                    }
-                    sign = -1;
-                    saw_flag = false;
-                    flags = flags ^ flags;
-                }
-                ':' | ')' => {
-                    if sign < 0 {
-                        if !saw_flag {
-                            return self.err(format!(
-                                "A valid flag does not follow negation in '{}'",
-                                self.slice(start, self.chari + 1)).as_slice())
-                        }
-                        flags = flags ^ flags;
-                    }
-                    if self.cur() == ':' {
-                        // Save the old flags with the opening paren.
-                        self.stack.push(Paren(self.flags, 0, "".to_string()));
-                    }
-                    self.flags = flags;
-                    return Ok(())
-                }
-                _ => return self.err(format!(
-                    "Unrecognized flag '{}'.", self.cur()).as_slice()),
-            }
-        }
-    }
-
-    // Peeks at the next character and returns whether it's ungreedy or not.
-    // If it is, then the next character is consumed.
-    fn get_next_greedy(&mut self) -> Result<Greed, Error> {
-        Ok(if self.peek_is(1, '?') {
-            try!(self.expect('?'))
-            Ungreedy
-        } else {
-            Greedy
-        }.swap(self.flags & FLAG_SWAP_GREED > 0))
-    }
-
-    // Searches the stack (starting at the top) until it finds an expression
-    // for which `pred` returns true. The index of that expression in the
-    // stack is returned.
-    // If there's no match, then one of two things happens depending on the
-    // values of `allow_start`. When it's true, then `0` will be returned.
-    // Otherwise, an error will be returned.
-    // Generally, `allow_start` is only true when you're *not* expecting an
-    // opening parenthesis.
-    fn pos_last(&self, allow_start: bool, pred: |&BuildAst| -> bool)
-               -> Result<uint, Error> {
-        let from = match self.stack.iter().rev().position(pred) {
-            Some(i) => i,
-            None => {
-                if allow_start {
-                    self.stack.len()
-                } else {
-                    return self.err("No matching opening parenthesis.")
-                }
-            }
-        };
-        // Adjust index since 'from' is for the reversed stack.
-        // Also, don't include the '(' or '|'.
-        Ok(self.stack.len() - from)
-    }
-
-    // concat starts at `from` in the parser's stack and concatenates all
-    // expressions up to the top of the stack. The resulting concatenation is
-    // then pushed on to the stack.
-    // Usually `from` corresponds to the position of an opening parenthesis,
-    // a '|' (alternation) or the start of the entire expression.
-    fn concat(&mut self, from: uint) -> Result<(), Error> {
-        let ast = try!(self.build_from(from, concat_flatten));
-        self.push(ast);
-        Ok(())
-    }
-
-    // concat starts at `from` in the parser's stack and alternates all
-    // expressions up to the top of the stack. The resulting alternation is
-    // then pushed on to the stack.
-    // Usually `from` corresponds to the position of an opening parenthesis
-    // or the start of the entire expression.
-    // This will also drop any opening parens or alternation bars found in
-    // the intermediate AST.
-    fn alternate(&mut self, mut from: uint) -> Result<(), Error> {
-        // Unlike in the concatenation case, we want 'build_from' to continue
-        // all the way to the opening left paren (so it will be popped off and
-        // thrown away). But be careful with overflow---we can't count on the
-        // open paren to be there.
-        if from > 0 { from = from - 1}
-        let ast = try!(self.build_from(from, |l,r| Alt(box l, box r)));
-        self.push(ast);
-        Ok(())
-    }
-
-    // build_from combines all AST elements starting at 'from' in the
-    // parser's stack using 'mk' to combine them. If any such element is not an
-    // AST then it is popped off the stack and ignored.
-    fn build_from(&mut self, from: uint, mk: |Ast, Ast| -> Ast)
-                 -> Result<Ast, Error> {
-        if from >= self.stack.len() {
-            return self.err("Empty group or alternate not allowed.")
-        }
-
-        let mut combined = try!(self.pop_ast());
-        let mut i = self.stack.len();
-        while i > from {
-            i = i - 1;
-            match self.stack.pop().unwrap() {
-                Ast(x) => combined = mk(x, combined),
-                _ => {},
-            }
-        }
-        Ok(combined)
-    }
-
-    fn parse_uint(&self, s: &str) -> Result<uint, Error> {
-        match from_str::<uint>(s) {
-            Some(i) => Ok(i),
-            None => {
-                self.err(format!("Expected an unsigned integer but got '{}'.",
-                                 s).as_slice())
-            }
-        }
-    }
-
-    fn char_from_u32(&self, n: u32) -> Result<char, Error> {
-        match char::from_u32(n) {
-            Some(c) => Ok(c),
-            None => {
-                self.err(format!("Could not decode '{}' to unicode \
-                                  character.",
-                                 n).as_slice())
-            }
-        }
-    }
-
-    fn pos(&self, c: char) -> Option<uint> {
-        self.chars.iter()
-            .skip(self.chari).position(|&c2| c2 == c).map(|i| self.chari + i)
-    }
-
-    fn err<T>(&self, msg: &str) -> Result<T, Error> {
-        Err(Error {
-            pos: self.chari,
-            msg: msg.to_string(),
-        })
-    }
-
-    fn peek(&self, offset: uint) -> Option<char> {
-        if self.chari + offset >= self.chars.len() {
-            return None
-        }
-        Some(*self.chars.get(self.chari + offset))
-    }
-
-    fn peek_is(&self, offset: uint, is: char) -> bool {
-        self.peek(offset) == Some(is)
-    }
-
-    fn cur(&self) -> char {
-        *self.chars.get(self.chari)
-    }
-
-    fn slice(&self, start: uint, end: uint) -> String {
-        str::from_chars(self.chars.as_slice().slice(start, end)).to_string()
-    }
-}
-
-// Given an unordered collection of character ranges, combine_ranges returns
-// an ordered sequence of character ranges where no two ranges overlap. They
-// are ordered from least to greatest (using start position).
-fn combine_ranges(unordered: Vec<(char, char)>) -> Vec<(char, char)> {
-    // Returns true iff the two character classes overlap or share a boundary.
-    // e.g., ('a', 'g') and ('h', 'm') would return true.
-    fn should_merge((a, b): (char, char), (x, y): (char, char)) -> bool {
-        cmp::max(a, x) as u32 <= cmp::min(b, y) as u32 + 1
-    }
-
-    // This is currently O(n^2), but I think with sufficient cleverness,
-    // it can be reduced to O(n) **if necessary**.
-    let mut ordered: Vec<(char, char)> = Vec::with_capacity(unordered.len());
-    for (us, ue) in unordered.move_iter() {
-        let (mut us, mut ue) = (us, ue);
-        assert!(us <= ue);
-        let mut which: Option<uint> = None;
-        for (i, &(os, oe)) in ordered.iter().enumerate() {
-            if should_merge((us, ue), (os, oe)) {
-                us = cmp::min(us, os);
-                ue = cmp::max(ue, oe);
-                which = Some(i);
-                break
-            }
-        }
-        match which {
-            None => ordered.push((us, ue)),
-            Some(i) => *ordered.get_mut(i) = (us, ue),
-        }
-    }
-    ordered.sort();
-    ordered
-}
-
-// Constructs a Unicode friendly Perl character class from \d, \s or \w
-// (or any of their negated forms). Note that this does not handle negation.
-fn perl_unicode_class(which: char) -> Vec<(char, char)> {
-    match which.to_lowercase() {
-        'd' => Vec::from_slice(PERLD),
-        's' => Vec::from_slice(PERLS),
-        'w' => Vec::from_slice(PERLW),
-        _ => unreachable!(),
-    }
-}
-
-// Returns a concatenation of two expressions. This also guarantees that a
-// `Cat` expression will never be a direct child of another `Cat` expression.
-fn concat_flatten(x: Ast, y: Ast) -> Ast {
-    match (x, y) {
-        (Cat(mut xs), Cat(ys)) => { xs.push_all_move(ys); Cat(xs) }
-        (Cat(mut xs), ast) => { xs.push(ast); Cat(xs) }
-        (ast, Cat(mut xs)) => { xs.unshift(ast); Cat(xs) }
-        (ast1, ast2) => Cat(vec!(ast1, ast2)),
-    }
-}
-
-pub fn is_punct(c: char) -> bool {
-    match c {
-        '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' |
-        '[' | ']' | '{' | '}' | '^' | '$' => true,
-        _ => false,
-    }
-}
-
-fn is_valid_cap(c: char) -> bool {
-    c == '_' || (c >= '0' && c <= '9')
-    || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
-}
-
-fn find_class(classes: NamedClasses, name: &str) -> Option<Vec<(char, char)>> {
-    match classes.bsearch(|&(s, _)| s.cmp(&name)) {
-        Some(i) => Some(Vec::from_slice(classes[i].val1())),
-        None => None,
-    }
-}
-
-type Class = &'static [(char, char)];
-type NamedClasses = &'static [(&'static str, Class)];
-
-static ASCII_CLASSES: NamedClasses = &[
-    // Classes must be in alphabetical order so that bsearch works.
-    // [:alnum:]      alphanumeric (== [0-9A-Za-z])
-    // [:alpha:]      alphabetic (== [A-Za-z])
-    // [:ascii:]      ASCII (== [\x00-\x7F])
-    // [:blank:]      blank (== [\t ])
-    // [:cntrl:]      control (== [\x00-\x1F\x7F])
-    // [:digit:]      digits (== [0-9])
-    // [:graph:]      graphical (== [!-~])
-    // [:lower:]      lower case (== [a-z])
-    // [:print:]      printable (== [ -~] == [ [:graph:]])
-    // [:punct:]      punctuation (== [!-/:-@[-`{-~])
-    // [:space:]      whitespace (== [\t\n\v\f\r ])
-    // [:upper:]      upper case (== [A-Z])
-    // [:word:]       word characters (== [0-9A-Za-z_])
-    // [:xdigit:]     hex digit (== [0-9A-Fa-f])
-    // Taken from: http://golang.org/pkg/regex/syntax/
-    ("alnum", &[('0', '9'), ('A', 'Z'), ('a', 'z')]),
-    ("alpha", &[('A', 'Z'), ('a', 'z')]),
-    ("ascii", &[('\x00', '\x7F')]),
-    ("blank", &[(' ', ' '), ('\t', '\t')]),
-    ("cntrl", &[('\x00', '\x1F'), ('\x7F', '\x7F')]),
-    ("digit", &[('0', '9')]),
-    ("graph", &[('!', '~')]),
-    ("lower", &[('a', 'z')]),
-    ("print", &[(' ', '~')]),
-    ("punct", &[('!', '/'), (':', '@'), ('[', '`'), ('{', '~')]),
-    ("space", &[('\t', '\t'), ('\n', '\n'), ('\x0B', '\x0B'), ('\x0C', '\x0C'),
-                ('\r', '\r'), (' ', ' ')]),
-    ("upper", &[('A', 'Z')]),
-    ("word", &[('0', '9'), ('A', 'Z'), ('a', 'z'), ('_', '_')]),
-    ("xdigit", &[('0', '9'), ('A', 'F'), ('a', 'f')]),
-];
diff --git a/src/libregex/parse/unicode.rs b/src/libregex/parse/unicode.rs
deleted file mode 100644 (file)
index c263827..0000000
+++ /dev/null
@@ -1,5537 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// DO NOT EDIT. Automatically generated by 'src/etc/regex-unicode-tables'
-// on 2014-04-23 00:13:04.445491.
-
-use parse::{Class, NamedClasses};
-
-pub static UNICODE_CLASSES: NamedClasses = &[
-
-("Arabic", &[
-    ('\U00000600', '\U00000604'),
-    ('\U00000606', '\U0000060b'),
-    ('\U0000060d', '\U0000061a'),
-    ('\U0000061c', '\U0000061c'),
-    ('\U0000061e', '\U0000061e'),
-    ('\U00000620', '\U0000063f'),
-    ('\U00000641', '\U0000064a'),
-    ('\U00000656', '\U0000065f'),
-    ('\U0000066a', '\U0000066f'),
-    ('\U00000671', '\U000006dc'),
-    ('\U000006de', '\U000006ff'),
-    ('\U00000750', '\U0000077f'),
-    ('\U000008a0', '\U000008a0'),
-    ('\U000008a2', '\U000008ac'),
-    ('\U000008e4', '\U000008fe'),
-    ('\U0000fb50', '\U0000fbc1'),
-    ('\U0000fbd3', '\U0000fd3d'),
-    ('\U0000fd50', '\U0000fd8f'),
-    ('\U0000fd92', '\U0000fdc7'),
-    ('\U0000fdf0', '\U0000fdfc'),
-    ('\U0000fe70', '\U0000fe74'),
-    ('\U0000fe76', '\U0000fefc'),
-    ('\U00010e60', '\U00010e7e'),
-    ('\U0001ee00', '\U0001ee03'),
-    ('\U0001ee05', '\U0001ee1f'),
-    ('\U0001ee21', '\U0001ee22'),
-    ('\U0001ee24', '\U0001ee24'),
-    ('\U0001ee27', '\U0001ee27'),
-    ('\U0001ee29', '\U0001ee32'),
-    ('\U0001ee34', '\U0001ee37'),
-    ('\U0001ee39', '\U0001ee39'),
-    ('\U0001ee3b', '\U0001ee3b'),
-    ('\U0001ee42', '\U0001ee42'),
-    ('\U0001ee47', '\U0001ee47'),
-    ('\U0001ee49', '\U0001ee49'),
-    ('\U0001ee4b', '\U0001ee4b'),
-    ('\U0001ee4d', '\U0001ee4f'),
-    ('\U0001ee51', '\U0001ee52'),
-    ('\U0001ee54', '\U0001ee54'),
-    ('\U0001ee57', '\U0001ee57'),
-    ('\U0001ee59', '\U0001ee59'),
-    ('\U0001ee5b', '\U0001ee5b'),
-    ('\U0001ee5d', '\U0001ee5d'),
-    ('\U0001ee5f', '\U0001ee5f'),
-    ('\U0001ee61', '\U0001ee62'),
-    ('\U0001ee64', '\U0001ee64'),
-    ('\U0001ee67', '\U0001ee6a'),
-    ('\U0001ee6c', '\U0001ee72'),
-    ('\U0001ee74', '\U0001ee77'),
-    ('\U0001ee79', '\U0001ee7c'),
-    ('\U0001ee7e', '\U0001ee7e'),
-    ('\U0001ee80', '\U0001ee89'),
-    ('\U0001ee8b', '\U0001ee9b'),
-    ('\U0001eea1', '\U0001eea3'),
-    ('\U0001eea5', '\U0001eea9'),
-    ('\U0001eeab', '\U0001eebb'),
-    ('\U0001eef0', '\U0001eef1')
-    ]),
-("Armenian", &[
-    ('\U00000531', '\U00000556'),
-    ('\U00000559', '\U0000055f'),
-    ('\U00000561', '\U00000587'),
-    ('\U0000058a', '\U0000058a'),
-    ('\U0000058f', '\U0000058f'),
-    ('\U0000fb13', '\U0000fb17')
-    ]),
-("Avestan", &[
-    ('\U00010b00', '\U00010b35'),
-    ('\U00010b39', '\U00010b3f')
-    ]),
-("Balinese", &[
-    ('\U00001b00', '\U00001b4b'),
-    ('\U00001b50', '\U00001b7c')
-    ]),
-("Bamum", &[
-    ('\U0000a6a0', '\U0000a6f7'),
-    ('\U00016800', '\U00016a38')
-    ]),
-("Batak", &[
-    ('\U00001bc0', '\U00001bf3'),
-    ('\U00001bfc', '\U00001bff')
-    ]),
-("Bengali", &[
-    ('\U00000981', '\U00000983'),
-    ('\U00000985', '\U0000098c'),
-    ('\U0000098f', '\U00000990'),
-    ('\U00000993', '\U000009a8'),
-    ('\U000009aa', '\U000009b0'),
-    ('\U000009b2', '\U000009b2'),
-    ('\U000009b6', '\U000009b9'),
-    ('\U000009bc', '\U000009c4'),
-    ('\U000009c7', '\U000009c8'),
-    ('\U000009cb', '\U000009ce'),
-    ('\U000009d7', '\U000009d7'),
-    ('\U000009dc', '\U000009dd'),
-    ('\U000009df', '\U000009e3'),
-    ('\U000009e6', '\U000009fb')
-    ]),
-("Bopomofo", &[
-    ('\U000002ea', '\U000002eb'),
-    ('\U00003105', '\U0000312d'),
-    ('\U000031a0', '\U000031ba')
-    ]),
-("Brahmi", &[
-    ('\U00011000', '\U0001104d'),
-    ('\U00011052', '\U0001106f')
-    ]),
-("Braille", &[
-    ('\U00002800', '\U000028ff')
-    ]),
-("Buginese", &[
-    ('\U00001a00', '\U00001a1b'),
-    ('\U00001a1e', '\U00001a1f')
-    ]),
-("Buhid", &[
-    ('\U00001740', '\U00001753')
-    ]),
-("C", &[
-    ('\U00000000', '\U0000001f'),
-    ('\U0000007f', '\U0000009f'),
-    ('\U000000ad', '\U000000ad'),
-    ('\U00000600', '\U00000604'),
-    ('\U0000061c', '\U0000061c'),
-    ('\U000006dd', '\U000006dd'),
-    ('\U0000070f', '\U0000070f'),
-    ('\U0000180e', '\U0000180e'),
-    ('\U0000200b', '\U0000200f'),
-    ('\U0000202a', '\U0000202e'),
-    ('\U00002060', '\U00002064'),
-    ('\U00002066', '\U0000206f'),
-    ('\U0000e000', '\U0000e000'),
-    ('\U0000f8ff', '\U0000f8ff'),
-    ('\U0000feff', '\U0000feff'),
-    ('\U0000fff9', '\U0000fffb'),
-    ('\U000110bd', '\U000110bd'),
-    ('\U0001d173', '\U0001d17a'),
-    ('\U000e0001', '\U000e0001'),
-    ('\U000e0020', '\U000e007f'),
-    ('\U000f0000', '\U000f0000'),
-    ('\U000ffffd', '\U000ffffd'),
-    ('\U00100000', '\U00100000'),
-    ('\U0010fffd', '\U0010fffd')
-    ]),
-("Canadian_Aboriginal", &[
-    ('\U00001400', '\U0000167f'),
-    ('\U000018b0', '\U000018f5')
-    ]),
-("Carian", &[
-    ('\U000102a0', '\U000102d0')
-    ]),
-("Cc", &[
-    ('\U00000000', '\U0000001f'),
-    ('\U0000007f', '\U0000009f')
-    ]),
-("Cf", &[
-    ('\U000000ad', '\U000000ad'),
-    ('\U00000600', '\U00000604'),
-    ('\U0000061c', '\U0000061c'),
-    ('\U000006dd', '\U000006dd'),
-    ('\U0000070f', '\U0000070f'),
-    ('\U0000180e', '\U0000180e'),
-    ('\U0000200b', '\U0000200f'),
-    ('\U0000202a', '\U0000202e'),
-    ('\U00002060', '\U00002064'),
-    ('\U00002066', '\U0000206f'),
-    ('\U0000feff', '\U0000feff'),
-    ('\U0000fff9', '\U0000fffb'),
-    ('\U000110bd', '\U000110bd'),
-    ('\U0001d173', '\U0001d17a'),
-    ('\U000e0001', '\U000e0001'),
-    ('\U000e0020', '\U000e007f')
-    ]),
-("Chakma", &[
-    ('\U00011100', '\U00011134'),
-    ('\U00011136', '\U00011143')
-    ]),
-("Cham", &[
-    ('\U0000aa00', '\U0000aa36'),
-    ('\U0000aa40', '\U0000aa4d'),
-    ('\U0000aa50', '\U0000aa59'),
-    ('\U0000aa5c', '\U0000aa5f')
-    ]),
-("Cherokee", &[
-    ('\U000013a0', '\U000013f4')
-    ]),
-("Co", &[
-    ('\U0000e000', '\U0000e000'),
-    ('\U0000f8ff', '\U0000f8ff'),
-    ('\U000f0000', '\U000f0000'),
-    ('\U000ffffd', '\U000ffffd'),
-    ('\U00100000', '\U00100000'),
-    ('\U0010fffd', '\U0010fffd')
-    ]),
-("Common", &[
-    ('\U00000000', '\U00000040'),
-    ('\U0000005b', '\U00000060'),
-    ('\U0000007b', '\U000000a9'),
-    ('\U000000ab', '\U000000b9'),
-    ('\U000000bb', '\U000000bf'),
-    ('\U000000d7', '\U000000d7'),
-    ('\U000000f7', '\U000000f7'),
-    ('\U000002b9', '\U000002df'),
-    ('\U000002e5', '\U000002e9'),
-    ('\U000002ec', '\U000002ff'),
-    ('\U00000374', '\U00000374'),
-    ('\U0000037e', '\U0000037e'),
-    ('\U00000385', '\U00000385'),
-    ('\U00000387', '\U00000387'),
-    ('\U00000589', '\U00000589'),
-    ('\U0000060c', '\U0000060c'),
-    ('\U0000061b', '\U0000061b'),
-    ('\U0000061f', '\U0000061f'),
-    ('\U00000640', '\U00000640'),
-    ('\U00000660', '\U00000669'),
-    ('\U000006dd', '\U000006dd'),
-    ('\U00000964', '\U00000965'),
-    ('\U00000e3f', '\U00000e3f'),
-    ('\U00000fd5', '\U00000fd8'),
-    ('\U000010fb', '\U000010fb'),
-    ('\U000016eb', '\U000016ed'),
-    ('\U00001735', '\U00001736'),
-    ('\U00001802', '\U00001803'),
-    ('\U00001805', '\U00001805'),
-    ('\U00001cd3', '\U00001cd3'),
-    ('\U00001ce1', '\U00001ce1'),
-    ('\U00001ce9', '\U00001cec'),
-    ('\U00001cee', '\U00001cf3'),
-    ('\U00001cf5', '\U00001cf6'),
-    ('\U00002000', '\U0000200b'),
-    ('\U0000200e', '\U00002064'),
-    ('\U00002066', '\U00002070'),
-    ('\U00002074', '\U0000207e'),
-    ('\U00002080', '\U0000208e'),
-    ('\U000020a0', '\U000020ba'),
-    ('\U00002100', '\U00002125'),
-    ('\U00002127', '\U00002129'),
-    ('\U0000212c', '\U00002131'),
-    ('\U00002133', '\U0000214d'),
-    ('\U0000214f', '\U0000215f'),
-    ('\U00002189', '\U00002189'),
-    ('\U00002190', '\U000023f3'),
-    ('\U00002400', '\U00002426'),
-    ('\U00002440', '\U0000244a'),
-    ('\U00002460', '\U000026ff'),
-    ('\U00002701', '\U000027ff'),
-    ('\U00002900', '\U00002b4c'),
-    ('\U00002b50', '\U00002b59'),
-    ('\U00002e00', '\U00002e3b'),
-    ('\U00002ff0', '\U00002ffb'),
-    ('\U00003000', '\U00003004'),
-    ('\U00003006', '\U00003006'),
-    ('\U00003008', '\U00003020'),
-    ('\U00003030', '\U00003037'),
-    ('\U0000303c', '\U0000303f'),
-    ('\U0000309b', '\U0000309c'),
-    ('\U000030a0', '\U000030a0'),
-    ('\U000030fb', '\U000030fc'),
-    ('\U00003190', '\U0000319f'),
-    ('\U000031c0', '\U000031e3'),
-    ('\U00003220', '\U0000325f'),
-    ('\U0000327f', '\U000032cf'),
-    ('\U00003358', '\U000033ff'),
-    ('\U00004dc0', '\U00004dff'),
-    ('\U0000a700', '\U0000a721'),
-    ('\U0000a788', '\U0000a78a'),
-    ('\U0000a830', '\U0000a839'),
-    ('\U0000a9cf', '\U0000a9cf'),
-    ('\U0000fd3e', '\U0000fd3f'),
-    ('\U0000fdfd', '\U0000fdfd'),
-    ('\U0000fe10', '\U0000fe19'),
-    ('\U0000fe30', '\U0000fe52'),
-    ('\U0000fe54', '\U0000fe66'),
-    ('\U0000fe68', '\U0000fe6b'),
-    ('\U0000feff', '\U0000feff'),
-    ('\U0000ff01', '\U0000ff20'),
-    ('\U0000ff3b', '\U0000ff40'),
-    ('\U0000ff5b', '\U0000ff65'),
-    ('\U0000ff70', '\U0000ff70'),
-    ('\U0000ff9e', '\U0000ff9f'),
-    ('\U0000ffe0', '\U0000ffe6'),
-    ('\U0000ffe8', '\U0000ffee'),
-    ('\U0000fff9', '\U0000fffd'),
-    ('\U00010100', '\U00010102'),
-    ('\U00010107', '\U00010133'),
-    ('\U00010137', '\U0001013f'),
-    ('\U00010190', '\U0001019b'),
-    ('\U000101d0', '\U000101fc'),
-    ('\U0001d000', '\U0001d0f5'),
-    ('\U0001d100', '\U0001d126'),
-    ('\U0001d129', '\U0001d166'),
-    ('\U0001d16a', '\U0001d17a'),
-    ('\U0001d183', '\U0001d184'),
-    ('\U0001d18c', '\U0001d1a9'),
-    ('\U0001d1ae', '\U0001d1dd'),
-    ('\U0001d300', '\U0001d356'),
-    ('\U0001d360', '\U0001d371'),
-    ('\U0001d400', '\U0001d454'),
-    ('\U0001d456', '\U0001d49c'),
-    ('\U0001d49e', '\U0001d49f'),
-    ('\U0001d4a2', '\U0001d4a2'),
-    ('\U0001d4a5', '\U0001d4a6'),
-    ('\U0001d4a9', '\U0001d4ac'),
-    ('\U0001d4ae', '\U0001d4b9'),
-    ('\U0001d4bb', '\U0001d4bb'),
-    ('\U0001d4bd', '\U0001d4c3'),
-    ('\U0001d4c5', '\U0001d505'),
-    ('\U0001d507', '\U0001d50a'),
-    ('\U0001d50d', '\U0001d514'),
-    ('\U0001d516', '\U0001d51c'),
-    ('\U0001d51e', '\U0001d539'),
-    ('\U0001d53b', '\U0001d53e'),
-    ('\U0001d540', '\U0001d544'),
-    ('\U0001d546', '\U0001d546'),
-    ('\U0001d54a', '\U0001d550'),
-    ('\U0001d552', '\U0001d6a5'),
-    ('\U0001d6a8', '\U0001d7cb'),
-    ('\U0001d7ce', '\U0001d7ff'),
-    ('\U0001f000', '\U0001f02b'),
-    ('\U0001f030', '\U0001f093'),
-    ('\U0001f0a0', '\U0001f0ae'),
-    ('\U0001f0b1', '\U0001f0be'),
-    ('\U0001f0c1', '\U0001f0cf'),
-    ('\U0001f0d1', '\U0001f0df'),
-    ('\U0001f100', '\U0001f10a'),
-    ('\U0001f110', '\U0001f12e'),
-    ('\U0001f130', '\U0001f16b'),
-    ('\U0001f170', '\U0001f19a'),
-    ('\U0001f1e6', '\U0001f1ff'),
-    ('\U0001f201', '\U0001f202'),
-    ('\U0001f210', '\U0001f23a'),
-    ('\U0001f240', '\U0001f248'),
-    ('\U0001f250', '\U0001f251'),
-    ('\U0001f300', '\U0001f320'),
-    ('\U0001f330', '\U0001f335'),
-    ('\U0001f337', '\U0001f37c'),
-    ('\U0001f380', '\U0001f393'),
-    ('\U0001f3a0', '\U0001f3c4'),
-    ('\U0001f3c6', '\U0001f3ca'),
-    ('\U0001f3e0', '\U0001f3f0'),
-    ('\U0001f400', '\U0001f43e'),
-    ('\U0001f440', '\U0001f440'),
-    ('\U0001f442', '\U0001f4f7'),
-    ('\U0001f4f9', '\U0001f4fc'),
-    ('\U0001f500', '\U0001f53d'),
-    ('\U0001f540', '\U0001f543'),
-    ('\U0001f550', '\U0001f567'),
-    ('\U0001f5fb', '\U0001f640'),
-    ('\U0001f645', '\U0001f64f'),
-    ('\U0001f680', '\U0001f6c5'),
-    ('\U0001f700', '\U0001f773'),
-    ('\U000e0001', '\U000e0001'),
-    ('\U000e0020', '\U000e007f')
-    ]),
-("Coptic", &[
-    ('\U000003e2', '\U000003ef'),
-    ('\U00002c80', '\U00002cf3'),
-    ('\U00002cf9', '\U00002cff')
-    ]),
-("Cuneiform", &[
-    ('\U00012000', '\U0001236e'),
-    ('\U00012400', '\U00012462'),
-    ('\U00012470', '\U00012473')
-    ]),
-("Cypriot", &[
-    ('\U00010800', '\U00010805'),
-    ('\U00010808', '\U00010808'),
-    ('\U0001080a', '\U00010835'),
-    ('\U00010837', '\U00010838'),
-    ('\U0001083c', '\U0001083c'),
-    ('\U0001083f', '\U0001083f')
-    ]),
-("Cyrillic", &[
-    ('\U00000400', '\U00000484'),
-    ('\U00000487', '\U00000527'),
-    ('\U00001d2b', '\U00001d2b'),
-    ('\U00001d78', '\U00001d78'),
-    ('\U00002de0', '\U00002dff'),
-    ('\U0000a640', '\U0000a697'),
-    ('\U0000a69f', '\U0000a69f')
-    ]),
-("Deseret", &[
-    ('\U00010400', '\U0001044f')
-    ]),
-("Devanagari", &[
-    ('\U00000900', '\U00000950'),
-    ('\U00000953', '\U00000963'),
-    ('\U00000966', '\U00000977'),
-    ('\U00000979', '\U0000097f'),
-    ('\U0000a8e0', '\U0000a8fb')
-    ]),
-("Egyptian_Hieroglyphs", &[
-    ('\U00013000', '\U0001342e')
-    ]),
-("Ethiopic", &[
-    ('\U00001200', '\U00001248'),
-    ('\U0000124a', '\U0000124d'),
-    ('\U00001250', '\U00001256'),
-    ('\U00001258', '\U00001258'),
-    ('\U0000125a', '\U0000125d'),
-    ('\U00001260', '\U00001288'),
-    ('\U0000128a', '\U0000128d'),
-    ('\U00001290', '\U000012b0'),
-    ('\U000012b2', '\U000012b5'),
-    ('\U000012b8', '\U000012be'),
-    ('\U000012c0', '\U000012c0'),
-    ('\U000012c2', '\U000012c5'),
-    ('\U000012c8', '\U000012d6'),
-    ('\U000012d8', '\U00001310'),
-    ('\U00001312', '\U00001315'),
-    ('\U00001318', '\U0000135a'),
-    ('\U0000135d', '\U0000137c'),
-    ('\U00001380', '\U00001399'),
-    ('\U00002d80', '\U00002d96'),
-    ('\U00002da0', '\U00002da6'),
-    ('\U00002da8', '\U00002dae'),
-    ('\U00002db0', '\U00002db6'),
-    ('\U00002db8', '\U00002dbe'),
-    ('\U00002dc0', '\U00002dc6'),
-    ('\U00002dc8', '\U00002dce'),
-    ('\U00002dd0', '\U00002dd6'),
-    ('\U00002dd8', '\U00002dde'),
-    ('\U0000ab01', '\U0000ab06'),
-    ('\U0000ab09', '\U0000ab0e'),
-    ('\U0000ab11', '\U0000ab16'),
-    ('\U0000ab20', '\U0000ab26'),
-    ('\U0000ab28', '\U0000ab2e')
-    ]),
-("Georgian", &[
-    ('\U000010a0', '\U000010c5'),
-    ('\U000010c7', '\U000010c7'),
-    ('\U000010cd', '\U000010cd'),
-    ('\U000010d0', '\U000010fa'),
-    ('\U000010fc', '\U000010ff'),
-    ('\U00002d00', '\U00002d25'),
-    ('\U00002d27', '\U00002d27'),
-    ('\U00002d2d', '\U00002d2d')
-    ]),
-("Glagolitic", &[
-    ('\U00002c00', '\U00002c2e'),
-    ('\U00002c30', '\U00002c5e')
-    ]),
-("Gothic", &[
-    ('\U00010330', '\U0001034a')
-    ]),
-("Greek", &[
-    ('\U00000370', '\U00000373'),
-    ('\U00000375', '\U00000377'),
-    ('\U0000037a', '\U0000037d'),
-    ('\U00000384', '\U00000384'),
-    ('\U00000386', '\U00000386'),
-    ('\U00000388', '\U0000038a'),
-    ('\U0000038c', '\U0000038c'),
-    ('\U0000038e', '\U000003a1'),
-    ('\U000003a3', '\U000003e1'),
-    ('\U000003f0', '\U000003ff'),
-    ('\U00001d26', '\U00001d2a'),
-    ('\U00001d5d', '\U00001d61'),
-    ('\U00001d66', '\U00001d6a'),
-    ('\U00001dbf', '\U00001dbf'),
-    ('\U00001f00', '\U00001f15'),
-    ('\U00001f18', '\U00001f1d'),
-    ('\U00001f20', '\U00001f45'),
-    ('\U00001f48', '\U00001f4d'),
-    ('\U00001f50', '\U00001f57'),
-    ('\U00001f59', '\U00001f59'),
-    ('\U00001f5b', '\U00001f5b'),
-    ('\U00001f5d', '\U00001f5d'),
-    ('\U00001f5f', '\U00001f7d'),
-    ('\U00001f80', '\U00001fb4'),
-    ('\U00001fb6', '\U00001fc4'),
-    ('\U00001fc6', '\U00001fd3'),
-    ('\U00001fd6', '\U00001fdb'),
-    ('\U00001fdd', '\U00001fef'),
-    ('\U00001ff2', '\U00001ff4'),
-    ('\U00001ff6', '\U00001ffe'),
-    ('\U00002126', '\U00002126'),
-    ('\U00010140', '\U0001018a'),
-    ('\U0001d200', '\U0001d245')
-    ]),
-("Gujarati", &[
-    ('\U00000a81', '\U00000a83'),
-    ('\U00000a85', '\U00000a8d'),
-    ('\U00000a8f', '\U00000a91'),
-    ('\U00000a93', '\U00000aa8'),
-    ('\U00000aaa', '\U00000ab0'),
-    ('\U00000ab2', '\U00000ab3'),
-    ('\U00000ab5', '\U00000ab9'),
-    ('\U00000abc', '\U00000ac5'),
-    ('\U00000ac7', '\U00000ac9'),
-    ('\U00000acb', '\U00000acd'),
-    ('\U00000ad0', '\U00000ad0'),
-    ('\U00000ae0', '\U00000ae3'),
-    ('\U00000ae6', '\U00000af1')
-    ]),
-("Gurmukhi", &[
-    ('\U00000a01', '\U00000a03'),
-    ('\U00000a05', '\U00000a0a'),
-    ('\U00000a0f', '\U00000a10'),
-    ('\U00000a13', '\U00000a28'),
-    ('\U00000a2a', '\U00000a30'),
-    ('\U00000a32', '\U00000a33'),
-    ('\U00000a35', '\U00000a36'),
-    ('\U00000a38', '\U00000a39'),
-    ('\U00000a3c', '\U00000a3c'),
-    ('\U00000a3e', '\U00000a42'),
-    ('\U00000a47', '\U00000a48'),
-    ('\U00000a4b', '\U00000a4d'),
-    ('\U00000a51', '\U00000a51'),
-    ('\U00000a59', '\U00000a5c'),
-    ('\U00000a5e', '\U00000a5e'),
-    ('\U00000a66', '\U00000a75')
-    ]),
-("Han", &[
-    ('\U00002e80', '\U00002e99'),
-    ('\U00002e9b', '\U00002ef3'),
-    ('\U00002f00', '\U00002fd5'),
-    ('\U00003005', '\U00003005'),
-    ('\U00003007', '\U00003007'),
-    ('\U00003021', '\U00003029'),
-    ('\U00003038', '\U0000303b'),
-    ('\U00003400', '\U00004db5'),
-    ('\U00004e00', '\U00009fcc'),
-    ('\U0000f900', '\U0000fa6d'),
-    ('\U0000fa70', '\U0000fad9'),
-    ('\U00020000', '\U0002a6d6'),
-    ('\U0002a700', '\U0002b734'),
-    ('\U0002b740', '\U0002b81d'),
-    ('\U0002f800', '\U0002fa1d')
-    ]),
-("Hangul", &[
-    ('\U00001100', '\U000011ff'),
-    ('\U0000302e', '\U0000302f'),
-    ('\U00003131', '\U0000318e'),
-    ('\U00003200', '\U0000321e'),
-    ('\U00003260', '\U0000327e'),
-    ('\U0000a960', '\U0000a97c'),
-    ('\U0000ac00', '\U0000d7a3'),
-    ('\U0000d7b0', '\U0000d7c6'),
-    ('\U0000d7cb', '\U0000d7fb'),
-    ('\U0000ffa0', '\U0000ffbe'),
-    ('\U0000ffc2', '\U0000ffc7'),
-    ('\U0000ffca', '\U0000ffcf'),
-    ('\U0000ffd2', '\U0000ffd7'),
-    ('\U0000ffda', '\U0000ffdc')
-    ]),
-("Hanunoo", &[
-    ('\U00001720', '\U00001734')
-    ]),
-("Hebrew", &[
-    ('\U00000591', '\U000005c7'),
-    ('\U000005d0', '\U000005ea'),
-    ('\U000005f0', '\U000005f4'),
-    ('\U0000fb1d', '\U0000fb36'),
-    ('\U0000fb38', '\U0000fb3c'),
-    ('\U0000fb3e', '\U0000fb3e'),
-    ('\U0000fb40', '\U0000fb41'),
-    ('\U0000fb43', '\U0000fb44'),
-    ('\U0000fb46', '\U0000fb4f')
-    ]),
-("Hiragana", &[
-    ('\U00003041', '\U00003096'),
-    ('\U0000309d', '\U0000309f'),
-    ('\U0001b001', '\U0001b001'),
-    ('\U0001f200', '\U0001f200')
-    ]),
-("Imperial_Aramaic", &[
-    ('\U00010840', '\U00010855'),
-    ('\U00010857', '\U0001085f')
-    ]),
-("Inherited", &[
-    ('\U00000300', '\U0000036f'),
-    ('\U00000485', '\U00000486'),
-    ('\U0000064b', '\U00000655'),
-    ('\U00000670', '\U00000670'),
-    ('\U00000951', '\U00000952'),
-    ('\U00001cd0', '\U00001cd2'),
-    ('\U00001cd4', '\U00001ce0'),
-    ('\U00001ce2', '\U00001ce8'),
-    ('\U00001ced', '\U00001ced'),
-    ('\U00001cf4', '\U00001cf4'),
-    ('\U00001dc0', '\U00001de6'),
-    ('\U00001dfc', '\U00001dff'),
-    ('\U0000200c', '\U0000200d'),
-    ('\U000020d0', '\U000020f0'),
-    ('\U0000302a', '\U0000302d'),
-    ('\U00003099', '\U0000309a'),
-    ('\U0000fe00', '\U0000fe0f'),
-    ('\U0000fe20', '\U0000fe26'),
-    ('\U000101fd', '\U000101fd'),
-    ('\U0001d167', '\U0001d169'),
-    ('\U0001d17b', '\U0001d182'),
-    ('\U0001d185', '\U0001d18b'),
-    ('\U0001d1aa', '\U0001d1ad'),
-    ('\U000e0100', '\U000e01ef')
-    ]),
-("Inscriptional_Pahlavi", &[
-    ('\U00010b60', '\U00010b72'),
-    ('\U00010b78', '\U00010b7f')
-    ]),
-("Inscriptional_Parthian", &[
-    ('\U00010b40', '\U00010b55'),
-    ('\U00010b58', '\U00010b5f')
-    ]),
-("Javanese", &[
-    ('\U0000a980', '\U0000a9cd'),
-    ('\U0000a9d0', '\U0000a9d9'),
-    ('\U0000a9de', '\U0000a9df')
-    ]),
-("Kaithi", &[
-    ('\U00011080', '\U000110c1')
-    ]),
-("Kannada", &[
-    ('\U00000c82', '\U00000c83'),
-    ('\U00000c85', '\U00000c8c'),
-    ('\U00000c8e', '\U00000c90'),
-    ('\U00000c92', '\U00000ca8'),
-    ('\U00000caa', '\U00000cb3'),
-    ('\U00000cb5', '\U00000cb9'),
-    ('\U00000cbc', '\U00000cc4'),
-    ('\U00000cc6', '\U00000cc8'),
-    ('\U00000cca', '\U00000ccd'),
-    ('\U00000cd5', '\U00000cd6'),
-    ('\U00000cde', '\U00000cde'),
-    ('\U00000ce0', '\U00000ce3'),
-    ('\U00000ce6', '\U00000cef'),
-    ('\U00000cf1', '\U00000cf2')
-    ]),
-("Katakana", &[
-    ('\U000030a1', '\U000030fa'),
-    ('\U000030fd', '\U000030ff'),
-    ('\U000031f0', '\U000031ff'),
-    ('\U000032d0', '\U000032fe'),
-    ('\U00003300', '\U00003357'),
-    ('\U0000ff66', '\U0000ff6f'),
-    ('\U0000ff71', '\U0000ff9d'),
-    ('\U0001b000', '\U0001b000')
-    ]),
-("Kayah_Li", &[
-    ('\U0000a900', '\U0000a92f')
-    ]),
-("Kharoshthi", &[
-    ('\U00010a00', '\U00010a03'),
-    ('\U00010a05', '\U00010a06'),
-    ('\U00010a0c', '\U00010a13'),
-    ('\U00010a15', '\U00010a17'),
-    ('\U00010a19', '\U00010a33'),
-    ('\U00010a38', '\U00010a3a'),
-    ('\U00010a3f', '\U00010a47'),
-    ('\U00010a50', '\U00010a58')
-    ]),
-("Khmer", &[
-    ('\U00001780', '\U000017dd'),
-    ('\U000017e0', '\U000017e9'),
-    ('\U000017f0', '\U000017f9'),
-    ('\U000019e0', '\U000019ff')
-    ]),
-("L", &[
-    ('\U00000041', '\U0000005a'),
-    ('\U00000061', '\U0000007a'),
-    ('\U000000aa', '\U000000aa'),
-    ('\U000000b5', '\U000000b5'),
-    ('\U000000ba', '\U000000ba'),
-    ('\U000000c0', '\U000000d6'),
-    ('\U000000d8', '\U000000f6'),
-    ('\U000000f8', '\U000002c1'),
-    ('\U000002c6', '\U000002d1'),
-    ('\U000002e0', '\U000002e4'),
-    ('\U000002ec', '\U000002ec'),
-    ('\U000002ee', '\U000002ee'),
-    ('\U00000370', '\U00000374'),
-    ('\U00000376', '\U00000377'),
-    ('\U0000037a', '\U0000037d'),
-    ('\U00000386', '\U00000386'),
-    ('\U00000388', '\U0000038a'),
-    ('\U0000038c', '\U0000038c'),
-    ('\U0000038e', '\U000003a1'),
-    ('\U000003a3', '\U000003f5'),
-    ('\U000003f7', '\U00000481'),
-    ('\U0000048a', '\U00000527'),
-    ('\U00000531', '\U00000556'),
-    ('\U00000559', '\U00000559'),
-    ('\U00000561', '\U00000587'),
-    ('\U000005d0', '\U000005ea'),
-    ('\U000005f0', '\U000005f2'),
-    ('\U00000620', '\U0000064a'),
-    ('\U0000066e', '\U0000066f'),
-    ('\U00000671', '\U000006d3'),
-    ('\U000006d5', '\U000006d5'),
-    ('\U000006e5', '\U000006e6'),
-    ('\U000006ee', '\U000006ef'),
-    ('\U000006fa', '\U000006fc'),
-    ('\U000006ff', '\U000006ff'),
-    ('\U00000710', '\U00000710'),
-    ('\U00000712', '\U0000072f'),
-    ('\U0000074d', '\U000007a5'),
-    ('\U000007b1', '\U000007b1'),
-    ('\U000007ca', '\U000007ea'),
-    ('\U000007f4', '\U000007f5'),
-    ('\U000007fa', '\U000007fa'),
-    ('\U00000800', '\U00000815'),
-    ('\U0000081a', '\U0000081a'),
-    ('\U00000824', '\U00000824'),
-    ('\U00000828', '\U00000828'),
-    ('\U00000840', '\U00000858'),
-    ('\U000008a0', '\U000008a0'),
-    ('\U000008a2', '\U000008ac'),
-    ('\U00000904', '\U00000939'),
-    ('\U0000093d', '\U0000093d'),
-    ('\U00000950', '\U00000950'),
-    ('\U00000958', '\U00000961'),
-    ('\U00000971', '\U00000977'),
-    ('\U00000979', '\U0000097f'),
-    ('\U00000985', '\U0000098c'),
-    ('\U0000098f', '\U00000990'),
-    ('\U00000993', '\U000009a8'),
-    ('\U000009aa', '\U000009b0'),
-    ('\U000009b2', '\U000009b2'),
-    ('\U000009b6', '\U000009b9'),
-    ('\U000009bd', '\U000009bd'),
-    ('\U000009ce', '\U000009ce'),
-    ('\U000009dc', '\U000009dd'),
-    ('\U000009df', '\U000009e1'),
-    ('\U000009f0', '\U000009f1'),
-    ('\U00000a05', '\U00000a0a'),
-    ('\U00000a0f', '\U00000a10'),
-    ('\U00000a13', '\U00000a28'),
-    ('\U00000a2a', '\U00000a30'),
-    ('\U00000a32', '\U00000a33'),
-    ('\U00000a35', '\U00000a36'),
-    ('\U00000a38', '\U00000a39'),
-    ('\U00000a59', '\U00000a5c'),
-    ('\U00000a5e', '\U00000a5e'),
-    ('\U00000a72', '\U00000a74'),
-    ('\U00000a85', '\U00000a8d'),
-    ('\U00000a8f', '\U00000a91'),
-    ('\U00000a93', '\U00000aa8'),
-    ('\U00000aaa', '\U00000ab0'),
-    ('\U00000ab2', '\U00000ab3'),
-    ('\U00000ab5', '\U00000ab9'),
-    ('\U00000abd', '\U00000abd'),
-    ('\U00000ad0', '\U00000ad0'),
-    ('\U00000ae0', '\U00000ae1'),
-    ('\U00000b05', '\U00000b0c'),
-    ('\U00000b0f', '\U00000b10'),
-    ('\U00000b13', '\U00000b28'),
-    ('\U00000b2a', '\U00000b30'),
-    ('\U00000b32', '\U00000b33'),
-    ('\U00000b35', '\U00000b39'),
-    ('\U00000b3d', '\U00000b3d'),
-    ('\U00000b5c', '\U00000b5d'),
-    ('\U00000b5f', '\U00000b61'),
-    ('\U00000b71', '\U00000b71'),
-    ('\U00000b83', '\U00000b83'),
-    ('\U00000b85', '\U00000b8a'),
-    ('\U00000b8e', '\U00000b90'),
-    ('\U00000b92', '\U00000b95'),
-    ('\U00000b99', '\U00000b9a'),
-    ('\U00000b9c', '\U00000b9c'),
-    ('\U00000b9e', '\U00000b9f'),
-    ('\U00000ba3', '\U00000ba4'),
-    ('\U00000ba8', '\U00000baa'),
-    ('\U00000bae', '\U00000bb9'),
-    ('\U00000bd0', '\U00000bd0'),
-    ('\U00000c05', '\U00000c0c'),
-    ('\U00000c0e', '\U00000c10'),
-    ('\U00000c12', '\U00000c28'),
-    ('\U00000c2a', '\U00000c33'),
-    ('\U00000c35', '\U00000c39'),
-    ('\U00000c3d', '\U00000c3d'),
-    ('\U00000c58', '\U00000c59'),
-    ('\U00000c60', '\U00000c61'),
-    ('\U00000c85', '\U00000c8c'),
-    ('\U00000c8e', '\U00000c90'),
-    ('\U00000c92', '\U00000ca8'),
-    ('\U00000caa', '\U00000cb3'),
-    ('\U00000cb5', '\U00000cb9'),
-    ('\U00000cbd', '\U00000cbd'),
-    ('\U00000cde', '\U00000cde'),
-    ('\U00000ce0', '\U00000ce1'),
-    ('\U00000cf1', '\U00000cf2'),
-    ('\U00000d05', '\U00000d0c'),
-    ('\U00000d0e', '\U00000d10'),
-    ('\U00000d12', '\U00000d3a'),
-    ('\U00000d3d', '\U00000d3d'),
-    ('\U00000d4e', '\U00000d4e'),
-    ('\U00000d60', '\U00000d61'),
-    ('\U00000d7a', '\U00000d7f'),
-    ('\U00000d85', '\U00000d96'),
-    ('\U00000d9a', '\U00000db1'),
-    ('\U00000db3', '\U00000dbb'),
-    ('\U00000dbd', '\U00000dbd'),
-    ('\U00000dc0', '\U00000dc6'),
-    ('\U00000e01', '\U00000e30'),
-    ('\U00000e32', '\U00000e33'),
-    ('\U00000e40', '\U00000e46'),
-    ('\U00000e81', '\U00000e82'),
-    ('\U00000e84', '\U00000e84'),
-    ('\U00000e87', '\U00000e88'),
-    ('\U00000e8a', '\U00000e8a'),
-    ('\U00000e8d', '\U00000e8d'),
-    ('\U00000e94', '\U00000e97'),
-    ('\U00000e99', '\U00000e9f'),
-    ('\U00000ea1', '\U00000ea3'),
-    ('\U00000ea5', '\U00000ea5'),
-    ('\U00000ea7', '\U00000ea7'),
-    ('\U00000eaa', '\U00000eab'),
-    ('\U00000ead', '\U00000eb0'),
-    ('\U00000eb2', '\U00000eb3'),
-    ('\U00000ebd', '\U00000ebd'),
-    ('\U00000ec0', '\U00000ec4'),
-    ('\U00000ec6', '\U00000ec6'),
-    ('\U00000edc', '\U00000edf'),
-    ('\U00000f00', '\U00000f00'),
-    ('\U00000f40', '\U00000f47'),
-    ('\U00000f49', '\U00000f6c'),
-    ('\U00000f88', '\U00000f8c'),
-    ('\U00001000', '\U0000102a'),
-    ('\U0000103f', '\U0000103f'),
-    ('\U00001050', '\U00001055'),
-    ('\U0000105a', '\U0000105d'),
-    ('\U00001061', '\U00001061'),
-    ('\U00001065', '\U00001066'),
-    ('\U0000106e', '\U00001070'),
-    ('\U00001075', '\U00001081'),
-    ('\U0000108e', '\U0000108e'),
-    ('\U000010a0', '\U000010c5'),
-    ('\U000010c7', '\U000010c7'),
-    ('\U000010cd', '\U000010cd'),
-    ('\U000010d0', '\U000010fa'),
-    ('\U000010fc', '\U00001248'),
-    ('\U0000124a', '\U0000124d'),
-    ('\U00001250', '\U00001256'),
-    ('\U00001258', '\U00001258'),
-    ('\U0000125a', '\U0000125d'),
-    ('\U00001260', '\U00001288'),
-    ('\U0000128a', '\U0000128d'),
-    ('\U00001290', '\U000012b0'),
-    ('\U000012b2', '\U000012b5'),
-    ('\U000012b8', '\U000012be'),
-    ('\U000012c0', '\U000012c0'),
-    ('\U000012c2', '\U000012c5'),
-    ('\U000012c8', '\U000012d6'),
-    ('\U000012d8', '\U00001310'),
-    ('\U00001312', '\U00001315'),
-    ('\U00001318', '\U0000135a'),
-    ('\U00001380', '\U0000138f'),
-    ('\U000013a0', '\U000013f4'),
-    ('\U00001401', '\U0000166c'),
-    ('\U0000166f', '\U0000167f'),
-    ('\U00001681', '\U0000169a'),
-    ('\U000016a0', '\U000016ea'),
-    ('\U00001700', '\U0000170c'),
-    ('\U0000170e', '\U00001711'),
-    ('\U00001720', '\U00001731'),
-    ('\U00001740', '\U00001751'),
-    ('\U00001760', '\U0000176c'),
-    ('\U0000176e', '\U00001770'),
-    ('\U00001780', '\U000017b3'),
-    ('\U000017d7', '\U000017d7'),
-    ('\U000017dc', '\U000017dc'),
-    ('\U00001820', '\U00001877'),
-    ('\U00001880', '\U000018a8'),
-    ('\U000018aa', '\U000018aa'),
-    ('\U000018b0', '\U000018f5'),
-    ('\U00001900', '\U0000191c'),
-    ('\U00001950', '\U0000196d'),
-    ('\U00001970', '\U00001974'),
-    ('\U00001980', '\U000019ab'),
-    ('\U000019c1', '\U000019c7'),
-    ('\U00001a00', '\U00001a16'),
-    ('\U00001a20', '\U00001a54'),
-    ('\U00001aa7', '\U00001aa7'),
-    ('\U00001b05', '\U00001b33'),
-    ('\U00001b45', '\U00001b4b'),
-    ('\U00001b83', '\U00001ba0'),
-    ('\U00001bae', '\U00001baf'),
-    ('\U00001bba', '\U00001be5'),
-    ('\U00001c00', '\U00001c23'),
-    ('\U00001c4d', '\U00001c4f'),
-    ('\U00001c5a', '\U00001c7d'),
-    ('\U00001ce9', '\U00001cec'),
-    ('\U00001cee', '\U00001cf1'),
-    ('\U00001cf5', '\U00001cf6'),
-    ('\U00001d00', '\U00001dbf'),
-    ('\U00001e00', '\U00001f15'),
-    ('\U00001f18', '\U00001f1d'),
-    ('\U00001f20', '\U00001f45'),
-    ('\U00001f48', '\U00001f4d'),
-    ('\U00001f50', '\U00001f57'),
-    ('\U00001f59', '\U00001f59'),
-    ('\U00001f5b', '\U00001f5b'),
-    ('\U00001f5d', '\U00001f5d'),
-    ('\U00001f5f', '\U00001f7d'),
-    ('\U00001f80', '\U00001fb4'),
-    ('\U00001fb6', '\U00001fbc'),
-    ('\U00001fbe', '\U00001fbe'),
-    ('\U00001fc2', '\U00001fc4'),
-    ('\U00001fc6', '\U00001fcc'),
-    ('\U00001fd0', '\U00001fd3'),
-    ('\U00001fd6', '\U00001fdb'),
-    ('\U00001fe0', '\U00001fec'),
-    ('\U00001ff2', '\U00001ff4'),
-    ('\U00001ff6', '\U00001ffc'),
-    ('\U00002071', '\U00002071'),
-    ('\U0000207f', '\U0000207f'),
-    ('\U00002090', '\U0000209c'),
-    ('\U00002102', '\U00002102'),
-    ('\U00002107', '\U00002107'),
-    ('\U0000210a', '\U00002113'),
-    ('\U00002115', '\U00002115'),
-    ('\U00002119', '\U0000211d'),
-    ('\U00002124', '\U00002124'),
-    ('\U00002126', '\U00002126'),
-    ('\U00002128', '\U00002128'),
-    ('\U0000212a', '\U0000212d'),
-    ('\U0000212f', '\U00002139'),
-    ('\U0000213c', '\U0000213f'),
-    ('\U00002145', '\U00002149'),
-    ('\U0000214e', '\U0000214e'),
-    ('\U00002183', '\U00002184'),
-    ('\U00002c00', '\U00002c2e'),
-    ('\U00002c30', '\U00002c5e'),
-    ('\U00002c60', '\U00002ce4'),
-    ('\U00002ceb', '\U00002cee'),
-    ('\U00002cf2', '\U00002cf3'),
-    ('\U00002d00', '\U00002d25'),
-    ('\U00002d27', '\U00002d27'),
-    ('\U00002d2d', '\U00002d2d'),
-    ('\U00002d30', '\U00002d67'),
-    ('\U00002d6f', '\U00002d6f'),
-    ('\U00002d80', '\U00002d96'),
-    ('\U00002da0', '\U00002da6'),
-    ('\U00002da8', '\U00002dae'),
-    ('\U00002db0', '\U00002db6'),
-    ('\U00002db8', '\U00002dbe'),
-    ('\U00002dc0', '\U00002dc6'),
-    ('\U00002dc8', '\U00002dce'),
-    ('\U00002dd0', '\U00002dd6'),
-    ('\U00002dd8', '\U00002dde'),
-    ('\U00002e2f', '\U00002e2f'),
-    ('\U00003005', '\U00003006'),
-    ('\U00003031', '\U00003035'),
-    ('\U0000303b', '\U0000303c'),
-    ('\U00003041', '\U00003096'),
-    ('\U0000309d', '\U0000309f'),
-    ('\U000030a1', '\U000030fa'),
-    ('\U000030fc', '\U000030ff'),
-    ('\U00003105', '\U0000312d'),
-    ('\U00003131', '\U0000318e'),
-    ('\U000031a0', '\U000031ba'),
-    ('\U000031f0', '\U000031ff'),
-    ('\U00003400', '\U00003400'),
-    ('\U00004db5', '\U00004db5'),
-    ('\U00004e00', '\U00004e00'),
-    ('\U00009fcc', '\U00009fcc'),
-    ('\U0000a000', '\U0000a48c'),
-    ('\U0000a4d0', '\U0000a4fd'),
-    ('\U0000a500', '\U0000a60c'),
-    ('\U0000a610', '\U0000a61f'),
-    ('\U0000a62a', '\U0000a62b'),
-    ('\U0000a640', '\U0000a66e'),
-    ('\U0000a67f', '\U0000a697'),
-    ('\U0000a6a0', '\U0000a6e5'),
-    ('\U0000a717', '\U0000a71f'),
-    ('\U0000a722', '\U0000a788'),
-    ('\U0000a78b', '\U0000a78e'),
-    ('\U0000a790', '\U0000a793'),
-    ('\U0000a7a0', '\U0000a7aa'),
-    ('\U0000a7f8', '\U0000a801'),
-    ('\U0000a803', '\U0000a805'),
-    ('\U0000a807', '\U0000a80a'),
-    ('\U0000a80c', '\U0000a822'),
-    ('\U0000a840', '\U0000a873'),
-    ('\U0000a882', '\U0000a8b3'),
-    ('\U0000a8f2', '\U0000a8f7'),
-    ('\U0000a8fb', '\U0000a8fb'),
-    ('\U0000a90a', '\U0000a925'),
-    ('\U0000a930', '\U0000a946'),
-    ('\U0000a960', '\U0000a97c'),
-    ('\U0000a984', '\U0000a9b2'),
-    ('\U0000a9cf', '\U0000a9cf'),
-    ('\U0000aa00', '\U0000aa28'),
-    ('\U0000aa40', '\U0000aa42'),
-    ('\U0000aa44', '\U0000aa4b'),
-    ('\U0000aa60', '\U0000aa76'),
-    ('\U0000aa7a', '\U0000aa7a'),
-    ('\U0000aa80', '\U0000aaaf'),
-    ('\U0000aab1', '\U0000aab1'),
-    ('\U0000aab5', '\U0000aab6'),
-    ('\U0000aab9', '\U0000aabd'),
-    ('\U0000aac0', '\U0000aac0'),
-    ('\U0000aac2', '\U0000aac2'),
-    ('\U0000aadb', '\U0000aadd'),
-    ('\U0000aae0', '\U0000aaea'),
-    ('\U0000aaf2', '\U0000aaf4'),
-    ('\U0000ab01', '\U0000ab06'),
-    ('\U0000ab09', '\U0000ab0e'),
-    ('\U0000ab11', '\U0000ab16'),
-    ('\U0000ab20', '\U0000ab26'),
-    ('\U0000ab28', '\U0000ab2e'),
-    ('\U0000abc0', '\U0000abe2'),
-    ('\U0000ac00', '\U0000ac00'),
-    ('\U0000d7a3', '\U0000d7a3'),
-    ('\U0000d7b0', '\U0000d7c6'),
-    ('\U0000d7cb', '\U0000d7fb'),
-    ('\U0000f900', '\U0000fa6d'),
-    ('\U0000fa70', '\U0000fad9'),
-    ('\U0000fb00', '\U0000fb06'),
-    ('\U0000fb13', '\U0000fb17'),
-    ('\U0000fb1d', '\U0000fb1d'),
-    ('\U0000fb1f', '\U0000fb28'),
-    ('\U0000fb2a', '\U0000fb36'),
-    ('\U0000fb38', '\U0000fb3c'),
-    ('\U0000fb3e', '\U0000fb3e'),
-    ('\U0000fb40', '\U0000fb41'),
-    ('\U0000fb43', '\U0000fb44'),
-    ('\U0000fb46', '\U0000fbb1'),
-    ('\U0000fbd3', '\U0000fd3d'),
-    ('\U0000fd50', '\U0000fd8f'),
-    ('\U0000fd92', '\U0000fdc7'),
-    ('\U0000fdf0', '\U0000fdfb'),
-    ('\U0000fe70', '\U0000fe74'),
-    ('\U0000fe76', '\U0000fefc'),
-    ('\U0000ff21', '\U0000ff3a'),
-    ('\U0000ff41', '\U0000ff5a'),
-    ('\U0000ff66', '\U0000ffbe'),
-    ('\U0000ffc2', '\U0000ffc7'),
-    ('\U0000ffca', '\U0000ffcf'),
-    ('\U0000ffd2', '\U0000ffd7'),
-    ('\U0000ffda', '\U0000ffdc'),
-    ('\U00010000', '\U0001000b'),
-    ('\U0001000d', '\U00010026'),
-    ('\U00010028', '\U0001003a'),
-    ('\U0001003c', '\U0001003d'),
-    ('\U0001003f', '\U0001004d'),
-    ('\U00010050', '\U0001005d'),
-    ('\U00010080', '\U000100fa'),
-    ('\U00010280', '\U0001029c'),
-    ('\U000102a0', '\U000102d0'),
-    ('\U00010300', '\U0001031e'),
-    ('\U00010330', '\U00010340'),
-    ('\U00010342', '\U00010349'),
-    ('\U00010380', '\U0001039d'),
-    ('\U000103a0', '\U000103c3'),
-    ('\U000103c8', '\U000103cf'),
-    ('\U00010400', '\U0001049d'),
-    ('\U00010800', '\U00010805'),
-    ('\U00010808', '\U00010808'),
-    ('\U0001080a', '\U00010835'),
-    ('\U00010837', '\U00010838'),
-    ('\U0001083c', '\U0001083c'),
-    ('\U0001083f', '\U00010855'),
-    ('\U00010900', '\U00010915'),
-    ('\U00010920', '\U00010939'),
-    ('\U00010980', '\U000109b7'),
-    ('\U000109be', '\U000109bf'),
-    ('\U00010a00', '\U00010a00'),
-    ('\U00010a10', '\U00010a13'),
-    ('\U00010a15', '\U00010a17'),
-    ('\U00010a19', '\U00010a33'),
-    ('\U00010a60', '\U00010a7c'),
-    ('\U00010b00', '\U00010b35'),
-    ('\U00010b40', '\U00010b55'),
-    ('\U00010b60', '\U00010b72'),
-    ('\U00010c00', '\U00010c48'),
-    ('\U00011003', '\U00011037'),
-    ('\U00011083', '\U000110af'),
-    ('\U000110d0', '\U000110e8'),
-    ('\U00011103', '\U00011126'),
-    ('\U00011183', '\U000111b2'),
-    ('\U000111c1', '\U000111c4'),
-    ('\U00011680', '\U000116aa'),
-    ('\U00012000', '\U0001236e'),
-    ('\U00013000', '\U0001342e'),
-    ('\U00016800', '\U00016a38'),
-    ('\U00016f00', '\U00016f44'),
-    ('\U00016f50', '\U00016f50'),
-    ('\U00016f93', '\U00016f9f'),
-    ('\U0001b000', '\U0001b001'),
-    ('\U0001d400', '\U0001d454'),
-    ('\U0001d456', '\U0001d49c'),
-    ('\U0001d49e', '\U0001d49f'),
-    ('\U0001d4a2', '\U0001d4a2'),
-    ('\U0001d4a5', '\U0001d4a6'),
-    ('\U0001d4a9', '\U0001d4ac'),
-    ('\U0001d4ae', '\U0001d4b9'),
-    ('\U0001d4bb', '\U0001d4bb'),
-    ('\U0001d4bd', '\U0001d4c3'),
-    ('\U0001d4c5', '\U0001d505'),
-    ('\U0001d507', '\U0001d50a'),
-    ('\U0001d50d', '\U0001d514'),
-    ('\U0001d516', '\U0001d51c'),
-    ('\U0001d51e', '\U0001d539'),
-    ('\U0001d53b', '\U0001d53e'),
-    ('\U0001d540', '\U0001d544'),
-    ('\U0001d546', '\U0001d546'),
-    ('\U0001d54a', '\U0001d550'),
-    ('\U0001d552', '\U0001d6a5'),
-    ('\U0001d6a8', '\U0001d6c0'),
-    ('\U0001d6c2', '\U0001d6da'),
-    ('\U0001d6dc', '\U0001d6fa'),
-    ('\U0001d6fc', '\U0001d714'),
-    ('\U0001d716', '\U0001d734'),
-    ('\U0001d736', '\U0001d74e'),
-    ('\U0001d750', '\U0001d76e'),
-    ('\U0001d770', '\U0001d788'),
-    ('\U0001d78a', '\U0001d7a8'),
-    ('\U0001d7aa', '\U0001d7c2'),
-    ('\U0001d7c4', '\U0001d7cb'),
-    ('\U0001ee00', '\U0001ee03'),
-    ('\U0001ee05', '\U0001ee1f'),
-    ('\U0001ee21', '\U0001ee22'),
-    ('\U0001ee24', '\U0001ee24'),
-    ('\U0001ee27', '\U0001ee27'),
-    ('\U0001ee29', '\U0001ee32'),
-    ('\U0001ee34', '\U0001ee37'),
-    ('\U0001ee39', '\U0001ee39'),
-    ('\U0001ee3b', '\U0001ee3b'),
-    ('\U0001ee42', '\U0001ee42'),
-    ('\U0001ee47', '\U0001ee47'),
-    ('\U0001ee49', '\U0001ee49'),
-    ('\U0001ee4b', '\U0001ee4b'),
-    ('\U0001ee4d', '\U0001ee4f'),
-    ('\U0001ee51', '\U0001ee52'),
-    ('\U0001ee54', '\U0001ee54'),
-    ('\U0001ee57', '\U0001ee57'),
-    ('\U0001ee59', '\U0001ee59'),
-    ('\U0001ee5b', '\U0001ee5b'),
-    ('\U0001ee5d', '\U0001ee5d'),
-    ('\U0001ee5f', '\U0001ee5f'),
-    ('\U0001ee61', '\U0001ee62'),
-    ('\U0001ee64', '\U0001ee64'),
-    ('\U0001ee67', '\U0001ee6a'),
-    ('\U0001ee6c', '\U0001ee72'),
-    ('\U0001ee74', '\U0001ee77'),
-    ('\U0001ee79', '\U0001ee7c'),
-    ('\U0001ee7e', '\U0001ee7e'),
-    ('\U0001ee80', '\U0001ee89'),
-    ('\U0001ee8b', '\U0001ee9b'),
-    ('\U0001eea1', '\U0001eea3'),
-    ('\U0001eea5', '\U0001eea9'),
-    ('\U0001eeab', '\U0001eebb'),
-    ('\U00020000', '\U00020000'),
-    ('\U0002a6d6', '\U0002a6d6'),
-    ('\U0002a700', '\U0002a700'),
-    ('\U0002b734', '\U0002b734'),
-    ('\U0002b740', '\U0002b740'),
-    ('\U0002b81d', '\U0002b81d'),
-    ('\U0002f800', '\U0002fa1d')
-    ]),
-("LC", &[
-    ('\U00000041', '\U0000005a'),
-    ('\U00000061', '\U0000007a'),
-    ('\U000000b5', '\U000000b5'),
-    ('\U000000c0', '\U000000d6'),
-    ('\U000000d8', '\U000000f6'),
-    ('\U000000f8', '\U000001ba'),
-    ('\U000001bc', '\U000001bf'),
-    ('\U000001c4', '\U00000293'),
-    ('\U00000295', '\U000002af'),
-    ('\U00000370', '\U00000373'),
-    ('\U00000376', '\U00000377'),
-    ('\U0000037b', '\U0000037d'),
-    ('\U00000386', '\U00000386'),
-    ('\U00000388', '\U0000038a'),
-    ('\U0000038c', '\U0000038c'),
-    ('\U0000038e', '\U000003a1'),
-    ('\U000003a3', '\U000003f5'),
-    ('\U000003f7', '\U00000481'),
-    ('\U0000048a', '\U00000527'),
-    ('\U00000531', '\U00000556'),
-    ('\U00000561', '\U00000587'),
-    ('\U000010a0', '\U000010c5'),
-    ('\U000010c7', '\U000010c7'),
-    ('\U000010cd', '\U000010cd'),
-    ('\U00001d00', '\U00001d2b'),
-    ('\U00001d6b', '\U00001d77'),
-    ('\U00001d79', '\U00001d9a'),
-    ('\U00001e00', '\U00001f15'),
-    ('\U00001f18', '\U00001f1d'),
-    ('\U00001f20', '\U00001f45'),
-    ('\U00001f48', '\U00001f4d'),
-    ('\U00001f50', '\U00001f57'),
-    ('\U00001f59', '\U00001f59'),
-    ('\U00001f5b', '\U00001f5b'),
-    ('\U00001f5d', '\U00001f5d'),
-    ('\U00001f5f', '\U00001f7d'),
-    ('\U00001f80', '\U00001fb4'),
-    ('\U00001fb6', '\U00001fbc'),
-    ('\U00001fbe', '\U00001fbe'),
-    ('\U00001fc2', '\U00001fc4'),
-    ('\U00001fc6', '\U00001fcc'),
-    ('\U00001fd0', '\U00001fd3'),
-    ('\U00001fd6', '\U00001fdb'),
-    ('\U00001fe0', '\U00001fec'),
-    ('\U00001ff2', '\U00001ff4'),
-    ('\U00001ff6', '\U00001ffc'),
-    ('\U00002102', '\U00002102'),
-    ('\U00002107', '\U00002107'),
-    ('\U0000210a', '\U00002113'),
-    ('\U00002115', '\U00002115'),
-    ('\U00002119', '\U0000211d'),
-    ('\U00002124', '\U00002124'),
-    ('\U00002126', '\U00002126'),
-    ('\U00002128', '\U00002128'),
-    ('\U0000212a', '\U0000212d'),
-    ('\U0000212f', '\U00002134'),
-    ('\U00002139', '\U00002139'),
-    ('\U0000213c', '\U0000213f'),
-    ('\U00002145', '\U00002149'),
-    ('\U0000214e', '\U0000214e'),
-    ('\U00002183', '\U00002184'),
-    ('\U00002c00', '\U00002c2e'),
-    ('\U00002c30', '\U00002c5e'),
-    ('\U00002c60', '\U00002c7b'),
-    ('\U00002c7e', '\U00002ce4'),
-    ('\U00002ceb', '\U00002cee'),
-    ('\U00002cf2', '\U00002cf3'),
-    ('\U00002d00', '\U00002d25'),
-    ('\U00002d27', '\U00002d27'),
-    ('\U00002d2d', '\U00002d2d'),
-    ('\U0000a640', '\U0000a66d'),
-    ('\U0000a680', '\U0000a697'),
-    ('\U0000a722', '\U0000a76f'),
-    ('\U0000a771', '\U0000a787'),
-    ('\U0000a78b', '\U0000a78e'),
-    ('\U0000a790', '\U0000a793'),
-    ('\U0000a7a0', '\U0000a7aa'),
-    ('\U0000a7fa', '\U0000a7fa'),
-    ('\U0000fb00', '\U0000fb06'),
-    ('\U0000fb13', '\U0000fb17'),
-    ('\U0000ff21', '\U0000ff3a'),
-    ('\U0000ff41', '\U0000ff5a'),
-    ('\U00010400', '\U0001044f'),
-    ('\U0001d400', '\U0001d454'),
-    ('\U0001d456', '\U0001d49c'),
-    ('\U0001d49e', '\U0001d49f'),
-    ('\U0001d4a2', '\U0001d4a2'),
-    ('\U0001d4a5', '\U0001d4a6'),
-    ('\U0001d4a9', '\U0001d4ac'),
-    ('\U0001d4ae', '\U0001d4b9'),
-    ('\U0001d4bb', '\U0001d4bb'),
-    ('\U0001d4bd', '\U0001d4c3'),
-    ('\U0001d4c5', '\U0001d505'),
-    ('\U0001d507', '\U0001d50a'),
-    ('\U0001d50d', '\U0001d514'),
-    ('\U0001d516', '\U0001d51c'),
-    ('\U0001d51e', '\U0001d539'),
-    ('\U0001d53b', '\U0001d53e'),
-    ('\U0001d540', '\U0001d544'),
-    ('\U0001d546', '\U0001d546'),
-    ('\U0001d54a', '\U0001d550'),
-    ('\U0001d552', '\U0001d6a5'),
-    ('\U0001d6a8', '\U0001d6c0'),
-    ('\U0001d6c2', '\U0001d6da'),
-    ('\U0001d6dc', '\U0001d6fa'),
-    ('\U0001d6fc', '\U0001d714'),
-    ('\U0001d716', '\U0001d734'),
-    ('\U0001d736', '\U0001d74e'),
-    ('\U0001d750', '\U0001d76e'),
-    ('\U0001d770', '\U0001d788'),
-    ('\U0001d78a', '\U0001d7a8'),
-    ('\U0001d7aa', '\U0001d7c2'),
-    ('\U0001d7c4', '\U0001d7cb')
-    ]),
-("Lao", &[
-    ('\U00000e81', '\U00000e82'),
-    ('\U00000e84', '\U00000e84'),
-    ('\U00000e87', '\U00000e88'),
-    ('\U00000e8a', '\U00000e8a'),
-    ('\U00000e8d', '\U00000e8d'),
-    ('\U00000e94', '\U00000e97'),
-    ('\U00000e99', '\U00000e9f'),
-    ('\U00000ea1', '\U00000ea3'),
-    ('\U00000ea5', '\U00000ea5'),
-    ('\U00000ea7', '\U00000ea7'),
-    ('\U00000eaa', '\U00000eab'),
-    ('\U00000ead', '\U00000eb9'),
-    ('\U00000ebb', '\U00000ebd'),
-    ('\U00000ec0', '\U00000ec4'),
-    ('\U00000ec6', '\U00000ec6'),
-    ('\U00000ec8', '\U00000ecd'),
-    ('\U00000ed0', '\U00000ed9'),
-    ('\U00000edc', '\U00000edf')
-    ]),
-("Latin", &[
-    ('\U00000041', '\U0000005a'),
-    ('\U00000061', '\U0000007a'),
-    ('\U000000aa', '\U000000aa'),
-    ('\U000000ba', '\U000000ba'),
-    ('\U000000c0', '\U000000d6'),
-    ('\U000000d8', '\U000000f6'),
-    ('\U000000f8', '\U000002b8'),
-    ('\U000002e0', '\U000002e4'),
-    ('\U00001d00', '\U00001d25'),
-    ('\U00001d2c', '\U00001d5c'),
-    ('\U00001d62', '\U00001d65'),
-    ('\U00001d6b', '\U00001d77'),
-    ('\U00001d79', '\U00001dbe'),
-    ('\U00001e00', '\U00001eff'),
-    ('\U00002071', '\U00002071'),
-    ('\U0000207f', '\U0000207f'),
-    ('\U00002090', '\U0000209c'),
-    ('\U0000212a', '\U0000212b'),
-    ('\U00002132', '\U00002132'),
-    ('\U0000214e', '\U0000214e'),
-    ('\U00002160', '\U00002188'),
-    ('\U00002c60', '\U00002c7f'),
-    ('\U0000a722', '\U0000a787'),
-    ('\U0000a78b', '\U0000a78e'),
-    ('\U0000a790', '\U0000a793'),
-    ('\U0000a7a0', '\U0000a7aa'),
-    ('\U0000a7f8', '\U0000a7ff'),
-    ('\U0000fb00', '\U0000fb06'),
-    ('\U0000ff21', '\U0000ff3a'),
-    ('\U0000ff41', '\U0000ff5a')
-    ]),
-("Lepcha", &[
-    ('\U00001c00', '\U00001c37'),
-    ('\U00001c3b', '\U00001c49'),
-    ('\U00001c4d', '\U00001c4f')
-    ]),
-("Limbu", &[
-    ('\U00001900', '\U0000191c'),
-    ('\U00001920', '\U0000192b'),
-    ('\U00001930', '\U0000193b'),
-    ('\U00001940', '\U00001940'),
-    ('\U00001944', '\U0000194f')
-    ]),
-("Linear_B", &[
-    ('\U00010000', '\U0001000b'),
-    ('\U0001000d', '\U00010026'),
-    ('\U00010028', '\U0001003a'),
-    ('\U0001003c', '\U0001003d'),
-    ('\U0001003f', '\U0001004d'),
-    ('\U00010050', '\U0001005d'),
-    ('\U00010080', '\U000100fa')
-    ]),
-("Lisu", &[
-    ('\U0000a4d0', '\U0000a4ff')
-    ]),
-("Ll", &[
-    ('\U00000061', '\U0000007a'),
-    ('\U000000b5', '\U000000b5'),
-    ('\U000000df', '\U000000f6'),
-    ('\U000000f8', '\U000000ff'),
-    ('\U00000101', '\U00000101'),
-    ('\U00000103', '\U00000103'),
-    ('\U00000105', '\U00000105'),
-    ('\U00000107', '\U00000107'),
-    ('\U00000109', '\U00000109'),
-    ('\U0000010b', '\U0000010b'),
-    ('\U0000010d', '\U0000010d'),
-    ('\U0000010f', '\U0000010f'),
-    ('\U00000111', '\U00000111'),
-    ('\U00000113', '\U00000113'),
-    ('\U00000115', '\U00000115'),
-    ('\U00000117', '\U00000117'),
-    ('\U00000119', '\U00000119'),
-    ('\U0000011b', '\U0000011b'),
-    ('\U0000011d', '\U0000011d'),
-    ('\U0000011f', '\U0000011f'),
-    ('\U00000121', '\U00000121'),
-    ('\U00000123', '\U00000123'),
-    ('\U00000125', '\U00000125'),
-    ('\U00000127', '\U00000127'),
-    ('\U00000129', '\U00000129'),
-    ('\U0000012b', '\U0000012b'),
-    ('\U0000012d', '\U0000012d'),
-    ('\U0000012f', '\U0000012f'),
-    ('\U00000131', '\U00000131'),
-    ('\U00000133', '\U00000133'),
-    ('\U00000135', '\U00000135'),
-    ('\U00000137', '\U00000138'),
-    ('\U0000013a', '\U0000013a'),
-    ('\U0000013c', '\U0000013c'),
-    ('\U0000013e', '\U0000013e'),
-    ('\U00000140', '\U00000140'),
-    ('\U00000142', '\U00000142'),
-    ('\U00000144', '\U00000144'),
-    ('\U00000146', '\U00000146'),
-    ('\U00000148', '\U00000149'),
-    ('\U0000014b', '\U0000014b'),
-    ('\U0000014d', '\U0000014d'),
-    ('\U0000014f', '\U0000014f'),
-    ('\U00000151', '\U00000151'),
-    ('\U00000153', '\U00000153'),
-    ('\U00000155', '\U00000155'),
-    ('\U00000157', '\U00000157'),
-    ('\U00000159', '\U00000159'),
-    ('\U0000015b', '\U0000015b'),
-    ('\U0000015d', '\U0000015d'),
-    ('\U0000015f', '\U0000015f'),
-    ('\U00000161', '\U00000161'),
-    ('\U00000163', '\U00000163'),
-    ('\U00000165', '\U00000165'),
-    ('\U00000167', '\U00000167'),
-    ('\U00000169', '\U00000169'),
-    ('\U0000016b', '\U0000016b'),
-    ('\U0000016d', '\U0000016d'),
-    ('\U0000016f', '\U0000016f'),
-    ('\U00000171', '\U00000171'),
-    ('\U00000173', '\U00000173'),
-    ('\U00000175', '\U00000175'),
-    ('\U00000177', '\U00000177'),
-    ('\U0000017a', '\U0000017a'),
-    ('\U0000017c', '\U0000017c'),
-    ('\U0000017e', '\U00000180'),
-    ('\U00000183', '\U00000183'),
-    ('\U00000185', '\U00000185'),
-    ('\U00000188', '\U00000188'),
-    ('\U0000018c', '\U0000018d'),
-    ('\U00000192', '\U00000192'),
-    ('\U00000195', '\U00000195'),
-    ('\U00000199', '\U0000019b'),
-    ('\U0000019e', '\U0000019e'),
-    ('\U000001a1', '\U000001a1'),
-    ('\U000001a3', '\U000001a3'),
-    ('\U000001a5', '\U000001a5'),
-    ('\U000001a8', '\U000001a8'),
-    ('\U000001aa', '\U000001ab'),
-    ('\U000001ad', '\U000001ad'),
-    ('\U000001b0', '\U000001b0'),
-    ('\U000001b4', '\U000001b4'),
-    ('\U000001b6', '\U000001b6'),
-    ('\U000001b9', '\U000001ba'),
-    ('\U000001bd', '\U000001bf'),
-    ('\U000001c6', '\U000001c6'),
-    ('\U000001c9', '\U000001c9'),
-    ('\U000001cc', '\U000001cc'),
-    ('\U000001ce', '\U000001ce'),
-    ('\U000001d0', '\U000001d0'),
-    ('\U000001d2', '\U000001d2'),
-    ('\U000001d4', '\U000001d4'),
-    ('\U000001d6', '\U000001d6'),
-    ('\U000001d8', '\U000001d8'),
-    ('\U000001da', '\U000001da'),
-    ('\U000001dc', '\U000001dd'),
-    ('\U000001df', '\U000001df'),
-    ('\U000001e1', '\U000001e1'),
-    ('\U000001e3', '\U000001e3'),
-    ('\U000001e5', '\U000001e5'),
-    ('\U000001e7', '\U000001e7'),
-    ('\U000001e9', '\U000001e9'),
-    ('\U000001eb', '\U000001eb'),
-    ('\U000001ed', '\U000001ed'),
-    ('\U000001ef', '\U000001f0'),
-    ('\U000001f3', '\U000001f3'),
-    ('\U000001f5', '\U000001f5'),
-    ('\U000001f9', '\U000001f9'),
-    ('\U000001fb', '\U000001fb'),
-    ('\U000001fd', '\U000001fd'),
-    ('\U000001ff', '\U000001ff'),
-    ('\U00000201', '\U00000201'),
-    ('\U00000203', '\U00000203'),
-    ('\U00000205', '\U00000205'),
-    ('\U00000207', '\U00000207'),
-    ('\U00000209', '\U00000209'),
-    ('\U0000020b', '\U0000020b'),
-    ('\U0000020d', '\U0000020d'),
-    ('\U0000020f', '\U0000020f'),
-    ('\U00000211', '\U00000211'),
-    ('\U00000213', '\U00000213'),
-    ('\U00000215', '\U00000215'),
-    ('\U00000217', '\U00000217'),
-    ('\U00000219', '\U00000219'),
-    ('\U0000021b', '\U0000021b'),
-    ('\U0000021d', '\U0000021d'),
-    ('\U0000021f', '\U0000021f'),
-    ('\U00000221', '\U00000221'),
-    ('\U00000223', '\U00000223'),
-    ('\U00000225', '\U00000225'),
-    ('\U00000227', '\U00000227'),
-    ('\U00000229', '\U00000229'),
-    ('\U0000022b', '\U0000022b'),
-    ('\U0000022d', '\U0000022d'),
-    ('\U0000022f', '\U0000022f'),
-    ('\U00000231', '\U00000231'),
-    ('\U00000233', '\U00000239'),
-    ('\U0000023c', '\U0000023c'),
-    ('\U0000023f', '\U00000240'),
-    ('\U00000242', '\U00000242'),
-    ('\U00000247', '\U00000247'),
-    ('\U00000249', '\U00000249'),
-    ('\U0000024b', '\U0000024b'),
-    ('\U0000024d', '\U0000024d'),
-    ('\U0000024f', '\U00000293'),
-    ('\U00000295', '\U000002af'),
-    ('\U00000371', '\U00000371'),
-    ('\U00000373', '\U00000373'),
-    ('\U00000377', '\U00000377'),
-    ('\U0000037b', '\U0000037d'),
-    ('\U00000390', '\U00000390'),
-    ('\U000003ac', '\U000003ce'),
-    ('\U000003d0', '\U000003d1'),
-    ('\U000003d5', '\U000003d7'),
-    ('\U000003d9', '\U000003d9'),
-    ('\U000003db', '\U000003db'),
-    ('\U000003dd', '\U000003dd'),
-    ('\U000003df', '\U000003df'),
-    ('\U000003e1', '\U000003e1'),
-    ('\U000003e3', '\U000003e3'),
-    ('\U000003e5', '\U000003e5'),
-    ('\U000003e7', '\U000003e7'),
-    ('\U000003e9', '\U000003e9'),
-    ('\U000003eb', '\U000003eb'),
-    ('\U000003ed', '\U000003ed'),
-    ('\U000003ef', '\U000003f3'),
-    ('\U000003f5', '\U000003f5'),
-    ('\U000003f8', '\U000003f8'),
-    ('\U000003fb', '\U000003fc'),
-    ('\U00000430', '\U0000045f'),
-    ('\U00000461', '\U00000461'),
-    ('\U00000463', '\U00000463'),
-    ('\U00000465', '\U00000465'),
-    ('\U00000467', '\U00000467'),
-    ('\U00000469', '\U00000469'),
-    ('\U0000046b', '\U0000046b'),
-    ('\U0000046d', '\U0000046d'),
-    ('\U0000046f', '\U0000046f'),
-    ('\U00000471', '\U00000471'),
-    ('\U00000473', '\U00000473'),
-    ('\U00000475', '\U00000475'),
-    ('\U00000477', '\U00000477'),
-    ('\U00000479', '\U00000479'),
-    ('\U0000047b', '\U0000047b'),
-    ('\U0000047d', '\U0000047d'),
-    ('\U0000047f', '\U0000047f'),
-    ('\U00000481', '\U00000481'),
-    ('\U0000048b', '\U0000048b'),
-    ('\U0000048d', '\U0000048d'),
-    ('\U0000048f', '\U0000048f'),
-    ('\U00000491', '\U00000491'),
-    ('\U00000493', '\U00000493'),
-    ('\U00000495', '\U00000495'),
-    ('\U00000497', '\U00000497'),
-    ('\U00000499', '\U00000499'),
-    ('\U0000049b', '\U0000049b'),
-    ('\U0000049d', '\U0000049d'),
-    ('\U0000049f', '\U0000049f'),
-    ('\U000004a1', '\U000004a1'),
-    ('\U000004a3', '\U000004a3'),
-    ('\U000004a5', '\U000004a5'),
-    ('\U000004a7', '\U000004a7'),
-    ('\U000004a9', '\U000004a9'),
-    ('\U000004ab', '\U000004ab'),
-    ('\U000004ad', '\U000004ad'),
-    ('\U000004af', '\U000004af'),
-    ('\U000004b1', '\U000004b1'),
-    ('\U000004b3', '\U000004b3'),
-    ('\U000004b5', '\U000004b5'),
-    ('\U000004b7', '\U000004b7'),
-    ('\U000004b9', '\U000004b9'),
-    ('\U000004bb', '\U000004bb'),
-    ('\U000004bd', '\U000004bd'),
-    ('\U000004bf', '\U000004bf'),
-    ('\U000004c2', '\U000004c2'),
-    ('\U000004c4', '\U000004c4'),
-    ('\U000004c6', '\U000004c6'),
-    ('\U000004c8', '\U000004c8'),
-    ('\U000004ca', '\U000004ca'),
-    ('\U000004cc', '\U000004cc'),
-    ('\U000004ce', '\U000004cf'),
-    ('\U000004d1', '\U000004d1'),
-    ('\U000004d3', '\U000004d3'),
-    ('\U000004d5', '\U000004d5'),
-    ('\U000004d7', '\U000004d7'),
-    ('\U000004d9', '\U000004d9'),
-    ('\U000004db', '\U000004db'),
-    ('\U000004dd', '\U000004dd'),
-    ('\U000004df', '\U000004df'),
-    ('\U000004e1', '\U000004e1'),
-    ('\U000004e3', '\U000004e3'),
-    ('\U000004e5', '\U000004e5'),
-    ('\U000004e7', '\U000004e7'),
-    ('\U000004e9', '\U000004e9'),
-    ('\U000004eb', '\U000004eb'),
-    ('\U000004ed', '\U000004ed'),
-    ('\U000004ef', '\U000004ef'),
-    ('\U000004f1', '\U000004f1'),
-    ('\U000004f3', '\U000004f3'),
-    ('\U000004f5', '\U000004f5'),
-    ('\U000004f7', '\U000004f7'),
-    ('\U000004f9', '\U000004f9'),
-    ('\U000004fb', '\U000004fb'),
-    ('\U000004fd', '\U000004fd'),
-    ('\U000004ff', '\U000004ff'),
-    ('\U00000501', '\U00000501'),
-    ('\U00000503', '\U00000503'),
-    ('\U00000505', '\U00000505'),
-    ('\U00000507', '\U00000507'),
-    ('\U00000509', '\U00000509'),
-    ('\U0000050b', '\U0000050b'),
-    ('\U0000050d', '\U0000050d'),
-    ('\U0000050f', '\U0000050f'),
-    ('\U00000511', '\U00000511'),
-    ('\U00000513', '\U00000513'),
-    ('\U00000515', '\U00000515'),
-    ('\U00000517', '\U00000517'),
-    ('\U00000519', '\U00000519'),
-    ('\U0000051b', '\U0000051b'),
-    ('\U0000051d', '\U0000051d'),
-    ('\U0000051f', '\U0000051f'),
-    ('\U00000521', '\U00000521'),
-    ('\U00000523', '\U00000523'),
-    ('\U00000525', '\U00000525'),
-    ('\U00000527', '\U00000527'),
-    ('\U00000561', '\U00000587'),
-    ('\U00001d00', '\U00001d2b'),
-    ('\U00001d6b', '\U00001d77'),
-    ('\U00001d79', '\U00001d9a'),
-    ('\U00001e01', '\U00001e01'),
-    ('\U00001e03', '\U00001e03'),
-    ('\U00001e05', '\U00001e05'),
-    ('\U00001e07', '\U00001e07'),
-    ('\U00001e09', '\U00001e09'),
-    ('\U00001e0b', '\U00001e0b'),
-    ('\U00001e0d', '\U00001e0d'),
-    ('\U00001e0f', '\U00001e0f'),
-    ('\U00001e11', '\U00001e11'),
-    ('\U00001e13', '\U00001e13'),
-    ('\U00001e15', '\U00001e15'),
-    ('\U00001e17', '\U00001e17'),
-    ('\U00001e19', '\U00001e19'),
-    ('\U00001e1b', '\U00001e1b'),
-    ('\U00001e1d', '\U00001e1d'),
-    ('\U00001e1f', '\U00001e1f'),
-    ('\U00001e21', '\U00001e21'),
-    ('\U00001e23', '\U00001e23'),
-    ('\U00001e25', '\U00001e25'),
-    ('\U00001e27', '\U00001e27'),
-    ('\U00001e29', '\U00001e29'),
-    ('\U00001e2b', '\U00001e2b'),
-    ('\U00001e2d', '\U00001e2d'),
-    ('\U00001e2f', '\U00001e2f'),
-    ('\U00001e31', '\U00001e31'),
-    ('\U00001e33', '\U00001e33'),
-    ('\U00001e35', '\U00001e35'),
-    ('\U00001e37', '\U00001e37'),
-    ('\U00001e39', '\U00001e39'),
-    ('\U00001e3b', '\U00001e3b'),
-    ('\U00001e3d', '\U00001e3d'),
-    ('\U00001e3f', '\U00001e3f'),
-    ('\U00001e41', '\U00001e41'),
-    ('\U00001e43', '\U00001e43'),
-    ('\U00001e45', '\U00001e45'),
-    ('\U00001e47', '\U00001e47'),
-    ('\U00001e49', '\U00001e49'),
-    ('\U00001e4b', '\U00001e4b'),
-    ('\U00001e4d', '\U00001e4d'),
-    ('\U00001e4f', '\U00001e4f'),
-    ('\U00001e51', '\U00001e51'),
-    ('\U00001e53', '\U00001e53'),
-    ('\U00001e55', '\U00001e55'),
-    ('\U00001e57', '\U00001e57'),
-    ('\U00001e59', '\U00001e59'),
-    ('\U00001e5b', '\U00001e5b'),
-    ('\U00001e5d', '\U00001e5d'),
-    ('\U00001e5f', '\U00001e5f'),
-    ('\U00001e61', '\U00001e61'),
-    ('\U00001e63', '\U00001e63'),
-    ('\U00001e65', '\U00001e65'),
-    ('\U00001e67', '\U00001e67'),
-    ('\U00001e69', '\U00001e69'),
-    ('\U00001e6b', '\U00001e6b'),
-    ('\U00001e6d', '\U00001e6d'),
-    ('\U00001e6f', '\U00001e6f'),
-    ('\U00001e71', '\U00001e71'),
-    ('\U00001e73', '\U00001e73'),
-    ('\U00001e75', '\U00001e75'),
-    ('\U00001e77', '\U00001e77'),
-    ('\U00001e79', '\U00001e79'),
-    ('\U00001e7b', '\U00001e7b'),
-    ('\U00001e7d', '\U00001e7d'),
-    ('\U00001e7f', '\U00001e7f'),
-    ('\U00001e81', '\U00001e81'),
-    ('\U00001e83', '\U00001e83'),
-    ('\U00001e85', '\U00001e85'),
-    ('\U00001e87', '\U00001e87'),
-    ('\U00001e89', '\U00001e89'),
-    ('\U00001e8b', '\U00001e8b'),
-    ('\U00001e8d', '\U00001e8d'),
-    ('\U00001e8f', '\U00001e8f'),
-    ('\U00001e91', '\U00001e91'),
-    ('\U00001e93', '\U00001e93'),
-    ('\U00001e95', '\U00001e9d'),
-    ('\U00001e9f', '\U00001e9f'),
-    ('\U00001ea1', '\U00001ea1'),
-    ('\U00001ea3', '\U00001ea3'),
-    ('\U00001ea5', '\U00001ea5'),
-    ('\U00001ea7', '\U00001ea7'),
-    ('\U00001ea9', '\U00001ea9'),
-    ('\U00001eab', '\U00001eab'),
-    ('\U00001ead', '\U00001ead'),
-    ('\U00001eaf', '\U00001eaf'),
-    ('\U00001eb1', '\U00001eb1'),
-    ('\U00001eb3', '\U00001eb3'),
-    ('\U00001eb5', '\U00001eb5'),
-    ('\U00001eb7', '\U00001eb7'),
-    ('\U00001eb9', '\U00001eb9'),
-    ('\U00001ebb', '\U00001ebb'),
-    ('\U00001ebd', '\U00001ebd'),
-    ('\U00001ebf', '\U00001ebf'),
-    ('\U00001ec1', '\U00001ec1'),
-    ('\U00001ec3', '\U00001ec3'),
-    ('\U00001ec5', '\U00001ec5'),
-    ('\U00001ec7', '\U00001ec7'),
-    ('\U00001ec9', '\U00001ec9'),
-    ('\U00001ecb', '\U00001ecb'),
-    ('\U00001ecd', '\U00001ecd'),
-    ('\U00001ecf', '\U00001ecf'),
-    ('\U00001ed1', '\U00001ed1'),
-    ('\U00001ed3', '\U00001ed3'),
-    ('\U00001ed5', '\U00001ed5'),
-    ('\U00001ed7', '\U00001ed7'),
-    ('\U00001ed9', '\U00001ed9'),
-    ('\U00001edb', '\U00001edb'),
-    ('\U00001edd', '\U00001edd'),
-    ('\U00001edf', '\U00001edf'),
-    ('\U00001ee1', '\U00001ee1'),
-    ('\U00001ee3', '\U00001ee3'),
-    ('\U00001ee5', '\U00001ee5'),
-    ('\U00001ee7', '\U00001ee7'),
-    ('\U00001ee9', '\U00001ee9'),
-    ('\U00001eeb', '\U00001eeb'),
-    ('\U00001eed', '\U00001eed'),
-    ('\U00001eef', '\U00001eef'),
-    ('\U00001ef1', '\U00001ef1'),
-    ('\U00001ef3', '\U00001ef3'),
-    ('\U00001ef5', '\U00001ef5'),
-    ('\U00001ef7', '\U00001ef7'),
-    ('\U00001ef9', '\U00001ef9'),
-    ('\U00001efb', '\U00001efb'),
-    ('\U00001efd', '\U00001efd'),
-    ('\U00001eff', '\U00001f07'),
-    ('\U00001f10', '\U00001f15'),
-    ('\U00001f20', '\U00001f27'),
-    ('\U00001f30', '\U00001f37'),
-    ('\U00001f40', '\U00001f45'),
-    ('\U00001f50', '\U00001f57'),
-    ('\U00001f60', '\U00001f67'),
-    ('\U00001f70', '\U00001f7d'),
-    ('\U00001f80', '\U00001f87'),
-    ('\U00001f90', '\U00001f97'),
-    ('\U00001fa0', '\U00001fa7'),
-    ('\U00001fb0', '\U00001fb4'),
-    ('\U00001fb6', '\U00001fb7'),
-    ('\U00001fbe', '\U00001fbe'),
-    ('\U00001fc2', '\U00001fc4'),
-    ('\U00001fc6', '\U00001fc7'),
-    ('\U00001fd0', '\U00001fd3'),
-    ('\U00001fd6', '\U00001fd7'),
-    ('\U00001fe0', '\U00001fe7'),
-    ('\U00001ff2', '\U00001ff4'),
-    ('\U00001ff6', '\U00001ff7'),
-    ('\U0000210a', '\U0000210a'),
-    ('\U0000210e', '\U0000210f'),
-    ('\U00002113', '\U00002113'),
-    ('\U0000212f', '\U0000212f'),
-    ('\U00002134', '\U00002134'),
-    ('\U00002139', '\U00002139'),
-    ('\U0000213c', '\U0000213d'),
-    ('\U00002146', '\U00002149'),
-    ('\U0000214e', '\U0000214e'),
-    ('\U00002184', '\U00002184'),
-    ('\U00002c30', '\U00002c5e'),
-    ('\U00002c61', '\U00002c61'),
-    ('\U00002c65', '\U00002c66'),
-    ('\U00002c68', '\U00002c68'),
-    ('\U00002c6a', '\U00002c6a'),
-    ('\U00002c6c', '\U00002c6c'),
-    ('\U00002c71', '\U00002c71'),
-    ('\U00002c73', '\U00002c74'),
-    ('\U00002c76', '\U00002c7b'),
-    ('\U00002c81', '\U00002c81'),
-    ('\U00002c83', '\U00002c83'),
-    ('\U00002c85', '\U00002c85'),
-    ('\U00002c87', '\U00002c87'),
-    ('\U00002c89', '\U00002c89'),
-    ('\U00002c8b', '\U00002c8b'),
-    ('\U00002c8d', '\U00002c8d'),
-    ('\U00002c8f', '\U00002c8f'),
-    ('\U00002c91', '\U00002c91'),
-    ('\U00002c93', '\U00002c93'),
-    ('\U00002c95', '\U00002c95'),
-    ('\U00002c97', '\U00002c97'),
-    ('\U00002c99', '\U00002c99'),
-    ('\U00002c9b', '\U00002c9b'),
-    ('\U00002c9d', '\U00002c9d'),
-    ('\U00002c9f', '\U00002c9f'),
-    ('\U00002ca1', '\U00002ca1'),
-    ('\U00002ca3', '\U00002ca3'),
-    ('\U00002ca5', '\U00002ca5'),
-    ('\U00002ca7', '\U00002ca7'),
-    ('\U00002ca9', '\U00002ca9'),
-    ('\U00002cab', '\U00002cab'),
-    ('\U00002cad', '\U00002cad'),
-    ('\U00002caf', '\U00002caf'),
-    ('\U00002cb1', '\U00002cb1'),
-    ('\U00002cb3', '\U00002cb3'),
-    ('\U00002cb5', '\U00002cb5'),
-    ('\U00002cb7', '\U00002cb7'),
-    ('\U00002cb9', '\U00002cb9'),
-    ('\U00002cbb', '\U00002cbb'),
-    ('\U00002cbd', '\U00002cbd'),
-    ('\U00002cbf', '\U00002cbf'),
-    ('\U00002cc1', '\U00002cc1'),
-    ('\U00002cc3', '\U00002cc3'),
-    ('\U00002cc5', '\U00002cc5'),
-    ('\U00002cc7', '\U00002cc7'),
-    ('\U00002cc9', '\U00002cc9'),
-    ('\U00002ccb', '\U00002ccb'),
-    ('\U00002ccd', '\U00002ccd'),
-    ('\U00002ccf', '\U00002ccf'),
-    ('\U00002cd1', '\U00002cd1'),
-    ('\U00002cd3', '\U00002cd3'),
-    ('\U00002cd5', '\U00002cd5'),
-    ('\U00002cd7', '\U00002cd7'),
-    ('\U00002cd9', '\U00002cd9'),
-    ('\U00002cdb', '\U00002cdb'),
-    ('\U00002cdd', '\U00002cdd'),
-    ('\U00002cdf', '\U00002cdf'),
-    ('\U00002ce1', '\U00002ce1'),
-    ('\U00002ce3', '\U00002ce4'),
-    ('\U00002cec', '\U00002cec'),
-    ('\U00002cee', '\U00002cee'),
-    ('\U00002cf3', '\U00002cf3'),
-    ('\U00002d00', '\U00002d25'),
-    ('\U00002d27', '\U00002d27'),
-    ('\U00002d2d', '\U00002d2d'),
-    ('\U0000a641', '\U0000a641'),
-    ('\U0000a643', '\U0000a643'),
-    ('\U0000a645', '\U0000a645'),
-    ('\U0000a647', '\U0000a647'),
-    ('\U0000a649', '\U0000a649'),
-    ('\U0000a64b', '\U0000a64b'),
-    ('\U0000a64d', '\U0000a64d'),
-    ('\U0000a64f', '\U0000a64f'),
-    ('\U0000a651', '\U0000a651'),
-    ('\U0000a653', '\U0000a653'),
-    ('\U0000a655', '\U0000a655'),
-    ('\U0000a657', '\U0000a657'),
-    ('\U0000a659', '\U0000a659'),
-    ('\U0000a65b', '\U0000a65b'),
-    ('\U0000a65d', '\U0000a65d'),
-    ('\U0000a65f', '\U0000a65f'),
-    ('\U0000a661', '\U0000a661'),
-    ('\U0000a663', '\U0000a663'),
-    ('\U0000a665', '\U0000a665'),
-    ('\U0000a667', '\U0000a667'),
-    ('\U0000a669', '\U0000a669'),
-    ('\U0000a66b', '\U0000a66b'),
-    ('\U0000a66d', '\U0000a66d'),
-    ('\U0000a681', '\U0000a681'),
-    ('\U0000a683', '\U0000a683'),
-    ('\U0000a685', '\U0000a685'),
-    ('\U0000a687', '\U0000a687'),
-    ('\U0000a689', '\U0000a689'),
-    ('\U0000a68b', '\U0000a68b'),
-    ('\U0000a68d', '\U0000a68d'),
-    ('\U0000a68f', '\U0000a68f'),
-    ('\U0000a691', '\U0000a691'),
-    ('\U0000a693', '\U0000a693'),
-    ('\U0000a695', '\U0000a695'),
-    ('\U0000a697', '\U0000a697'),
-    ('\U0000a723', '\U0000a723'),
-    ('\U0000a725', '\U0000a725'),
-    ('\U0000a727', '\U0000a727'),
-    ('\U0000a729', '\U0000a729'),
-    ('\U0000a72b', '\U0000a72b'),
-    ('\U0000a72d', '\U0000a72d'),
-    ('\U0000a72f', '\U0000a731'),
-    ('\U0000a733', '\U0000a733'),
-    ('\U0000a735', '\U0000a735'),
-    ('\U0000a737', '\U0000a737'),
-    ('\U0000a739', '\U0000a739'),
-    ('\U0000a73b', '\U0000a73b'),
-    ('\U0000a73d', '\U0000a73d'),
-    ('\U0000a73f', '\U0000a73f'),
-    ('\U0000a741', '\U0000a741'),
-    ('\U0000a743', '\U0000a743'),
-    ('\U0000a745', '\U0000a745'),
-    ('\U0000a747', '\U0000a747'),
-    ('\U0000a749', '\U0000a749'),
-    ('\U0000a74b', '\U0000a74b'),
-    ('\U0000a74d', '\U0000a74d'),
-    ('\U0000a74f', '\U0000a74f'),
-    ('\U0000a751', '\U0000a751'),
-    ('\U0000a753', '\U0000a753'),
-    ('\U0000a755', '\U0000a755'),
-    ('\U0000a757', '\U0000a757'),
-    ('\U0000a759', '\U0000a759'),
-    ('\U0000a75b', '\U0000a75b'),
-    ('\U0000a75d', '\U0000a75d'),
-    ('\U0000a75f', '\U0000a75f'),
-    ('\U0000a761', '\U0000a761'),
-    ('\U0000a763', '\U0000a763'),
-    ('\U0000a765', '\U0000a765'),
-    ('\U0000a767', '\U0000a767'),
-    ('\U0000a769', '\U0000a769'),
-    ('\U0000a76b', '\U0000a76b'),
-    ('\U0000a76d', '\U0000a76d'),
-    ('\U0000a76f', '\U0000a76f'),
-    ('\U0000a771', '\U0000a778'),
-    ('\U0000a77a', '\U0000a77a'),
-    ('\U0000a77c', '\U0000a77c'),
-    ('\U0000a77f', '\U0000a77f'),
-    ('\U0000a781', '\U0000a781'),
-    ('\U0000a783', '\U0000a783'),
-    ('\U0000a785', '\U0000a785'),
-    ('\U0000a787', '\U0000a787'),
-    ('\U0000a78c', '\U0000a78c'),
-    ('\U0000a78e', '\U0000a78e'),
-    ('\U0000a791', '\U0000a791'),
-    ('\U0000a793', '\U0000a793'),
-    ('\U0000a7a1', '\U0000a7a1'),
-    ('\U0000a7a3', '\U0000a7a3'),
-    ('\U0000a7a5', '\U0000a7a5'),
-    ('\U0000a7a7', '\U0000a7a7'),
-    ('\U0000a7a9', '\U0000a7a9'),
-    ('\U0000a7fa', '\U0000a7fa'),
-    ('\U0000fb00', '\U0000fb06'),
-    ('\U0000fb13', '\U0000fb17'),
-    ('\U0000ff41', '\U0000ff5a'),
-    ('\U00010428', '\U0001044f'),
-    ('\U0001d41a', '\U0001d433'),
-    ('\U0001d44e', '\U0001d454'),
-    ('\U0001d456', '\U0001d467'),
-    ('\U0001d482', '\U0001d49b'),
-    ('\U0001d4b6', '\U0001d4b9'),
-    ('\U0001d4bb', '\U0001d4bb'),
-    ('\U0001d4bd', '\U0001d4c3'),
-    ('\U0001d4c5', '\U0001d4cf'),
-    ('\U0001d4ea', '\U0001d503'),
-    ('\U0001d51e', '\U0001d537'),
-    ('\U0001d552', '\U0001d56b'),
-    ('\U0001d586', '\U0001d59f'),
-    ('\U0001d5ba', '\U0001d5d3'),
-    ('\U0001d5ee', '\U0001d607'),
-    ('\U0001d622', '\U0001d63b'),
-    ('\U0001d656', '\U0001d66f'),
-    ('\U0001d68a', '\U0001d6a5'),
-    ('\U0001d6c2', '\U0001d6da'),
-    ('\U0001d6dc', '\U0001d6e1'),
-    ('\U0001d6fc', '\U0001d714'),
-    ('\U0001d716', '\U0001d71b'),
-    ('\U0001d736', '\U0001d74e'),
-    ('\U0001d750', '\U0001d755'),
-    ('\U0001d770', '\U0001d788'),
-    ('\U0001d78a', '\U0001d78f'),
-    ('\U0001d7aa', '\U0001d7c2'),
-    ('\U0001d7c4', '\U0001d7c9'),
-    ('\U0001d7cb', '\U0001d7cb')
-    ]),
-("Lm", &[
-    ('\U000002b0', '\U000002c1'),
-    ('\U000002c6', '\U000002d1'),
-    ('\U000002e0', '\U000002e4'),
-    ('\U000002ec', '\U000002ec'),
-    ('\U000002ee', '\U000002ee'),
-    ('\U00000374', '\U00000374'),
-    ('\U0000037a', '\U0000037a'),
-    ('\U00000559', '\U00000559'),
-    ('\U00000640', '\U00000640'),
-    ('\U000006e5', '\U000006e6'),
-    ('\U000007f4', '\U000007f5'),
-    ('\U000007fa', '\U000007fa'),
-    ('\U0000081a', '\U0000081a'),
-    ('\U00000824', '\U00000824'),
-    ('\U00000828', '\U00000828'),
-    ('\U00000971', '\U00000971'),
-    ('\U00000e46', '\U00000e46'),
-    ('\U00000ec6', '\U00000ec6'),
-    ('\U000010fc', '\U000010fc'),
-    ('\U000017d7', '\U000017d7'),
-    ('\U00001843', '\U00001843'),
-    ('\U00001aa7', '\U00001aa7'),
-    ('\U00001c78', '\U00001c7d'),
-    ('\U00001d2c', '\U00001d6a'),
-    ('\U00001d78', '\U00001d78'),
-    ('\U00001d9b', '\U00001dbf'),
-    ('\U00002071', '\U00002071'),
-    ('\U0000207f', '\U0000207f'),
-    ('\U00002090', '\U0000209c'),
-    ('\U00002c7c', '\U00002c7d'),
-    ('\U00002d6f', '\U00002d6f'),
-    ('\U00002e2f', '\U00002e2f'),
-    ('\U00003005', '\U00003005'),
-    ('\U00003031', '\U00003035'),
-    ('\U0000303b', '\U0000303b'),
-    ('\U0000309d', '\U0000309e'),
-    ('\U000030fc', '\U000030fe'),
-    ('\U0000a015', '\U0000a015'),
-    ('\U0000a4f8', '\U0000a4fd'),
-    ('\U0000a60c', '\U0000a60c'),
-    ('\U0000a67f', '\U0000a67f'),
-    ('\U0000a717', '\U0000a71f'),
-    ('\U0000a770', '\U0000a770'),
-    ('\U0000a788', '\U0000a788'),
-    ('\U0000a7f8', '\U0000a7f9'),
-    ('\U0000a9cf', '\U0000a9cf'),
-    ('\U0000aa70', '\U0000aa70'),
-    ('\U0000aadd', '\U0000aadd'),
-    ('\U0000aaf3', '\U0000aaf4'),
-    ('\U0000ff70', '\U0000ff70'),
-    ('\U0000ff9e', '\U0000ff9f'),
-    ('\U00016f93', '\U00016f9f')
-    ]),
-("Lo", &[
-    ('\U000000aa', '\U000000aa'),
-    ('\U000000ba', '\U000000ba'),
-    ('\U000001bb', '\U000001bb'),
-    ('\U000001c0', '\U000001c3'),
-    ('\U00000294', '\U00000294'),
-    ('\U000005d0', '\U000005ea'),
-    ('\U000005f0', '\U000005f2'),
-    ('\U00000620', '\U0000063f'),
-    ('\U00000641', '\U0000064a'),
-    ('\U0000066e', '\U0000066f'),
-    ('\U00000671', '\U000006d3'),
-    ('\U000006d5', '\U000006d5'),
-    ('\U000006ee', '\U000006ef'),
-    ('\U000006fa', '\U000006fc'),
-    ('\U000006ff', '\U000006ff'),
-    ('\U00000710', '\U00000710'),
-    ('\U00000712', '\U0000072f'),
-    ('\U0000074d', '\U000007a5'),
-    ('\U000007b1', '\U000007b1'),
-    ('\U000007ca', '\U000007ea'),
-    ('\U00000800', '\U00000815'),
-    ('\U00000840', '\U00000858'),
-    ('\U000008a0', '\U000008a0'),
-    ('\U000008a2', '\U000008ac'),
-    ('\U00000904', '\U00000939'),
-    ('\U0000093d', '\U0000093d'),
-    ('\U00000950', '\U00000950'),
-    ('\U00000958', '\U00000961'),
-    ('\U00000972', '\U00000977'),
-    ('\U00000979', '\U0000097f'),
-    ('\U00000985', '\U0000098c'),
-    ('\U0000098f', '\U00000990'),
-    ('\U00000993', '\U000009a8'),
-    ('\U000009aa', '\U000009b0'),
-    ('\U000009b2', '\U000009b2'),
-    ('\U000009b6', '\U000009b9'),
-    ('\U000009bd', '\U000009bd'),
-    ('\U000009ce', '\U000009ce'),
-    ('\U000009dc', '\U000009dd'),
-    ('\U000009df', '\U000009e1'),
-    ('\U000009f0', '\U000009f1'),
-    ('\U00000a05', '\U00000a0a'),
-    ('\U00000a0f', '\U00000a10'),
-    ('\U00000a13', '\U00000a28'),
-    ('\U00000a2a', '\U00000a30'),
-    ('\U00000a32', '\U00000a33'),
-    ('\U00000a35', '\U00000a36'),
-    ('\U00000a38', '\U00000a39'),
-    ('\U00000a59', '\U00000a5c'),
-    ('\U00000a5e', '\U00000a5e'),
-    ('\U00000a72', '\U00000a74'),
-    ('\U00000a85', '\U00000a8d'),
-    ('\U00000a8f', '\U00000a91'),
-    ('\U00000a93', '\U00000aa8'),
-    ('\U00000aaa', '\U00000ab0'),
-    ('\U00000ab2', '\U00000ab3'),
-    ('\U00000ab5', '\U00000ab9'),
-    ('\U00000abd', '\U00000abd'),
-    ('\U00000ad0', '\U00000ad0'),
-    ('\U00000ae0', '\U00000ae1'),
-    ('\U00000b05', '\U00000b0c'),
-    ('\U00000b0f', '\U00000b10'),
-    ('\U00000b13', '\U00000b28'),
-    ('\U00000b2a', '\U00000b30'),
-    ('\U00000b32', '\U00000b33'),
-    ('\U00000b35', '\U00000b39'),
-    ('\U00000b3d', '\U00000b3d'),
-    ('\U00000b5c', '\U00000b5d'),
-    ('\U00000b5f', '\U00000b61'),
-    ('\U00000b71', '\U00000b71'),
-    ('\U00000b83', '\U00000b83'),
-    ('\U00000b85', '\U00000b8a'),
-    ('\U00000b8e', '\U00000b90'),
-    ('\U00000b92', '\U00000b95'),
-    ('\U00000b99', '\U00000b9a'),
-    ('\U00000b9c', '\U00000b9c'),
-    ('\U00000b9e', '\U00000b9f'),
-    ('\U00000ba3', '\U00000ba4'),
-    ('\U00000ba8', '\U00000baa'),
-    ('\U00000bae', '\U00000bb9'),
-    ('\U00000bd0', '\U00000bd0'),
-    ('\U00000c05', '\U00000c0c'),
-    ('\U00000c0e', '\U00000c10'),
-    ('\U00000c12', '\U00000c28'),
-    ('\U00000c2a', '\U00000c33'),
-    ('\U00000c35', '\U00000c39'),
-    ('\U00000c3d', '\U00000c3d'),
-    ('\U00000c58', '\U00000c59'),
-    ('\U00000c60', '\U00000c61'),
-    ('\U00000c85', '\U00000c8c'),
-    ('\U00000c8e', '\U00000c90'),
-    ('\U00000c92', '\U00000ca8'),
-    ('\U00000caa', '\U00000cb3'),
-    ('\U00000cb5', '\U00000cb9'),
-    ('\U00000cbd', '\U00000cbd'),
-    ('\U00000cde', '\U00000cde'),
-    ('\U00000ce0', '\U00000ce1'),
-    ('\U00000cf1', '\U00000cf2'),
-    ('\U00000d05', '\U00000d0c'),
-    ('\U00000d0e', '\U00000d10'),
-    ('\U00000d12', '\U00000d3a'),
-    ('\U00000d3d', '\U00000d3d'),
-    ('\U00000d4e', '\U00000d4e'),
-    ('\U00000d60', '\U00000d61'),
-    ('\U00000d7a', '\U00000d7f'),
-    ('\U00000d85', '\U00000d96'),
-    ('\U00000d9a', '\U00000db1'),
-    ('\U00000db3', '\U00000dbb'),
-    ('\U00000dbd', '\U00000dbd'),
-    ('\U00000dc0', '\U00000dc6'),
-    ('\U00000e01', '\U00000e30'),
-    ('\U00000e32', '\U00000e33'),
-    ('\U00000e40', '\U00000e45'),
-    ('\U00000e81', '\U00000e82'),
-    ('\U00000e84', '\U00000e84'),
-    ('\U00000e87', '\U00000e88'),
-    ('\U00000e8a', '\U00000e8a'),
-    ('\U00000e8d', '\U00000e8d'),
-    ('\U00000e94', '\U00000e97'),
-    ('\U00000e99', '\U00000e9f'),
-    ('\U00000ea1', '\U00000ea3'),
-    ('\U00000ea5', '\U00000ea5'),
-    ('\U00000ea7', '\U00000ea7'),
-    ('\U00000eaa', '\U00000eab'),
-    ('\U00000ead', '\U00000eb0'),
-    ('\U00000eb2', '\U00000eb3'),
-    ('\U00000ebd', '\U00000ebd'),
-    ('\U00000ec0', '\U00000ec4'),
-    ('\U00000edc', '\U00000edf'),
-    ('\U00000f00', '\U00000f00'),
-    ('\U00000f40', '\U00000f47'),
-    ('\U00000f49', '\U00000f6c'),
-    ('\U00000f88', '\U00000f8c'),
-    ('\U00001000', '\U0000102a'),
-    ('\U0000103f', '\U0000103f'),
-    ('\U00001050', '\U00001055'),
-    ('\U0000105a', '\U0000105d'),
-    ('\U00001061', '\U00001061'),
-    ('\U00001065', '\U00001066'),
-    ('\U0000106e', '\U00001070'),
-    ('\U00001075', '\U00001081'),
-    ('\U0000108e', '\U0000108e'),
-    ('\U000010d0', '\U000010fa'),
-    ('\U000010fd', '\U00001248'),
-    ('\U0000124a', '\U0000124d'),
-    ('\U00001250', '\U00001256'),
-    ('\U00001258', '\U00001258'),
-    ('\U0000125a', '\U0000125d'),
-    ('\U00001260', '\U00001288'),
-    ('\U0000128a', '\U0000128d'),
-    ('\U00001290', '\U000012b0'),
-    ('\U000012b2', '\U000012b5'),
-    ('\U000012b8', '\U000012be'),
-    ('\U000012c0', '\U000012c0'),
-    ('\U000012c2', '\U000012c5'),
-    ('\U000012c8', '\U000012d6'),
-    ('\U000012d8', '\U00001310'),
-    ('\U00001312', '\U00001315'),
-    ('\U00001318', '\U0000135a'),
-    ('\U00001380', '\U0000138f'),
-    ('\U000013a0', '\U000013f4'),
-    ('\U00001401', '\U0000166c'),
-    ('\U0000166f', '\U0000167f'),
-    ('\U00001681', '\U0000169a'),
-    ('\U000016a0', '\U000016ea'),
-    ('\U00001700', '\U0000170c'),
-    ('\U0000170e', '\U00001711'),
-    ('\U00001720', '\U00001731'),
-    ('\U00001740', '\U00001751'),
-    ('\U00001760', '\U0000176c'),
-    ('\U0000176e', '\U00001770'),
-    ('\U00001780', '\U000017b3'),
-    ('\U000017dc', '\U000017dc'),
-    ('\U00001820', '\U00001842'),
-    ('\U00001844', '\U00001877'),
-    ('\U00001880', '\U000018a8'),
-    ('\U000018aa', '\U000018aa'),
-    ('\U000018b0', '\U000018f5'),
-    ('\U00001900', '\U0000191c'),
-    ('\U00001950', '\U0000196d'),
-    ('\U00001970', '\U00001974'),
-    ('\U00001980', '\U000019ab'),
-    ('\U000019c1', '\U000019c7'),
-    ('\U00001a00', '\U00001a16'),
-    ('\U00001a20', '\U00001a54'),
-    ('\U00001b05', '\U00001b33'),
-    ('\U00001b45', '\U00001b4b'),
-    ('\U00001b83', '\U00001ba0'),
-    ('\U00001bae', '\U00001baf'),
-    ('\U00001bba', '\U00001be5'),
-    ('\U00001c00', '\U00001c23'),
-    ('\U00001c4d', '\U00001c4f'),
-    ('\U00001c5a', '\U00001c77'),
-    ('\U00001ce9', '\U00001cec'),
-    ('\U00001cee', '\U00001cf1'),
-    ('\U00001cf5', '\U00001cf6'),
-    ('\U00002135', '\U00002138'),
-    ('\U00002d30', '\U00002d67'),
-    ('\U00002d80', '\U00002d96'),
-    ('\U00002da0', '\U00002da6'),
-    ('\U00002da8', '\U00002dae'),
-    ('\U00002db0', '\U00002db6'),
-    ('\U00002db8', '\U00002dbe'),
-    ('\U00002dc0', '\U00002dc6'),
-    ('\U00002dc8', '\U00002dce'),
-    ('\U00002dd0', '\U00002dd6'),
-    ('\U00002dd8', '\U00002dde'),
-    ('\U00003006', '\U00003006'),
-    ('\U0000303c', '\U0000303c'),
-    ('\U00003041', '\U00003096'),
-    ('\U0000309f', '\U0000309f'),
-    ('\U000030a1', '\U000030fa'),
-    ('\U000030ff', '\U000030ff'),
-    ('\U00003105', '\U0000312d'),
-    ('\U00003131', '\U0000318e'),
-    ('\U000031a0', '\U000031ba'),
-    ('\U000031f0', '\U000031ff'),
-    ('\U00003400', '\U00003400'),
-    ('\U00004db5', '\U00004db5'),
-    ('\U00004e00', '\U00004e00'),
-    ('\U00009fcc', '\U00009fcc'),
-    ('\U0000a000', '\U0000a014'),
-    ('\U0000a016', '\U0000a48c'),
-    ('\U0000a4d0', '\U0000a4f7'),
-    ('\U0000a500', '\U0000a60b'),
-    ('\U0000a610', '\U0000a61f'),
-    ('\U0000a62a', '\U0000a62b'),
-    ('\U0000a66e', '\U0000a66e'),
-    ('\U0000a6a0', '\U0000a6e5'),
-    ('\U0000a7fb', '\U0000a801'),
-    ('\U0000a803', '\U0000a805'),
-    ('\U0000a807', '\U0000a80a'),
-    ('\U0000a80c', '\U0000a822'),
-    ('\U0000a840', '\U0000a873'),
-    ('\U0000a882', '\U0000a8b3'),
-    ('\U0000a8f2', '\U0000a8f7'),
-    ('\U0000a8fb', '\U0000a8fb'),
-    ('\U0000a90a', '\U0000a925'),
-    ('\U0000a930', '\U0000a946'),
-    ('\U0000a960', '\U0000a97c'),
-    ('\U0000a984', '\U0000a9b2'),
-    ('\U0000aa00', '\U0000aa28'),
-    ('\U0000aa40', '\U0000aa42'),
-    ('\U0000aa44', '\U0000aa4b'),
-    ('\U0000aa60', '\U0000aa6f'),
-    ('\U0000aa71', '\U0000aa76'),
-    ('\U0000aa7a', '\U0000aa7a'),
-    ('\U0000aa80', '\U0000aaaf'),
-    ('\U0000aab1', '\U0000aab1'),
-    ('\U0000aab5', '\U0000aab6'),
-    ('\U0000aab9', '\U0000aabd'),
-    ('\U0000aac0', '\U0000aac0'),
-    ('\U0000aac2', '\U0000aac2'),
-    ('\U0000aadb', '\U0000aadc'),
-    ('\U0000aae0', '\U0000aaea'),
-    ('\U0000aaf2', '\U0000aaf2'),
-    ('\U0000ab01', '\U0000ab06'),
-    ('\U0000ab09', '\U0000ab0e'),
-    ('\U0000ab11', '\U0000ab16'),
-    ('\U0000ab20', '\U0000ab26'),
-    ('\U0000ab28', '\U0000ab2e'),
-    ('\U0000abc0', '\U0000abe2'),
-    ('\U0000ac00', '\U0000ac00'),
-    ('\U0000d7a3', '\U0000d7a3'),
-    ('\U0000d7b0', '\U0000d7c6'),
-    ('\U0000d7cb', '\U0000d7fb'),
-    ('\U0000f900', '\U0000fa6d'),
-    ('\U0000fa70', '\U0000fad9'),
-    ('\U0000fb1d', '\U0000fb1d'),
-    ('\U0000fb1f', '\U0000fb28'),
-    ('\U0000fb2a', '\U0000fb36'),
-    ('\U0000fb38', '\U0000fb3c'),
-    ('\U0000fb3e', '\U0000fb3e'),
-    ('\U0000fb40', '\U0000fb41'),
-    ('\U0000fb43', '\U0000fb44'),
-    ('\U0000fb46', '\U0000fbb1'),
-    ('\U0000fbd3', '\U0000fd3d'),
-    ('\U0000fd50', '\U0000fd8f'),
-    ('\U0000fd92', '\U0000fdc7'),
-    ('\U0000fdf0', '\U0000fdfb'),
-    ('\U0000fe70', '\U0000fe74'),
-    ('\U0000fe76', '\U0000fefc'),
-    ('\U0000ff66', '\U0000ff6f'),
-    ('\U0000ff71', '\U0000ff9d'),
-    ('\U0000ffa0', '\U0000ffbe'),
-    ('\U0000ffc2', '\U0000ffc7'),
-    ('\U0000ffca', '\U0000ffcf'),
-    ('\U0000ffd2', '\U0000ffd7'),
-    ('\U0000ffda', '\U0000ffdc'),
-    ('\U00010000', '\U0001000b'),
-    ('\U0001000d', '\U00010026'),
-    ('\U00010028', '\U0001003a'),
-    ('\U0001003c', '\U0001003d'),
-    ('\U0001003f', '\U0001004d'),
-    ('\U00010050', '\U0001005d'),
-    ('\U00010080', '\U000100fa'),
-    ('\U00010280', '\U0001029c'),
-    ('\U000102a0', '\U000102d0'),
-    ('\U00010300', '\U0001031e'),
-    ('\U00010330', '\U00010340'),
-    ('\U00010342', '\U00010349'),
-    ('\U00010380', '\U0001039d'),
-    ('\U000103a0', '\U000103c3'),
-    ('\U000103c8', '\U000103cf'),
-    ('\U00010450', '\U0001049d'),
-    ('\U00010800', '\U00010805'),
-    ('\U00010808', '\U00010808'),
-    ('\U0001080a', '\U00010835'),
-    ('\U00010837', '\U00010838'),
-    ('\U0001083c', '\U0001083c'),
-    ('\U0001083f', '\U00010855'),
-    ('\U00010900', '\U00010915'),
-    ('\U00010920', '\U00010939'),
-    ('\U00010980', '\U000109b7'),
-    ('\U000109be', '\U000109bf'),
-    ('\U00010a00', '\U00010a00'),
-    ('\U00010a10', '\U00010a13'),
-    ('\U00010a15', '\U00010a17'),
-    ('\U00010a19', '\U00010a33'),
-    ('\U00010a60', '\U00010a7c'),
-    ('\U00010b00', '\U00010b35'),
-    ('\U00010b40', '\U00010b55'),
-    ('\U00010b60', '\U00010b72'),
-    ('\U00010c00', '\U00010c48'),
-    ('\U00011003', '\U00011037'),
-    ('\U00011083', '\U000110af'),
-    ('\U000110d0', '\U000110e8'),
-    ('\U00011103', '\U00011126'),
-    ('\U00011183', '\U000111b2'),
-    ('\U000111c1', '\U000111c4'),
-    ('\U00011680', '\U000116aa'),
-    ('\U00012000', '\U0001236e'),
-    ('\U00013000', '\U0001342e'),
-    ('\U00016800', '\U00016a38'),
-    ('\U00016f00', '\U00016f44'),
-    ('\U00016f50', '\U00016f50'),
-    ('\U0001b000', '\U0001b001'),
-    ('\U0001ee00', '\U0001ee03'),
-    ('\U0001ee05', '\U0001ee1f'),
-    ('\U0001ee21', '\U0001ee22'),
-    ('\U0001ee24', '\U0001ee24'),
-    ('\U0001ee27', '\U0001ee27'),
-    ('\U0001ee29', '\U0001ee32'),
-    ('\U0001ee34', '\U0001ee37'),
-    ('\U0001ee39', '\U0001ee39'),
-    ('\U0001ee3b', '\U0001ee3b'),
-    ('\U0001ee42', '\U0001ee42'),
-    ('\U0001ee47', '\U0001ee47'),
-    ('\U0001ee49', '\U0001ee49'),
-    ('\U0001ee4b', '\U0001ee4b'),
-    ('\U0001ee4d', '\U0001ee4f'),
-    ('\U0001ee51', '\U0001ee52'),
-    ('\U0001ee54', '\U0001ee54'),
-    ('\U0001ee57', '\U0001ee57'),
-    ('\U0001ee59', '\U0001ee59'),
-    ('\U0001ee5b', '\U0001ee5b'),
-    ('\U0001ee5d', '\U0001ee5d'),
-    ('\U0001ee5f', '\U0001ee5f'),
-    ('\U0001ee61', '\U0001ee62'),
-    ('\U0001ee64', '\U0001ee64'),
-    ('\U0001ee67', '\U0001ee6a'),
-    ('\U0001ee6c', '\U0001ee72'),
-    ('\U0001ee74', '\U0001ee77'),
-    ('\U0001ee79', '\U0001ee7c'),
-    ('\U0001ee7e', '\U0001ee7e'),
-    ('\U0001ee80', '\U0001ee89'),
-    ('\U0001ee8b', '\U0001ee9b'),
-    ('\U0001eea1', '\U0001eea3'),
-    ('\U0001eea5', '\U0001eea9'),
-    ('\U0001eeab', '\U0001eebb'),
-    ('\U00020000', '\U00020000'),
-    ('\U0002a6d6', '\U0002a6d6'),
-    ('\U0002a700', '\U0002a700'),
-    ('\U0002b734', '\U0002b734'),
-    ('\U0002b740', '\U0002b740'),
-    ('\U0002b81d', '\U0002b81d'),
-    ('\U0002f800', '\U0002fa1d')
-    ]),
-("Lt", &[
-    ('\U000001c5', '\U000001c5'),
-    ('\U000001c8', '\U000001c8'),
-    ('\U000001cb', '\U000001cb'),
-    ('\U000001f2', '\U000001f2'),
-    ('\U00001f88', '\U00001f8f'),
-    ('\U00001f98', '\U00001f9f'),
-    ('\U00001fa8', '\U00001faf'),
-    ('\U00001fbc', '\U00001fbc'),
-    ('\U00001fcc', '\U00001fcc'),
-    ('\U00001ffc', '\U00001ffc')
-    ]),
-("Lu", &[
-    ('\U00000041', '\U0000005a'),
-    ('\U000000c0', '\U000000d6'),
-    ('\U000000d8', '\U000000de'),
-    ('\U00000100', '\U00000100'),
-    ('\U00000102', '\U00000102'),
-    ('\U00000104', '\U00000104'),
-    ('\U00000106', '\U00000106'),
-    ('\U00000108', '\U00000108'),
-    ('\U0000010a', '\U0000010a'),
-    ('\U0000010c', '\U0000010c'),
-    ('\U0000010e', '\U0000010e'),
-    ('\U00000110', '\U00000110'),
-    ('\U00000112', '\U00000112'),
-    ('\U00000114', '\U00000114'),
-    ('\U00000116', '\U00000116'),
-    ('\U00000118', '\U00000118'),
-    ('\U0000011a', '\U0000011a'),
-    ('\U0000011c', '\U0000011c'),
-    ('\U0000011e', '\U0000011e'),
-    ('\U00000120', '\U00000120'),
-    ('\U00000122', '\U00000122'),
-    ('\U00000124', '\U00000124'),
-    ('\U00000126', '\U00000126'),
-    ('\U00000128', '\U00000128'),
-    ('\U0000012a', '\U0000012a'),
-    ('\U0000012c', '\U0000012c'),
-    ('\U0000012e', '\U0000012e'),
-    ('\U00000130', '\U00000130'),
-    ('\U00000132', '\U00000132'),
-    ('\U00000134', '\U00000134'),
-    ('\U00000136', '\U00000136'),
-    ('\U00000139', '\U00000139'),
-    ('\U0000013b', '\U0000013b'),
-    ('\U0000013d', '\U0000013d'),
-    ('\U0000013f', '\U0000013f'),
-    ('\U00000141', '\U00000141'),
-    ('\U00000143', '\U00000143'),
-    ('\U00000145', '\U00000145'),
-    ('\U00000147', '\U00000147'),
-    ('\U0000014a', '\U0000014a'),
-    ('\U0000014c', '\U0000014c'),
-    ('\U0000014e', '\U0000014e'),
-    ('\U00000150', '\U00000150'),
-    ('\U00000152', '\U00000152'),
-    ('\U00000154', '\U00000154'),
-    ('\U00000156', '\U00000156'),
-    ('\U00000158', '\U00000158'),
-    ('\U0000015a', '\U0000015a'),
-    ('\U0000015c', '\U0000015c'),
-    ('\U0000015e', '\U0000015e'),
-    ('\U00000160', '\U00000160'),
-    ('\U00000162', '\U00000162'),
-    ('\U00000164', '\U00000164'),
-    ('\U00000166', '\U00000166'),
-    ('\U00000168', '\U00000168'),
-    ('\U0000016a', '\U0000016a'),
-    ('\U0000016c', '\U0000016c'),
-    ('\U0000016e', '\U0000016e'),
-    ('\U00000170', '\U00000170'),
-    ('\U00000172', '\U00000172'),
-    ('\U00000174', '\U00000174'),
-    ('\U00000176', '\U00000176'),
-    ('\U00000178', '\U00000179'),
-    ('\U0000017b', '\U0000017b'),
-    ('\U0000017d', '\U0000017d'),
-    ('\U00000181', '\U00000182'),
-    ('\U00000184', '\U00000184'),
-    ('\U00000186', '\U00000187'),
-    ('\U00000189', '\U0000018b'),
-    ('\U0000018e', '\U00000191'),
-    ('\U00000193', '\U00000194'),
-    ('\U00000196', '\U00000198'),
-    ('\U0000019c', '\U0000019d'),
-    ('\U0000019f', '\U000001a0'),
-    ('\U000001a2', '\U000001a2'),
-    ('\U000001a4', '\U000001a4'),
-    ('\U000001a6', '\U000001a7'),
-    ('\U000001a9', '\U000001a9'),
-    ('\U000001ac', '\U000001ac'),
-    ('\U000001ae', '\U000001af'),
-    ('\U000001b1', '\U000001b3'),
-    ('\U000001b5', '\U000001b5'),
-    ('\U000001b7', '\U000001b8'),
-    ('\U000001bc', '\U000001bc'),
-    ('\U000001c4', '\U000001c4'),
-    ('\U000001c7', '\U000001c7'),
-    ('\U000001ca', '\U000001ca'),
-    ('\U000001cd', '\U000001cd'),
-    ('\U000001cf', '\U000001cf'),
-    ('\U000001d1', '\U000001d1'),
-    ('\U000001d3', '\U000001d3'),
-    ('\U000001d5', '\U000001d5'),
-    ('\U000001d7', '\U000001d7'),
-    ('\U000001d9', '\U000001d9'),
-    ('\U000001db', '\U000001db'),
-    ('\U000001de', '\U000001de'),
-    ('\U000001e0', '\U000001e0'),
-    ('\U000001e2', '\U000001e2'),
-    ('\U000001e4', '\U000001e4'),
-    ('\U000001e6', '\U000001e6'),
-    ('\U000001e8', '\U000001e8'),
-    ('\U000001ea', '\U000001ea'),
-    ('\U000001ec', '\U000001ec'),
-    ('\U000001ee', '\U000001ee'),
-    ('\U000001f1', '\U000001f1'),
-    ('\U000001f4', '\U000001f4'),
-    ('\U000001f6', '\U000001f8'),
-    ('\U000001fa', '\U000001fa'),
-    ('\U000001fc', '\U000001fc'),
-    ('\U000001fe', '\U000001fe'),
-    ('\U00000200', '\U00000200'),
-    ('\U00000202', '\U00000202'),
-    ('\U00000204', '\U00000204'),
-    ('\U00000206', '\U00000206'),
-    ('\U00000208', '\U00000208'),
-    ('\U0000020a', '\U0000020a'),
-    ('\U0000020c', '\U0000020c'),
-    ('\U0000020e', '\U0000020e'),
-    ('\U00000210', '\U00000210'),
-    ('\U00000212', '\U00000212'),
-    ('\U00000214', '\U00000214'),
-    ('\U00000216', '\U00000216'),
-    ('\U00000218', '\U00000218'),
-    ('\U0000021a', '\U0000021a'),
-    ('\U0000021c', '\U0000021c'),
-    ('\U0000021e', '\U0000021e'),
-    ('\U00000220', '\U00000220'),
-    ('\U00000222', '\U00000222'),
-    ('\U00000224', '\U00000224'),
-    ('\U00000226', '\U00000226'),
-    ('\U00000228', '\U00000228'),
-    ('\U0000022a', '\U0000022a'),
-    ('\U0000022c', '\U0000022c'),
-    ('\U0000022e', '\U0000022e'),
-    ('\U00000230', '\U00000230'),
-    ('\U00000232', '\U00000232'),
-    ('\U0000023a', '\U0000023b'),
-    ('\U0000023d', '\U0000023e'),
-    ('\U00000241', '\U00000241'),
-    ('\U00000243', '\U00000246'),
-    ('\U00000248', '\U00000248'),
-    ('\U0000024a', '\U0000024a'),
-    ('\U0000024c', '\U0000024c'),
-    ('\U0000024e', '\U0000024e'),
-    ('\U00000370', '\U00000370'),
-    ('\U00000372', '\U00000372'),
-    ('\U00000376', '\U00000376'),
-    ('\U00000386', '\U00000386'),
-    ('\U00000388', '\U0000038a'),
-    ('\U0000038c', '\U0000038c'),
-    ('\U0000038e', '\U0000038f'),
-    ('\U00000391', '\U000003a1'),
-    ('\U000003a3', '\U000003ab'),
-    ('\U000003cf', '\U000003cf'),
-    ('\U000003d2', '\U000003d4'),
-    ('\U000003d8', '\U000003d8'),
-    ('\U000003da', '\U000003da'),
-    ('\U000003dc', '\U000003dc'),
-    ('\U000003de', '\U000003de'),
-    ('\U000003e0', '\U000003e0'),
-    ('\U000003e2', '\U000003e2'),
-    ('\U000003e4', '\U000003e4'),
-    ('\U000003e6', '\U000003e6'),
-    ('\U000003e8', '\U000003e8'),
-    ('\U000003ea', '\U000003ea'),
-    ('\U000003ec', '\U000003ec'),
-    ('\U000003ee', '\U000003ee'),
-    ('\U000003f4', '\U000003f4'),
-    ('\U000003f7', '\U000003f7'),
-    ('\U000003f9', '\U000003fa'),
-    ('\U000003fd', '\U0000042f'),
-    ('\U00000460', '\U00000460'),
-    ('\U00000462', '\U00000462'),
-    ('\U00000464', '\U00000464'),
-    ('\U00000466', '\U00000466'),
-    ('\U00000468', '\U00000468'),
-    ('\U0000046a', '\U0000046a'),
-    ('\U0000046c', '\U0000046c'),
-    ('\U0000046e', '\U0000046e'),
-    ('\U00000470', '\U00000470'),
-    ('\U00000472', '\U00000472'),
-    ('\U00000474', '\U00000474'),
-    ('\U00000476', '\U00000476'),
-    ('\U00000478', '\U00000478'),
-    ('\U0000047a', '\U0000047a'),
-    ('\U0000047c', '\U0000047c'),
-    ('\U0000047e', '\U0000047e'),
-    ('\U00000480', '\U00000480'),
-    ('\U0000048a', '\U0000048a'),
-    ('\U0000048c', '\U0000048c'),
-    ('\U0000048e', '\U0000048e'),
-    ('\U00000490', '\U00000490'),
-    ('\U00000492', '\U00000492'),
-    ('\U00000494', '\U00000494'),
-    ('\U00000496', '\U00000496'),
-    ('\U00000498', '\U00000498'),
-    ('\U0000049a', '\U0000049a'),
-    ('\U0000049c', '\U0000049c'),
-    ('\U0000049e', '\U0000049e'),
-    ('\U000004a0', '\U000004a0'),
-    ('\U000004a2', '\U000004a2'),
-    ('\U000004a4', '\U000004a4'),
-    ('\U000004a6', '\U000004a6'),
-    ('\U000004a8', '\U000004a8'),
-    ('\U000004aa', '\U000004aa'),
-    ('\U000004ac', '\U000004ac'),
-    ('\U000004ae', '\U000004ae'),
-    ('\U000004b0', '\U000004b0'),
-    ('\U000004b2', '\U000004b2'),
-    ('\U000004b4', '\U000004b4'),
-    ('\U000004b6', '\U000004b6'),
-    ('\U000004b8', '\U000004b8'),
-    ('\U000004ba', '\U000004ba'),
-    ('\U000004bc', '\U000004bc'),
-    ('\U000004be', '\U000004be'),
-    ('\U000004c0', '\U000004c1'),
-    ('\U000004c3', '\U000004c3'),
-    ('\U000004c5', '\U000004c5'),
-    ('\U000004c7', '\U000004c7'),
-    ('\U000004c9', '\U000004c9'),
-    ('\U000004cb', '\U000004cb'),
-    ('\U000004cd', '\U000004cd'),
-    ('\U000004d0', '\U000004d0'),
-    ('\U000004d2', '\U000004d2'),
-    ('\U000004d4', '\U000004d4'),
-    ('\U000004d6', '\U000004d6'),
-    ('\U000004d8', '\U000004d8'),
-    ('\U000004da', '\U000004da'),
-    ('\U000004dc', '\U000004dc'),
-    ('\U000004de', '\U000004de'),
-    ('\U000004e0', '\U000004e0'),
-    ('\U000004e2', '\U000004e2'),
-    ('\U000004e4', '\U000004e4'),
-    ('\U000004e6', '\U000004e6'),
-    ('\U000004e8', '\U000004e8'),
-    ('\U000004ea', '\U000004ea'),
-    ('\U000004ec', '\U000004ec'),
-    ('\U000004ee', '\U000004ee'),
-    ('\U000004f0', '\U000004f0'),
-    ('\U000004f2', '\U000004f2'),
-    ('\U000004f4', '\U000004f4'),
-    ('\U000004f6', '\U000004f6'),
-    ('\U000004f8', '\U000004f8'),
-    ('\U000004fa', '\U000004fa'),
-    ('\U000004fc', '\U000004fc'),
-    ('\U000004fe', '\U000004fe'),
-    ('\U00000500', '\U00000500'),
-    ('\U00000502', '\U00000502'),
-    ('\U00000504', '\U00000504'),
-    ('\U00000506', '\U00000506'),
-    ('\U00000508', '\U00000508'),
-    ('\U0000050a', '\U0000050a'),
-    ('\U0000050c', '\U0000050c'),
-    ('\U0000050e', '\U0000050e'),
-    ('\U00000510', '\U00000510'),
-    ('\U00000512', '\U00000512'),
-    ('\U00000514', '\U00000514'),
-    ('\U00000516', '\U00000516'),
-    ('\U00000518', '\U00000518'),
-    ('\U0000051a', '\U0000051a'),
-    ('\U0000051c', '\U0000051c'),
-    ('\U0000051e', '\U0000051e'),
-    ('\U00000520', '\U00000520'),
-    ('\U00000522', '\U00000522'),
-    ('\U00000524', '\U00000524'),
-    ('\U00000526', '\U00000526'),
-    ('\U00000531', '\U00000556'),
-    ('\U000010a0', '\U000010c5'),
-    ('\U000010c7', '\U000010c7'),
-    ('\U000010cd', '\U000010cd'),
-    ('\U00001e00', '\U00001e00'),
-    ('\U00001e02', '\U00001e02'),
-    ('\U00001e04', '\U00001e04'),
-    ('\U00001e06', '\U00001e06'),
-    ('\U00001e08', '\U00001e08'),
-    ('\U00001e0a', '\U00001e0a'),
-    ('\U00001e0c', '\U00001e0c'),
-    ('\U00001e0e', '\U00001e0e'),
-    ('\U00001e10', '\U00001e10'),
-    ('\U00001e12', '\U00001e12'),
-    ('\U00001e14', '\U00001e14'),
-    ('\U00001e16', '\U00001e16'),
-    ('\U00001e18', '\U00001e18'),
-    ('\U00001e1a', '\U00001e1a'),
-    ('\U00001e1c', '\U00001e1c'),
-    ('\U00001e1e', '\U00001e1e'),
-    ('\U00001e20', '\U00001e20'),
-    ('\U00001e22', '\U00001e22'),
-    ('\U00001e24', '\U00001e24'),
-    ('\U00001e26', '\U00001e26'),
-    ('\U00001e28', '\U00001e28'),
-    ('\U00001e2a', '\U00001e2a'),
-    ('\U00001e2c', '\U00001e2c'),
-    ('\U00001e2e', '\U00001e2e'),
-    ('\U00001e30', '\U00001e30'),
-    ('\U00001e32', '\U00001e32'),
-    ('\U00001e34', '\U00001e34'),
-    ('\U00001e36', '\U00001e36'),
-    ('\U00001e38', '\U00001e38'),
-    ('\U00001e3a', '\U00001e3a'),
-    ('\U00001e3c', '\U00001e3c'),
-    ('\U00001e3e', '\U00001e3e'),
-    ('\U00001e40', '\U00001e40'),
-    ('\U00001e42', '\U00001e42'),
-    ('\U00001e44', '\U00001e44'),
-    ('\U00001e46', '\U00001e46'),
-    ('\U00001e48', '\U00001e48'),
-    ('\U00001e4a', '\U00001e4a'),
-    ('\U00001e4c', '\U00001e4c'),
-    ('\U00001e4e', '\U00001e4e'),
-    ('\U00001e50', '\U00001e50'),
-    ('\U00001e52', '\U00001e52'),
-    ('\U00001e54', '\U00001e54'),
-    ('\U00001e56', '\U00001e56'),
-    ('\U00001e58', '\U00001e58'),
-    ('\U00001e5a', '\U00001e5a'),
-    ('\U00001e5c', '\U00001e5c'),
-    ('\U00001e5e', '\U00001e5e'),
-    ('\U00001e60', '\U00001e60'),
-    ('\U00001e62', '\U00001e62'),
-    ('\U00001e64', '\U00001e64'),
-    ('\U00001e66', '\U00001e66'),
-    ('\U00001e68', '\U00001e68'),
-    ('\U00001e6a', '\U00001e6a'),
-    ('\U00001e6c', '\U00001e6c'),
-    ('\U00001e6e', '\U00001e6e'),
-    ('\U00001e70', '\U00001e70'),
-    ('\U00001e72', '\U00001e72'),
-    ('\U00001e74', '\U00001e74'),
-    ('\U00001e76', '\U00001e76'),
-    ('\U00001e78', '\U00001e78'),
-    ('\U00001e7a', '\U00001e7a'),
-    ('\U00001e7c', '\U00001e7c'),
-    ('\U00001e7e', '\U00001e7e'),
-    ('\U00001e80', '\U00001e80'),
-    ('\U00001e82', '\U00001e82'),
-    ('\U00001e84', '\U00001e84'),
-    ('\U00001e86', '\U00001e86'),
-    ('\U00001e88', '\U00001e88'),
-    ('\U00001e8a', '\U00001e8a'),
-    ('\U00001e8c', '\U00001e8c'),
-    ('\U00001e8e', '\U00001e8e'),
-    ('\U00001e90', '\U00001e90'),
-    ('\U00001e92', '\U00001e92'),
-    ('\U00001e94', '\U00001e94'),
-    ('\U00001e9e', '\U00001e9e'),
-    ('\U00001ea0', '\U00001ea0'),
-    ('\U00001ea2', '\U00001ea2'),
-    ('\U00001ea4', '\U00001ea4'),
-    ('\U00001ea6', '\U00001ea6'),
-    ('\U00001ea8', '\U00001ea8'),
-    ('\U00001eaa', '\U00001eaa'),
-    ('\U00001eac', '\U00001eac'),
-    ('\U00001eae', '\U00001eae'),
-    ('\U00001eb0', '\U00001eb0'),
-    ('\U00001eb2', '\U00001eb2'),
-    ('\U00001eb4', '\U00001eb4'),
-    ('\U00001eb6', '\U00001eb6'),
-    ('\U00001eb8', '\U00001eb8'),
-    ('\U00001eba', '\U00001eba'),
-    ('\U00001ebc', '\U00001ebc'),
-    ('\U00001ebe', '\U00001ebe'),
-    ('\U00001ec0', '\U00001ec0'),
-    ('\U00001ec2', '\U00001ec2'),
-    ('\U00001ec4', '\U00001ec4'),
-    ('\U00001ec6', '\U00001ec6'),
-    ('\U00001ec8', '\U00001ec8'),
-    ('\U00001eca', '\U00001eca'),
-    ('\U00001ecc', '\U00001ecc'),
-    ('\U00001ece', '\U00001ece'),
-    ('\U00001ed0', '\U00001ed0'),
-    ('\U00001ed2', '\U00001ed2'),
-    ('\U00001ed4', '\U00001ed4'),
-    ('\U00001ed6', '\U00001ed6'),
-    ('\U00001ed8', '\U00001ed8'),
-    ('\U00001eda', '\U00001eda'),
-    ('\U00001edc', '\U00001edc'),
-    ('\U00001ede', '\U00001ede'),
-    ('\U00001ee0', '\U00001ee0'),
-    ('\U00001ee2', '\U00001ee2'),
-    ('\U00001ee4', '\U00001ee4'),
-    ('\U00001ee6', '\U00001ee6'),
-    ('\U00001ee8', '\U00001ee8'),
-    ('\U00001eea', '\U00001eea'),
-    ('\U00001eec', '\U00001eec'),
-    ('\U00001eee', '\U00001eee'),
-    ('\U00001ef0', '\U00001ef0'),
-    ('\U00001ef2', '\U00001ef2'),
-    ('\U00001ef4', '\U00001ef4'),
-    ('\U00001ef6', '\U00001ef6'),
-    ('\U00001ef8', '\U00001ef8'),
-    ('\U00001efa', '\U00001efa'),
-    ('\U00001efc', '\U00001efc'),
-    ('\U00001efe', '\U00001efe'),
-    ('\U00001f08', '\U00001f0f'),
-    ('\U00001f18', '\U00001f1d'),
-    ('\U00001f28', '\U00001f2f'),
-    ('\U00001f38', '\U00001f3f'),
-    ('\U00001f48', '\U00001f4d'),
-    ('\U00001f59', '\U00001f59'),
-    ('\U00001f5b', '\U00001f5b'),
-    ('\U00001f5d', '\U00001f5d'),
-    ('\U00001f5f', '\U00001f5f'),
-    ('\U00001f68', '\U00001f6f'),
-    ('\U00001fb8', '\U00001fbb'),
-    ('\U00001fc8', '\U00001fcb'),
-    ('\U00001fd8', '\U00001fdb'),
-    ('\U00001fe8', '\U00001fec'),
-    ('\U00001ff8', '\U00001ffb'),
-    ('\U00002102', '\U00002102'),
-    ('\U00002107', '\U00002107'),
-    ('\U0000210b', '\U0000210d'),
-    ('\U00002110', '\U00002112'),
-    ('\U00002115', '\U00002115'),
-    ('\U00002119', '\U0000211d'),
-    ('\U00002124', '\U00002124'),
-    ('\U00002126', '\U00002126'),
-    ('\U00002128', '\U00002128'),
-    ('\U0000212a', '\U0000212d'),
-    ('\U00002130', '\U00002133'),
-    ('\U0000213e', '\U0000213f'),
-    ('\U00002145', '\U00002145'),
-    ('\U00002183', '\U00002183'),
-    ('\U00002c00', '\U00002c2e'),
-    ('\U00002c60', '\U00002c60'),
-    ('\U00002c62', '\U00002c64'),
-    ('\U00002c67', '\U00002c67'),
-    ('\U00002c69', '\U00002c69'),
-    ('\U00002c6b', '\U00002c6b'),
-    ('\U00002c6d', '\U00002c70'),
-    ('\U00002c72', '\U00002c72'),
-    ('\U00002c75', '\U00002c75'),
-    ('\U00002c7e', '\U00002c80'),
-    ('\U00002c82', '\U00002c82'),
-    ('\U00002c84', '\U00002c84'),
-    ('\U00002c86', '\U00002c86'),
-    ('\U00002c88', '\U00002c88'),
-    ('\U00002c8a', '\U00002c8a'),
-    ('\U00002c8c', '\U00002c8c'),
-    ('\U00002c8e', '\U00002c8e'),
-    ('\U00002c90', '\U00002c90'),
-    ('\U00002c92', '\U00002c92'),
-    ('\U00002c94', '\U00002c94'),
-    ('\U00002c96', '\U00002c96'),
-    ('\U00002c98', '\U00002c98'),
-    ('\U00002c9a', '\U00002c9a'),
-    ('\U00002c9c', '\U00002c9c'),
-    ('\U00002c9e', '\U00002c9e'),
-    ('\U00002ca0', '\U00002ca0'),
-    ('\U00002ca2', '\U00002ca2'),
-    ('\U00002ca4', '\U00002ca4'),
-    ('\U00002ca6', '\U00002ca6'),
-    ('\U00002ca8', '\U00002ca8'),
-    ('\U00002caa', '\U00002caa'),
-    ('\U00002cac', '\U00002cac'),
-    ('\U00002cae', '\U00002cae'),
-    ('\U00002cb0', '\U00002cb0'),
-    ('\U00002cb2', '\U00002cb2'),
-    ('\U00002cb4', '\U00002cb4'),
-    ('\U00002cb6', '\U00002cb6'),
-    ('\U00002cb8', '\U00002cb8'),
-    ('\U00002cba', '\U00002cba'),
-    ('\U00002cbc', '\U00002cbc'),
-    ('\U00002cbe', '\U00002cbe'),
-    ('\U00002cc0', '\U00002cc0'),
-    ('\U00002cc2', '\U00002cc2'),
-    ('\U00002cc4', '\U00002cc4'),
-    ('\U00002cc6', '\U00002cc6'),
-    ('\U00002cc8', '\U00002cc8'),
-    ('\U00002cca', '\U00002cca'),
-    ('\U00002ccc', '\U00002ccc'),
-    ('\U00002cce', '\U00002cce'),
-    ('\U00002cd0', '\U00002cd0'),
-    ('\U00002cd2', '\U00002cd2'),
-    ('\U00002cd4', '\U00002cd4'),
-    ('\U00002cd6', '\U00002cd6'),
-    ('\U00002cd8', '\U00002cd8'),
-    ('\U00002cda', '\U00002cda'),
-    ('\U00002cdc', '\U00002cdc'),
-    ('\U00002cde', '\U00002cde'),
-    ('\U00002ce0', '\U00002ce0'),
-    ('\U00002ce2', '\U00002ce2'),
-    ('\U00002ceb', '\U00002ceb'),
-    ('\U00002ced', '\U00002ced'),
-    ('\U00002cf2', '\U00002cf2'),
-    ('\U0000a640', '\U0000a640'),
-    ('\U0000a642', '\U0000a642'),
-    ('\U0000a644', '\U0000a644'),
-    ('\U0000a646', '\U0000a646'),
-    ('\U0000a648', '\U0000a648'),
-    ('\U0000a64a', '\U0000a64a'),
-    ('\U0000a64c', '\U0000a64c'),
-    ('\U0000a64e', '\U0000a64e'),
-    ('\U0000a650', '\U0000a650'),
-    ('\U0000a652', '\U0000a652'),
-    ('\U0000a654', '\U0000a654'),
-    ('\U0000a656', '\U0000a656'),
-    ('\U0000a658', '\U0000a658'),
-    ('\U0000a65a', '\U0000a65a'),
-    ('\U0000a65c', '\U0000a65c'),
-    ('\U0000a65e', '\U0000a65e'),
-    ('\U0000a660', '\U0000a660'),
-    ('\U0000a662', '\U0000a662'),
-    ('\U0000a664', '\U0000a664'),
-    ('\U0000a666', '\U0000a666'),
-    ('\U0000a668', '\U0000a668'),
-    ('\U0000a66a', '\U0000a66a'),
-    ('\U0000a66c', '\U0000a66c'),
-    ('\U0000a680', '\U0000a680'),
-    ('\U0000a682', '\U0000a682'),
-    ('\U0000a684', '\U0000a684'),
-    ('\U0000a686', '\U0000a686'),
-    ('\U0000a688', '\U0000a688'),
-    ('\U0000a68a', '\U0000a68a'),
-    ('\U0000a68c', '\U0000a68c'),
-    ('\U0000a68e', '\U0000a68e'),
-    ('\U0000a690', '\U0000a690'),
-    ('\U0000a692', '\U0000a692'),
-    ('\U0000a694', '\U0000a694'),
-    ('\U0000a696', '\U0000a696'),
-    ('\U0000a722', '\U0000a722'),
-    ('\U0000a724', '\U0000a724'),
-    ('\U0000a726', '\U0000a726'),
-    ('\U0000a728', '\U0000a728'),
-    ('\U0000a72a', '\U0000a72a'),
-    ('\U0000a72c', '\U0000a72c'),
-    ('\U0000a72e', '\U0000a72e'),
-    ('\U0000a732', '\U0000a732'),
-    ('\U0000a734', '\U0000a734'),
-    ('\U0000a736', '\U0000a736'),
-    ('\U0000a738', '\U0000a738'),
-    ('\U0000a73a', '\U0000a73a'),
-    ('\U0000a73c', '\U0000a73c'),
-    ('\U0000a73e', '\U0000a73e'),
-    ('\U0000a740', '\U0000a740'),
-    ('\U0000a742', '\U0000a742'),
-    ('\U0000a744', '\U0000a744'),
-    ('\U0000a746', '\U0000a746'),
-    ('\U0000a748', '\U0000a748'),
-    ('\U0000a74a', '\U0000a74a'),
-    ('\U0000a74c', '\U0000a74c'),
-    ('\U0000a74e', '\U0000a74e'),
-    ('\U0000a750', '\U0000a750'),
-    ('\U0000a752', '\U0000a752'),
-    ('\U0000a754', '\U0000a754'),
-    ('\U0000a756', '\U0000a756'),
-    ('\U0000a758', '\U0000a758'),
-    ('\U0000a75a', '\U0000a75a'),
-    ('\U0000a75c', '\U0000a75c'),
-    ('\U0000a75e', '\U0000a75e'),
-    ('\U0000a760', '\U0000a760'),
-    ('\U0000a762', '\U0000a762'),
-    ('\U0000a764', '\U0000a764'),
-    ('\U0000a766', '\U0000a766'),
-    ('\U0000a768', '\U0000a768'),
-    ('\U0000a76a', '\U0000a76a'),
-    ('\U0000a76c', '\U0000a76c'),
-    ('\U0000a76e', '\U0000a76e'),
-    ('\U0000a779', '\U0000a779'),
-    ('\U0000a77b', '\U0000a77b'),
-    ('\U0000a77d', '\U0000a77e'),
-    ('\U0000a780', '\U0000a780'),
-    ('\U0000a782', '\U0000a782'),
-    ('\U0000a784', '\U0000a784'),
-    ('\U0000a786', '\U0000a786'),
-    ('\U0000a78b', '\U0000a78b'),
-    ('\U0000a78d', '\U0000a78d'),
-    ('\U0000a790', '\U0000a790'),
-    ('\U0000a792', '\U0000a792'),
-    ('\U0000a7a0', '\U0000a7a0'),
-    ('\U0000a7a2', '\U0000a7a2'),
-    ('\U0000a7a4', '\U0000a7a4'),
-    ('\U0000a7a6', '\U0000a7a6'),
-    ('\U0000a7a8', '\U0000a7a8'),
-    ('\U0000a7aa', '\U0000a7aa'),
-    ('\U0000ff21', '\U0000ff3a'),
-    ('\U00010400', '\U00010427'),
-    ('\U0001d400', '\U0001d419'),
-    ('\U0001d434', '\U0001d44d'),
-    ('\U0001d468', '\U0001d481'),
-    ('\U0001d49c', '\U0001d49c'),
-    ('\U0001d49e', '\U0001d49f'),
-    ('\U0001d4a2', '\U0001d4a2'),
-    ('\U0001d4a5', '\U0001d4a6'),
-    ('\U0001d4a9', '\U0001d4ac'),
-    ('\U0001d4ae', '\U0001d4b5'),
-    ('\U0001d4d0', '\U0001d4e9'),
-    ('\U0001d504', '\U0001d505'),
-    ('\U0001d507', '\U0001d50a'),
-    ('\U0001d50d', '\U0001d514'),
-    ('\U0001d516', '\U0001d51c'),
-    ('\U0001d538', '\U0001d539'),
-    ('\U0001d53b', '\U0001d53e'),
-    ('\U0001d540', '\U0001d544'),
-    ('\U0001d546', '\U0001d546'),
-    ('\U0001d54a', '\U0001d550'),
-    ('\U0001d56c', '\U0001d585'),
-    ('\U0001d5a0', '\U0001d5b9'),
-    ('\U0001d5d4', '\U0001d5ed'),
-    ('\U0001d608', '\U0001d621'),
-    ('\U0001d63c', '\U0001d655'),
-    ('\U0001d670', '\U0001d689'),
-    ('\U0001d6a8', '\U0001d6c0'),
-    ('\U0001d6e2', '\U0001d6fa'),
-    ('\U0001d71c', '\U0001d734'),
-    ('\U0001d756', '\U0001d76e'),
-    ('\U0001d790', '\U0001d7a8'),
-    ('\U0001d7ca', '\U0001d7ca')
-    ]),
-("Lycian", &[
-    ('\U00010280', '\U0001029c')
-    ]),
-("Lydian", &[
-    ('\U00010920', '\U00010939'),
-    ('\U0001093f', '\U0001093f')
-    ]),
-("M", &[
-    ('\U00000300', '\U0000036f'),
-    ('\U00000483', '\U00000489'),
-    ('\U00000591', '\U000005bd'),
-    ('\U000005bf', '\U000005bf'),
-    ('\U000005c1', '\U000005c2'),
-    ('\U000005c4', '\U000005c5'),
-    ('\U000005c7', '\U000005c7'),
-    ('\U00000610', '\U0000061a'),
-    ('\U0000064b', '\U0000065f'),
-    ('\U00000670', '\U00000670'),
-    ('\U000006d6', '\U000006dc'),
-    ('\U000006df', '\U000006e4'),
-    ('\U000006e7', '\U000006e8'),
-    ('\U000006ea', '\U000006ed'),
-    ('\U00000711', '\U00000711'),
-    ('\U00000730', '\U0000074a'),
-    ('\U000007a6', '\U000007b0'),
-    ('\U000007eb', '\U000007f3'),
-    ('\U00000816', '\U00000819'),
-    ('\U0000081b', '\U00000823'),
-    ('\U00000825', '\U00000827'),
-    ('\U00000829', '\U0000082d'),
-    ('\U00000859', '\U0000085b'),
-    ('\U000008e4', '\U000008fe'),
-    ('\U00000900', '\U00000903'),
-    ('\U0000093a', '\U0000093c'),
-    ('\U0000093e', '\U0000094f'),
-    ('\U00000951', '\U00000957'),
-    ('\U00000962', '\U00000963'),
-    ('\U00000981', '\U00000983'),
-    ('\U000009bc', '\U000009bc'),
-    ('\U000009be', '\U000009c4'),
-    ('\U000009c7', '\U000009c8'),
-    ('\U000009cb', '\U000009cd'),
-    ('\U000009d7', '\U000009d7'),
-    ('\U000009e2', '\U000009e3'),
-    ('\U00000a01', '\U00000a03'),
-    ('\U00000a3c', '\U00000a3c'),
-    ('\U00000a3e', '\U00000a42'),
-    ('\U00000a47', '\U00000a48'),
-    ('\U00000a4b', '\U00000a4d'),
-    ('\U00000a51', '\U00000a51'),
-    ('\U00000a70', '\U00000a71'),
-    ('\U00000a75', '\U00000a75'),
-    ('\U00000a81', '\U00000a83'),
-    ('\U00000abc', '\U00000abc'),
-    ('\U00000abe', '\U00000ac5'),
-    ('\U00000ac7', '\U00000ac9'),
-    ('\U00000acb', '\U00000acd'),
-    ('\U00000ae2', '\U00000ae3'),
-    ('\U00000b01', '\U00000b03'),
-    ('\U00000b3c', '\U00000b3c'),
-    ('\U00000b3e', '\U00000b44'),
-    ('\U00000b47', '\U00000b48'),
-    ('\U00000b4b', '\U00000b4d'),
-    ('\U00000b56', '\U00000b57'),
-    ('\U00000b62', '\U00000b63'),
-    ('\U00000b82', '\U00000b82'),
-    ('\U00000bbe', '\U00000bc2'),
-    ('\U00000bc6', '\U00000bc8'),
-    ('\U00000bca', '\U00000bcd'),
-    ('\U00000bd7', '\U00000bd7'),
-    ('\U00000c01', '\U00000c03'),
-    ('\U00000c3e', '\U00000c44'),
-    ('\U00000c46', '\U00000c48'),
-    ('\U00000c4a', '\U00000c4d'),
-    ('\U00000c55', '\U00000c56'),
-    ('\U00000c62', '\U00000c63'),
-    ('\U00000c82', '\U00000c83'),
-    ('\U00000cbc', '\U00000cbc'),
-    ('\U00000cbe', '\U00000cc4'),
-    ('\U00000cc6', '\U00000cc8'),
-    ('\U00000cca', '\U00000ccd'),
-    ('\U00000cd5', '\U00000cd6'),
-    ('\U00000ce2', '\U00000ce3'),
-    ('\U00000d02', '\U00000d03'),
-    ('\U00000d3e', '\U00000d44'),
-    ('\U00000d46', '\U00000d48'),
-    ('\U00000d4a', '\U00000d4d'),
-    ('\U00000d57', '\U00000d57'),
-    ('\U00000d62', '\U00000d63'),
-    ('\U00000d82', '\U00000d83'),
-    ('\U00000dca', '\U00000dca'),
-    ('\U00000dcf', '\U00000dd4'),
-    ('\U00000dd6', '\U00000dd6'),
-    ('\U00000dd8', '\U00000ddf'),
-    ('\U00000df2', '\U00000df3'),
-    ('\U00000e31', '\U00000e31'),
-    ('\U00000e34', '\U00000e3a'),
-    ('\U00000e47', '\U00000e4e'),
-    ('\U00000eb1', '\U00000eb1'),
-    ('\U00000eb4', '\U00000eb9'),
-    ('\U00000ebb', '\U00000ebc'),
-    ('\U00000ec8', '\U00000ecd'),
-    ('\U00000f18', '\U00000f19'),
-    ('\U00000f35', '\U00000f35'),
-    ('\U00000f37', '\U00000f37'),
-    ('\U00000f39', '\U00000f39'),
-    ('\U00000f3e', '\U00000f3f'),
-    ('\U00000f71', '\U00000f84'),
-    ('\U00000f86', '\U00000f87'),
-    ('\U00000f8d', '\U00000f97'),
-    ('\U00000f99', '\U00000fbc'),
-    ('\U00000fc6', '\U00000fc6'),
-    ('\U0000102b', '\U0000103e'),
-    ('\U00001056', '\U00001059'),
-    ('\U0000105e', '\U00001060'),
-    ('\U00001062', '\U00001064'),
-    ('\U00001067', '\U0000106d'),
-    ('\U00001071', '\U00001074'),
-    ('\U00001082', '\U0000108d'),
-    ('\U0000108f', '\U0000108f'),
-    ('\U0000109a', '\U0000109d'),
-    ('\U0000135d', '\U0000135f'),
-    ('\U00001712', '\U00001714'),
-    ('\U00001732', '\U00001734'),
-    ('\U00001752', '\U00001753'),
-    ('\U00001772', '\U00001773'),
-    ('\U000017b4', '\U000017d3'),
-    ('\U000017dd', '\U000017dd'),
-    ('\U0000180b', '\U0000180d'),
-    ('\U000018a9', '\U000018a9'),
-    ('\U00001920', '\U0000192b'),
-    ('\U00001930', '\U0000193b'),
-    ('\U000019b0', '\U000019c0'),
-    ('\U000019c8', '\U000019c9'),
-    ('\U00001a17', '\U00001a1b'),
-    ('\U00001a55', '\U00001a5e'),
-    ('\U00001a60', '\U00001a7c'),
-    ('\U00001a7f', '\U00001a7f'),
-    ('\U00001b00', '\U00001b04'),
-    ('\U00001b34', '\U00001b44'),
-    ('\U00001b6b', '\U00001b73'),
-    ('\U00001b80', '\U00001b82'),
-    ('\U00001ba1', '\U00001bad'),
-    ('\U00001be6', '\U00001bf3'),
-    ('\U00001c24', '\U00001c37'),
-    ('\U00001cd0', '\U00001cd2'),
-    ('\U00001cd4', '\U00001ce8'),
-    ('\U00001ced', '\U00001ced'),
-    ('\U00001cf2', '\U00001cf4'),
-    ('\U00001dc0', '\U00001de6'),
-    ('\U00001dfc', '\U00001dff'),
-    ('\U000020d0', '\U000020f0'),
-    ('\U00002cef', '\U00002cf1'),
-    ('\U00002d7f', '\U00002d7f'),
-    ('\U00002de0', '\U00002dff'),
-    ('\U0000302a', '\U0000302f'),
-    ('\U00003099', '\U0000309a'),
-    ('\U0000a66f', '\U0000a672'),
-    ('\U0000a674', '\U0000a67d'),
-    ('\U0000a69f', '\U0000a69f'),
-    ('\U0000a6f0', '\U0000a6f1'),
-    ('\U0000a802', '\U0000a802'),
-    ('\U0000a806', '\U0000a806'),
-    ('\U0000a80b', '\U0000a80b'),
-    ('\U0000a823', '\U0000a827'),
-    ('\U0000a880', '\U0000a881'),
-    ('\U0000a8b4', '\U0000a8c4'),
-    ('\U0000a8e0', '\U0000a8f1'),
-    ('\U0000a926', '\U0000a92d'),
-    ('\U0000a947', '\U0000a953'),
-    ('\U0000a980', '\U0000a983'),
-    ('\U0000a9b3', '\U0000a9c0'),
-    ('\U0000aa29', '\U0000aa36'),
-    ('\U0000aa43', '\U0000aa43'),
-    ('\U0000aa4c', '\U0000aa4d'),
-    ('\U0000aa7b', '\U0000aa7b'),
-    ('\U0000aab0', '\U0000aab0'),
-    ('\U0000aab2', '\U0000aab4'),
-    ('\U0000aab7', '\U0000aab8'),
-    ('\U0000aabe', '\U0000aabf'),
-    ('\U0000aac1', '\U0000aac1'),
-    ('\U0000aaeb', '\U0000aaef'),
-    ('\U0000aaf5', '\U0000aaf6'),
-    ('\U0000abe3', '\U0000abea'),
-    ('\U0000abec', '\U0000abed'),
-    ('\U0000fb1e', '\U0000fb1e'),
-    ('\U0000fe00', '\U0000fe0f'),
-    ('\U0000fe20', '\U0000fe26'),
-    ('\U000101fd', '\U000101fd'),
-    ('\U00010a01', '\U00010a03'),
-    ('\U00010a05', '\U00010a06'),
-    ('\U00010a0c', '\U00010a0f'),
-    ('\U00010a38', '\U00010a3a'),
-    ('\U00010a3f', '\U00010a3f'),
-    ('\U00011000', '\U00011002'),
-    ('\U00011038', '\U00011046'),
-    ('\U00011080', '\U00011082'),
-    ('\U000110b0', '\U000110ba'),
-    ('\U00011100', '\U00011102'),
-    ('\U00011127', '\U00011134'),
-    ('\U00011180', '\U00011182'),
-    ('\U000111b3', '\U000111c0'),
-    ('\U000116ab', '\U000116b7'),
-    ('\U00016f51', '\U00016f7e'),
-    ('\U00016f8f', '\U00016f92'),
-    ('\U0001d165', '\U0001d169'),
-    ('\U0001d16d', '\U0001d172'),
-    ('\U0001d17b', '\U0001d182'),
-    ('\U0001d185', '\U0001d18b'),
-    ('\U0001d1aa', '\U0001d1ad'),
-    ('\U0001d242', '\U0001d244'),
-    ('\U000e0100', '\U000e01ef')
-    ]),
-("Malayalam", &[
-    ('\U00000d02', '\U00000d03'),
-    ('\U00000d05', '\U00000d0c'),
-    ('\U00000d0e', '\U00000d10'),
-    ('\U00000d12', '\U00000d3a'),
-    ('\U00000d3d', '\U00000d44'),
-    ('\U00000d46', '\U00000d48'),
-    ('\U00000d4a', '\U00000d4e'),
-    ('\U00000d57', '\U00000d57'),
-    ('\U00000d60', '\U00000d63'),
-    ('\U00000d66', '\U00000d75'),
-    ('\U00000d79', '\U00000d7f')
-    ]),
-("Mandaic", &[
-    ('\U00000840', '\U0000085b'),
-    ('\U0000085e', '\U0000085e')
-    ]),
-("Mc", &[
-    ('\U00000903', '\U00000903'),
-    ('\U0000093b', '\U0000093b'),
-    ('\U0000093e', '\U00000940'),
-    ('\U00000949', '\U0000094c'),
-    ('\U0000094e', '\U0000094f'),
-    ('\U00000982', '\U00000983'),
-    ('\U000009be', '\U000009c0'),
-    ('\U000009c7', '\U000009c8'),
-    ('\U000009cb', '\U000009cc'),
-    ('\U000009d7', '\U000009d7'),
-    ('\U00000a03', '\U00000a03'),
-    ('\U00000a3e', '\U00000a40'),
-    ('\U00000a83', '\U00000a83'),
-    ('\U00000abe', '\U00000ac0'),
-    ('\U00000ac9', '\U00000ac9'),
-    ('\U00000acb', '\U00000acc'),
-    ('\U00000b02', '\U00000b03'),
-    ('\U00000b3e', '\U00000b3e'),
-    ('\U00000b40', '\U00000b40'),
-    ('\U00000b47', '\U00000b48'),
-    ('\U00000b4b', '\U00000b4c'),
-    ('\U00000b57', '\U00000b57'),
-    ('\U00000bbe', '\U00000bbf'),
-    ('\U00000bc1', '\U00000bc2'),
-    ('\U00000bc6', '\U00000bc8'),
-    ('\U00000bca', '\U00000bcc'),
-    ('\U00000bd7', '\U00000bd7'),
-    ('\U00000c01', '\U00000c03'),
-    ('\U00000c41', '\U00000c44'),
-    ('\U00000c82', '\U00000c83'),
-    ('\U00000cbe', '\U00000cbe'),
-    ('\U00000cc0', '\U00000cc4'),
-    ('\U00000cc7', '\U00000cc8'),
-    ('\U00000cca', '\U00000ccb'),
-    ('\U00000cd5', '\U00000cd6'),
-    ('\U00000d02', '\U00000d03'),
-    ('\U00000d3e', '\U00000d40'),
-    ('\U00000d46', '\U00000d48'),
-    ('\U00000d4a', '\U00000d4c'),
-    ('\U00000d57', '\U00000d57'),
-    ('\U00000d82', '\U00000d83'),
-    ('\U00000dcf', '\U00000dd1'),
-    ('\U00000dd8', '\U00000ddf'),
-    ('\U00000df2', '\U00000df3'),
-    ('\U00000f3e', '\U00000f3f'),
-    ('\U00000f7f', '\U00000f7f'),
-    ('\U0000102b', '\U0000102c'),
-    ('\U00001031', '\U00001031'),
-    ('\U00001038', '\U00001038'),
-    ('\U0000103b', '\U0000103c'),
-    ('\U00001056', '\U00001057'),
-    ('\U00001062', '\U00001064'),
-    ('\U00001067', '\U0000106d'),
-    ('\U00001083', '\U00001084'),
-    ('\U00001087', '\U0000108c'),
-    ('\U0000108f', '\U0000108f'),
-    ('\U0000109a', '\U0000109c'),
-    ('\U000017b6', '\U000017b6'),
-    ('\U000017be', '\U000017c5'),
-    ('\U000017c7', '\U000017c8'),
-    ('\U00001923', '\U00001926'),
-    ('\U00001929', '\U0000192b'),
-    ('\U00001930', '\U00001931'),
-    ('\U00001933', '\U00001938'),
-    ('\U000019b0', '\U000019c0'),
-    ('\U000019c8', '\U000019c9'),
-    ('\U00001a19', '\U00001a1a'),
-    ('\U00001a55', '\U00001a55'),
-    ('\U00001a57', '\U00001a57'),
-    ('\U00001a61', '\U00001a61'),
-    ('\U00001a63', '\U00001a64'),
-    ('\U00001a6d', '\U00001a72'),
-    ('\U00001b04', '\U00001b04'),
-    ('\U00001b35', '\U00001b35'),
-    ('\U00001b3b', '\U00001b3b'),
-    ('\U00001b3d', '\U00001b41'),
-    ('\U00001b43', '\U00001b44'),
-    ('\U00001b82', '\U00001b82'),
-    ('\U00001ba1', '\U00001ba1'),
-    ('\U00001ba6', '\U00001ba7'),
-    ('\U00001baa', '\U00001baa'),
-    ('\U00001bac', '\U00001bad'),
-    ('\U00001be7', '\U00001be7'),
-    ('\U00001bea', '\U00001bec'),
-    ('\U00001bee', '\U00001bee'),
-    ('\U00001bf2', '\U00001bf3'),
-    ('\U00001c24', '\U00001c2b'),
-    ('\U00001c34', '\U00001c35'),
-    ('\U00001ce1', '\U00001ce1'),
-    ('\U00001cf2', '\U00001cf3'),
-    ('\U0000302e', '\U0000302f'),
-    ('\U0000a823', '\U0000a824'),
-    ('\U0000a827', '\U0000a827'),
-    ('\U0000a880', '\U0000a881'),
-    ('\U0000a8b4', '\U0000a8c3'),
-    ('\U0000a952', '\U0000a953'),
-    ('\U0000a983', '\U0000a983'),
-    ('\U0000a9b4', '\U0000a9b5'),
-    ('\U0000a9ba', '\U0000a9bb'),
-    ('\U0000a9bd', '\U0000a9c0'),
-    ('\U0000aa2f', '\U0000aa30'),
-    ('\U0000aa33', '\U0000aa34'),
-    ('\U0000aa4d', '\U0000aa4d'),
-    ('\U0000aa7b', '\U0000aa7b'),
-    ('\U0000aaeb', '\U0000aaeb'),
-    ('\U0000aaee', '\U0000aaef'),
-    ('\U0000aaf5', '\U0000aaf5'),
-    ('\U0000abe3', '\U0000abe4'),
-    ('\U0000abe6', '\U0000abe7'),
-    ('\U0000abe9', '\U0000abea'),
-    ('\U0000abec', '\U0000abec'),
-    ('\U00011000', '\U00011000'),
-    ('\U00011002', '\U00011002'),
-    ('\U00011082', '\U00011082'),
-    ('\U000110b0', '\U000110b2'),
-    ('\U000110b7', '\U000110b8'),
-    ('\U0001112c', '\U0001112c'),
-    ('\U00011182', '\U00011182'),
-    ('\U000111b3', '\U000111b5'),
-    ('\U000111bf', '\U000111c0'),
-    ('\U000116ac', '\U000116ac'),
-    ('\U000116ae', '\U000116af'),
-    ('\U000116b6', '\U000116b6'),
-    ('\U00016f51', '\U00016f7e'),
-    ('\U0001d165', '\U0001d166'),
-    ('\U0001d16d', '\U0001d172')
-    ]),
-("Me", &[
-    ('\U00000488', '\U00000489'),
-    ('\U000020dd', '\U000020e0'),
-    ('\U000020e2', '\U000020e4'),
-    ('\U0000a670', '\U0000a672')
-    ]),
-("Meetei_Mayek", &[
-    ('\U0000aae0', '\U0000aaf6'),
-    ('\U0000abc0', '\U0000abed'),
-    ('\U0000abf0', '\U0000abf9')
-    ]),
-("Meroitic_Cursive", &[
-    ('\U000109a0', '\U000109b7'),
-    ('\U000109be', '\U000109bf')
-    ]),
-("Meroitic_Hieroglyphs", &[
-    ('\U00010980', '\U0001099f')
-    ]),
-("Miao", &[
-    ('\U00016f00', '\U00016f44'),
-    ('\U00016f50', '\U00016f7e'),
-    ('\U00016f8f', '\U00016f9f')
-    ]),
-("Mn", &[
-    ('\U00000300', '\U0000036f'),
-    ('\U00000483', '\U00000487'),
-    ('\U00000591', '\U000005bd'),
-    ('\U000005bf', '\U000005bf'),
-    ('\U000005c1', '\U000005c2'),
-    ('\U000005c4', '\U000005c5'),
-    ('\U000005c7', '\U000005c7'),
-    ('\U00000610', '\U0000061a'),
-    ('\U0000064b', '\U0000065f'),
-    ('\U00000670', '\U00000670'),
-    ('\U000006d6', '\U000006dc'),
-    ('\U000006df', '\U000006e4'),
-    ('\U000006e7', '\U000006e8'),
-    ('\U000006ea', '\U000006ed'),
-    ('\U00000711', '\U00000711'),
-    ('\U00000730', '\U0000074a'),
-    ('\U000007a6', '\U000007b0'),
-    ('\U000007eb', '\U000007f3'),
-    ('\U00000816', '\U00000819'),
-    ('\U0000081b', '\U00000823'),
-    ('\U00000825', '\U00000827'),
-    ('\U00000829', '\U0000082d'),
-    ('\U00000859', '\U0000085b'),
-    ('\U000008e4', '\U000008fe'),
-    ('\U00000900', '\U00000902'),
-    ('\U0000093a', '\U0000093a'),
-    ('\U0000093c', '\U0000093c'),
-    ('\U00000941', '\U00000948'),
-    ('\U0000094d', '\U0000094d'),
-    ('\U00000951', '\U00000957'),
-    ('\U00000962', '\U00000963'),
-    ('\U00000981', '\U00000981'),
-    ('\U000009bc', '\U000009bc'),
-    ('\U000009c1', '\U000009c4'),
-    ('\U000009cd', '\U000009cd'),
-    ('\U000009e2', '\U000009e3'),
-    ('\U00000a01', '\U00000a02'),
-    ('\U00000a3c', '\U00000a3c'),
-    ('\U00000a41', '\U00000a42'),
-    ('\U00000a47', '\U00000a48'),
-    ('\U00000a4b', '\U00000a4d'),
-    ('\U00000a51', '\U00000a51'),
-    ('\U00000a70', '\U00000a71'),
-    ('\U00000a75', '\U00000a75'),
-    ('\U00000a81', '\U00000a82'),
-    ('\U00000abc', '\U00000abc'),
-    ('\U00000ac1', '\U00000ac5'),
-    ('\U00000ac7', '\U00000ac8'),
-    ('\U00000acd', '\U00000acd'),
-    ('\U00000ae2', '\U00000ae3'),
-    ('\U00000b01', '\U00000b01'),
-    ('\U00000b3c', '\U00000b3c'),
-    ('\U00000b3f', '\U00000b3f'),
-    ('\U00000b41', '\U00000b44'),
-    ('\U00000b4d', '\U00000b4d'),
-    ('\U00000b56', '\U00000b56'),
-    ('\U00000b62', '\U00000b63'),
-    ('\U00000b82', '\U00000b82'),
-    ('\U00000bc0', '\U00000bc0'),
-    ('\U00000bcd', '\U00000bcd'),
-    ('\U00000c3e', '\U00000c40'),
-    ('\U00000c46', '\U00000c48'),
-    ('\U00000c4a', '\U00000c4d'),
-    ('\U00000c55', '\U00000c56'),
-    ('\U00000c62', '\U00000c63'),
-    ('\U00000cbc', '\U00000cbc'),
-    ('\U00000cbf', '\U00000cbf'),
-    ('\U00000cc6', '\U00000cc6'),
-    ('\U00000ccc', '\U00000ccd'),
-    ('\U00000ce2', '\U00000ce3'),
-    ('\U00000d41', '\U00000d44'),
-    ('\U00000d4d', '\U00000d4d'),
-    ('\U00000d62', '\U00000d63'),
-    ('\U00000dca', '\U00000dca'),
-    ('\U00000dd2', '\U00000dd4'),
-    ('\U00000dd6', '\U00000dd6'),
-    ('\U00000e31', '\U00000e31'),
-    ('\U00000e34', '\U00000e3a'),
-    ('\U00000e47', '\U00000e4e'),
-    ('\U00000eb1', '\U00000eb1'),
-    ('\U00000eb4', '\U00000eb9'),
-    ('\U00000ebb', '\U00000ebc'),
-    ('\U00000ec8', '\U00000ecd'),
-    ('\U00000f18', '\U00000f19'),
-    ('\U00000f35', '\U00000f35'),
-    ('\U00000f37', '\U00000f37'),
-    ('\U00000f39', '\U00000f39'),
-    ('\U00000f71', '\U00000f7e'),
-    ('\U00000f80', '\U00000f84'),
-    ('\U00000f86', '\U00000f87'),
-    ('\U00000f8d', '\U00000f97'),
-    ('\U00000f99', '\U00000fbc'),
-    ('\U00000fc6', '\U00000fc6'),
-    ('\U0000102d', '\U00001030'),
-    ('\U00001032', '\U00001037'),
-    ('\U00001039', '\U0000103a'),
-    ('\U0000103d', '\U0000103e'),
-    ('\U00001058', '\U00001059'),
-    ('\U0000105e', '\U00001060'),
-    ('\U00001071', '\U00001074'),
-    ('\U00001082', '\U00001082'),
-    ('\U00001085', '\U00001086'),
-    ('\U0000108d', '\U0000108d'),
-    ('\U0000109d', '\U0000109d'),
-    ('\U0000135d', '\U0000135f'),
-    ('\U00001712', '\U00001714'),
-    ('\U00001732', '\U00001734'),
-    ('\U00001752', '\U00001753'),
-    ('\U00001772', '\U00001773'),
-    ('\U000017b4', '\U000017b5'),
-    ('\U000017b7', '\U000017bd'),
-    ('\U000017c6', '\U000017c6'),
-    ('\U000017c9', '\U000017d3'),
-    ('\U000017dd', '\U000017dd'),
-    ('\U0000180b', '\U0000180d'),
-    ('\U000018a9', '\U000018a9'),
-    ('\U00001920', '\U00001922'),
-    ('\U00001927', '\U00001928'),
-    ('\U00001932', '\U00001932'),
-    ('\U00001939', '\U0000193b'),
-    ('\U00001a17', '\U00001a18'),
-    ('\U00001a1b', '\U00001a1b'),
-    ('\U00001a56', '\U00001a56'),
-    ('\U00001a58', '\U00001a5e'),
-    ('\U00001a60', '\U00001a60'),
-    ('\U00001a62', '\U00001a62'),
-    ('\U00001a65', '\U00001a6c'),
-    ('\U00001a73', '\U00001a7c'),
-    ('\U00001a7f', '\U00001a7f'),
-    ('\U00001b00', '\U00001b03'),
-    ('\U00001b34', '\U00001b34'),
-    ('\U00001b36', '\U00001b3a'),
-    ('\U00001b3c', '\U00001b3c'),
-    ('\U00001b42', '\U00001b42'),
-    ('\U00001b6b', '\U00001b73'),
-    ('\U00001b80', '\U00001b81'),
-    ('\U00001ba2', '\U00001ba5'),
-    ('\U00001ba8', '\U00001ba9'),
-    ('\U00001bab', '\U00001bab'),
-    ('\U00001be6', '\U00001be6'),
-    ('\U00001be8', '\U00001be9'),
-    ('\U00001bed', '\U00001bed'),
-    ('\U00001bef', '\U00001bf1'),
-    ('\U00001c2c', '\U00001c33'),
-    ('\U00001c36', '\U00001c37'),
-    ('\U00001cd0', '\U00001cd2'),
-    ('\U00001cd4', '\U00001ce0'),
-    ('\U00001ce2', '\U00001ce8'),
-    ('\U00001ced', '\U00001ced'),
-    ('\U00001cf4', '\U00001cf4'),
-    ('\U00001dc0', '\U00001de6'),
-    ('\U00001dfc', '\U00001dff'),
-    ('\U000020d0', '\U000020dc'),
-    ('\U000020e1', '\U000020e1'),
-    ('\U000020e5', '\U000020f0'),
-    ('\U00002cef', '\U00002cf1'),
-    ('\U00002d7f', '\U00002d7f'),
-    ('\U00002de0', '\U00002dff'),
-    ('\U0000302a', '\U0000302d'),
-    ('\U00003099', '\U0000309a'),
-    ('\U0000a66f', '\U0000a66f'),
-    ('\U0000a674', '\U0000a67d'),
-    ('\U0000a69f', '\U0000a69f'),
-    ('\U0000a6f0', '\U0000a6f1'),
-    ('\U0000a802', '\U0000a802'),
-    ('\U0000a806', '\U0000a806'),
-    ('\U0000a80b', '\U0000a80b'),
-    ('\U0000a825', '\U0000a826'),
-    ('\U0000a8c4', '\U0000a8c4'),
-    ('\U0000a8e0', '\U0000a8f1'),
-    ('\U0000a926', '\U0000a92d'),
-    ('\U0000a947', '\U0000a951'),
-    ('\U0000a980', '\U0000a982'),
-    ('\U0000a9b3', '\U0000a9b3'),
-    ('\U0000a9b6', '\U0000a9b9'),
-    ('\U0000a9bc', '\U0000a9bc'),
-    ('\U0000aa29', '\U0000aa2e'),
-    ('\U0000aa31', '\U0000aa32'),
-    ('\U0000aa35', '\U0000aa36'),
-    ('\U0000aa43', '\U0000aa43'),
-    ('\U0000aa4c', '\U0000aa4c'),
-    ('\U0000aab0', '\U0000aab0'),
-    ('\U0000aab2', '\U0000aab4'),
-    ('\U0000aab7', '\U0000aab8'),
-    ('\U0000aabe', '\U0000aabf'),
-    ('\U0000aac1', '\U0000aac1'),
-    ('\U0000aaec', '\U0000aaed'),
-    ('\U0000aaf6', '\U0000aaf6'),
-    ('\U0000abe5', '\U0000abe5'),
-    ('\U0000abe8', '\U0000abe8'),
-    ('\U0000abed', '\U0000abed'),
-    ('\U0000fb1e', '\U0000fb1e'),
-    ('\U0000fe00', '\U0000fe0f'),
-    ('\U0000fe20', '\U0000fe26'),
-    ('\U000101fd', '\U000101fd'),
-    ('\U00010a01', '\U00010a03'),
-    ('\U00010a05', '\U00010a06'),
-    ('\U00010a0c', '\U00010a0f'),
-    ('\U00010a38', '\U00010a3a'),
-    ('\U00010a3f', '\U00010a3f'),
-    ('\U00011001', '\U00011001'),
-    ('\U00011038', '\U00011046'),
-    ('\U00011080', '\U00011081'),
-    ('\U000110b3', '\U000110b6'),
-    ('\U000110b9', '\U000110ba'),
-    ('\U00011100', '\U00011102'),
-    ('\U00011127', '\U0001112b'),
-    ('\U0001112d', '\U00011134'),
-    ('\U00011180', '\U00011181'),
-    ('\U000111b6', '\U000111be'),
-    ('\U000116ab', '\U000116ab'),
-    ('\U000116ad', '\U000116ad'),
-    ('\U000116b0', '\U000116b5'),
-    ('\U000116b7', '\U000116b7'),
-    ('\U00016f8f', '\U00016f92'),
-    ('\U0001d167', '\U0001d169'),
-    ('\U0001d17b', '\U0001d182'),
-    ('\U0001d185', '\U0001d18b'),
-    ('\U0001d1aa', '\U0001d1ad'),
-    ('\U0001d242', '\U0001d244'),
-    ('\U000e0100', '\U000e01ef')
-    ]),
-("Mongolian", &[
-    ('\U00001800', '\U00001801'),
-    ('\U00001804', '\U00001804'),
-    ('\U00001806', '\U0000180e'),
-    ('\U00001810', '\U00001819'),
-    ('\U00001820', '\U00001877'),
-    ('\U00001880', '\U000018aa')
-    ]),
-("Myanmar", &[
-    ('\U00001000', '\U0000109f'),
-    ('\U0000aa60', '\U0000aa7b')
-    ]),
-("N", &[
-    ('\U00000030', '\U00000039'),
-    ('\U00000660', '\U00000669'),
-    ('\U000006f0', '\U000006f9'),
-    ('\U000007c0', '\U000007c9'),
-    ('\U00000966', '\U0000096f'),
-    ('\U000009e6', '\U000009ef'),
-    ('\U00000a66', '\U00000a6f'),
-    ('\U00000ae6', '\U00000aef'),
-    ('\U00000b66', '\U00000b6f'),
-    ('\U00000be6', '\U00000bef'),
-    ('\U00000c66', '\U00000c6f'),
-    ('\U00000ce6', '\U00000cef'),
-    ('\U00000d66', '\U00000d6f'),
-    ('\U00000e50', '\U00000e59'),
-    ('\U00000ed0', '\U00000ed9'),
-    ('\U00000f20', '\U00000f29'),
-    ('\U00001040', '\U00001049'),
-    ('\U00001090', '\U00001099'),
-    ('\U000016ee', '\U000016f0'),
-    ('\U000017e0', '\U000017e9'),
-    ('\U00001810', '\U00001819'),
-    ('\U00001946', '\U0000194f'),
-    ('\U000019d0', '\U000019d9'),
-    ('\U00001a80', '\U00001a89'),
-    ('\U00001a90', '\U00001a99'),
-    ('\U00001b50', '\U00001b59'),
-    ('\U00001bb0', '\U00001bb9'),
-    ('\U00001c40', '\U00001c49'),
-    ('\U00001c50', '\U00001c59'),
-    ('\U00002160', '\U00002182'),
-    ('\U00002185', '\U00002188'),
-    ('\U00003007', '\U00003007'),
-    ('\U00003021', '\U00003029'),
-    ('\U00003038', '\U0000303a'),
-    ('\U0000a620', '\U0000a629'),
-    ('\U0000a6e6', '\U0000a6ef'),
-    ('\U0000a8d0', '\U0000a8d9'),
-    ('\U0000a900', '\U0000a909'),
-    ('\U0000a9d0', '\U0000a9d9'),
-    ('\U0000aa50', '\U0000aa59'),
-    ('\U0000abf0', '\U0000abf9'),
-    ('\U0000ff10', '\U0000ff19'),
-    ('\U00010140', '\U00010174'),
-    ('\U00010341', '\U00010341'),
-    ('\U0001034a', '\U0001034a'),
-    ('\U000103d1', '\U000103d5'),
-    ('\U000104a0', '\U000104a9'),
-    ('\U00011066', '\U0001106f'),
-    ('\U000110f0', '\U000110f9'),
-    ('\U00011136', '\U0001113f'),
-    ('\U000111d0', '\U000111d9'),
-    ('\U000116c0', '\U000116c9'),
-    ('\U00012400', '\U00012462'),
-    ('\U0001d7ce', '\U0001d7ff')
-    ]),
-("Nd", &[
-    ('\U00000030', '\U00000039'),
-    ('\U00000660', '\U00000669'),
-    ('\U000006f0', '\U000006f9'),
-    ('\U000007c0', '\U000007c9'),
-    ('\U00000966', '\U0000096f'),
-    ('\U000009e6', '\U000009ef'),
-    ('\U00000a66', '\U00000a6f'),
-    ('\U00000ae6', '\U00000aef'),
-    ('\U00000b66', '\U00000b6f'),
-    ('\U00000be6', '\U00000bef'),
-    ('\U00000c66', '\U00000c6f'),
-    ('\U00000ce6', '\U00000cef'),
-    ('\U00000d66', '\U00000d6f'),
-    ('\U00000e50', '\U00000e59'),
-    ('\U00000ed0', '\U00000ed9'),
-    ('\U00000f20', '\U00000f29'),
-    ('\U00001040', '\U00001049'),
-    ('\U00001090', '\U00001099'),
-    ('\U000017e0', '\U000017e9'),
-    ('\U00001810', '\U00001819'),
-    ('\U00001946', '\U0000194f'),
-    ('\U000019d0', '\U000019d9'),
-    ('\U00001a80', '\U00001a89'),
-    ('\U00001a90', '\U00001a99'),
-    ('\U00001b50', '\U00001b59'),
-    ('\U00001bb0', '\U00001bb9'),
-    ('\U00001c40', '\U00001c49'),
-    ('\U00001c50', '\U00001c59'),
-    ('\U0000a620', '\U0000a629'),
-    ('\U0000a8d0', '\U0000a8d9'),
-    ('\U0000a900', '\U0000a909'),
-    ('\U0000a9d0', '\U0000a9d9'),
-    ('\U0000aa50', '\U0000aa59'),
-    ('\U0000abf0', '\U0000abf9'),
-    ('\U0000ff10', '\U0000ff19'),
-    ('\U000104a0', '\U000104a9'),
-    ('\U00011066', '\U0001106f'),
-    ('\U000110f0', '\U000110f9'),
-    ('\U00011136', '\U0001113f'),
-    ('\U000111d0', '\U000111d9'),
-    ('\U000116c0', '\U000116c9'),
-    ('\U0001d7ce', '\U0001d7ff')
-    ]),
-("New_Tai_Lue", &[
-    ('\U00001980', '\U000019ab'),
-    ('\U000019b0', '\U000019c9'),
-    ('\U000019d0', '\U000019da'),
-    ('\U000019de', '\U000019df')
-    ]),
-("Nko", &[
-    ('\U000007c0', '\U000007fa')
-    ]),
-("Nl", &[
-    ('\U000016ee', '\U000016f0'),
-    ('\U00002160', '\U00002182'),
-    ('\U00002185', '\U00002188'),
-    ('\U00003007', '\U00003007'),
-    ('\U00003021', '\U00003029'),
-    ('\U00003038', '\U0000303a'),
-    ('\U0000a6e6', '\U0000a6ef'),
-    ('\U00010140', '\U00010174'),
-    ('\U00010341', '\U00010341'),
-    ('\U0001034a', '\U0001034a'),
-    ('\U000103d1', '\U000103d5'),
-    ('\U00012400', '\U00012462')
-    ]),
-("No", &[
-    ('\U000000b2', '\U000000b3'),
-    ('\U000000b9', '\U000000b9'),
-    ('\U000000bc', '\U000000be'),
-    ('\U000009f4', '\U000009f9'),
-    ('\U00000b72', '\U00000b77'),
-    ('\U00000bf0', '\U00000bf2'),
-    ('\U00000c78', '\U00000c7e'),
-    ('\U00000d70', '\U00000d75'),
-    ('\U00000f2a', '\U00000f33'),
-    ('\U00001369', '\U0000137c'),
-    ('\U000017f0', '\U000017f9'),
-    ('\U000019da', '\U000019da'),
-    ('\U00002070', '\U00002070'),
-    ('\U00002074', '\U00002079'),
-    ('\U00002080', '\U00002089'),
-    ('\U00002150', '\U0000215f'),
-    ('\U00002189', '\U00002189'),
-    ('\U00002460', '\U0000249b'),
-    ('\U000024ea', '\U000024ff'),
-    ('\U00002776', '\U00002793'),
-    ('\U00002cfd', '\U00002cfd'),
-    ('\U00003192', '\U00003195'),
-    ('\U00003220', '\U00003229'),
-    ('\U00003248', '\U0000324f'),
-    ('\U00003251', '\U0000325f'),
-    ('\U00003280', '\U00003289'),
-    ('\U000032b1', '\U000032bf'),
-    ('\U0000a830', '\U0000a835'),
-    ('\U00010107', '\U00010133'),
-    ('\U00010175', '\U00010178'),
-    ('\U0001018a', '\U0001018a'),
-    ('\U00010320', '\U00010323'),
-    ('\U00010858', '\U0001085f'),
-    ('\U00010916', '\U0001091b'),
-    ('\U00010a40', '\U00010a47'),
-    ('\U00010a7d', '\U00010a7e'),
-    ('\U00010b58', '\U00010b5f'),
-    ('\U00010b78', '\U00010b7f'),
-    ('\U00010e60', '\U00010e7e'),
-    ('\U00011052', '\U00011065'),
-    ('\U0001d360', '\U0001d371'),
-    ('\U0001f100', '\U0001f10a')
-    ]),
-("Ogham", &[
-    ('\U00001680', '\U0000169c')
-    ]),
-("Ol_Chiki", &[
-    ('\U00001c50', '\U00001c7f')
-    ]),
-("Old_Italic", &[
-    ('\U00010300', '\U0001031e'),
-    ('\U00010320', '\U00010323')
-    ]),
-("Old_Persian", &[
-    ('\U000103a0', '\U000103c3'),
-    ('\U000103c8', '\U000103d5')
-    ]),
-("Old_South_Arabian", &[
-    ('\U00010a60', '\U00010a7f')
-    ]),
-("Old_Turkic", &[
-    ('\U00010c00', '\U00010c48')
-    ]),
-("Oriya", &[
-    ('\U00000b01', '\U00000b03'),
-    ('\U00000b05', '\U00000b0c'),
-    ('\U00000b0f', '\U00000b10'),
-    ('\U00000b13', '\U00000b28'),
-    ('\U00000b2a', '\U00000b30'),
-    ('\U00000b32', '\U00000b33'),
-    ('\U00000b35', '\U00000b39'),
-    ('\U00000b3c', '\U00000b44'),
-    ('\U00000b47', '\U00000b48'),
-    ('\U00000b4b', '\U00000b4d'),
-    ('\U00000b56', '\U00000b57'),
-    ('\U00000b5c', '\U00000b5d'),
-    ('\U00000b5f', '\U00000b63'),
-    ('\U00000b66', '\U00000b77')
-    ]),
-("Osmanya", &[
-    ('\U00010480', '\U0001049d'),
-    ('\U000104a0', '\U000104a9')
-    ]),
-("P", &[
-    ('\U00000021', '\U00000023'),
-    ('\U00000025', '\U0000002a'),
-    ('\U0000002c', '\U0000002f'),
-    ('\U0000003a', '\U0000003b'),
-    ('\U0000003f', '\U00000040'),
-    ('\U0000005b', '\U0000005d'),
-    ('\U0000005f', '\U0000005f'),
-    ('\U0000007b', '\U0000007b'),
-    ('\U0000007d', '\U0000007d'),
-    ('\U000000a1', '\U000000a1'),
-    ('\U000000a7', '\U000000a7'),
-    ('\U000000ab', '\U000000ab'),
-    ('\U000000b6', '\U000000b7'),
-    ('\U000000bb', '\U000000bb'),
-    ('\U000000bf', '\U000000bf'),
-    ('\U0000037e', '\U0000037e'),
-    ('\U00000387', '\U00000387'),
-    ('\U0000055a', '\U0000055f'),
-    ('\U00000589', '\U0000058a'),
-    ('\U000005be', '\U000005be'),
-    ('\U000005c0', '\U000005c0'),
-    ('\U000005c3', '\U000005c3'),
-    ('\U000005c6', '\U000005c6'),
-    ('\U000005f3', '\U000005f4'),
-    ('\U00000609', '\U0000060a'),
-    ('\U0000060c', '\U0000060d'),
-    ('\U0000061b', '\U0000061b'),
-    ('\U0000061e', '\U0000061f'),
-    ('\U0000066a', '\U0000066d'),
-    ('\U000006d4', '\U000006d4'),
-    ('\U00000700', '\U0000070d'),
-    ('\U000007f7', '\U000007f9'),
-    ('\U00000830', '\U0000083e'),
-    ('\U0000085e', '\U0000085e'),
-    ('\U00000964', '\U00000965'),
-    ('\U00000970', '\U00000970'),
-    ('\U00000af0', '\U00000af0'),
-    ('\U00000df4', '\U00000df4'),
-    ('\U00000e4f', '\U00000e4f'),
-    ('\U00000e5a', '\U00000e5b'),
-    ('\U00000f04', '\U00000f12'),
-    ('\U00000f14', '\U00000f14'),
-    ('\U00000f3a', '\U00000f3d'),
-    ('\U00000f85', '\U00000f85'),
-    ('\U00000fd0', '\U00000fd4'),
-    ('\U00000fd9', '\U00000fda'),
-    ('\U0000104a', '\U0000104f'),
-    ('\U000010fb', '\U000010fb'),
-    ('\U00001360', '\U00001368'),
-    ('\U00001400', '\U00001400'),
-    ('\U0000166d', '\U0000166e'),
-    ('\U0000169b', '\U0000169c'),
-    ('\U000016eb', '\U000016ed'),
-    ('\U00001735', '\U00001736'),
-    ('\U000017d4', '\U000017d6'),
-    ('\U000017d8', '\U000017da'),
-    ('\U00001800', '\U0000180a'),
-    ('\U00001944', '\U00001945'),
-    ('\U00001a1e', '\U00001a1f'),
-    ('\U00001aa0', '\U00001aa6'),
-    ('\U00001aa8', '\U00001aad'),
-    ('\U00001b5a', '\U00001b60'),
-    ('\U00001bfc', '\U00001bff'),
-    ('\U00001c3b', '\U00001c3f'),
-    ('\U00001c7e', '\U00001c7f'),
-    ('\U00001cc0', '\U00001cc7'),
-    ('\U00001cd3', '\U00001cd3'),
-    ('\U00002010', '\U00002027'),
-    ('\U00002030', '\U00002043'),
-    ('\U00002045', '\U00002051'),
-    ('\U00002053', '\U0000205e'),
-    ('\U0000207d', '\U0000207e'),
-    ('\U0000208d', '\U0000208e'),
-    ('\U00002308', '\U0000230b'),
-    ('\U00002329', '\U0000232a'),
-    ('\U00002768', '\U00002775'),
-    ('\U000027c5', '\U000027c6'),
-    ('\U000027e6', '\U000027ef'),
-    ('\U00002983', '\U00002998'),
-    ('\U000029d8', '\U000029db'),
-    ('\U000029fc', '\U000029fd'),
-    ('\U00002cf9', '\U00002cfc'),
-    ('\U00002cfe', '\U00002cff'),
-    ('\U00002d70', '\U00002d70'),
-    ('\U00002e00', '\U00002e2e'),
-    ('\U00002e30', '\U00002e3b'),
-    ('\U00003001', '\U00003003'),
-    ('\U00003008', '\U00003011'),
-    ('\U00003014', '\U0000301f'),
-    ('\U00003030', '\U00003030'),
-    ('\U0000303d', '\U0000303d'),
-    ('\U000030a0', '\U000030a0'),
-    ('\U000030fb', '\U000030fb'),
-    ('\U0000a4fe', '\U0000a4ff'),
-    ('\U0000a60d', '\U0000a60f'),
-    ('\U0000a673', '\U0000a673'),
-    ('\U0000a67e', '\U0000a67e'),
-    ('\U0000a6f2', '\U0000a6f7'),
-    ('\U0000a874', '\U0000a877'),
-    ('\U0000a8ce', '\U0000a8cf'),
-    ('\U0000a8f8', '\U0000a8fa'),
-    ('\U0000a92e', '\U0000a92f'),
-    ('\U0000a95f', '\U0000a95f'),
-    ('\U0000a9c1', '\U0000a9cd'),
-    ('\U0000a9de', '\U0000a9df'),
-    ('\U0000aa5c', '\U0000aa5f'),
-    ('\U0000aade', '\U0000aadf'),
-    ('\U0000aaf0', '\U0000aaf1'),
-    ('\U0000abeb', '\U0000abeb'),
-    ('\U0000fd3e', '\U0000fd3f'),
-    ('\U0000fe10', '\U0000fe19'),
-    ('\U0000fe30', '\U0000fe52'),
-    ('\U0000fe54', '\U0000fe61'),
-    ('\U0000fe63', '\U0000fe63'),
-    ('\U0000fe68', '\U0000fe68'),
-    ('\U0000fe6a', '\U0000fe6b'),
-    ('\U0000ff01', '\U0000ff03'),
-    ('\U0000ff05', '\U0000ff0a'),
-    ('\U0000ff0c', '\U0000ff0f'),
-    ('\U0000ff1a', '\U0000ff1b'),
-    ('\U0000ff1f', '\U0000ff20'),
-    ('\U0000ff3b', '\U0000ff3d'),
-    ('\U0000ff3f', '\U0000ff3f'),
-    ('\U0000ff5b', '\U0000ff5b'),
-    ('\U0000ff5d', '\U0000ff5d'),
-    ('\U0000ff5f', '\U0000ff65'),
-    ('\U00010100', '\U00010102'),
-    ('\U0001039f', '\U0001039f'),
-    ('\U000103d0', '\U000103d0'),
-    ('\U00010857', '\U00010857'),
-    ('\U0001091f', '\U0001091f'),
-    ('\U0001093f', '\U0001093f'),
-    ('\U00010a50', '\U00010a58'),
-    ('\U00010a7f', '\U00010a7f'),
-    ('\U00010b39', '\U00010b3f'),
-    ('\U00011047', '\U0001104d'),
-    ('\U000110bb', '\U000110bc'),
-    ('\U000110be', '\U000110c1'),
-    ('\U00011140', '\U00011143'),
-    ('\U000111c5', '\U000111c8'),
-    ('\U00012470', '\U00012473')
-    ]),
-("Pc", &[
-    ('\U0000005f', '\U0000005f'),
-    ('\U0000203f', '\U00002040'),
-    ('\U00002054', '\U00002054'),
-    ('\U0000fe33', '\U0000fe34'),
-    ('\U0000fe4d', '\U0000fe4f'),
-    ('\U0000ff3f', '\U0000ff3f')
-    ]),
-("Pd", &[
-    ('\U0000002d', '\U0000002d'),
-    ('\U0000058a', '\U0000058a'),
-    ('\U000005be', '\U000005be'),
-    ('\U00001400', '\U00001400'),
-    ('\U00001806', '\U00001806'),
-    ('\U00002010', '\U00002015'),
-    ('\U00002e17', '\U00002e17'),
-    ('\U00002e1a', '\U00002e1a'),
-    ('\U00002e3a', '\U00002e3b'),
-    ('\U0000301c', '\U0000301c'),
-    ('\U00003030', '\U00003030'),
-    ('\U000030a0', '\U000030a0'),
-    ('\U0000fe31', '\U0000fe32'),
-    ('\U0000fe58', '\U0000fe58'),
-    ('\U0000fe63', '\U0000fe63'),
-    ('\U0000ff0d', '\U0000ff0d')
-    ]),
-("Pe", &[
-    ('\U00000029', '\U00000029'),
-    ('\U0000005d', '\U0000005d'),
-    ('\U0000007d', '\U0000007d'),
-    ('\U00000f3b', '\U00000f3b'),
-    ('\U00000f3d', '\U00000f3d'),
-    ('\U0000169c', '\U0000169c'),
-    ('\U00002046', '\U00002046'),
-    ('\U0000207e', '\U0000207e'),
-    ('\U0000208e', '\U0000208e'),
-    ('\U00002309', '\U00002309'),
-    ('\U0000230b', '\U0000230b'),
-    ('\U0000232a', '\U0000232a'),
-    ('\U00002769', '\U00002769'),
-    ('\U0000276b', '\U0000276b'),
-    ('\U0000276d', '\U0000276d'),
-    ('\U0000276f', '\U0000276f'),
-    ('\U00002771', '\U00002771'),
-    ('\U00002773', '\U00002773'),
-    ('\U00002775', '\U00002775'),
-    ('\U000027c6', '\U000027c6'),
-    ('\U000027e7', '\U000027e7'),
-    ('\U000027e9', '\U000027e9'),
-    ('\U000027eb', '\U000027eb'),
-    ('\U000027ed', '\U000027ed'),
-    ('\U000027ef', '\U000027ef'),
-    ('\U00002984', '\U00002984'),
-    ('\U00002986', '\U00002986'),
-    ('\U00002988', '\U00002988'),
-    ('\U0000298a', '\U0000298a'),
-    ('\U0000298c', '\U0000298c'),
-    ('\U0000298e', '\U0000298e'),
-    ('\U00002990', '\U00002990'),
-    ('\U00002992', '\U00002992'),
-    ('\U00002994', '\U00002994'),
-    ('\U00002996', '\U00002996'),
-    ('\U00002998', '\U00002998'),
-    ('\U000029d9', '\U000029d9'),
-    ('\U000029db', '\U000029db'),
-    ('\U000029fd', '\U000029fd'),
-    ('\U00002e23', '\U00002e23'),
-    ('\U00002e25', '\U00002e25'),
-    ('\U00002e27', '\U00002e27'),
-    ('\U00002e29', '\U00002e29'),
-    ('\U00003009', '\U00003009'),
-    ('\U0000300b', '\U0000300b'),
-    ('\U0000300d', '\U0000300d'),
-    ('\U0000300f', '\U0000300f'),
-    ('\U00003011', '\U00003011'),
-    ('\U00003015', '\U00003015'),
-    ('\U00003017', '\U00003017'),
-    ('\U00003019', '\U00003019'),
-    ('\U0000301b', '\U0000301b'),
-    ('\U0000301e', '\U0000301f'),
-    ('\U0000fd3f', '\U0000fd3f'),
-    ('\U0000fe18', '\U0000fe18'),
-    ('\U0000fe36', '\U0000fe36'),
-    ('\U0000fe38', '\U0000fe38'),
-    ('\U0000fe3a', '\U0000fe3a'),
-    ('\U0000fe3c', '\U0000fe3c'),
-    ('\U0000fe3e', '\U0000fe3e'),
-    ('\U0000fe40', '\U0000fe40'),
-    ('\U0000fe42', '\U0000fe42'),
-    ('\U0000fe44', '\U0000fe44'),
-    ('\U0000fe48', '\U0000fe48'),
-    ('\U0000fe5a', '\U0000fe5a'),
-    ('\U0000fe5c', '\U0000fe5c'),
-    ('\U0000fe5e', '\U0000fe5e'),
-    ('\U0000ff09', '\U0000ff09'),
-    ('\U0000ff3d', '\U0000ff3d'),
-    ('\U0000ff5d', '\U0000ff5d'),
-    ('\U0000ff60', '\U0000ff60'),
-    ('\U0000ff63', '\U0000ff63')
-    ]),
-("Pf", &[
-    ('\U000000bb', '\U000000bb'),
-    ('\U00002019', '\U00002019'),
-    ('\U0000201d', '\U0000201d'),
-    ('\U0000203a', '\U0000203a'),
-    ('\U00002e03', '\U00002e03'),
-    ('\U00002e05', '\U00002e05'),
-    ('\U00002e0a', '\U00002e0a'),
-    ('\U00002e0d', '\U00002e0d'),
-    ('\U00002e1d', '\U00002e1d'),
-    ('\U00002e21', '\U00002e21')
-    ]),
-("Phags_Pa", &[
-    ('\U0000a840', '\U0000a877')
-    ]),
-("Phoenician", &[
-    ('\U00010900', '\U0001091b'),
-    ('\U0001091f', '\U0001091f')
-    ]),
-("Pi", &[
-    ('\U000000ab', '\U000000ab'),
-    ('\U00002018', '\U00002018'),
-    ('\U0000201b', '\U0000201c'),
-    ('\U0000201f', '\U0000201f'),
-    ('\U00002039', '\U00002039'),
-    ('\U00002e02', '\U00002e02'),
-    ('\U00002e04', '\U00002e04'),
-    ('\U00002e09', '\U00002e09'),
-    ('\U00002e0c', '\U00002e0c'),
-    ('\U00002e1c', '\U00002e1c'),
-    ('\U00002e20', '\U00002e20')
-    ]),
-("Po", &[
-    ('\U00000021', '\U00000023'),
-    ('\U00000025', '\U00000027'),
-    ('\U0000002a', '\U0000002a'),
-    ('\U0000002c', '\U0000002c'),
-    ('\U0000002e', '\U0000002f'),
-    ('\U0000003a', '\U0000003b'),
-    ('\U0000003f', '\U00000040'),
-    ('\U0000005c', '\U0000005c'),
-    ('\U000000a1', '\U000000a1'),
-    ('\U000000a7', '\U000000a7'),
-    ('\U000000b6', '\U000000b7'),
-    ('\U000000bf', '\U000000bf'),
-    ('\U0000037e', '\U0000037e'),
-    ('\U00000387', '\U00000387'),
-    ('\U0000055a', '\U0000055f'),
-    ('\U00000589', '\U00000589'),
-    ('\U000005c0', '\U000005c0'),
-    ('\U000005c3', '\U000005c3'),
-    ('\U000005c6', '\U000005c6'),
-    ('\U000005f3', '\U000005f4'),
-    ('\U00000609', '\U0000060a'),
-    ('\U0000060c', '\U0000060d'),
-    ('\U0000061b', '\U0000061b'),
-    ('\U0000061e', '\U0000061f'),
-    ('\U0000066a', '\U0000066d'),
-    ('\U000006d4', '\U000006d4'),
-    ('\U00000700', '\U0000070d'),
-    ('\U000007f7', '\U000007f9'),
-    ('\U00000830', '\U0000083e'),
-    ('\U0000085e', '\U0000085e'),
-    ('\U00000964', '\U00000965'),
-    ('\U00000970', '\U00000970'),
-    ('\U00000af0', '\U00000af0'),
-    ('\U00000df4', '\U00000df4'),
-    ('\U00000e4f', '\U00000e4f'),
-    ('\U00000e5a', '\U00000e5b'),
-    ('\U00000f04', '\U00000f12'),
-    ('\U00000f14', '\U00000f14'),
-    ('\U00000f85', '\U00000f85'),
-    ('\U00000fd0', '\U00000fd4'),
-    ('\U00000fd9', '\U00000fda'),
-    ('\U0000104a', '\U0000104f'),
-    ('\U000010fb', '\U000010fb'),
-    ('\U00001360', '\U00001368'),
-    ('\U0000166d', '\U0000166e'),
-    ('\U000016eb', '\U000016ed'),
-    ('\U00001735', '\U00001736'),
-    ('\U000017d4', '\U000017d6'),
-    ('\U000017d8', '\U000017da'),
-    ('\U00001800', '\U00001805'),
-    ('\U00001807', '\U0000180a'),
-    ('\U00001944', '\U00001945'),
-    ('\U00001a1e', '\U00001a1f'),
-    ('\U00001aa0', '\U00001aa6'),
-    ('\U00001aa8', '\U00001aad'),
-    ('\U00001b5a', '\U00001b60'),
-    ('\U00001bfc', '\U00001bff'),
-    ('\U00001c3b', '\U00001c3f'),
-    ('\U00001c7e', '\U00001c7f'),
-    ('\U00001cc0', '\U00001cc7'),
-    ('\U00001cd3', '\U00001cd3'),
-    ('\U00002016', '\U00002017'),
-    ('\U00002020', '\U00002027'),
-    ('\U00002030', '\U00002038'),
-    ('\U0000203b', '\U0000203e'),
-    ('\U00002041', '\U00002043'),
-    ('\U00002047', '\U00002051'),
-    ('\U00002053', '\U00002053'),
-    ('\U00002055', '\U0000205e'),
-    ('\U00002cf9', '\U00002cfc'),
-    ('\U00002cfe', '\U00002cff'),
-    ('\U00002d70', '\U00002d70'),
-    ('\U00002e00', '\U00002e01'),
-    ('\U00002e06', '\U00002e08'),
-    ('\U00002e0b', '\U00002e0b'),
-    ('\U00002e0e', '\U00002e16'),
-    ('\U00002e18', '\U00002e19'),
-    ('\U00002e1b', '\U00002e1b'),
-    ('\U00002e1e', '\U00002e1f'),
-    ('\U00002e2a', '\U00002e2e'),
-    ('\U00002e30', '\U00002e39'),
-    ('\U00003001', '\U00003003'),
-    ('\U0000303d', '\U0000303d'),
-    ('\U000030fb', '\U000030fb'),
-    ('\U0000a4fe', '\U0000a4ff'),
-    ('\U0000a60d', '\U0000a60f'),
-    ('\U0000a673', '\U0000a673'),
-    ('\U0000a67e', '\U0000a67e'),
-    ('\U0000a6f2', '\U0000a6f7'),
-    ('\U0000a874', '\U0000a877'),
-    ('\U0000a8ce', '\U0000a8cf'),
-    ('\U0000a8f8', '\U0000a8fa'),
-    ('\U0000a92e', '\U0000a92f'),
-    ('\U0000a95f', '\U0000a95f'),
-    ('\U0000a9c1', '\U0000a9cd'),
-    ('\U0000a9de', '\U0000a9df'),
-    ('\U0000aa5c', '\U0000aa5f'),
-    ('\U0000aade', '\U0000aadf'),
-    ('\U0000aaf0', '\U0000aaf1'),
-    ('\U0000abeb', '\U0000abeb'),
-    ('\U0000fe10', '\U0000fe16'),
-    ('\U0000fe19', '\U0000fe19'),
-    ('\U0000fe30', '\U0000fe30'),
-    ('\U0000fe45', '\U0000fe46'),
-    ('\U0000fe49', '\U0000fe4c'),
-    ('\U0000fe50', '\U0000fe52'),
-    ('\U0000fe54', '\U0000fe57'),
-    ('\U0000fe5f', '\U0000fe61'),
-    ('\U0000fe68', '\U0000fe68'),
-    ('\U0000fe6a', '\U0000fe6b'),
-    ('\U0000ff01', '\U0000ff03'),
-    ('\U0000ff05', '\U0000ff07'),
-    ('\U0000ff0a', '\U0000ff0a'),
-    ('\U0000ff0c', '\U0000ff0c'),
-    ('\U0000ff0e', '\U0000ff0f'),
-    ('\U0000ff1a', '\U0000ff1b'),
-    ('\U0000ff1f', '\U0000ff20'),
-    ('\U0000ff3c', '\U0000ff3c'),
-    ('\U0000ff61', '\U0000ff61'),
-    ('\U0000ff64', '\U0000ff65'),
-    ('\U00010100', '\U00010102'),
-    ('\U0001039f', '\U0001039f'),
-    ('\U000103d0', '\U000103d0'),
-    ('\U00010857', '\U00010857'),
-    ('\U0001091f', '\U0001091f'),
-    ('\U0001093f', '\U0001093f'),
-    ('\U00010a50', '\U00010a58'),
-    ('\U00010a7f', '\U00010a7f'),
-    ('\U00010b39', '\U00010b3f'),
-    ('\U00011047', '\U0001104d'),
-    ('\U000110bb', '\U000110bc'),
-    ('\U000110be', '\U000110c1'),
-    ('\U00011140', '\U00011143'),
-    ('\U000111c5', '\U000111c8'),
-    ('\U00012470', '\U00012473')
-    ]),
-("Ps", &[
-    ('\U00000028', '\U00000028'),
-    ('\U0000005b', '\U0000005b'),
-    ('\U0000007b', '\U0000007b'),
-    ('\U00000f3a', '\U00000f3a'),
-    ('\U00000f3c', '\U00000f3c'),
-    ('\U0000169b', '\U0000169b'),
-    ('\U0000201a', '\U0000201a'),
-    ('\U0000201e', '\U0000201e'),
-    ('\U00002045', '\U00002045'),
-    ('\U0000207d', '\U0000207d'),
-    ('\U0000208d', '\U0000208d'),
-    ('\U00002308', '\U00002308'),
-    ('\U0000230a', '\U0000230a'),
-    ('\U00002329', '\U00002329'),
-    ('\U00002768', '\U00002768'),
-    ('\U0000276a', '\U0000276a'),
-    ('\U0000276c', '\U0000276c'),
-    ('\U0000276e', '\U0000276e'),
-    ('\U00002770', '\U00002770'),
-    ('\U00002772', '\U00002772'),
-    ('\U00002774', '\U00002774'),
-    ('\U000027c5', '\U000027c5'),
-    ('\U000027e6', '\U000027e6'),
-    ('\U000027e8', '\U000027e8'),
-    ('\U000027ea', '\U000027ea'),
-    ('\U000027ec', '\U000027ec'),
-    ('\U000027ee', '\U000027ee'),
-    ('\U00002983', '\U00002983'),
-    ('\U00002985', '\U00002985'),
-    ('\U00002987', '\U00002987'),
-    ('\U00002989', '\U00002989'),
-    ('\U0000298b', '\U0000298b'),
-    ('\U0000298d', '\U0000298d'),
-    ('\U0000298f', '\U0000298f'),
-    ('\U00002991', '\U00002991'),
-    ('\U00002993', '\U00002993'),
-    ('\U00002995', '\U00002995'),
-    ('\U00002997', '\U00002997'),
-    ('\U000029d8', '\U000029d8'),
-    ('\U000029da', '\U000029da'),
-    ('\U000029fc', '\U000029fc'),
-    ('\U00002e22', '\U00002e22'),
-    ('\U00002e24', '\U00002e24'),
-    ('\U00002e26', '\U00002e26'),
-    ('\U00002e28', '\U00002e28'),
-    ('\U00003008', '\U00003008'),
-    ('\U0000300a', '\U0000300a'),
-    ('\U0000300c', '\U0000300c'),
-    ('\U0000300e', '\U0000300e'),
-    ('\U00003010', '\U00003010'),
-    ('\U00003014', '\U00003014'),
-    ('\U00003016', '\U00003016'),
-    ('\U00003018', '\U00003018'),
-    ('\U0000301a', '\U0000301a'),
-    ('\U0000301d', '\U0000301d'),
-    ('\U0000fd3e', '\U0000fd3e'),
-    ('\U0000fe17', '\U0000fe17'),
-    ('\U0000fe35', '\U0000fe35'),
-    ('\U0000fe37', '\U0000fe37'),
-    ('\U0000fe39', '\U0000fe39'),
-    ('\U0000fe3b', '\U0000fe3b'),
-    ('\U0000fe3d', '\U0000fe3d'),
-    ('\U0000fe3f', '\U0000fe3f'),
-    ('\U0000fe41', '\U0000fe41'),
-    ('\U0000fe43', '\U0000fe43'),
-    ('\U0000fe47', '\U0000fe47'),
-    ('\U0000fe59', '\U0000fe59'),
-    ('\U0000fe5b', '\U0000fe5b'),
-    ('\U0000fe5d', '\U0000fe5d'),
-    ('\U0000ff08', '\U0000ff08'),
-    ('\U0000ff3b', '\U0000ff3b'),
-    ('\U0000ff5b', '\U0000ff5b'),
-    ('\U0000ff5f', '\U0000ff5f'),
-    ('\U0000ff62', '\U0000ff62')
-    ]),
-("Rejang", &[
-    ('\U0000a930', '\U0000a953'),
-    ('\U0000a95f', '\U0000a95f')
-    ]),
-("Runic", &[
-    ('\U000016a0', '\U000016ea'),
-    ('\U000016ee', '\U000016f0')
-    ]),
-("S", &[
-    ('\U00000024', '\U00000024'),
-    ('\U0000002b', '\U0000002b'),
-    ('\U0000003c', '\U0000003e'),
-    ('\U0000005e', '\U0000005e'),
-    ('\U00000060', '\U00000060'),
-    ('\U0000007c', '\U0000007c'),
-    ('\U0000007e', '\U0000007e'),
-    ('\U000000a2', '\U000000a6'),
-    ('\U000000a8', '\U000000a9'),
-    ('\U000000ac', '\U000000ac'),
-    ('\U000000ae', '\U000000b1'),
-    ('\U000000b4', '\U000000b4'),
-    ('\U000000b8', '\U000000b8'),
-    ('\U000000d7', '\U000000d7'),
-    ('\U000000f7', '\U000000f7'),
-    ('\U000002c2', '\U000002c5'),
-    ('\U000002d2', '\U000002df'),
-    ('\U000002e5', '\U000002eb'),
-    ('\U000002ed', '\U000002ed'),
-    ('\U000002ef', '\U000002ff'),
-    ('\U00000375', '\U00000375'),
-    ('\U00000384', '\U00000385'),
-    ('\U000003f6', '\U000003f6'),
-    ('\U00000482', '\U00000482'),
-    ('\U0000058f', '\U0000058f'),
-    ('\U00000606', '\U00000608'),
-    ('\U0000060b', '\U0000060b'),
-    ('\U0000060e', '\U0000060f'),
-    ('\U000006de', '\U000006de'),
-    ('\U000006e9', '\U000006e9'),
-    ('\U000006fd', '\U000006fe'),
-    ('\U000007f6', '\U000007f6'),
-    ('\U000009f2', '\U000009f3'),
-    ('\U000009fa', '\U000009fb'),
-    ('\U00000af1', '\U00000af1'),
-    ('\U00000b70', '\U00000b70'),
-    ('\U00000bf3', '\U00000bfa'),
-    ('\U00000c7f', '\U00000c7f'),
-    ('\U00000d79', '\U00000d79'),
-    ('\U00000e3f', '\U00000e3f'),
-    ('\U00000f01', '\U00000f03'),
-    ('\U00000f13', '\U00000f13'),
-    ('\U00000f15', '\U00000f17'),
-    ('\U00000f1a', '\U00000f1f'),
-    ('\U00000f34', '\U00000f34'),
-    ('\U00000f36', '\U00000f36'),
-    ('\U00000f38', '\U00000f38'),
-    ('\U00000fbe', '\U00000fc5'),
-    ('\U00000fc7', '\U00000fcc'),
-    ('\U00000fce', '\U00000fcf'),
-    ('\U00000fd5', '\U00000fd8'),
-    ('\U0000109e', '\U0000109f'),
-    ('\U00001390', '\U00001399'),
-    ('\U000017db', '\U000017db'),
-    ('\U00001940', '\U00001940'),
-    ('\U000019de', '\U000019ff'),
-    ('\U00001b61', '\U00001b6a'),
-    ('\U00001b74', '\U00001b7c'),
-    ('\U00001fbd', '\U00001fbd'),
-    ('\U00001fbf', '\U00001fc1'),
-    ('\U00001fcd', '\U00001fcf'),
-    ('\U00001fdd', '\U00001fdf'),
-    ('\U00001fed', '\U00001fef'),
-    ('\U00001ffd', '\U00001ffe'),
-    ('\U00002044', '\U00002044'),
-    ('\U00002052', '\U00002052'),
-    ('\U0000207a', '\U0000207c'),
-    ('\U0000208a', '\U0000208c'),
-    ('\U000020a0', '\U000020ba'),
-    ('\U00002100', '\U00002101'),
-    ('\U00002103', '\U00002106'),
-    ('\U00002108', '\U00002109'),
-    ('\U00002114', '\U00002114'),
-    ('\U00002116', '\U00002118'),
-    ('\U0000211e', '\U00002123'),
-    ('\U00002125', '\U00002125'),
-    ('\U00002127', '\U00002127'),
-    ('\U00002129', '\U00002129'),
-    ('\U0000212e', '\U0000212e'),
-    ('\U0000213a', '\U0000213b'),
-    ('\U00002140', '\U00002144'),
-    ('\U0000214a', '\U0000214d'),
-    ('\U0000214f', '\U0000214f'),
-    ('\U00002190', '\U00002307'),
-    ('\U0000230c', '\U00002328'),
-    ('\U0000232b', '\U000023f3'),
-    ('\U00002400', '\U00002426'),
-    ('\U00002440', '\U0000244a'),
-    ('\U0000249c', '\U000024e9'),
-    ('\U00002500', '\U000026ff'),
-    ('\U00002701', '\U00002767'),
-    ('\U00002794', '\U000027c4'),
-    ('\U000027c7', '\U000027e5'),
-    ('\U000027f0', '\U00002982'),
-    ('\U00002999', '\U000029d7'),
-    ('\U000029dc', '\U000029fb'),
-    ('\U000029fe', '\U00002b4c'),
-    ('\U00002b50', '\U00002b59'),
-    ('\U00002ce5', '\U00002cea'),
-    ('\U00002e80', '\U00002e99'),
-    ('\U00002e9b', '\U00002ef3'),
-    ('\U00002f00', '\U00002fd5'),
-    ('\U00002ff0', '\U00002ffb'),
-    ('\U00003004', '\U00003004'),
-    ('\U00003012', '\U00003013'),
-    ('\U00003020', '\U00003020'),
-    ('\U00003036', '\U00003037'),
-    ('\U0000303e', '\U0000303f'),
-    ('\U0000309b', '\U0000309c'),
-    ('\U00003190', '\U00003191'),
-    ('\U00003196', '\U0000319f'),
-    ('\U000031c0', '\U000031e3'),
-    ('\U00003200', '\U0000321e'),
-    ('\U0000322a', '\U00003247'),
-    ('\U00003250', '\U00003250'),
-    ('\U00003260', '\U0000327f'),
-    ('\U0000328a', '\U000032b0'),
-    ('\U000032c0', '\U000032fe'),
-    ('\U00003300', '\U000033ff'),
-    ('\U00004dc0', '\U00004dff'),
-    ('\U0000a490', '\U0000a4c6'),
-    ('\U0000a700', '\U0000a716'),
-    ('\U0000a720', '\U0000a721'),
-    ('\U0000a789', '\U0000a78a'),
-    ('\U0000a828', '\U0000a82b'),
-    ('\U0000a836', '\U0000a839'),
-    ('\U0000aa77', '\U0000aa79'),
-    ('\U0000fb29', '\U0000fb29'),
-    ('\U0000fbb2', '\U0000fbc1'),
-    ('\U0000fdfc', '\U0000fdfd'),
-    ('\U0000fe62', '\U0000fe62'),
-    ('\U0000fe64', '\U0000fe66'),
-    ('\U0000fe69', '\U0000fe69'),
-    ('\U0000ff04', '\U0000ff04'),
-    ('\U0000ff0b', '\U0000ff0b'),
-    ('\U0000ff1c', '\U0000ff1e'),
-    ('\U0000ff3e', '\U0000ff3e'),
-    ('\U0000ff40', '\U0000ff40'),
-    ('\U0000ff5c', '\U0000ff5c'),
-    ('\U0000ff5e', '\U0000ff5e'),
-    ('\U0000ffe0', '\U0000ffe6'),
-    ('\U0000ffe8', '\U0000ffee'),
-    ('\U0000fffc', '\U0000fffd'),
-    ('\U00010137', '\U0001013f'),
-    ('\U00010179', '\U00010189'),
-    ('\U00010190', '\U0001019b'),
-    ('\U000101d0', '\U000101fc'),
-    ('\U0001d000', '\U0001d0f5'),
-    ('\U0001d100', '\U0001d126'),
-    ('\U0001d129', '\U0001d164'),
-    ('\U0001d16a', '\U0001d16c'),
-    ('\U0001d183', '\U0001d184'),
-    ('\U0001d18c', '\U0001d1a9'),
-    ('\U0001d1ae', '\U0001d1dd'),
-    ('\U0001d200', '\U0001d241'),
-    ('\U0001d245', '\U0001d245'),
-    ('\U0001d300', '\U0001d356'),
-    ('\U0001d6c1', '\U0001d6c1'),
-    ('\U0001d6db', '\U0001d6db'),
-    ('\U0001d6fb', '\U0001d6fb'),
-    ('\U0001d715', '\U0001d715'),
-    ('\U0001d735', '\U0001d735'),
-    ('\U0001d74f', '\U0001d74f'),
-    ('\U0001d76f', '\U0001d76f'),
-    ('\U0001d789', '\U0001d789'),
-    ('\U0001d7a9', '\U0001d7a9'),
-    ('\U0001d7c3', '\U0001d7c3'),
-    ('\U0001eef0', '\U0001eef1'),
-    ('\U0001f000', '\U0001f02b'),
-    ('\U0001f030', '\U0001f093'),
-    ('\U0001f0a0', '\U0001f0ae'),
-    ('\U0001f0b1', '\U0001f0be'),
-    ('\U0001f0c1', '\U0001f0cf'),
-    ('\U0001f0d1', '\U0001f0df'),
-    ('\U0001f110', '\U0001f12e'),
-    ('\U0001f130', '\U0001f16b'),
-    ('\U0001f170', '\U0001f19a'),
-    ('\U0001f1e6', '\U0001f202'),
-    ('\U0001f210', '\U0001f23a'),
-    ('\U0001f240', '\U0001f248'),
-    ('\U0001f250', '\U0001f251'),
-    ('\U0001f300', '\U0001f320'),
-    ('\U0001f330', '\U0001f335'),
-    ('\U0001f337', '\U0001f37c'),
-    ('\U0001f380', '\U0001f393'),
-    ('\U0001f3a0', '\U0001f3c4'),
-    ('\U0001f3c6', '\U0001f3ca'),
-    ('\U0001f3e0', '\U0001f3f0'),
-    ('\U0001f400', '\U0001f43e'),
-    ('\U0001f440', '\U0001f440'),
-    ('\U0001f442', '\U0001f4f7'),
-    ('\U0001f4f9', '\U0001f4fc'),
-    ('\U0001f500', '\U0001f53d'),
-    ('\U0001f540', '\U0001f543'),
-    ('\U0001f550', '\U0001f567'),
-    ('\U0001f5fb', '\U0001f640'),
-    ('\U0001f645', '\U0001f64f'),
-    ('\U0001f680', '\U0001f6c5'),
-    ('\U0001f700', '\U0001f773')
-    ]),
-("Samaritan", &[
-    ('\U00000800', '\U0000082d'),
-    ('\U00000830', '\U0000083e')
-    ]),
-("Saurashtra", &[
-    ('\U0000a880', '\U0000a8c4'),
-    ('\U0000a8ce', '\U0000a8d9')
-    ]),
-("Sc", &[
-    ('\U00000024', '\U00000024'),
-    ('\U000000a2', '\U000000a5'),
-    ('\U0000058f', '\U0000058f'),
-    ('\U0000060b', '\U0000060b'),
-    ('\U000009f2', '\U000009f3'),
-    ('\U000009fb', '\U000009fb'),
-    ('\U00000af1', '\U00000af1'),
-    ('\U00000bf9', '\U00000bf9'),
-    ('\U00000e3f', '\U00000e3f'),
-    ('\U000017db', '\U000017db'),
-    ('\U000020a0', '\U000020ba'),
-    ('\U0000a838', '\U0000a838'),
-    ('\U0000fdfc', '\U0000fdfc'),
-    ('\U0000fe69', '\U0000fe69'),
-    ('\U0000ff04', '\U0000ff04'),
-    ('\U0000ffe0', '\U0000ffe1'),
-    ('\U0000ffe5', '\U0000ffe6')
-    ]),
-("Sharada", &[
-    ('\U00011180', '\U000111c8'),
-    ('\U000111d0', '\U000111d9')
-    ]),
-("Shavian", &[
-    ('\U00010450', '\U0001047f')
-    ]),
-("Sinhala", &[
-    ('\U00000d82', '\U00000d83'),
-    ('\U00000d85', '\U00000d96'),
-    ('\U00000d9a', '\U00000db1'),
-    ('\U00000db3', '\U00000dbb'),
-    ('\U00000dbd', '\U00000dbd'),
-    ('\U00000dc0', '\U00000dc6'),
-    ('\U00000dca', '\U00000dca'),
-    ('\U00000dcf', '\U00000dd4'),
-    ('\U00000dd6', '\U00000dd6'),
-    ('\U00000dd8', '\U00000ddf'),
-    ('\U00000df2', '\U00000df4')
-    ]),
-("Sk", &[
-    ('\U0000005e', '\U0000005e'),
-    ('\U00000060', '\U00000060'),
-    ('\U000000a8', '\U000000a8'),
-    ('\U000000af', '\U000000af'),
-    ('\U000000b4', '\U000000b4'),
-    ('\U000000b8', '\U000000b8'),
-    ('\U000002c2', '\U000002c5'),
-    ('\U000002d2', '\U000002df'),
-    ('\U000002e5', '\U000002eb'),
-    ('\U000002ed', '\U000002ed'),
-    ('\U000002ef', '\U000002ff'),
-    ('\U00000375', '\U00000375'),
-    ('\U00000384', '\U00000385'),
-    ('\U00001fbd', '\U00001fbd'),
-    ('\U00001fbf', '\U00001fc1'),
-    ('\U00001fcd', '\U00001fcf'),
-    ('\U00001fdd', '\U00001fdf'),
-    ('\U00001fed', '\U00001fef'),
-    ('\U00001ffd', '\U00001ffe'),
-    ('\U0000309b', '\U0000309c'),
-    ('\U0000a700', '\U0000a716'),
-    ('\U0000a720', '\U0000a721'),
-    ('\U0000a789', '\U0000a78a'),
-    ('\U0000fbb2', '\U0000fbc1'),
-    ('\U0000ff3e', '\U0000ff3e'),
-    ('\U0000ff40', '\U0000ff40'),
-    ('\U0000ffe3', '\U0000ffe3')
-    ]),
-("Sm", &[
-    ('\U0000002b', '\U0000002b'),
-    ('\U0000003c', '\U0000003e'),
-    ('\U0000007c', '\U0000007c'),
-    ('\U0000007e', '\U0000007e'),
-    ('\U000000ac', '\U000000ac'),
-    ('\U000000b1', '\U000000b1'),
-    ('\U000000d7', '\U000000d7'),
-    ('\U000000f7', '\U000000f7'),
-    ('\U000003f6', '\U000003f6'),
-    ('\U00000606', '\U00000608'),
-    ('\U00002044', '\U00002044'),
-    ('\U00002052', '\U00002052'),
-    ('\U0000207a', '\U0000207c'),
-    ('\U0000208a', '\U0000208c'),
-    ('\U00002118', '\U00002118'),
-    ('\U00002140', '\U00002144'),
-    ('\U0000214b', '\U0000214b'),
-    ('\U00002190', '\U00002194'),
-    ('\U0000219a', '\U0000219b'),
-    ('\U000021a0', '\U000021a0'),
-    ('\U000021a3', '\U000021a3'),
-    ('\U000021a6', '\U000021a6'),
-    ('\U000021ae', '\U000021ae'),
-    ('\U000021ce', '\U000021cf'),
-    ('\U000021d2', '\U000021d2'),
-    ('\U000021d4', '\U000021d4'),
-    ('\U000021f4', '\U000022ff'),
-    ('\U00002320', '\U00002321'),
-    ('\U0000237c', '\U0000237c'),
-    ('\U0000239b', '\U000023b3'),
-    ('\U000023dc', '\U000023e1'),
-    ('\U000025b7', '\U000025b7'),
-    ('\U000025c1', '\U000025c1'),
-    ('\U000025f8', '\U000025ff'),
-    ('\U0000266f', '\U0000266f'),
-    ('\U000027c0', '\U000027c4'),
-    ('\U000027c7', '\U000027e5'),
-    ('\U000027f0', '\U000027ff'),
-    ('\U00002900', '\U00002982'),
-    ('\U00002999', '\U000029d7'),
-    ('\U000029dc', '\U000029fb'),
-    ('\U000029fe', '\U00002aff'),
-    ('\U00002b30', '\U00002b44'),
-    ('\U00002b47', '\U00002b4c'),
-    ('\U0000fb29', '\U0000fb29'),
-    ('\U0000fe62', '\U0000fe62'),
-    ('\U0000fe64', '\U0000fe66'),
-    ('\U0000ff0b', '\U0000ff0b'),
-    ('\U0000ff1c', '\U0000ff1e'),
-    ('\U0000ff5c', '\U0000ff5c'),
-    ('\U0000ff5e', '\U0000ff5e'),
-    ('\U0000ffe2', '\U0000ffe2'),
-    ('\U0000ffe9', '\U0000ffec'),
-    ('\U0001d6c1', '\U0001d6c1'),
-    ('\U0001d6db', '\U0001d6db'),
-    ('\U0001d6fb', '\U0001d6fb'),
-    ('\U0001d715', '\U0001d715'),
-    ('\U0001d735', '\U0001d735'),
-    ('\U0001d74f', '\U0001d74f'),
-    ('\U0001d76f', '\U0001d76f'),
-    ('\U0001d789', '\U0001d789'),
-    ('\U0001d7a9', '\U0001d7a9'),
-    ('\U0001d7c3', '\U0001d7c3'),
-    ('\U0001eef0', '\U0001eef1')
-    ]),
-("So", &[
-    ('\U000000a6', '\U000000a6'),
-    ('\U000000a9', '\U000000a9'),
-    ('\U000000ae', '\U000000ae'),
-    ('\U000000b0', '\U000000b0'),
-    ('\U00000482', '\U00000482'),
-    ('\U0000060e', '\U0000060f'),
-    ('\U000006de', '\U000006de'),
-    ('\U000006e9', '\U000006e9'),
-    ('\U000006fd', '\U000006fe'),
-    ('\U000007f6', '\U000007f6'),
-    ('\U000009fa', '\U000009fa'),
-    ('\U00000b70', '\U00000b70'),
-    ('\U00000bf3', '\U00000bf8'),
-    ('\U00000bfa', '\U00000bfa'),
-    ('\U00000c7f', '\U00000c7f'),
-    ('\U00000d79', '\U00000d79'),
-    ('\U00000f01', '\U00000f03'),
-    ('\U00000f13', '\U00000f13'),
-    ('\U00000f15', '\U00000f17'),
-    ('\U00000f1a', '\U00000f1f'),
-    ('\U00000f34', '\U00000f34'),
-    ('\U00000f36', '\U00000f36'),
-    ('\U00000f38', '\U00000f38'),
-    ('\U00000fbe', '\U00000fc5'),
-    ('\U00000fc7', '\U00000fcc'),
-    ('\U00000fce', '\U00000fcf'),
-    ('\U00000fd5', '\U00000fd8'),
-    ('\U0000109e', '\U0000109f'),
-    ('\U00001390', '\U00001399'),
-    ('\U00001940', '\U00001940'),
-    ('\U000019de', '\U000019ff'),
-    ('\U00001b61', '\U00001b6a'),
-    ('\U00001b74', '\U00001b7c'),
-    ('\U00002100', '\U00002101'),
-    ('\U00002103', '\U00002106'),
-    ('\U00002108', '\U00002109'),
-    ('\U00002114', '\U00002114'),
-    ('\U00002116', '\U00002117'),
-    ('\U0000211e', '\U00002123'),
-    ('\U00002125', '\U00002125'),
-    ('\U00002127', '\U00002127'),
-    ('\U00002129', '\U00002129'),
-    ('\U0000212e', '\U0000212e'),
-    ('\U0000213a', '\U0000213b'),
-    ('\U0000214a', '\U0000214a'),
-    ('\U0000214c', '\U0000214d'),
-    ('\U0000214f', '\U0000214f'),
-    ('\U00002195', '\U00002199'),
-    ('\U0000219c', '\U0000219f'),
-    ('\U000021a1', '\U000021a2'),
-    ('\U000021a4', '\U000021a5'),
-    ('\U000021a7', '\U000021ad'),
-    ('\U000021af', '\U000021cd'),
-    ('\U000021d0', '\U000021d1'),
-    ('\U000021d3', '\U000021d3'),
-    ('\U000021d5', '\U000021f3'),
-    ('\U00002300', '\U00002307'),
-    ('\U0000230c', '\U0000231f'),
-    ('\U00002322', '\U00002328'),
-    ('\U0000232b', '\U0000237b'),
-    ('\U0000237d', '\U0000239a'),
-    ('\U000023b4', '\U000023db'),
-    ('\U000023e2', '\U000023f3'),
-    ('\U00002400', '\U00002426'),
-    ('\U00002440', '\U0000244a'),
-    ('\U0000249c', '\U000024e9'),
-    ('\U00002500', '\U000025b6'),
-    ('\U000025b8', '\U000025c0'),
-    ('\U000025c2', '\U000025f7'),
-    ('\U00002600', '\U0000266e'),
-    ('\U00002670', '\U000026ff'),
-    ('\U00002701', '\U00002767'),
-    ('\U00002794', '\U000027bf'),
-    ('\U00002800', '\U000028ff'),
-    ('\U00002b00', '\U00002b2f'),
-    ('\U00002b45', '\U00002b46'),
-    ('\U00002b50', '\U00002b59'),
-    ('\U00002ce5', '\U00002cea'),
-    ('\U00002e80', '\U00002e99'),
-    ('\U00002e9b', '\U00002ef3'),
-    ('\U00002f00', '\U00002fd5'),
-    ('\U00002ff0', '\U00002ffb'),
-    ('\U00003004', '\U00003004'),
-    ('\U00003012', '\U00003013'),
-    ('\U00003020', '\U00003020'),
-    ('\U00003036', '\U00003037'),
-    ('\U0000303e', '\U0000303f'),
-    ('\U00003190', '\U00003191'),
-    ('\U00003196', '\U0000319f'),
-    ('\U000031c0', '\U000031e3'),
-    ('\U00003200', '\U0000321e'),
-    ('\U0000322a', '\U00003247'),
-    ('\U00003250', '\U00003250'),
-    ('\U00003260', '\U0000327f'),
-    ('\U0000328a', '\U000032b0'),
-    ('\U000032c0', '\U000032fe'),
-    ('\U00003300', '\U000033ff'),
-    ('\U00004dc0', '\U00004dff'),
-    ('\U0000a490', '\U0000a4c6'),
-    ('\U0000a828', '\U0000a82b'),
-    ('\U0000a836', '\U0000a837'),
-    ('\U0000a839', '\U0000a839'),
-    ('\U0000aa77', '\U0000aa79'),
-    ('\U0000fdfd', '\U0000fdfd'),
-    ('\U0000ffe4', '\U0000ffe4'),
-    ('\U0000ffe8', '\U0000ffe8'),
-    ('\U0000ffed', '\U0000ffee'),
-    ('\U0000fffc', '\U0000fffd'),
-    ('\U00010137', '\U0001013f'),
-    ('\U00010179', '\U00010189'),
-    ('\U00010190', '\U0001019b'),
-    ('\U000101d0', '\U000101fc'),
-    ('\U0001d000', '\U0001d0f5'),
-    ('\U0001d100', '\U0001d126'),
-    ('\U0001d129', '\U0001d164'),
-    ('\U0001d16a', '\U0001d16c'),
-    ('\U0001d183', '\U0001d184'),
-    ('\U0001d18c', '\U0001d1a9'),
-    ('\U0001d1ae', '\U0001d1dd'),
-    ('\U0001d200', '\U0001d241'),
-    ('\U0001d245', '\U0001d245'),
-    ('\U0001d300', '\U0001d356'),
-    ('\U0001f000', '\U0001f02b'),
-    ('\U0001f030', '\U0001f093'),
-    ('\U0001f0a0', '\U0001f0ae'),
-    ('\U0001f0b1', '\U0001f0be'),
-    ('\U0001f0c1', '\U0001f0cf'),
-    ('\U0001f0d1', '\U0001f0df'),
-    ('\U0001f110', '\U0001f12e'),
-    ('\U0001f130', '\U0001f16b'),
-    ('\U0001f170', '\U0001f19a'),
-    ('\U0001f1e6', '\U0001f202'),
-    ('\U0001f210', '\U0001f23a'),
-    ('\U0001f240', '\U0001f248'),
-    ('\U0001f250', '\U0001f251'),
-    ('\U0001f300', '\U0001f320'),
-    ('\U0001f330', '\U0001f335'),
-    ('\U0001f337', '\U0001f37c'),
-    ('\U0001f380', '\U0001f393'),
-    ('\U0001f3a0', '\U0001f3c4'),
-    ('\U0001f3c6', '\U0001f3ca'),
-    ('\U0001f3e0', '\U0001f3f0'),
-    ('\U0001f400', '\U0001f43e'),
-    ('\U0001f440', '\U0001f440'),
-    ('\U0001f442', '\U0001f4f7'),
-    ('\U0001f4f9', '\U0001f4fc'),
-    ('\U0001f500', '\U0001f53d'),
-    ('\U0001f540', '\U0001f543'),
-    ('\U0001f550', '\U0001f567'),
-    ('\U0001f5fb', '\U0001f640'),
-    ('\U0001f645', '\U0001f64f'),
-    ('\U0001f680', '\U0001f6c5'),
-    ('\U0001f700', '\U0001f773')
-    ]),
-("Sora_Sompeng", &[
-    ('\U000110d0', '\U000110e8'),
-    ('\U000110f0', '\U000110f9')
-    ]),
-("Sundanese", &[
-    ('\U00001b80', '\U00001bbf'),
-    ('\U00001cc0', '\U00001cc7')
-    ]),
-("Syloti_Nagri", &[
-    ('\U0000a800', '\U0000a82b')
-    ]),
-("Syriac", &[
-    ('\U00000700', '\U0000070d'),
-    ('\U0000070f', '\U0000074a'),
-    ('\U0000074d', '\U0000074f')
-    ]),
-("Tagalog", &[
-    ('\U00001700', '\U0000170c'),
-    ('\U0000170e', '\U00001714')
-    ]),
-("Tagbanwa", &[
-    ('\U00001760', '\U0000176c'),
-    ('\U0000176e', '\U00001770'),
-    ('\U00001772', '\U00001773')
-    ]),
-("Tai_Le", &[
-    ('\U00001950', '\U0000196d'),
-    ('\U00001970', '\U00001974')
-    ]),
-("Tai_Tham", &[
-    ('\U00001a20', '\U00001a5e'),
-    ('\U00001a60', '\U00001a7c'),
-    ('\U00001a7f', '\U00001a89'),
-    ('\U00001a90', '\U00001a99'),
-    ('\U00001aa0', '\U00001aad')
-    ]),
-("Tai_Viet", &[
-    ('\U0000aa80', '\U0000aac2'),
-    ('\U0000aadb', '\U0000aadf')
-    ]),
-("Takri", &[
-    ('\U00011680', '\U000116b7'),
-    ('\U000116c0', '\U000116c9')
-    ]),
-("Tamil", &[
-    ('\U00000b82', '\U00000b83'),
-    ('\U00000b85', '\U00000b8a'),
-    ('\U00000b8e', '\U00000b90'),
-    ('\U00000b92', '\U00000b95'),
-    ('\U00000b99', '\U00000b9a'),
-    ('\U00000b9c', '\U00000b9c'),
-    ('\U00000b9e', '\U00000b9f'),
-    ('\U00000ba3', '\U00000ba4'),
-    ('\U00000ba8', '\U00000baa'),
-    ('\U00000bae', '\U00000bb9'),
-    ('\U00000bbe', '\U00000bc2'),
-    ('\U00000bc6', '\U00000bc8'),
-    ('\U00000bca', '\U00000bcd'),
-    ('\U00000bd0', '\U00000bd0'),
-    ('\U00000bd7', '\U00000bd7'),
-    ('\U00000be6', '\U00000bfa')
-    ]),
-("Telugu", &[
-    ('\U00000c01', '\U00000c03'),
-    ('\U00000c05', '\U00000c0c'),
-    ('\U00000c0e', '\U00000c10'),
-    ('\U00000c12', '\U00000c28'),
-    ('\U00000c2a', '\U00000c33'),
-    ('\U00000c35', '\U00000c39'),
-    ('\U00000c3d', '\U00000c44'),
-    ('\U00000c46', '\U00000c48'),
-    ('\U00000c4a', '\U00000c4d'),
-    ('\U00000c55', '\U00000c56'),
-    ('\U00000c58', '\U00000c59'),
-    ('\U00000c60', '\U00000c63'),
-    ('\U00000c66', '\U00000c6f'),
-    ('\U00000c78', '\U00000c7f')
-    ]),
-("Thaana", &[
-    ('\U00000780', '\U000007b1')
-    ]),
-("Thai", &[
-    ('\U00000e01', '\U00000e3a'),
-    ('\U00000e40', '\U00000e5b')
-    ]),
-("Tibetan", &[
-    ('\U00000f00', '\U00000f47'),
-    ('\U00000f49', '\U00000f6c'),
-    ('\U00000f71', '\U00000f97'),
-    ('\U00000f99', '\U00000fbc'),
-    ('\U00000fbe', '\U00000fcc'),
-    ('\U00000fce', '\U00000fd4'),
-    ('\U00000fd9', '\U00000fda')
-    ]),
-("Tifinagh", &[
-    ('\U00002d30', '\U00002d67'),
-    ('\U00002d6f', '\U00002d70'),
-    ('\U00002d7f', '\U00002d7f')
-    ]),
-("Ugaritic", &[
-    ('\U00010380', '\U0001039d'),
-    ('\U0001039f', '\U0001039f')
-    ]),
-("Vai", &[
-    ('\U0000a500', '\U0000a62b')
-    ]),
-("Yi", &[
-    ('\U0000a000', '\U0000a48c'),
-    ('\U0000a490', '\U0000a4c6')
-    ]),
-("Z", &[
-    ('\U00000020', '\U00000020'),
-    ('\U000000a0', '\U000000a0'),
-    ('\U00001680', '\U00001680'),
-    ('\U00002000', '\U0000200a'),
-    ('\U00002028', '\U00002029'),
-    ('\U0000202f', '\U0000202f'),
-    ('\U0000205f', '\U0000205f'),
-    ('\U00003000', '\U00003000')
-    ]),
-("Zl", &[
-    ('\U00002028', '\U00002028')
-    ]),
-("Zp", &[
-    ('\U00002029', '\U00002029')
-    ]),
-("Zs", &[
-    ('\U00000020', '\U00000020'),
-    ('\U000000a0', '\U000000a0'),
-    ('\U00001680', '\U00001680'),
-    ('\U00002000', '\U0000200a'),
-    ('\U0000202f', '\U0000202f'),
-    ('\U0000205f', '\U0000205f'),
-    ('\U00003000', '\U00003000')
-    ]),
-
-];
-
-pub static PERLD: Class = &[
-    ('\U00000030', '\U00000039'),
-    ('\U00000660', '\U00000669'),
-    ('\U000006f0', '\U000006f9'),
-    ('\U000007c0', '\U000007c9'),
-    ('\U00000966', '\U0000096f'),
-    ('\U000009e6', '\U000009ef'),
-    ('\U00000a66', '\U00000a6f'),
-    ('\U00000ae6', '\U00000aef'),
-    ('\U00000b66', '\U00000b6f'),
-    ('\U00000be6', '\U00000bef'),
-    ('\U00000c66', '\U00000c6f'),
-    ('\U00000ce6', '\U00000cef'),
-    ('\U00000d66', '\U00000d6f'),
-    ('\U00000e50', '\U00000e59'),
-    ('\U00000ed0', '\U00000ed9'),
-    ('\U00000f20', '\U00000f29'),
-    ('\U00001040', '\U00001049'),
-    ('\U00001090', '\U00001099'),
-    ('\U000017e0', '\U000017e9'),
-    ('\U00001810', '\U00001819'),
-    ('\U00001946', '\U0000194f'),
-    ('\U000019d0', '\U000019d9'),
-    ('\U00001a80', '\U00001a89'),
-    ('\U00001a90', '\U00001a99'),
-    ('\U00001b50', '\U00001b59'),
-    ('\U00001bb0', '\U00001bb9'),
-    ('\U00001c40', '\U00001c49'),
-    ('\U00001c50', '\U00001c59'),
-    ('\U0000a620', '\U0000a629'),
-    ('\U0000a8d0', '\U0000a8d9'),
-    ('\U0000a900', '\U0000a909'),
-    ('\U0000a9d0', '\U0000a9d9'),
-    ('\U0000aa50', '\U0000aa59'),
-    ('\U0000abf0', '\U0000abf9'),
-    ('\U0000ff10', '\U0000ff19'),
-    ('\U000104a0', '\U000104a9'),
-    ('\U00011066', '\U0001106f'),
-    ('\U000110f0', '\U000110f9'),
-    ('\U00011136', '\U0001113f'),
-    ('\U000111d0', '\U000111d9'),
-    ('\U000116c0', '\U000116c9'),
-    ('\U0001d7ce', '\U0001d7ff')
-];
-
-pub static PERLS: Class = &[
-    ('\U00000009', '\U0000000a'),
-    ('\U0000000c', '\U0000000d'),
-    ('\U00000020', '\U00000020'),
-    ('\U000000a0', '\U000000a0'),
-    ('\U00001680', '\U00001680'),
-    ('\U00002000', '\U0000200a'),
-    ('\U00002028', '\U00002029'),
-    ('\U0000202f', '\U0000202f'),
-    ('\U0000205f', '\U0000205f'),
-    ('\U00003000', '\U00003000')
-];
-
-pub static PERLW: Class = &[
-    ('\U00000030', '\U00000039'),
-    ('\U00000041', '\U0000005a'),
-    ('\U0000005f', '\U0000005f'),
-    ('\U00000061', '\U0000007a'),
-    ('\U000000aa', '\U000000aa'),
-    ('\U000000b5', '\U000000b5'),
-    ('\U000000ba', '\U000000ba'),
-    ('\U000000c0', '\U000000d6'),
-    ('\U000000d8', '\U000000f6'),
-    ('\U000000f8', '\U000002c1'),
-    ('\U000002c6', '\U000002d1'),
-    ('\U000002e0', '\U000002e4'),
-    ('\U000002ec', '\U000002ec'),
-    ('\U000002ee', '\U000002ee'),
-    ('\U00000370', '\U00000374'),
-    ('\U00000376', '\U00000377'),
-    ('\U0000037a', '\U0000037d'),
-    ('\U00000386', '\U00000386'),
-    ('\U00000388', '\U0000038a'),
-    ('\U0000038c', '\U0000038c'),
-    ('\U0000038e', '\U000003a1'),
-    ('\U000003a3', '\U000003f5'),
-    ('\U000003f7', '\U00000481'),
-    ('\U0000048a', '\U00000527'),
-    ('\U00000531', '\U00000556'),
-    ('\U00000559', '\U00000559'),
-    ('\U00000561', '\U00000587'),
-    ('\U000005d0', '\U000005ea'),
-    ('\U000005f0', '\U000005f2'),
-    ('\U00000620', '\U0000064a'),
-    ('\U0000066e', '\U0000066f'),
-    ('\U00000671', '\U000006d3'),
-    ('\U000006d5', '\U000006d5'),
-    ('\U000006e5', '\U000006e6'),
-    ('\U000006ee', '\U000006ef'),
-    ('\U000006fa', '\U000006fc'),
-    ('\U000006ff', '\U000006ff'),
-    ('\U00000710', '\U00000710'),
-    ('\U00000712', '\U0000072f'),
-    ('\U0000074d', '\U000007a5'),
-    ('\U000007b1', '\U000007b1'),
-    ('\U000007ca', '\U000007ea'),
-    ('\U000007f4', '\U000007f5'),
-    ('\U000007fa', '\U000007fa'),
-    ('\U00000800', '\U00000815'),
-    ('\U0000081a', '\U0000081a'),
-    ('\U00000824', '\U00000824'),
-    ('\U00000828', '\U00000828'),
-    ('\U00000840', '\U00000858'),
-    ('\U000008a0', '\U000008a0'),
-    ('\U000008a2', '\U000008ac'),
-    ('\U00000904', '\U00000939'),
-    ('\U0000093d', '\U0000093d'),
-    ('\U00000950', '\U00000950'),
-    ('\U00000958', '\U00000961'),
-    ('\U00000971', '\U00000977'),
-    ('\U00000979', '\U0000097f'),
-    ('\U00000985', '\U0000098c'),
-    ('\U0000098f', '\U00000990'),
-    ('\U00000993', '\U000009a8'),
-    ('\U000009aa', '\U000009b0'),
-    ('\U000009b2', '\U000009b2'),
-    ('\U000009b6', '\U000009b9'),
-    ('\U000009bd', '\U000009bd'),
-    ('\U000009ce', '\U000009ce'),
-    ('\U000009dc', '\U000009dd'),
-    ('\U000009df', '\U000009e1'),
-    ('\U000009f0', '\U000009f1'),
-    ('\U00000a05', '\U00000a0a'),
-    ('\U00000a0f', '\U00000a10'),
-    ('\U00000a13', '\U00000a28'),
-    ('\U00000a2a', '\U00000a30'),
-    ('\U00000a32', '\U00000a33'),
-    ('\U00000a35', '\U00000a36'),
-    ('\U00000a38', '\U00000a39'),
-    ('\U00000a59', '\U00000a5c'),
-    ('\U00000a5e', '\U00000a5e'),
-    ('\U00000a72', '\U00000a74'),
-    ('\U00000a85', '\U00000a8d'),
-    ('\U00000a8f', '\U00000a91'),
-    ('\U00000a93', '\U00000aa8'),
-    ('\U00000aaa', '\U00000ab0'),
-    ('\U00000ab2', '\U00000ab3'),
-    ('\U00000ab5', '\U00000ab9'),
-    ('\U00000abd', '\U00000abd'),
-    ('\U00000ad0', '\U00000ad0'),
-    ('\U00000ae0', '\U00000ae1'),
-    ('\U00000b05', '\U00000b0c'),
-    ('\U00000b0f', '\U00000b10'),
-    ('\U00000b13', '\U00000b28'),
-    ('\U00000b2a', '\U00000b30'),
-    ('\U00000b32', '\U00000b33'),
-    ('\U00000b35', '\U00000b39'),
-    ('\U00000b3d', '\U00000b3d'),
-    ('\U00000b5c', '\U00000b5d'),
-    ('\U00000b5f', '\U00000b61'),
-    ('\U00000b71', '\U00000b71'),
-    ('\U00000b83', '\U00000b83'),
-    ('\U00000b85', '\U00000b8a'),
-    ('\U00000b8e', '\U00000b90'),
-    ('\U00000b92', '\U00000b95'),
-    ('\U00000b99', '\U00000b9a'),
-    ('\U00000b9c', '\U00000b9c'),
-    ('\U00000b9e', '\U00000b9f'),
-    ('\U00000ba3', '\U00000ba4'),
-    ('\U00000ba8', '\U00000baa'),
-    ('\U00000bae', '\U00000bb9'),
-    ('\U00000bd0', '\U00000bd0'),
-    ('\U00000c05', '\U00000c0c'),
-    ('\U00000c0e', '\U00000c10'),
-    ('\U00000c12', '\U00000c28'),
-    ('\U00000c2a', '\U00000c33'),
-    ('\U00000c35', '\U00000c39'),
-    ('\U00000c3d', '\U00000c3d'),
-    ('\U00000c58', '\U00000c59'),
-    ('\U00000c60', '\U00000c61'),
-    ('\U00000c85', '\U00000c8c'),
-    ('\U00000c8e', '\U00000c90'),
-    ('\U00000c92', '\U00000ca8'),
-    ('\U00000caa', '\U00000cb3'),
-    ('\U00000cb5', '\U00000cb9'),
-    ('\U00000cbd', '\U00000cbd'),
-    ('\U00000cde', '\U00000cde'),
-    ('\U00000ce0', '\U00000ce1'),
-    ('\U00000cf1', '\U00000cf2'),
-    ('\U00000d05', '\U00000d0c'),
-    ('\U00000d0e', '\U00000d10'),
-    ('\U00000d12', '\U00000d3a'),
-    ('\U00000d3d', '\U00000d3d'),
-    ('\U00000d4e', '\U00000d4e'),
-    ('\U00000d60', '\U00000d61'),
-    ('\U00000d7a', '\U00000d7f'),
-    ('\U00000d85', '\U00000d96'),
-    ('\U00000d9a', '\U00000db1'),
-    ('\U00000db3', '\U00000dbb'),
-    ('\U00000dbd', '\U00000dbd'),
-    ('\U00000dc0', '\U00000dc6'),
-    ('\U00000e01', '\U00000e30'),
-    ('\U00000e32', '\U00000e33'),
-    ('\U00000e40', '\U00000e46'),
-    ('\U00000e81', '\U00000e82'),
-    ('\U00000e84', '\U00000e84'),
-    ('\U00000e87', '\U00000e88'),
-    ('\U00000e8a', '\U00000e8a'),
-    ('\U00000e8d', '\U00000e8d'),
-    ('\U00000e94', '\U00000e97'),
-    ('\U00000e99', '\U00000e9f'),
-    ('\U00000ea1', '\U00000ea3'),
-    ('\U00000ea5', '\U00000ea5'),
-    ('\U00000ea7', '\U00000ea7'),
-    ('\U00000eaa', '\U00000eab'),
-    ('\U00000ead', '\U00000eb0'),
-    ('\U00000eb2', '\U00000eb3'),
-    ('\U00000ebd', '\U00000ebd'),
-    ('\U00000ec0', '\U00000ec4'),
-    ('\U00000ec6', '\U00000ec6'),
-    ('\U00000edc', '\U00000edf'),
-    ('\U00000f00', '\U00000f00'),
-    ('\U00000f40', '\U00000f47'),
-    ('\U00000f49', '\U00000f6c'),
-    ('\U00000f88', '\U00000f8c'),
-    ('\U00001000', '\U0000102a'),
-    ('\U0000103f', '\U0000103f'),
-    ('\U00001050', '\U00001055'),
-    ('\U0000105a', '\U0000105d'),
-    ('\U00001061', '\U00001061'),
-    ('\U00001065', '\U00001066'),
-    ('\U0000106e', '\U00001070'),
-    ('\U00001075', '\U00001081'),
-    ('\U0000108e', '\U0000108e'),
-    ('\U000010a0', '\U000010c5'),
-    ('\U000010c7', '\U000010c7'),
-    ('\U000010cd', '\U000010cd'),
-    ('\U000010d0', '\U000010fa'),
-    ('\U000010fc', '\U00001248'),
-    ('\U0000124a', '\U0000124d'),
-    ('\U00001250', '\U00001256'),
-    ('\U00001258', '\U00001258'),
-    ('\U0000125a', '\U0000125d'),
-    ('\U00001260', '\U00001288'),
-    ('\U0000128a', '\U0000128d'),
-    ('\U00001290', '\U000012b0'),
-    ('\U000012b2', '\U000012b5'),
-    ('\U000012b8', '\U000012be'),
-    ('\U000012c0', '\U000012c0'),
-    ('\U000012c2', '\U000012c5'),
-    ('\U000012c8', '\U000012d6'),
-    ('\U000012d8', '\U00001310'),
-    ('\U00001312', '\U00001315'),
-    ('\U00001318', '\U0000135a'),
-    ('\U00001380', '\U0000138f'),
-    ('\U000013a0', '\U000013f4'),
-    ('\U00001401', '\U0000166c'),
-    ('\U0000166f', '\U0000167f'),
-    ('\U00001681', '\U0000169a'),
-    ('\U000016a0', '\U000016ea'),
-    ('\U00001700', '\U0000170c'),
-    ('\U0000170e', '\U00001711'),
-    ('\U00001720', '\U00001731'),
-    ('\U00001740', '\U00001751'),
-    ('\U00001760', '\U0000176c'),
-    ('\U0000176e', '\U00001770'),
-    ('\U00001780', '\U000017b3'),
-    ('\U000017d7', '\U000017d7'),
-    ('\U000017dc', '\U000017dc'),
-    ('\U00001820', '\U00001877'),
-    ('\U00001880', '\U000018a8'),
-    ('\U000018aa', '\U000018aa'),
-    ('\U000018b0', '\U000018f5'),
-    ('\U00001900', '\U0000191c'),
-    ('\U00001950', '\U0000196d'),
-    ('\U00001970', '\U00001974'),
-    ('\U00001980', '\U000019ab'),
-    ('\U000019c1', '\U000019c7'),
-    ('\U00001a00', '\U00001a16'),
-    ('\U00001a20', '\U00001a54'),
-    ('\U00001aa7', '\U00001aa7'),
-    ('\U00001b05', '\U00001b33'),
-    ('\U00001b45', '\U00001b4b'),
-    ('\U00001b83', '\U00001ba0'),
-    ('\U00001bae', '\U00001baf'),
-    ('\U00001bba', '\U00001be5'),
-    ('\U00001c00', '\U00001c23'),
-    ('\U00001c4d', '\U00001c4f'),
-    ('\U00001c5a', '\U00001c7d'),
-    ('\U00001ce9', '\U00001cec'),
-    ('\U00001cee', '\U00001cf1'),
-    ('\U00001cf5', '\U00001cf6'),
-    ('\U00001d00', '\U00001dbf'),
-    ('\U00001e00', '\U00001f15'),
-    ('\U00001f18', '\U00001f1d'),
-    ('\U00001f20', '\U00001f45'),
-    ('\U00001f48', '\U00001f4d'),
-    ('\U00001f50', '\U00001f57'),
-    ('\U00001f59', '\U00001f59'),
-    ('\U00001f5b', '\U00001f5b'),
-    ('\U00001f5d', '\U00001f5d'),
-    ('\U00001f5f', '\U00001f7d'),
-    ('\U00001f80', '\U00001fb4'),
-    ('\U00001fb6', '\U00001fbc'),
-    ('\U00001fbe', '\U00001fbe'),
-    ('\U00001fc2', '\U00001fc4'),
-    ('\U00001fc6', '\U00001fcc'),
-    ('\U00001fd0', '\U00001fd3'),
-    ('\U00001fd6', '\U00001fdb'),
-    ('\U00001fe0', '\U00001fec'),
-    ('\U00001ff2', '\U00001ff4'),
-    ('\U00001ff6', '\U00001ffc'),
-    ('\U00002071', '\U00002071'),
-    ('\U0000207f', '\U0000207f'),
-    ('\U00002090', '\U0000209c'),
-    ('\U00002102', '\U00002102'),
-    ('\U00002107', '\U00002107'),
-    ('\U0000210a', '\U00002113'),
-    ('\U00002115', '\U00002115'),
-    ('\U00002119', '\U0000211d'),
-    ('\U00002124', '\U00002124'),
-    ('\U00002126', '\U00002126'),
-    ('\U00002128', '\U00002128'),
-    ('\U0000212a', '\U0000212d'),
-    ('\U0000212f', '\U00002139'),
-    ('\U0000213c', '\U0000213f'),
-    ('\U00002145', '\U00002149'),
-    ('\U0000214e', '\U0000214e'),
-    ('\U00002183', '\U00002184'),
-    ('\U00002c00', '\U00002c2e'),
-    ('\U00002c30', '\U00002c5e'),
-    ('\U00002c60', '\U00002ce4'),
-    ('\U00002ceb', '\U00002cee'),
-    ('\U00002cf2', '\U00002cf3'),
-    ('\U00002d00', '\U00002d25'),
-    ('\U00002d27', '\U00002d27'),
-    ('\U00002d2d', '\U00002d2d'),
-    ('\U00002d30', '\U00002d67'),
-    ('\U00002d6f', '\U00002d6f'),
-    ('\U00002d80', '\U00002d96'),
-    ('\U00002da0', '\U00002da6'),
-    ('\U00002da8', '\U00002dae'),
-    ('\U00002db0', '\U00002db6'),
-    ('\U00002db8', '\U00002dbe'),
-    ('\U00002dc0', '\U00002dc6'),
-    ('\U00002dc8', '\U00002dce'),
-    ('\U00002dd0', '\U00002dd6'),
-    ('\U00002dd8', '\U00002dde'),
-    ('\U00002e2f', '\U00002e2f'),
-    ('\U00003005', '\U00003006'),
-    ('\U00003031', '\U00003035'),
-    ('\U0000303b', '\U0000303c'),
-    ('\U00003041', '\U00003096'),
-    ('\U0000309d', '\U0000309f'),
-    ('\U000030a1', '\U000030fa'),
-    ('\U000030fc', '\U000030ff'),
-    ('\U00003105', '\U0000312d'),
-    ('\U00003131', '\U0000318e'),
-    ('\U000031a0', '\U000031ba'),
-    ('\U000031f0', '\U000031ff'),
-    ('\U00003400', '\U00003400'),
-    ('\U00004db5', '\U00004db5'),
-    ('\U00004e00', '\U00004e00'),
-    ('\U00009fcc', '\U00009fcc'),
-    ('\U0000a000', '\U0000a48c'),
-    ('\U0000a4d0', '\U0000a4fd'),
-    ('\U0000a500', '\U0000a60c'),
-    ('\U0000a610', '\U0000a61f'),
-    ('\U0000a62a', '\U0000a62b'),
-    ('\U0000a640', '\U0000a66e'),
-    ('\U0000a67f', '\U0000a697'),
-    ('\U0000a6a0', '\U0000a6e5'),
-    ('\U0000a717', '\U0000a71f'),
-    ('\U0000a722', '\U0000a788'),
-    ('\U0000a78b', '\U0000a78e'),
-    ('\U0000a790', '\U0000a793'),
-    ('\U0000a7a0', '\U0000a7aa'),
-    ('\U0000a7f8', '\U0000a801'),
-    ('\U0000a803', '\U0000a805'),
-    ('\U0000a807', '\U0000a80a'),
-    ('\U0000a80c', '\U0000a822'),
-    ('\U0000a840', '\U0000a873'),
-    ('\U0000a882', '\U0000a8b3'),
-    ('\U0000a8f2', '\U0000a8f7'),
-    ('\U0000a8fb', '\U0000a8fb'),
-    ('\U0000a90a', '\U0000a925'),
-    ('\U0000a930', '\U0000a946'),
-    ('\U0000a960', '\U0000a97c'),
-    ('\U0000a984', '\U0000a9b2'),
-    ('\U0000a9cf', '\U0000a9cf'),
-    ('\U0000aa00', '\U0000aa28'),
-    ('\U0000aa40', '\U0000aa42'),
-    ('\U0000aa44', '\U0000aa4b'),
-    ('\U0000aa60', '\U0000aa76'),
-    ('\U0000aa7a', '\U0000aa7a'),
-    ('\U0000aa80', '\U0000aaaf'),
-    ('\U0000aab1', '\U0000aab1'),
-    ('\U0000aab5', '\U0000aab6'),
-    ('\U0000aab9', '\U0000aabd'),
-    ('\U0000aac0', '\U0000aac0'),
-    ('\U0000aac2', '\U0000aac2'),
-    ('\U0000aadb', '\U0000aadd'),
-    ('\U0000aae0', '\U0000aaea'),
-    ('\U0000aaf2', '\U0000aaf4'),
-    ('\U0000ab01', '\U0000ab06'),
-    ('\U0000ab09', '\U0000ab0e'),
-    ('\U0000ab11', '\U0000ab16'),
-    ('\U0000ab20', '\U0000ab26'),
-    ('\U0000ab28', '\U0000ab2e'),
-    ('\U0000abc0', '\U0000abe2'),
-    ('\U0000ac00', '\U0000ac00'),
-    ('\U0000d7a3', '\U0000d7a3'),
-    ('\U0000d7b0', '\U0000d7c6'),
-    ('\U0000d7cb', '\U0000d7fb'),
-    ('\U0000f900', '\U0000fa6d'),
-    ('\U0000fa70', '\U0000fad9'),
-    ('\U0000fb00', '\U0000fb06'),
-    ('\U0000fb13', '\U0000fb17'),
-    ('\U0000fb1d', '\U0000fb1d'),
-    ('\U0000fb1f', '\U0000fb28'),
-    ('\U0000fb2a', '\U0000fb36'),
-    ('\U0000fb38', '\U0000fb3c'),
-    ('\U0000fb3e', '\U0000fb3e'),
-    ('\U0000fb40', '\U0000fb41'),
-    ('\U0000fb43', '\U0000fb44'),
-    ('\U0000fb46', '\U0000fbb1'),
-    ('\U0000fbd3', '\U0000fd3d'),
-    ('\U0000fd50', '\U0000fd8f'),
-    ('\U0000fd92', '\U0000fdc7'),
-    ('\U0000fdf0', '\U0000fdfb'),
-    ('\U0000fe70', '\U0000fe74'),
-    ('\U0000fe76', '\U0000fefc'),
-    ('\U0000ff21', '\U0000ff3a'),
-    ('\U0000ff41', '\U0000ff5a'),
-    ('\U0000ff66', '\U0000ffbe'),
-    ('\U0000ffc2', '\U0000ffc7'),
-    ('\U0000ffca', '\U0000ffcf'),
-    ('\U0000ffd2', '\U0000ffd7'),
-    ('\U0000ffda', '\U0000ffdc'),
-    ('\U00010000', '\U0001000b'),
-    ('\U0001000d', '\U00010026'),
-    ('\U00010028', '\U0001003a'),
-    ('\U0001003c', '\U0001003d'),
-    ('\U0001003f', '\U0001004d'),
-    ('\U00010050', '\U0001005d'),
-    ('\U00010080', '\U000100fa'),
-    ('\U00010280', '\U0001029c'),
-    ('\U000102a0', '\U000102d0'),
-    ('\U00010300', '\U0001031e'),
-    ('\U00010330', '\U00010340'),
-    ('\U00010342', '\U00010349'),
-    ('\U00010380', '\U0001039d'),
-    ('\U000103a0', '\U000103c3'),
-    ('\U000103c8', '\U000103cf'),
-    ('\U00010400', '\U0001049d'),
-    ('\U00010800', '\U00010805'),
-    ('\U00010808', '\U00010808'),
-    ('\U0001080a', '\U00010835'),
-    ('\U00010837', '\U00010838'),
-    ('\U0001083c', '\U0001083c'),
-    ('\U0001083f', '\U00010855'),
-    ('\U00010900', '\U00010915'),
-    ('\U00010920', '\U00010939'),
-    ('\U00010980', '\U000109b7'),
-    ('\U000109be', '\U000109bf'),
-    ('\U00010a00', '\U00010a00'),
-    ('\U00010a10', '\U00010a13'),
-    ('\U00010a15', '\U00010a17'),
-    ('\U00010a19', '\U00010a33'),
-    ('\U00010a60', '\U00010a7c'),
-    ('\U00010b00', '\U00010b35'),
-    ('\U00010b40', '\U00010b55'),
-    ('\U00010b60', '\U00010b72'),
-    ('\U00010c00', '\U00010c48'),
-    ('\U00011003', '\U00011037'),
-    ('\U00011083', '\U000110af'),
-    ('\U000110d0', '\U000110e8'),
-    ('\U00011103', '\U00011126'),
-    ('\U00011183', '\U000111b2'),
-    ('\U000111c1', '\U000111c4'),
-    ('\U00011680', '\U000116aa'),
-    ('\U00012000', '\U0001236e'),
-    ('\U00013000', '\U0001342e'),
-    ('\U00016800', '\U00016a38'),
-    ('\U00016f00', '\U00016f44'),
-    ('\U00016f50', '\U00016f50'),
-    ('\U00016f93', '\U00016f9f'),
-    ('\U0001b000', '\U0001b001'),
-    ('\U0001d400', '\U0001d454'),
-    ('\U0001d456', '\U0001d49c'),
-    ('\U0001d49e', '\U0001d49f'),
-    ('\U0001d4a2', '\U0001d4a2'),
-    ('\U0001d4a5', '\U0001d4a6'),
-    ('\U0001d4a9', '\U0001d4ac'),
-    ('\U0001d4ae', '\U0001d4b9'),
-    ('\U0001d4bb', '\U0001d4bb'),
-    ('\U0001d4bd', '\U0001d4c3'),
-    ('\U0001d4c5', '\U0001d505'),
-    ('\U0001d507', '\U0001d50a'),
-    ('\U0001d50d', '\U0001d514'),
-    ('\U0001d516', '\U0001d51c'),
-    ('\U0001d51e', '\U0001d539'),
-    ('\U0001d53b', '\U0001d53e'),
-    ('\U0001d540', '\U0001d544'),
-    ('\U0001d546', '\U0001d546'),
-    ('\U0001d54a', '\U0001d550'),
-    ('\U0001d552', '\U0001d6a5'),
-    ('\U0001d6a8', '\U0001d6c0'),
-    ('\U0001d6c2', '\U0001d6da'),
-    ('\U0001d6dc', '\U0001d6fa'),
-    ('\U0001d6fc', '\U0001d714'),
-    ('\U0001d716', '\U0001d734'),
-    ('\U0001d736', '\U0001d74e'),
-    ('\U0001d750', '\U0001d76e'),
-    ('\U0001d770', '\U0001d788'),
-    ('\U0001d78a', '\U0001d7a8'),
-    ('\U0001d7aa', '\U0001d7c2'),
-    ('\U0001d7c4', '\U0001d7cb'),
-    ('\U0001ee00', '\U0001ee03'),
-    ('\U0001ee05', '\U0001ee1f'),
-    ('\U0001ee21', '\U0001ee22'),
-    ('\U0001ee24', '\U0001ee24'),
-    ('\U0001ee27', '\U0001ee27'),
-    ('\U0001ee29', '\U0001ee32'),
-    ('\U0001ee34', '\U0001ee37'),
-    ('\U0001ee39', '\U0001ee39'),
-    ('\U0001ee3b', '\U0001ee3b'),
-    ('\U0001ee42', '\U0001ee42'),
-    ('\U0001ee47', '\U0001ee47'),
-    ('\U0001ee49', '\U0001ee49'),
-    ('\U0001ee4b', '\U0001ee4b'),
-    ('\U0001ee4d', '\U0001ee4f'),
-    ('\U0001ee51', '\U0001ee52'),
-    ('\U0001ee54', '\U0001ee54'),
-    ('\U0001ee57', '\U0001ee57'),
-    ('\U0001ee59', '\U0001ee59'),
-    ('\U0001ee5b', '\U0001ee5b'),
-    ('\U0001ee5d', '\U0001ee5d'),
-    ('\U0001ee5f', '\U0001ee5f'),
-    ('\U0001ee61', '\U0001ee62'),
-    ('\U0001ee64', '\U0001ee64'),
-    ('\U0001ee67', '\U0001ee6a'),
-    ('\U0001ee6c', '\U0001ee72'),
-    ('\U0001ee74', '\U0001ee77'),
-    ('\U0001ee79', '\U0001ee7c'),
-    ('\U0001ee7e', '\U0001ee7e'),
-    ('\U0001ee80', '\U0001ee89'),
-    ('\U0001ee8b', '\U0001ee9b'),
-    ('\U0001eea1', '\U0001eea3'),
-    ('\U0001eea5', '\U0001eea9'),
-    ('\U0001eeab', '\U0001eebb'),
-    ('\U00020000', '\U00020000'),
-    ('\U0002a6d6', '\U0002a6d6'),
-    ('\U0002a700', '\U0002a700'),
-    ('\U0002b734', '\U0002b734'),
-    ('\U0002b740', '\U0002b740'),
-    ('\U0002b81d', '\U0002b81d'),
-    ('\U0002f800', '\U0002fa1d')
-];
-
index 35cb7c3c5b09c78185e3e8225d6e8f0897dd1152..251ab10ad34e9d47c2950357647522ccf340b238 100644 (file)
@@ -195,8 +195,8 @@ fn $name() {
 
 // Test the Unicode friendliness of Perl character classes.
 mat!(uni_perl_w, r"\w+", "dδd", Some((0, 4)))
-mat!(uni_perl_w_not, r"\w+", "â\85¡", None)
-mat!(uni_perl_w_neg, r"\W+", "â\85¡", Some((0, 3)))
+mat!(uni_perl_w_not, r"\w+", "⥡", None)
+mat!(uni_perl_w_neg, r"\W+", "⥡", Some((0, 3)))
 mat!(uni_perl_d, r"\d+", "1२३9", Some((0, 8)))
 mat!(uni_perl_d_not, r"\d+", "Ⅱ", None)
 mat!(uni_perl_d_neg, r"\D+", "Ⅱ", Some((0, 3)))
index ea89c8986930eb17f4841c9482912ca205f1939d..782078ced497b9d09cf139416bc9e226848d5619 100644 (file)
@@ -42,7 +42,7 @@
     Save, Jump, Split,
 };
 use parse::{FLAG_NOCASE, FLAG_MULTI, FLAG_DOTNL, FLAG_NEGATED};
-use parse::unicode::PERLW;
+use unicode::regex::PERLW;
 
 pub type CaptureLocs = Vec<Option<uint>>;
 
index b21b51bf4eb5e7e1a3bb915d194e4a668b18b704..6545163fdbb68199ccb5a98ce581631c0a3cd8aa 100644 (file)
 //! This crate provides the `regex!` macro. Its use is documented in the
 //! `regex` crate.
 
-#![crate_id = "regex_macros#0.11.0"]
+#![crate_name = "regex_macros"]
 #![crate_type = "dylib"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 
 #![feature(plugin_registrar, managed_boxes, quote)]
 
@@ -85,7 +85,7 @@ fn native(cx: &mut ExtCtxt, sp: codemap::Span, tts: &[ast::TokenTree])
     let re = match Regex::new(regex.as_slice()) {
         Ok(re) => re,
         Err(err) => {
-            cx.span_err(sp, err.to_str().as_slice());
+            cx.span_err(sp, err.to_string().as_slice());
             return DummyResult::any(sp)
         }
     };
@@ -316,7 +316,7 @@ fn pc(&self, i: uint) -> uint {
 
         #[inline]
         fn groups<'r>(&'r mut self, i: uint) -> &'r mut Captures {
-            &'r mut self.queue[i].groups
+            &mut self.queue[i].groups
         }
     }
 }
@@ -619,11 +619,11 @@ fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
     let regex = match entry.node {
         ast::ExprLit(lit) => {
             match lit.node {
-                ast::LitStr(ref s, _) => s.to_str(),
+                ast::LitStr(ref s, _) => s.to_string(),
                 _ => {
                     cx.span_err(entry.span, format!(
                         "expected string literal but got `{}`",
-                        pprust::lit_to_str(lit)).as_slice());
+                        pprust::lit_to_string(lit)).as_slice());
                     return None
                 }
             }
@@ -631,7 +631,7 @@ fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
         _ => {
             cx.span_err(entry.span, format!(
                 "expected string literal but got `{}`",
-                pprust::expr_to_str(entry)).as_slice());
+                pprust::expr_to_string(entry)).as_slice());
             return None
         }
     };
index c653e1ca07787afc4b141a772ac9588d26a847c9..cb27596c98c6b1a92159b30e24cda00239f353ce 100644 (file)
 //! necessary. It is an error to include this library when also linking with
 //! the system libc library.
 
-#![crate_id = "rlibc#0.11.0"]
+#![crate_name = "rlibc"]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 #![feature(intrinsics)]
 
 #![no_std]
diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs
deleted file mode 100644 (file)
index c722beb..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub static box_field_refcnt: uint = 0u;
-pub static box_field_tydesc: uint = 1u;
-pub static box_field_body: uint = 4u;
-
-pub static tydesc_field_visit_glue: uint = 3u;
-
-// The two halves of a closure: code and environment.
-pub static fn_field_code: uint = 0u;
-pub static fn_field_box: uint = 1u;
-
-// The two fields of a trait object/trait instance: vtable and box.
-// The vtable contains the type descriptor as first element.
-pub static trt_field_vtable: uint = 0u;
-pub static trt_field_box: uint = 1u;
-
-pub static vec_elt_fill: uint = 0u;
-
-pub static vec_elt_alloc: uint = 1u;
-
-pub static vec_elt_elems: uint = 2u;
-
-pub static slice_elt_base: uint = 0u;
-pub static slice_elt_len: uint = 1u;
diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs
deleted file mode 100644 (file)
index 4d921fb..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2013-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.
-
-//! A helper class for dealing with static archives
-
-use back::link::{get_ar_prog};
-use driver::session::Session;
-use metadata::filesearch;
-use lib::llvm::{ArchiveRef, llvm};
-
-use libc;
-use std::io::process::{Command, ProcessOutput};
-use std::io::{fs, TempDir};
-use std::io;
-use std::mem;
-use std::os;
-use std::raw;
-use std::str;
-use syntax::abi;
-
-pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";
-
-pub struct Archive<'a> {
-    sess: &'a Session,
-    dst: Path,
-}
-
-pub struct ArchiveRO {
-    ptr: ArchiveRef,
-}
-
-fn run_ar(sess: &Session, args: &str, cwd: Option<&Path>,
-          paths: &[&Path]) -> ProcessOutput {
-    let ar = get_ar_prog(sess);
-    let mut cmd = Command::new(ar.as_slice());
-
-    cmd.arg(args).args(paths);
-    debug!("{}", cmd);
-
-    match cwd {
-        Some(p) => {
-            cmd.cwd(p);
-            debug!("inside {}", p.display());
-        }
-        None => {}
-    }
-
-    match cmd.spawn() {
-        Ok(prog) => {
-            let o = prog.wait_with_output().unwrap();
-            if !o.status.success() {
-                sess.err(format!("{} failed with: {}",
-                                 cmd,
-                                 o.status).as_slice());
-                sess.note(format!("stdout ---\n{}",
-                                  str::from_utf8(o.output
-                                                  .as_slice()).unwrap())
-                          .as_slice());
-                sess.note(format!("stderr ---\n{}",
-                                  str::from_utf8(o.error
-                                                  .as_slice()).unwrap())
-                          .as_slice());
-                sess.abort_if_errors();
-            }
-            o
-        },
-        Err(e) => {
-            sess.err(format!("could not exec `{}`: {}", ar.as_slice(),
-                             e).as_slice());
-            sess.abort_if_errors();
-            fail!("rustc::back::archive::run_ar() should not reach this point");
-        }
-    }
-}
-
-impl<'a> Archive<'a> {
-    /// Initializes a new static archive with the given object file
-    pub fn create<'b>(sess: &'a Session, dst: &'b Path,
-                      initial_object: &'b Path) -> Archive<'a> {
-        run_ar(sess, "crus", None, [dst, initial_object]);
-        Archive { sess: sess, dst: dst.clone() }
-    }
-
-    /// Opens an existing static archive
-    pub fn open(sess: &'a Session, dst: Path) -> Archive<'a> {
-        assert!(dst.exists());
-        Archive { sess: sess, dst: dst }
-    }
-
-    /// Adds all of the contents of a native library to this archive. This will
-    /// search in the relevant locations for a library named `name`.
-    pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
-        let location = self.find_library(name);
-        self.add_archive(&location, name, [])
-    }
-
-    /// Adds all of the contents of the rlib at the specified path to this
-    /// archive.
-    ///
-    /// This ignores adding the bytecode from the rlib, and if LTO is enabled
-    /// then the object file also isn't added.
-    pub fn add_rlib(&mut self, rlib: &Path, name: &str,
-                    lto: bool) -> io::IoResult<()> {
-        let object = format!("{}.o", name);
-        let bytecode = format!("{}.bytecode.deflate", name);
-        let mut ignore = vec!(bytecode.as_slice(), METADATA_FILENAME);
-        if lto {
-            ignore.push(object.as_slice());
-        }
-        self.add_archive(rlib, name, ignore.as_slice())
-    }
-
-    /// Adds an arbitrary file to this archive
-    pub fn add_file(&mut self, file: &Path, has_symbols: bool) {
-        let cmd = if has_symbols {"r"} else {"rS"};
-        run_ar(self.sess, cmd, None, [&self.dst, file]);
-    }
-
-    /// Removes a file from this archive
-    pub fn remove_file(&mut self, file: &str) {
-        run_ar(self.sess, "d", None, [&self.dst, &Path::new(file)]);
-    }
-
-    /// Updates all symbols in the archive (runs 'ar s' over it)
-    pub fn update_symbols(&mut self) {
-        run_ar(self.sess, "s", None, [&self.dst]);
-    }
-
-    /// Lists all files in an archive
-    pub fn files(&self) -> Vec<String> {
-        let output = run_ar(self.sess, "t", None, [&self.dst]);
-        let output = str::from_utf8(output.output.as_slice()).unwrap();
-        // use lines_any because windows delimits output with `\r\n` instead of
-        // just `\n`
-        output.lines_any().map(|s| s.to_string()).collect()
-    }
-
-    fn add_archive(&mut self, archive: &Path, name: &str,
-                   skip: &[&str]) -> io::IoResult<()> {
-        let loc = TempDir::new("rsar").unwrap();
-
-        // First, extract the contents of the archive to a temporary directory
-        let archive = os::make_absolute(archive);
-        run_ar(self.sess, "x", Some(loc.path()), [&archive]);
-
-        // Next, we must rename all of the inputs to "guaranteed unique names".
-        // The reason for this is that archives are keyed off the name of the
-        // files, so if two files have the same name they will override one
-        // another in the archive (bad).
-        //
-        // We skip any files explicitly desired for skipping, and we also skip
-        // all SYMDEF files as these are just magical placeholders which get
-        // re-created when we make a new archive anyway.
-        let files = try!(fs::readdir(loc.path()));
-        let mut inputs = Vec::new();
-        for file in files.iter() {
-            let filename = file.filename_str().unwrap();
-            if skip.iter().any(|s| *s == filename) { continue }
-            if filename.contains(".SYMDEF") { continue }
-
-            let filename = format!("r-{}-{}", name, filename);
-            // LLDB (as mentioned in back::link) crashes on filenames of exactly
-            // 16 bytes in length. If we're including an object file with
-            // exactly 16-bytes of characters, give it some prefix so that it's
-            // not 16 bytes.
-            let filename = if filename.len() == 16 {
-                format!("lldb-fix-{}", filename)
-            } else {
-                filename
-            };
-            let new_filename = file.with_filename(filename);
-            try!(fs::rename(file, &new_filename));
-            inputs.push(new_filename);
-        }
-        if inputs.len() == 0 { return Ok(()) }
-
-        // Finally, add all the renamed files to this archive
-        let mut args = vec!(&self.dst);
-        args.extend(inputs.iter());
-        run_ar(self.sess, "r", None, args.as_slice());
-        Ok(())
-    }
-
-    fn find_library(&self, name: &str) -> Path {
-        let (osprefix, osext) = match self.sess.targ_cfg.os {
-            abi::OsWin32 => ("", "lib"), _ => ("lib", "a"),
-        };
-        // On Windows, static libraries sometimes show up as libfoo.a and other
-        // times show up as foo.lib
-        let oslibname = format!("{}{}.{}", osprefix, name, osext);
-        let unixlibname = format!("lib{}.a", name);
-
-        let mut rustpath = filesearch::rust_path();
-        rustpath.push(self.sess.target_filesearch().get_lib_path());
-        let search = self.sess.opts.addl_lib_search_paths.borrow();
-        for path in search.iter().chain(rustpath.iter()) {
-            debug!("looking for {} inside {}", name, path.display());
-            let test = path.join(oslibname.as_slice());
-            if test.exists() { return test }
-            if oslibname != unixlibname {
-                let test = path.join(unixlibname.as_slice());
-                if test.exists() { return test }
-            }
-        }
-        self.sess.fatal(format!("could not find native static library `{}`, \
-                                 perhaps an -L flag is missing?",
-                                name).as_slice());
-    }
-}
-
-impl ArchiveRO {
-    /// Opens a static archive for read-only purposes. This is more optimized
-    /// than the `open` method because it uses LLVM's internal `Archive` class
-    /// rather than shelling out to `ar` for everything.
-    ///
-    /// If this archive is used with a mutable method, then an error will be
-    /// raised.
-    pub fn open(dst: &Path) -> Option<ArchiveRO> {
-        unsafe {
-            let ar = dst.with_c_str(|dst| {
-                llvm::LLVMRustOpenArchive(dst)
-            });
-            if ar.is_null() {
-                None
-            } else {
-                Some(ArchiveRO { ptr: ar })
-            }
-        }
-    }
-
-    /// Reads a file in the archive
-    pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
-        unsafe {
-            let mut size = 0 as libc::size_t;
-            let ptr = file.with_c_str(|file| {
-                llvm::LLVMRustArchiveReadSection(self.ptr, file, &mut size)
-            });
-            if ptr.is_null() {
-                None
-            } else {
-                Some(mem::transmute(raw::Slice {
-                    data: ptr,
-                    len: size as uint,
-                }))
-            }
-        }
-    }
-}
-
-impl Drop for ArchiveRO {
-    fn drop(&mut self) {
-        unsafe {
-            llvm::LLVMRustDestroyArchive(self.ptr);
-        }
-    }
-}
diff --git a/src/librustc/back/arm.rs b/src/librustc/back/arm.rs
deleted file mode 100644 (file)
index 7a7d248..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
-    let cc_args = if target_triple.as_slice().contains("thumb") {
-        vec!("-mthumb".to_string())
-    } else {
-        vec!("-marm".to_string())
-    };
-    return target_strs::t {
-        module_asm: "".to_string(),
-
-        data_layout: match target_os {
-          abi::OsMacos => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsiOS => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsWin32 => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsLinux => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsAndroid => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsFreebsd => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-        },
-
-        target_triple: target_triple,
-
-        cc_args: cc_args,
-    };
-}
index a190d9309cc8df8612f6fbe85f5a8b76173be14f..cad164c9e2019d0c271c5c7c00b3b2988cedffaf 100644 (file)
@@ -8,18 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use back::archive::{Archive, METADATA_FILENAME};
-use back::rpath;
-use back::svh::Svh;
-use driver::driver::{CrateTranslation, OutputFilenames};
+use super::archive::{Archive, ArchiveConfig, METADATA_FILENAME};
+use super::rpath;
+use super::rpath::RPathConfig;
+use super::svh::Svh;
+use driver::driver::{CrateTranslation, OutputFilenames, Input, FileInput};
 use driver::config::NoDebugInfo;
 use driver::session::Session;
 use driver::config;
-use lib::llvm::llvm;
-use lib::llvm::ModuleRef;
-use lib;
+use llvm;
+use llvm::ModuleRef;
 use metadata::common::LinkMeta;
-use metadata::{encoder, cstore, filesearch, csearch, loader};
+use metadata::{encoder, cstore, filesearch, csearch, loader, creader};
 use middle::trans::context::CrateContext;
 use middle::trans::common::gensym_name;
 use middle::ty;
@@ -29,6 +29,7 @@
 
 use std::c_str::{ToCStr, CString};
 use std::char;
+use std::collections::HashSet;
 use std::io::{fs, TempDir, Command};
 use std::io;
 use std::ptr;
@@ -40,9 +41,8 @@
 use syntax::ast;
 use syntax::ast_map::{PathElem, PathElems, PathName};
 use syntax::ast_map;
-use syntax::attr;
 use syntax::attr::AttrMetaMethods;
-use syntax::crateid::CrateId;
+use syntax::codemap::Span;
 use syntax::parse::token;
 
 #[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
@@ -71,11 +71,11 @@ pub fn llvm_err(sess: &Session, msg: String) -> ! {
 
 pub fn write_output_file(
         sess: &Session,
-        target: lib::llvm::TargetMachineRef,
-        pm: lib::llvm::PassManagerRef,
+        target: llvm::TargetMachineRef,
+        pm: llvm::PassManagerRef,
         m: ModuleRef,
         output: &Path,
-        file_type: lib::llvm::FileType) {
+        file_type: llvm::FileType) {
     unsafe {
         output.with_c_str(|output| {
             let result = llvm::LLVMRustWriteOutputFile(
@@ -89,18 +89,17 @@ pub fn write_output_file(
 
 pub mod write {
 
-    use back::lto;
-    use back::link::{write_output_file, OutputType};
-    use back::link::{OutputTypeAssembly, OutputTypeBitcode};
-    use back::link::{OutputTypeExe, OutputTypeLlvmAssembly};
-    use back::link::{OutputTypeObject};
+    use super::super::lto;
+    use super::{write_output_file, OutputType};
+    use super::{OutputTypeAssembly, OutputTypeBitcode};
+    use super::{OutputTypeExe, OutputTypeLlvmAssembly};
+    use super::{OutputTypeObject};
     use driver::driver::{CrateTranslation, OutputFilenames};
     use driver::config::NoDebugInfo;
     use driver::session::Session;
     use driver::config;
-    use lib::llvm::llvm;
-    use lib::llvm::{ModuleRef, TargetMachineRef, PassManagerRef};
-    use lib;
+    use llvm;
+    use llvm::{ModuleRef, TargetMachineRef, PassManagerRef};
     use util::common::time;
     use syntax::abi;
 
@@ -153,10 +152,10 @@ pub fn run_passes(sess: &Session,
             }
 
             let opt_level = match sess.opts.optimize {
-              config::No => lib::llvm::CodeGenLevelNone,
-              config::Less => lib::llvm::CodeGenLevelLess,
-              config::Default => lib::llvm::CodeGenLevelDefault,
-              config::Aggressive => lib::llvm::CodeGenLevelAggressive,
+              config::No => llvm::CodeGenLevelNone,
+              config::Less => llvm::CodeGenLevelLess,
+              config::Default => llvm::CodeGenLevelDefault,
+              config::Aggressive => llvm::CodeGenLevelAggressive,
             };
             let use_softfp = sess.opts.cg.soft_float;
 
@@ -173,10 +172,10 @@ pub fn run_passes(sess: &Session,
             let fdata_sections = ffunction_sections;
 
             let reloc_model = match sess.opts.cg.relocation_model.as_slice() {
-                "pic" => lib::llvm::RelocPIC,
-                "static" => lib::llvm::RelocStatic,
-                "default" => lib::llvm::RelocDefault,
-                "dynamic-no-pic" => lib::llvm::RelocDynamicNoPic,
+                "pic" => llvm::RelocPIC,
+                "static" => llvm::RelocStatic,
+                "default" => llvm::RelocDefault,
+                "dynamic-no-pic" => llvm::RelocDynamicNoPic,
                 _ => {
                     sess.err(format!("{} is not a valid relocation mode",
                                      sess.opts
@@ -196,7 +195,7 @@ pub fn run_passes(sess: &Session,
                     target_feature(sess).with_c_str(|features| {
                         llvm::LLVMRustCreateTargetMachine(
                             t, cpu, features,
-                            lib::llvm::CodeModelDefault,
+                            llvm::CodeModelDefault,
                             reloc_model,
                             opt_level,
                             true /* EnableSegstk */,
@@ -321,7 +320,7 @@ fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef,
                         };
                         with_codegen(tm, llmod, trans.no_builtins, |cpm| {
                             write_output_file(sess, tm, cpm, llmod, &path,
-                                            lib::llvm::AssemblyFile);
+                                            llvm::AssemblyFile);
                         });
                     }
                     OutputTypeObject => {
@@ -339,7 +338,7 @@ fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef,
                     Some(ref path) => {
                         with_codegen(tm, llmod, trans.no_builtins, |cpm| {
                             write_output_file(sess, tm, cpm, llmod, path,
-                                            lib::llvm::ObjectFile);
+                                            llvm::ObjectFile);
                         });
                     }
                     None => {}
@@ -351,7 +350,7 @@ fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef,
                                         .with_extension("metadata.o");
                         write_output_file(sess, tm, cpm,
                                         trans.metadata_module, &out,
-                                        lib::llvm::ObjectFile);
+                                        llvm::ObjectFile);
                     })
                 }
             });
@@ -456,29 +455,29 @@ unsafe fn configure_llvm(sess: &Session) {
         });
     }
 
-    unsafe fn populate_llvm_passes(fpm: lib::llvm::PassManagerRef,
-                                   mpm: lib::llvm::PassManagerRef,
+    unsafe fn populate_llvm_passes(fpm: llvm::PassManagerRef,
+                                   mpm: llvm::PassManagerRef,
                                    llmod: ModuleRef,
-                                   opt: lib::llvm::CodeGenOptLevel,
+                                   opt: llvm::CodeGenOptLevel,
                                    no_builtins: bool) {
         // Create the PassManagerBuilder for LLVM. We configure it with
         // reasonable defaults and prepare it to actually populate the pass
         // manager.
         let builder = llvm::LLVMPassManagerBuilderCreate();
         match opt {
-            lib::llvm::CodeGenLevelNone => {
+            llvm::CodeGenLevelNone => {
                 // Don't add lifetime intrinsics at O0
                 llvm::LLVMRustAddAlwaysInlinePass(builder, false);
             }
-            lib::llvm::CodeGenLevelLess => {
+            llvm::CodeGenLevelLess => {
                 llvm::LLVMRustAddAlwaysInlinePass(builder, true);
             }
             // numeric values copied from clang
-            lib::llvm::CodeGenLevelDefault => {
+            llvm::CodeGenLevelDefault => {
                 llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder,
                                                                     225);
             }
-            lib::llvm::CodeGenLevelAggressive => {
+            llvm::CodeGenLevelAggressive => {
                 llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder,
                                                                     275);
             }
@@ -546,32 +545,73 @@ unsafe fn populate_llvm_passes(fpm: lib::llvm::PassManagerRef,
  *    system linkers understand.
  */
 
-// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
-pub fn find_crate_id(attrs: &[ast::Attribute], out_filestem: &str) -> CrateId {
-    match attr::find_crateid(attrs) {
-        None => from_str(out_filestem).unwrap_or_else(|| {
-            let mut s = out_filestem.chars().filter(|c| c.is_XID_continue());
-            from_str(s.collect::<String>().as_slice())
-                .or(from_str("rust-out")).unwrap()
-        }),
-        Some(s) => s,
+pub fn find_crate_name(sess: Option<&Session>,
+                       attrs: &[ast::Attribute],
+                       input: &Input) -> String {
+    use syntax::crateid::CrateId;
+
+    let validate = |s: String, span: Option<Span>| {
+        creader::validate_crate_name(sess, s.as_slice(), span);
+        s
+    };
+
+    // Look in attributes 100% of the time to make sure the attribute is marked
+    // as used. After doing this, however, favor crate names from the command
+    // line.
+    let attr_crate_name = attrs.iter().find(|at| at.check_name("crate_name"))
+                               .and_then(|at| at.value_str().map(|s| (at, s)));
+
+    match sess {
+        Some(sess) => {
+            match sess.opts.crate_name {
+                Some(ref s) => return validate(s.clone(), None),
+                None => {}
+            }
+        }
+        None => {}
     }
-}
 
-pub fn crate_id_hash(crate_id: &CrateId) -> String {
-    // This calculates CMH as defined above. Note that we don't use the path of
-    // the crate id in the hash because lookups are only done by (name/vers),
-    // not by path.
-    let mut s = Sha256::new();
-    s.input_str(crate_id.short_name_with_version().as_slice());
-    truncated_hash_result(&mut s).as_slice().slice_to(8).to_string()
+    match attr_crate_name {
+        Some((attr, s)) => return validate(s.get().to_string(), Some(attr.span)),
+        None => {}
+    }
+    let crate_id = attrs.iter().find(|at| at.check_name("crate_id"))
+                        .and_then(|at| at.value_str().map(|s| (at, s)))
+                        .and_then(|(at, s)| {
+                            from_str::<CrateId>(s.get()).map(|id| (at, id))
+                        });
+    match crate_id {
+        Some((attr, id)) => {
+            match sess {
+                Some(sess) => {
+                    sess.span_warn(attr.span, "the #[crate_id] attribute is \
+                                               deprecated for the \
+                                               #[crate_name] attribute");
+                }
+                None => {}
+            }
+            return validate(id.name, Some(attr.span))
+        }
+        None => {}
+    }
+    match *input {
+        FileInput(ref path) => {
+            match path.filestem_str() {
+                Some(s) => return validate(s.to_string(), None),
+                None => {}
+            }
+        }
+        _ => {}
+    }
+
+    "rust-out".to_string()
 }
 
-// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
-pub fn build_link_meta(krate: &ast::Crate, out_filestem: &str) -> LinkMeta {
+pub fn build_link_meta(sess: &Session, krate: &ast::Crate,
+                       name: String) -> LinkMeta {
     let r = LinkMeta {
-        crateid: find_crate_id(krate.attrs.as_slice(), out_filestem),
-        crate_hash: Svh::calculate(krate),
+        crate_name: name,
+        crate_hash: Svh::calculate(&sess.opts.cg.metadata, krate),
     };
     info!("{}", r);
     return r;
@@ -594,9 +634,12 @@ fn symbol_hash(tcx: &ty::ctxt,
     // to be independent of one another in the crate.
 
     symbol_hasher.reset();
-    symbol_hasher.input_str(link_meta.crateid.name.as_slice());
+    symbol_hasher.input_str(link_meta.crate_name.as_slice());
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(link_meta.crate_hash.as_str());
+    for meta in tcx.sess.crate_metadata.borrow().iter() {
+        symbol_hasher.input_str(meta.as_slice());
+    }
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(encoder::encoded_ty(tcx, t).as_slice());
     // Prefix with 'h' so that it never blends into adjacent digits
@@ -666,8 +709,7 @@ pub fn sanitize(s: &str) -> String {
 }
 
 pub fn mangle<PI: Iterator<PathElem>>(mut path: PI,
-                                      hash: Option<&str>,
-                                      vers: Option<&str>) -> String {
+                                      hash: Option<&str>) -> String {
     // Follow C++ namespace-mangling style, see
     // http://en.wikipedia.org/wiki/Name_mangling for more info.
     //
@@ -698,25 +740,13 @@ fn push(n: &mut String, s: &str) {
         Some(s) => push(&mut n, s),
         None => {}
     }
-    match vers {
-        Some(s) => push(&mut n, s),
-        None => {}
-    }
 
     n.push_char('E'); // End name-sequence.
     n
 }
 
-pub fn exported_name(path: PathElems, hash: &str, vers: &str) -> String {
-    // The version will get mangled to have a leading '_', but it makes more
-    // sense to lead with a 'v' b/c this is a version...
-    let vers = if vers.len() > 0 && !char::is_XID_start(vers.char_at(0)) {
-        format!("v{}", vers)
-    } else {
-        vers.to_string()
-    };
-
-    mangle(path, Some(hash), Some(vers.as_slice()))
+pub fn exported_name(path: PathElems, hash: &str) -> String {
+    mangle(path, Some(hash))
 }
 
 pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
@@ -741,27 +771,21 @@ pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
     hash.push_char(EXTRA_CHARS.as_bytes()[extra2] as char);
     hash.push_char(EXTRA_CHARS.as_bytes()[extra3] as char);
 
-    exported_name(path,
-                  hash.as_slice(),
-                  ccx.link_meta.crateid.version_or_default())
+    exported_name(path, hash.as_slice())
 }
 
 pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
                                             t: ty::t,
                                             name: &str) -> String {
-    let s = ppaux::ty_to_str(ccx.tcx(), t);
+    let s = ppaux::ty_to_string(ccx.tcx(), t);
     let path = [PathName(token::intern(s.as_slice())),
                 gensym_name(name)];
     let hash = get_symbol_hash(ccx, t);
-    mangle(ast_map::Values(path.iter()), Some(hash.as_slice()), None)
+    mangle(ast_map::Values(path.iter()), Some(hash.as_slice()))
 }
 
 pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
-    mangle(path.chain(Some(gensym_name(flav)).move_iter()), None, None)
-}
-
-pub fn output_lib_filename(id: &CrateId) -> String {
-    format!("{}-{}-{}", id.name, crate_id_hash(id), id.version_or_default())
+    mangle(path.chain(Some(gensym_name(flav)).move_iter()), None)
 }
 
 pub fn get_cc_prog(sess: &Session) -> String {
@@ -803,14 +827,15 @@ fn remove(sess: &Session, path: &Path) {
 pub fn link_binary(sess: &Session,
                    trans: &CrateTranslation,
                    outputs: &OutputFilenames,
-                   id: &CrateId) -> Vec<Path> {
+                   crate_name: &str) -> Vec<Path> {
     let mut out_filenames = Vec::new();
     for &crate_type in sess.crate_types.borrow().iter() {
         if invalid_output_for_target(sess, crate_type) {
             sess.bug(format!("invalid output type `{}` for target os `{}`",
                              crate_type, sess.targ_cfg.os).as_slice());
         }
-        let out_file = link_binary_output(sess, trans, crate_type, outputs, id);
+        let out_file = link_binary_output(sess, trans, crate_type, outputs,
+                                          crate_name);
         out_filenames.push(out_file);
     }
 
@@ -859,9 +884,11 @@ fn is_writeable(p: &Path) -> bool {
     }
 }
 
-pub fn filename_for_input(sess: &Session, crate_type: config::CrateType,
-                          id: &CrateId, out_filename: &Path) -> Path {
-    let libname = output_lib_filename(id);
+pub fn filename_for_input(sess: &Session,
+                          crate_type: config::CrateType,
+                          name: &str,
+                          out_filename: &Path) -> Path {
+    let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
     match crate_type {
         config::CrateTypeRlib => {
             out_filename.with_filename(format!("lib{}.rlib", libname))
@@ -891,13 +918,13 @@ fn link_binary_output(sess: &Session,
                       trans: &CrateTranslation,
                       crate_type: config::CrateType,
                       outputs: &OutputFilenames,
-                      id: &CrateId) -> Path {
+                      crate_name: &str) -> Path {
     let obj_filename = outputs.temp_path(OutputTypeObject);
     let out_filename = match outputs.single_output_file {
         Some(ref file) => file.clone(),
         None => {
             let out_filename = outputs.path(OutputTypeExe);
-            filename_for_input(sess, crate_type, id, &out_filename)
+            filename_for_input(sess, crate_type, crate_name, &out_filename)
         }
     };
 
@@ -936,6 +963,17 @@ fn link_binary_output(sess: &Session,
     out_filename
 }
 
+fn archive_search_paths(sess: &Session) -> Vec<Path> {
+    let mut rustpath = filesearch::rust_path();
+    rustpath.push(sess.target_filesearch().get_lib_path());
+    // FIXME: Addl lib search paths are an unordered HashSet?
+    // Shouldn't this search be done in some order?
+    let addl_lib_paths: HashSet<Path> = sess.opts.addl_lib_search_paths.borrow().clone();
+    let mut search: Vec<Path> = addl_lib_paths.move_iter().collect();
+    search.push_all(rustpath.as_slice());
+    return search;
+}
+
 // Create an 'rlib'
 //
 // An rlib in its current incarnation is essentially a renamed .a file. The
@@ -946,7 +984,15 @@ fn link_rlib<'a>(sess: &'a Session,
                  trans: Option<&CrateTranslation>, // None == no metadata/bytecode
                  obj_filename: &Path,
                  out_filename: &Path) -> Archive<'a> {
-    let mut a = Archive::create(sess, out_filename, obj_filename);
+    let handler = &sess.diagnostic().handler;
+    let config = ArchiveConfig {
+        handler: handler,
+        dst: out_filename.clone(),
+        lib_search_paths: archive_search_paths(sess),
+        os: sess.targ_cfg.os,
+        maybe_ar_prog: sess.opts.cg.ar.clone()
+    };
+    let mut a = Archive::create(config, obj_filename);
 
     for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
         match kind {
@@ -1340,7 +1386,7 @@ fn link_args(cmd: &mut Command,
         if sess.targ_cfg.os == abi::OsMacos {
             cmd.args(["-dynamiclib", "-Wl,-dylib"]);
 
-            if !sess.opts.cg.no_rpath {
+            if sess.opts.cg.rpath {
                 let mut v = Vec::from_slice("-Wl,-install_name,@rpath/".as_bytes());
                 v.push_all(out_filename.filename().unwrap());
                 cmd.arg(v.as_slice());
@@ -1359,8 +1405,25 @@ fn link_args(cmd: &mut Command,
     // FIXME (#2397): At some point we want to rpath our guesses as to
     // where extern libraries might live, based on the
     // addl_lib_search_paths
-    if !sess.opts.cg.no_rpath {
-        cmd.args(rpath::get_rpath_flags(sess, out_filename).as_slice());
+    if sess.opts.cg.rpath {
+        let sysroot = sess.sysroot();
+        let target_triple = sess.opts.target_triple.as_slice();
+        let get_install_prefix_lib_path = || {
+            let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
+            let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
+            let mut path = Path::new(install_prefix);
+            path.push(&tlib);
+
+            path
+        };
+        let rpath_config = RPathConfig {
+            os: sess.targ_cfg.os,
+            used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
+            out_filename: out_filename.clone(),
+            get_install_prefix_lib_path: get_install_prefix_lib_path,
+            realpath: ::util::fs::realpath
+        };
+        cmd.args(rpath::get_rpath_flags(rpath_config).as_slice());
     }
 
     // compiler-rt contains implementations of low-level LLVM helpers. This is
@@ -1518,7 +1581,15 @@ fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path,
                         sess.abort_if_errors();
                     }
                 }
-                let mut archive = Archive::open(sess, dst.clone());
+                let handler = &sess.diagnostic().handler;
+                let config = ArchiveConfig {
+                    handler: handler,
+                    dst: dst.clone(),
+                    lib_search_paths: archive_search_paths(sess),
+                    os: sess.targ_cfg.os,
+                    maybe_ar_prog: sess.opts.cg.ar.clone()
+                };
+                let mut archive = Archive::open(config);
                 archive.remove_file(format!("{}.o", name).as_slice());
                 let files = archive.files();
                 if files.iter().any(|s| s.as_slice().ends_with(".o")) {
index b9ae9530f8e1c3291aa4a15be0393484b844b0e5..6184ea4591f084ae5041f04c56372e6cd516d8f5 100644 (file)
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use back::archive::ArchiveRO;
-use back::link;
+use super::link;
 use driver::session;
 use driver::config;
-use lib::llvm::{ModuleRef, TargetMachineRef, llvm, True, False};
+use llvm;
+use llvm::archive_ro::ArchiveRO;
+use llvm::{ModuleRef, TargetMachineRef, True, False};
 use metadata::cstore;
 use util::common::time;
 
diff --git a/src/librustc/back/mips.rs b/src/librustc/back/mips.rs
deleted file mode 100644 (file)
index 8f3da03..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
-    return target_strs::t {
-        module_asm: "".to_string(),
-
-        data_layout: match target_os {
-          abi::OsMacos => {
-            "E-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsiOS => {
-            "E-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsWin32 => {
-            "E-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsLinux => {
-            "E-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsAndroid => {
-            "E-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsFreebsd => {
-            "E-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-        },
-
-        target_triple: target_triple,
-
-        cc_args: Vec::new(),
-    };
-}
diff --git a/src/librustc/back/mipsel.rs b/src/librustc/back/mipsel.rs
deleted file mode 100644 (file)
index c2c48a4..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
-    return target_strs::t {
-        module_asm: "".to_string(),
-
-        data_layout: match target_os {
-          abi::OsMacos => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsiOS => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsWin32 => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsLinux => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsAndroid => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-
-          abi::OsFreebsd => {
-            "e-p:32:32:32\
-                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
-                -f32:32:32-f64:64:64\
-                -v64:64:64-v128:64:128\
-                -a0:0:64-n32".to_string()
-          }
-        },
-
-        target_triple: target_triple,
-
-        cc_args: Vec::new(),
-    };
-}
diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs
deleted file mode 100644 (file)
index a458cf2..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-use driver::session::Session;
-use metadata::cstore;
-use metadata::filesearch;
-use util::fs;
-
-use std::collections::HashSet;
-use std::os;
-use syntax::abi;
-
-fn not_win32(os: abi::Os) -> bool {
-  os != abi::OsWin32
-}
-
-pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<String> {
-    let os = sess.targ_cfg.os;
-
-    // No rpath on windows
-    if os == abi::OsWin32 {
-        return Vec::new();
-    }
-
-    let mut flags = Vec::new();
-
-    if sess.targ_cfg.os == abi::OsFreebsd {
-        flags.push_all(["-Wl,-rpath,/usr/local/lib/gcc46".to_string(),
-                        "-Wl,-rpath,/usr/local/lib/gcc44".to_string(),
-                        "-Wl,-z,origin".to_string()]);
-    }
-
-    debug!("preparing the RPATH!");
-
-    let sysroot = sess.sysroot();
-    let output = out_filename;
-    let libs = sess.cstore.get_used_crates(cstore::RequireDynamic);
-    let libs = libs.move_iter().filter_map(|(_, l)| {
-        l.map(|p| p.clone())
-    }).collect::<Vec<_>>();
-
-    let rpaths = get_rpaths(os,
-                            sysroot,
-                            output,
-                            libs.as_slice(),
-                            sess.opts.target_triple.as_slice());
-    flags.push_all(rpaths_to_flags(rpaths.as_slice()).as_slice());
-    flags
-}
-
-pub fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
-    let mut ret = Vec::new();
-    for rpath in rpaths.iter() {
-        ret.push(format!("-Wl,-rpath,{}", (*rpath).as_slice()));
-    }
-    return ret;
-}
-
-fn get_rpaths(os: abi::Os,
-              sysroot: &Path,
-              output: &Path,
-              libs: &[Path],
-              target_triple: &str) -> Vec<String> {
-    debug!("sysroot: {}", sysroot.display());
-    debug!("output: {}", output.display());
-    debug!("libs:");
-    for libpath in libs.iter() {
-        debug!("    {}", libpath.display());
-    }
-    debug!("target_triple: {}", target_triple);
-
-    // Use relative paths to the libraries. Binaries can be moved
-    // as long as they maintain the relative relationship to the
-    // crates they depend on.
-    let rel_rpaths = get_rpaths_relative_to_output(os, output, libs);
-
-    // And a final backup rpath to the global library location.
-    let fallback_rpaths = vec!(get_install_prefix_rpath(sysroot, target_triple));
-
-    fn log_rpaths(desc: &str, rpaths: &[String]) {
-        debug!("{} rpaths:", desc);
-        for rpath in rpaths.iter() {
-            debug!("    {}", *rpath);
-        }
-    }
-
-    log_rpaths("relative", rel_rpaths.as_slice());
-    log_rpaths("fallback", fallback_rpaths.as_slice());
-
-    let mut rpaths = rel_rpaths;
-    rpaths.push_all(fallback_rpaths.as_slice());
-
-    // Remove duplicates
-    let rpaths = minimize_rpaths(rpaths.as_slice());
-    return rpaths;
-}
-
-fn get_rpaths_relative_to_output(os: abi::Os,
-                                 output: &Path,
-                                 libs: &[Path]) -> Vec<String> {
-    libs.iter().map(|a| get_rpath_relative_to_output(os, output, a)).collect()
-}
-
-pub fn get_rpath_relative_to_output(os: abi::Os,
-                                    output: &Path,
-                                    lib: &Path)
-                                 -> String {
-    use std::os;
-
-    assert!(not_win32(os));
-
-    // Mac doesn't appear to support $ORIGIN
-    let prefix = match os {
-        abi::OsAndroid | abi::OsLinux | abi::OsFreebsd
-                          => "$ORIGIN",
-        abi::OsMacos => "@loader_path",
-        abi::OsWin32 | abi::OsiOS => unreachable!()
-    };
-
-    let mut lib = fs::realpath(&os::make_absolute(lib)).unwrap();
-    lib.pop();
-    let mut output = fs::realpath(&os::make_absolute(output)).unwrap();
-    output.pop();
-    let relative = lib.path_relative_from(&output);
-    let relative = relative.expect("could not create rpath relative to output");
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    format!("{}/{}",
-            prefix,
-            relative.as_str().expect("non-utf8 component in path"))
-}
-
-pub fn get_install_prefix_rpath(sysroot: &Path, target_triple: &str) -> String {
-    let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
-
-    let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
-    let mut path = Path::new(install_prefix);
-    path.push(&tlib);
-    let path = os::make_absolute(&path);
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    path.as_str().expect("non-utf8 component in rpath").to_string()
-}
-
-pub fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
-    let mut set = HashSet::new();
-    let mut minimized = Vec::new();
-    for rpath in rpaths.iter() {
-        if set.insert(rpath.as_slice()) {
-            minimized.push(rpath.clone());
-        }
-    }
-    minimized
-}
-
-#[cfg(unix, test)]
-mod test {
-    use back::rpath::get_install_prefix_rpath;
-    use back::rpath::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
-    use syntax::abi;
-    use metadata::filesearch;
-
-    #[test]
-    fn test_rpaths_to_flags() {
-        let flags = rpaths_to_flags([
-            "path1".to_string(),
-            "path2".to_string()
-        ]);
-        assert_eq!(flags,
-                   vec!("-Wl,-rpath,path1".to_string(),
-                        "-Wl,-rpath,path2".to_string()));
-    }
-
-    #[test]
-    fn test_prefix_rpath() {
-        let sysroot = filesearch::get_or_default_sysroot();
-        let res = get_install_prefix_rpath(&sysroot, "triple");
-        let mut d = Path::new((option_env!("CFG_PREFIX")).expect("CFG_PREFIX"));
-        d.push("lib");
-        d.push(filesearch::rustlibdir());
-        d.push("triple/lib");
-        debug!("test_prefix_path: {} vs. {}",
-               res,
-               d.display());
-        assert!(res.as_bytes().ends_with(d.as_vec()));
-    }
-
-    #[test]
-    fn test_prefix_rpath_abs() {
-        let sysroot = filesearch::get_or_default_sysroot();
-        let res = get_install_prefix_rpath(&sysroot, "triple");
-        assert!(Path::new(res).is_absolute());
-    }
-
-    #[test]
-    fn test_minimize1() {
-        let res = minimize_rpaths([
-            "rpath1".to_string(),
-            "rpath2".to_string(),
-            "rpath1".to_string()
-        ]);
-        assert!(res.as_slice() == [
-            "rpath1".to_string(),
-            "rpath2".to_string()
-        ]);
-    }
-
-    #[test]
-    fn test_minimize2() {
-        let res = minimize_rpaths([
-            "1a".to_string(),
-            "2".to_string(),
-            "2".to_string(),
-            "1a".to_string(),
-            "4a".to_string(),
-            "1a".to_string(),
-            "2".to_string(),
-            "3".to_string(),
-            "4a".to_string(),
-            "3".to_string()
-        ]);
-        assert!(res.as_slice() == [
-            "1a".to_string(),
-            "2".to_string(),
-            "4a".to_string(),
-            "3".to_string()
-        ]);
-    }
-
-    #[test]
-    #[cfg(target_os = "linux")]
-    #[cfg(target_os = "android")]
-    fn test_rpath_relative() {
-      let o = abi::OsLinux;
-      let res = get_rpath_relative_to_output(o,
-            &Path::new("bin/rustc"), &Path::new("lib/libstd.so"));
-      assert_eq!(res.as_slice(), "$ORIGIN/../lib");
-    }
-
-    #[test]
-    #[cfg(target_os = "freebsd")]
-    fn test_rpath_relative() {
-        let o = abi::OsFreebsd;
-        let res = get_rpath_relative_to_output(o,
-            &Path::new("bin/rustc"), &Path::new("lib/libstd.so"));
-        assert_eq!(res.as_slice(), "$ORIGIN/../lib");
-    }
-
-    #[test]
-    #[cfg(target_os = "macos")]
-    fn test_rpath_relative() {
-        let o = abi::OsMacos;
-        let res = get_rpath_relative_to_output(o,
-                                               &Path::new("bin/rustc"),
-                                               &Path::new("lib/libstd.so"));
-        assert_eq!(res.as_slice(), "@loader_path/../lib");
-    }
-}
diff --git a/src/librustc/back/svh.rs b/src/librustc/back/svh.rs
deleted file mode 100644 (file)
index c487f67..0000000
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright 2012-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.
-
-//! Calculation and management of a Strict Version Hash for crates
-//!
-//! # Today's ABI problem
-//!
-//! In today's implementation of rustc, it is incredibly difficult to achieve
-//! forward binary compatibility without resorting to C-like interfaces. Within
-//! rust code itself, abi details such as symbol names suffer from a variety of
-//! unrelated factors to code changing such as the "def id drift" problem. This
-//! ends up yielding confusing error messages about metadata mismatches and
-//! such.
-//!
-//! The core of this problem is when an upstream dependency changes and
-//! downstream dependents are not recompiled. This causes compile errors because
-//! the upstream crate's metadata has changed but the downstream crates are
-//! still referencing the older crate's metadata.
-//!
-//! This problem exists for many reasons, the primary of which is that rust does
-//! not currently support forwards ABI compatibility (in place upgrades of a
-//! crate).
-//!
-//! # SVH and how it alleviates the problem
-//!
-//! With all of this knowledge on hand, this module contains the implementation
-//! of a notion of a "Strict Version Hash" for a crate. This is essentially a
-//! hash of all contents of a crate which can somehow be exposed to downstream
-//! crates.
-//!
-//! This hash is currently calculated by just hashing the AST, but this is
-//! obviously wrong (doc changes should not result in an incompatible ABI).
-//! Implementation-wise, this is required at this moment in time.
-//!
-//! By encoding this strict version hash into all crate's metadata, stale crates
-//! can be detected immediately and error'd about by rustc itself.
-//!
-//! # Relevant links
-//!
-//! Original issue: https://github.com/rust-lang/rust/issues/10207
-
-use std::fmt;
-use std::hash::Hash;
-use std::hash::sip::SipState;
-use std::iter::range_step;
-use syntax::ast;
-use syntax::visit;
-
-#[deriving(Clone, PartialEq)]
-pub struct Svh {
-    hash: String,
-}
-
-impl Svh {
-    pub fn new(hash: &str) -> Svh {
-        assert!(hash.len() == 16);
-        Svh { hash: hash.to_string() }
-    }
-
-    pub fn as_str<'a>(&'a self) -> &'a str {
-        self.hash.as_slice()
-    }
-
-    pub fn calculate(krate: &ast::Crate) -> Svh {
-        // FIXME (#14132): This is better than it used to be, but it still not
-        // ideal. We now attempt to hash only the relevant portions of the
-        // Crate AST as well as the top-level crate attributes. (However,
-        // the hashing of the crate attributes should be double-checked
-        // to ensure it is not incorporating implementation artifacts into
-        // the hash that are not otherwise visible.)
-
-        // FIXME: this should use SHA1, not SipHash. SipHash is not built to
-        //        avoid collisions.
-        let mut state = SipState::new();
-
-        {
-            let mut visit = svh_visitor::make(&mut state);
-            visit::walk_crate(&mut visit, krate, ());
-        }
-
-        // FIXME (#14132): This hash is still sensitive to e.g. the
-        // spans of the crate Attributes and their underlying
-        // MetaItems; we should make ContentHashable impl for those
-        // types and then use hash_content.  But, since all crate
-        // attributes should appear near beginning of the file, it is
-        // not such a big deal to be sensitive to their spans for now.
-        //
-        // We hash only the MetaItems instead of the entire Attribute
-        // to avoid hashing the AttrId
-        for attr in krate.attrs.iter() {
-            attr.node.value.hash(&mut state);
-        }
-
-        let hash = state.result();
-        return Svh {
-            hash: range_step(0u, 64u, 4u).map(|i| hex(hash >> i)).collect()
-        };
-
-        fn hex(b: u64) -> char {
-            let b = (b & 0xf) as u8;
-            let b = match b {
-                0 .. 9 => '0' as u8 + b,
-                _ => 'a' as u8 + b - 10,
-            };
-            b as char
-        }
-    }
-}
-
-impl fmt::Show for Svh {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.pad(self.as_str())
-    }
-}
-
-// FIXME (#14132): Even this SVH computation still has implementation
-// artifacts: namely, the order of item declaration will affect the
-// hash computation, but for many kinds of items the order of
-// declaration should be irrelevant to the ABI.
-
-mod svh_visitor {
-    use syntax::ast;
-    use syntax::ast::*;
-    use syntax::codemap::Span;
-    use syntax::parse::token;
-    use syntax::print::pprust;
-    use syntax::visit;
-    use syntax::visit::{Visitor, FnKind};
-
-    use std::hash::Hash;
-    use std::hash::sip::SipState;
-
-    pub struct StrictVersionHashVisitor<'a> {
-        pub st: &'a mut SipState,
-    }
-
-    pub fn make<'a>(st: &'a mut SipState) -> StrictVersionHashVisitor<'a> {
-        StrictVersionHashVisitor { st: st }
-    }
-
-    // To off-load the bulk of the hash-computation on deriving(Hash),
-    // we define a set of enums corresponding to the content that our
-    // crate visitor will encounter as it traverses the ast.
-    //
-    // The important invariant is that all of the Saw*Component enums
-    // do not carry any Spans, Names, or Idents.
-    //
-    // Not carrying any Names/Idents is the important fix for problem
-    // noted on PR #13948: using the ident.name as the basis for a
-    // hash leads to unstable SVH, because ident.name is just an index
-    // into intern table (i.e. essentially a random address), not
-    // computed from the name content.
-    //
-    // With the below enums, the SVH computation is not sensitive to
-    // artifacts of how rustc was invoked nor of how the source code
-    // was laid out.  (Or at least it is *less* sensitive.)
-
-    // This enum represents the different potential bits of code the
-    // visitor could encounter that could affect the ABI for the crate,
-    // and assigns each a distinct tag to feed into the hash computation.
-    #[deriving(Hash)]
-    enum SawAbiComponent<'a> {
-
-        // FIXME (#14132): should we include (some function of)
-        // ident.ctxt as well?
-        SawIdent(token::InternedString),
-        SawStructDef(token::InternedString),
-
-        SawLifetimeRef(token::InternedString),
-        SawLifetimeDecl(token::InternedString),
-
-        SawMod,
-        SawViewItem,
-        SawForeignItem,
-        SawItem,
-        SawDecl,
-        SawTy,
-        SawGenerics,
-        SawFn,
-        SawTyMethod,
-        SawTraitMethod,
-        SawStructField,
-        SawVariant,
-        SawExplicitSelf,
-        SawPath,
-        SawOptLifetimeRef,
-        SawBlock,
-        SawPat,
-        SawLocal,
-        SawArm,
-        SawExpr(SawExprComponent<'a>),
-        SawStmt(SawStmtComponent),
-    }
-
-    /// SawExprComponent carries all of the information that we want
-    /// to include in the hash that *won't* be covered by the
-    /// subsequent recursive traversal of the expression's
-    /// substructure by the visitor.
-    ///
-    /// We know every Expr_ variant is covered by a variant because
-    /// `fn saw_expr` maps each to some case below.  Ensuring that
-    /// each variant carries an appropriate payload has to be verified
-    /// by hand.
-    ///
-    /// (However, getting that *exactly* right is not so important
-    /// because the SVH is just a developer convenience; there is no
-    /// guarantee of collision-freedom, hash collisions are just
-    /// (hopefully) unlikely.)
-    #[deriving(Hash)]
-    pub enum SawExprComponent<'a> {
-
-        SawExprLoop(Option<token::InternedString>),
-        SawExprField(token::InternedString),
-        SawExprBreak(Option<token::InternedString>),
-        SawExprAgain(Option<token::InternedString>),
-
-        SawExprVstore,
-        SawExprBox,
-        SawExprVec,
-        SawExprCall,
-        SawExprMethodCall,
-        SawExprTup,
-        SawExprBinary(ast::BinOp),
-        SawExprUnary(ast::UnOp),
-        SawExprLit(ast::Lit_),
-        SawExprCast,
-        SawExprIf,
-        SawExprWhile,
-        SawExprMatch,
-        SawExprFnBlock,
-        SawExprProc,
-        SawExprBlock,
-        SawExprAssign,
-        SawExprAssignOp(ast::BinOp),
-        SawExprIndex,
-        SawExprPath,
-        SawExprAddrOf(ast::Mutability),
-        SawExprRet,
-        SawExprInlineAsm(&'a ast::InlineAsm),
-        SawExprStruct,
-        SawExprRepeat,
-        SawExprParen,
-    }
-
-    fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> {
-        match *node {
-            ExprVstore(..)           => SawExprVstore,
-            ExprBox(..)              => SawExprBox,
-            ExprVec(..)              => SawExprVec,
-            ExprCall(..)             => SawExprCall,
-            ExprMethodCall(..)       => SawExprMethodCall,
-            ExprTup(..)              => SawExprTup,
-            ExprBinary(op, _, _)     => SawExprBinary(op),
-            ExprUnary(op, _)         => SawExprUnary(op),
-            ExprLit(lit)             => SawExprLit(lit.node.clone()),
-            ExprCast(..)             => SawExprCast,
-            ExprIf(..)               => SawExprIf,
-            ExprWhile(..)            => SawExprWhile,
-            ExprLoop(_, id)          => SawExprLoop(id.map(content)),
-            ExprMatch(..)            => SawExprMatch,
-            ExprFnBlock(..)          => SawExprFnBlock,
-            ExprProc(..)             => SawExprProc,
-            ExprBlock(..)            => SawExprBlock,
-            ExprAssign(..)           => SawExprAssign,
-            ExprAssignOp(op, _, _)   => SawExprAssignOp(op),
-            ExprField(_, id, _)      => SawExprField(content(id.node)),
-            ExprIndex(..)            => SawExprIndex,
-            ExprPath(..)             => SawExprPath,
-            ExprAddrOf(m, _)         => SawExprAddrOf(m),
-            ExprBreak(id)            => SawExprBreak(id.map(content)),
-            ExprAgain(id)            => SawExprAgain(id.map(content)),
-            ExprRet(..)              => SawExprRet,
-            ExprInlineAsm(ref asm)   => SawExprInlineAsm(asm),
-            ExprStruct(..)           => SawExprStruct,
-            ExprRepeat(..)           => SawExprRepeat,
-            ExprParen(..)            => SawExprParen,
-
-            // just syntactic artifacts, expanded away by time of SVH.
-            ExprForLoop(..)          => unreachable!(),
-            ExprMac(..)              => unreachable!(),
-        }
-    }
-
-    /// SawStmtComponent is analogous to SawExprComponent, but for statements.
-    #[deriving(Hash)]
-    pub enum SawStmtComponent {
-        SawStmtDecl,
-        SawStmtExpr,
-        SawStmtSemi,
-    }
-
-    fn saw_stmt(node: &Stmt_) -> SawStmtComponent {
-        match *node {
-            StmtDecl(..) => SawStmtDecl,
-            StmtExpr(..) => SawStmtExpr,
-            StmtSemi(..) => SawStmtSemi,
-            StmtMac(..)  => unreachable!(),
-        }
-    }
-
-    // Ad-hoc overloading between Ident and Name to their intern table lookups.
-    trait InternKey { fn get_content(self) -> token::InternedString; }
-    impl InternKey for Ident {
-        fn get_content(self) -> token::InternedString { token::get_ident(self) }
-    }
-    impl InternKey for Name {
-        fn get_content(self) -> token::InternedString { token::get_name(self) }
-    }
-    fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() }
-
-    // local short-hand eases writing signatures of syntax::visit mod.
-    type E = ();
-
-    impl<'a> Visitor<E> for StrictVersionHashVisitor<'a> {
-
-        fn visit_mac(&mut self, macro: &Mac, e: E) {
-            // macro invocations, namely macro_rules definitions,
-            // *can* appear as items, even in the expanded crate AST.
-
-            if macro_name(macro).get() == "macro_rules" {
-                // Pretty-printing definition to a string strips out
-                // surface artifacts (currently), such as the span
-                // information, yielding a content-based hash.
-
-                // FIXME (#14132): building temporary string is
-                // expensive; a direct content-based hash on token
-                // trees might be faster. Implementing this is far
-                // easier in short term.
-                let macro_defn_as_string =
-                    pprust::to_str(|pp_state| pp_state.print_mac(macro));
-                macro_defn_as_string.hash(self.st);
-            } else {
-                // It is not possible to observe any kind of macro
-                // invocation at this stage except `macro_rules!`.
-                fail!("reached macro somehow: {}",
-                      pprust::to_str(|pp_state| pp_state.print_mac(macro)));
-            }
-
-            visit::walk_mac(self, macro, e);
-
-            fn macro_name(macro: &Mac) -> token::InternedString {
-                match &macro.node {
-                    &MacInvocTT(ref path, ref _tts, ref _stx_ctxt) => {
-                        let s = path.segments.as_slice();
-                        assert_eq!(s.len(), 1);
-                        content(s[0].identifier)
-                    }
-                }
-            }
-        }
-
-        fn visit_struct_def(&mut self, s: &StructDef, ident: Ident,
-                            g: &Generics, _: NodeId, e: E) {
-            SawStructDef(content(ident)).hash(self.st);
-            visit::walk_generics(self, g, e.clone());
-            visit::walk_struct_def(self, s, e)
-        }
-
-        fn visit_variant(&mut self, v: &Variant, g: &Generics, e: E) {
-            SawVariant.hash(self.st);
-            // walk_variant does not call walk_generics, so do it here.
-            visit::walk_generics(self, g, e.clone());
-            visit::walk_variant(self, v, g, e)
-        }
-
-        fn visit_opt_lifetime_ref(&mut self, _: Span, l: &Option<Lifetime>, env: E) {
-            SawOptLifetimeRef.hash(self.st);
-            // (This is a strange method in the visitor trait, in that
-            // it does not expose a walk function to do the subroutine
-            // calls.)
-            match *l {
-                Some(ref l) => self.visit_lifetime_ref(l, env),
-                None => ()
-            }
-        }
-
-        // All of the remaining methods just record (in the hash
-        // SipState) that the visitor saw that particular variant
-        // (with its payload), and continue walking as the default
-        // visitor would.
-        //
-        // Some of the implementations have some notes as to how one
-        // might try to make their SVH computation less discerning
-        // (e.g. by incorporating reachability analysis).  But
-        // currently all of their implementations are uniform and
-        // uninteresting.
-        //
-        // (If you edit a method such that it deviates from the
-        // pattern, please move that method up above this comment.)
-
-        fn visit_ident(&mut self, _: Span, ident: Ident, _: E) {
-            SawIdent(content(ident)).hash(self.st);
-        }
-
-        fn visit_lifetime_ref(&mut self, l: &Lifetime, _: E) {
-            SawLifetimeRef(content(l.name)).hash(self.st);
-        }
-
-        fn visit_lifetime_decl(&mut self, l: &Lifetime, _: E) {
-            SawLifetimeDecl(content(l.name)).hash(self.st);
-        }
-
-        // We do recursively walk the bodies of functions/methods
-        // (rather than omitting their bodies from the hash) since
-        // monomorphization and cross-crate inlining generally implies
-        // that a change to a crate body will require downstream
-        // crates to be recompiled.
-        fn visit_expr(&mut self, ex: &Expr, e: E) {
-            SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex, e)
-        }
-
-        fn visit_stmt(&mut self, s: &Stmt, e: E) {
-            SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s, e)
-        }
-
-        fn visit_view_item(&mut self, i: &ViewItem, e: E) {
-            // Two kinds of view items can affect the ABI for a crate:
-            // exported `pub use` view items (since that may expose
-            // items that downstream crates can call), and `use
-            // foo::Trait`, since changing that may affect method
-            // resolution.
-            //
-            // The simplest approach to handling both of the above is
-            // just to adopt the same simple-minded (fine-grained)
-            // hash that I am deploying elsewhere here.
-            SawViewItem.hash(self.st); visit::walk_view_item(self, i, e)
-        }
-
-        fn visit_foreign_item(&mut self, i: &ForeignItem, e: E) {
-            // FIXME (#14132) ideally we would incorporate privacy (or
-            // perhaps reachability) somewhere here, so foreign items
-            // that do not leak into downstream crates would not be
-            // part of the ABI.
-            SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i, e)
-        }
-
-        fn visit_item(&mut self, i: &Item, e: E) {
-            // FIXME (#14132) ideally would incorporate reachability
-            // analysis somewhere here, so items that never leak into
-            // downstream crates (e.g. via monomorphisation or
-            // inlining) would not be part of the ABI.
-            SawItem.hash(self.st); visit::walk_item(self, i, e)
-        }
-
-        fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId, e: E) {
-            SawMod.hash(self.st); visit::walk_mod(self, m, e)
-        }
-
-        fn visit_decl(&mut self, d: &Decl, e: E) {
-            SawDecl.hash(self.st); visit::walk_decl(self, d, e)
-        }
-
-        fn visit_ty(&mut self, t: &Ty, e: E) {
-            SawTy.hash(self.st); visit::walk_ty(self, t, e)
-        }
-
-        fn visit_generics(&mut self, g: &Generics, e: E) {
-            SawGenerics.hash(self.st); visit::walk_generics(self, g, e)
-        }
-
-        fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId, e: E) {
-            SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s, e)
-        }
-
-        fn visit_ty_method(&mut self, t: &TypeMethod, e: E) {
-            SawTyMethod.hash(self.st); visit::walk_ty_method(self, t, e)
-        }
-
-        fn visit_trait_method(&mut self, t: &TraitMethod, e: E) {
-            SawTraitMethod.hash(self.st); visit::walk_trait_method(self, t, e)
-        }
-
-        fn visit_struct_field(&mut self, s: &StructField, e: E) {
-            SawStructField.hash(self.st); visit::walk_struct_field(self, s, e)
-        }
-
-        fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) {
-            SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es, e)
-        }
-
-        fn visit_path(&mut self, path: &Path, _: ast::NodeId, e: E) {
-            SawPath.hash(self.st); visit::walk_path(self, path, e)
-        }
-
-        fn visit_block(&mut self, b: &Block, e: E) {
-            SawBlock.hash(self.st); visit::walk_block(self, b, e)
-        }
-
-        fn visit_pat(&mut self, p: &Pat, e: E) {
-            SawPat.hash(self.st); visit::walk_pat(self, p, e)
-        }
-
-        fn visit_local(&mut self, l: &Local, e: E) {
-            SawLocal.hash(self.st); visit::walk_local(self, l, e)
-        }
-
-        fn visit_arm(&mut self, a: &Arm, e: E) {
-            SawArm.hash(self.st); visit::walk_arm(self, a, e)
-        }
-    }
-}
diff --git a/src/librustc/back/target_strs.rs b/src/librustc/back/target_strs.rs
deleted file mode 100644 (file)
index 7928f3d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(non_camel_case_types)]
-
-pub struct t {
-    pub module_asm: String,
-    pub data_layout: String,
-    pub target_triple: String,
-    pub cc_args: Vec<String> ,
-}
diff --git a/src/librustc/back/x86.rs b/src/librustc/back/x86.rs
deleted file mode 100644 (file)
index d2dac03..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os)
-                       -> target_strs::t {
-    return target_strs::t {
-        module_asm: "".to_string(),
-
-        data_layout: match target_os {
-          abi::OsMacos => {
-            "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
-                -i32:32:32-i64:32:64\
-                -f32:32:32-f64:32:64-v64:64:64\
-                -v128:128:128-a0:0:64-f80:128:128\
-                -n8:16:32".to_string()
-          }
-
-          abi::OsiOS => {
-            "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
-                -i32:32:32-i64:32:64\
-                -f32:32:32-f64:32:64-v64:64:64\
-                -v128:128:128-a0:0:64-f80:128:128\
-                -n8:16:32".to_string()
-          }
-
-          abi::OsWin32 => {
-            "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32".to_string()
-          }
-
-          abi::OsLinux => {
-            "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
-          }
-          abi::OsAndroid => {
-            "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
-          }
-
-          abi::OsFreebsd => {
-            "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
-          }
-        },
-
-        target_triple: target_triple,
-
-        cc_args: vec!("-m32".to_string()),
-    };
-}
diff --git a/src/librustc/back/x86_64.rs b/src/librustc/back/x86_64.rs
deleted file mode 100644 (file)
index c2eae18..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
-    return target_strs::t {
-        module_asm: "".to_string(),
-
-        data_layout: match target_os {
-          abi::OsMacos => {
-            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
-                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
-                s0:64:64-f80:128:128-n8:16:32:64".to_string()
-          }
-
-          abi::OsiOS => {
-            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
-                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
-                s0:64:64-f80:128:128-n8:16:32:64".to_string()
-          }
-
-          abi::OsWin32 => {
-            // FIXME: Test this. Copied from linux (#2398)
-            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
-                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
-                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
-          }
-
-          abi::OsLinux => {
-            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
-                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
-                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
-          }
-          abi::OsAndroid => {
-            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
-                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
-                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
-          }
-
-          abi::OsFreebsd => {
-            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
-                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
-                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
-          }
-        },
-
-        target_triple: target_triple,
-
-        cc_args: vec!("-m64".to_string()),
-    };
-}
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
new file mode 100644 (file)
index 0000000..0499795
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+register_diagnostic!(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 preceeding patterns will match.
+
+    This means that perhaps some of the preceeding patterns are too general, this
+    one is too specific or the ordering is incorrect.
+"##)
index 558d2ad71f33f3fa06927c119c5bec601851a634..345877d9ab6c47beea8f81694eeccb00af7c462b 100644 (file)
@@ -11,7 +11,7 @@
 //! Contains infrastructure for configuring the compiler, including parsing
 //! command line options.
 
-use driver::early_error;
+use driver::{early_error, early_warn};
 use driver::driver;
 use driver::session::Session;
 
 use syntax::parse;
 use syntax::parse::token::InternedString;
 
-use std::collections::HashSet;
+use std::collections::{HashSet, HashMap};
 use getopts::{optopt, optmulti, optflag, optflagopt};
 use getopts;
-use lib::llvm::llvm;
 use std::cell::{RefCell};
 use std::fmt;
 
+use llvm;
 
 pub struct Config {
     pub os: abi::Os,
@@ -91,10 +91,12 @@ pub struct Options {
     pub debugging_opts: u64,
     /// Whether to write dependency files. It's (enabled, optional filename).
     pub write_dependency_info: (bool, Option<Path>),
-    /// Crate id-related things to maybe print. It's (crate_id, crate_name, crate_file_name).
-    pub print_metas: (bool, bool, bool),
+    /// Crate id-related things to maybe print. It's (crate_name, crate_file_name).
+    pub print_metas: (bool, bool),
     pub cg: CodegenOptions,
     pub color: ColorConfig,
+    pub externs: HashMap<String, Vec<String>>,
+    pub crate_name: Option<String>,
 }
 
 /// Some reasonable defaults
@@ -117,9 +119,11 @@ pub fn basic_options() -> Options {
         no_analysis: false,
         debugging_opts: 0,
         write_dependency_info: (false, None),
-        print_metas: (false, false, false),
+        print_metas: (false, false),
         cg: basic_codegen_options(),
         color: Auto,
+        externs: HashMap::new(),
+        crate_name: None,
     }
 }
 
@@ -175,7 +179,11 @@ macro_rules! debugging_opts(
         AST_JSON,
         AST_JSON_NOEXPAND,
         LS,
-        SAVE_ANALYSIS
+        SAVE_ANALYSIS,
+        FLOWGRAPH_PRINT_LOANS,
+        FLOWGRAPH_PRINT_MOVES,
+        FLOWGRAPH_PRINT_ASSIGNS,
+        FLOWGRAPH_PRINT_ALL
     ]
     0
 )
@@ -211,7 +219,15 @@ pub fn debugging_opts_map() -> Vec<(&'static str, &'static str, u64)> {
      ("ast-json-noexpand", "Print the pre-expansion AST as JSON and halt", AST_JSON_NOEXPAND),
      ("ls", "List the symbols defined by a library crate", LS),
      ("save-analysis", "Write syntax and type analysis information \
-                        in addition to normal output", SAVE_ANALYSIS))
+                        in addition to normal output", SAVE_ANALYSIS),
+     ("flowgraph-print-loans", "Include loan analysis data in \
+                       --pretty flowgraph output", FLOWGRAPH_PRINT_LOANS),
+     ("flowgraph-print-moves", "Include move analysis data in \
+                       --pretty flowgraph output", FLOWGRAPH_PRINT_MOVES),
+     ("flowgraph-print-assigns", "Include assignment analysis data in \
+                       --pretty flowgraph output", FLOWGRAPH_PRINT_ASSIGNS),
+     ("flowgraph-print-all", "Include all dataflow analysis data in \
+                       --pretty flowgraph output", FLOWGRAPH_PRINT_ALL))
 }
 
 /// Declare a macro that will define all CodegenOptions fields and parsers all
@@ -302,8 +318,8 @@ fn parse_list(slot: &mut Vec<String>, v: Option<&str>)
         "a list of arguments to pass to llvm (space separated)"),
     save_temps: bool = (false, parse_bool,
         "save all temporary output files during compilation"),
-    no_rpath: bool = (false, parse_bool,
-        "disables setting the rpath in libs/exes"),
+    rpath: bool = (false, parse_bool,
+        "set rpath values in libs/exes"),
     no_prepopulate_passes: bool = (false, parse_bool,
         "don't pre-populate the pass manager with a list of passes"),
     no_vectorize_loops: bool = (false, parse_bool,
@@ -318,6 +334,10 @@ fn parse_list(slot: &mut Vec<String>, v: Option<&str>)
         "use an external assembler rather than LLVM's integrated one"),
     relocation_model: String = ("pic".to_string(), parse_string,
          "choose the relocation model to use (llc -relocation-model for details)"),
+    metadata: Vec<String> = (Vec::new(), parse_list,
+         "metadata to mangle symbol names with"),
+    extra_filename: String = ("".to_string(), parse_string,
+         "extra data to put in each output filename"),
 )
 
 pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
@@ -427,7 +447,7 @@ pub fn get_os(triple: &str) -> Option<abi::Os> {
     }
     None
 }
-static os_names : &'static [(&'static str, abi::Os)] = &'static [
+static os_names : &'static [(&'static str, abi::Os)] = &[
     ("mingw32", abi::OsWin32),
     ("win32",   abi::OsWin32),
     ("darwin",  abi::OsMacos),
@@ -442,7 +462,7 @@ pub fn get_arch(triple: &str) -> Option<abi::Architecture> {
     }
     None
 }
-static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'static [
+static architecture_abis : &'static [(&'static str, abi::Architecture)] = &[
     ("i386",   abi::X86),
     ("i486",   abi::X86),
     ("i586",   abi::X86),
@@ -505,10 +525,12 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
                  "[bin|lib|rlib|dylib|staticlib]"),
         optmulti("", "emit", "Comma separated list of types of output for the compiler to emit",
                  "[asm|bc|ir|obj|link]"),
-        optflag("", "crate-id", "Output the crate id and exit"),
-        optflag("", "crate-name", "Output the crate name and exit"),
-        optflag("", "crate-file-name", "Output the file(s) that would be written if compilation \
+        optopt("", "crate-name", "Specify the name of the crate being built",
+               "NAME"),
+        optflag("", "print-crate-name", "Output the crate name and exit"),
+        optflag("", "print-file-name", "Output the file(s) that would be written if compilation \
               continued and exit"),
+        optflag("", "crate-file-name", "deprecated in favor of --print-file-name"),
         optflag("g",  "",  "Equivalent to --debuginfo=2"),
         optopt("",  "debuginfo",  "Emit DWARF debug info to the objects created:
              0 = no debug info,
@@ -522,6 +544,7 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
         optopt("", "opt-level", "Optimize with possible levels 0-3", "LEVEL"),
         optopt( "",  "out-dir", "Write output to compiler-chosen filename in <dir>", "DIR"),
         optflag("", "parse-only", "Parse only; do not compile, assemble, or link"),
+        optopt("", "explain", "Provide a detailed explanation of an error message", "OPT"),
         optflagopt("", "pretty",
                    "Pretty-print the input instead of compiling;
                    valid types are: `normal` (un-annotated source),
@@ -548,7 +571,9 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
         optopt("", "color", "Configure coloring of output:
             auto   = colorize, if output goes to a tty (default);
             always = always colorize output;
-            never  = never colorize output", "auto|always|never")
+            never  = never colorize output", "auto|always|never"),
+        optmulti("", "extern", "Specify where an external rust library is located",
+                 "PATH"),
     )
 }
 
@@ -709,9 +734,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
                                  matches.opt_str("dep-info")
                                         .map(|p| Path::new(p)));
 
-    let print_metas = (matches.opt_present("crate-id"),
-                       matches.opt_present("crate-name"),
+    let print_metas = (matches.opt_present("print-crate-name"),
+                       matches.opt_present("print-file-name") ||
                        matches.opt_present("crate-file-name"));
+    if matches.opt_present("crate-file-name") {
+        early_warn("the --crate-file-name argument has been renamed to \
+                    --print-file-name");
+    }
     let cg = build_codegen_options(matches);
 
     let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) {
@@ -728,6 +757,23 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         }
     };
 
+    let mut externs = HashMap::new();
+    for arg in matches.opt_strs("extern").iter() {
+        let mut parts = arg.as_slice().splitn('=', 1);
+        let name = match parts.next() {
+            Some(s) => s,
+            None => early_error("--extern value must not be empty"),
+        };
+        let location = match parts.next() {
+            Some(s) => s,
+            None => early_error("--extern value must be of the format `foo=bar`"),
+        };
+        let locs = externs.find_or_insert(name.to_string(), Vec::new());
+        locs.push(location.to_string());
+    }
+
+    let crate_name = matches.opt_str("crate-name");
+
     Options {
         crate_types: crate_types,
         gc: gc,
@@ -748,7 +794,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         write_dependency_info: write_dependency_info,
         print_metas: print_metas,
         cg: cg,
-        color: color
+        color: color,
+        externs: externs,
+        crate_name: crate_name,
     }
 }
 
@@ -772,6 +820,7 @@ mod test {
     use getopts::getopts;
     use syntax::attr;
     use syntax::attr::AttrMetaMethods;
+    use syntax::diagnostics;
 
     // When the user supplies --test we should implicitly supply --cfg test
     #[test]
@@ -781,8 +830,9 @@ fn test_switch_implies_cfg_test() {
               Ok(m) => m,
               Err(f) => fail!("test_switch_implies_cfg_test: {}", f)
             };
+        let registry = diagnostics::registry::Registry::new([]);
         let sessopts = build_session_options(matches);
-        let sess = build_session(sessopts, None);
+        let sess = build_session(sessopts, None, registry);
         let cfg = build_configuration(&sess);
         assert!((attr::contains_name(cfg.as_slice(), "test")));
     }
@@ -799,8 +849,9 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
                 fail!("test_switch_implies_cfg_test_unless_cfg_test: {}", f)
               }
             };
+        let registry = diagnostics::registry::Registry::new([]);
         let sessopts = build_session_options(matches);
-        let sess = build_session(sessopts, None);
+        let sess = build_session(sessopts, None, registry);
         let cfg = build_configuration(&sess);
         let mut test_items = cfg.iter().filter(|m| m.name().equiv(&("test")));
         assert!(test_items.next().is_some());
index 978a43106526f3b5a16929329cf210a1c629a3a9..87693658afd03d05b41715f279b9224f29fe3faa 100644 (file)
 use driver::{PpmFlowGraph, PpmExpanded, PpmExpandedIdentified, PpmTyped};
 use driver::{PpmIdentified};
 use front;
-use lib::llvm::{ContextRef, ModuleRef};
+use lint;
+use llvm::{ContextRef, ModuleRef};
 use metadata::common::LinkMeta;
 use metadata::creader;
+use middle::borrowck::{FnPartsWithCFG};
+use middle::borrowck;
+use borrowck_dot = middle::borrowck::graphviz;
 use middle::cfg;
 use middle::cfg::graphviz::LabelledCFG;
 use middle::{trans, freevars, stability, kind, ty, typeck, reachable};
@@ -26,7 +30,7 @@
 use plugin::load::Plugins;
 use plugin::registry::Registry;
 use plugin;
-use lint;
+
 use util::common::time;
 use util::ppaux;
 use util::nodemap::{NodeSet};
 use std::io::fs;
 use std::io::MemReader;
 use syntax::ast;
+use syntax::ast_map::blocks;
 use syntax::attr;
 use syntax::attr::{AttrMetaMethods};
-use syntax::crateid::CrateId;
+use syntax::diagnostics;
 use syntax::parse;
 use syntax::parse::token;
 use syntax::print::{pp, pprust};
@@ -69,7 +74,7 @@ pub fn compile_input(sess: Session,
     // large chunks of memory alive and we want to free them as soon as
     // possible to keep the peak memory usage low
     let (outputs, trans, sess) = {
-        let (outputs, expanded_crate, ast_map) = {
+        let (outputs, expanded_crate, ast_map, id) = {
             let krate = phase_1_parse_input(&sess, cfg, input);
             if stop_after_phase_1(&sess) { return; }
             let outputs = build_output_filenames(input,
@@ -77,25 +82,25 @@ pub fn compile_input(sess: Session,
                                                  output,
                                                  krate.attrs.as_slice(),
                                                  &sess);
-            let id = link::find_crate_id(krate.attrs.as_slice(),
-                                         outputs.out_filestem.as_slice());
+            let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
+                                           input);
             let (expanded_crate, ast_map)
-                = match phase_2_configure_and_expand(&sess, krate, &id) {
+                = match phase_2_configure_and_expand(&sess, krate, id.as_slice()) {
                     None => return,
                     Some(p) => p,
                 };
 
-            (outputs, expanded_crate, ast_map)
+            (outputs, expanded_crate, ast_map, id)
         };
-        write_out_deps(&sess, input, &outputs, &expanded_crate);
+        write_out_deps(&sess, input, &outputs, id.as_slice());
 
         if stop_after_phase_2(&sess) { return; }
 
-        let analysis = phase_3_run_analysis_passes(sess, &expanded_crate, ast_map);
+        let analysis = phase_3_run_analysis_passes(sess, &expanded_crate,
+                                                   ast_map, id);
         phase_save_analysis(&analysis.ty_cx.sess, &expanded_crate, &analysis, outdir);
         if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
-        let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate,
-                                                     analysis, &outputs);
+        let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate, analysis);
 
         // Discard interned strings as they are no longer required.
         token::get_ident_interner().clear();
@@ -181,11 +186,14 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
 /// Returns `None` if we're aborting after handling -W help.
 pub fn phase_2_configure_and_expand(sess: &Session,
                                     mut krate: ast::Crate,
-                                    crate_id: &CrateId)
+                                    crate_name: &str)
                                     -> Option<(ast::Crate, syntax::ast_map::Map)> {
     let time_passes = sess.time_passes();
 
-    *sess.crate_types.borrow_mut() = collect_crate_types(sess, krate.attrs.as_slice());
+    *sess.crate_types.borrow_mut() =
+        collect_crate_types(sess, krate.attrs.as_slice());
+    *sess.crate_metadata.borrow_mut() =
+        collect_crate_metadata(sess, krate.attrs.as_slice());
 
     time(time_passes, "gated feature checking", (), |_|
          front::feature_gate::check_crate(sess, &krate));
@@ -211,6 +219,15 @@ pub fn phase_2_configure_and_expand(sess: &Session,
     let mut registry = Registry::new(&krate);
 
     time(time_passes, "plugin registration", (), |_| {
+        if sess.features.rustc_diagnostic_macros.get() {
+            registry.register_macro("__diagnostic_used",
+                diagnostics::plugin::expand_diagnostic_used);
+            registry.register_macro("__register_diagnostic",
+                diagnostics::plugin::expand_register_diagnostic);
+            registry.register_macro("__build_diagnostic_array",
+                diagnostics::plugin::expand_build_diagnostic_array);
+        }
+
         for &registrar in registrars.iter() {
             registrar(&mut registry);
         }
@@ -247,7 +264,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
             }
             let cfg = syntax::ext::expand::ExpansionConfig {
                 deriving_hash_type_parameter: sess.features.default_type_params.get(),
-                crate_id: crate_id.clone(),
+                crate_name: crate_name.to_string(),
             };
             syntax::ext::expand::expand_crate(&sess.parse_sess,
                                               cfg,
@@ -257,6 +274,8 @@ pub fn phase_2_configure_and_expand(sess: &Session,
         }
     );
 
+    // JBC: make CFG processing part of expansion to avoid this problem:
+
     // strip again, in case expansion added anything with a #[cfg].
     krate = time(time_passes, "configuration 2", krate, |krate|
                  front::config::strip_unconfigured_items(krate));
@@ -277,6 +296,9 @@ pub fn phase_2_configure_and_expand(sess: &Session,
         krate.encode(&mut json).unwrap();
     }
 
+    time(time_passes, "checking that all macro invocations are gone", &krate, |krate|
+         syntax::ext::expand::check_for_macros(&sess.parse_sess, krate));
+
     Some((krate, map))
 }
 
@@ -286,15 +308,17 @@ pub struct CrateAnalysis {
     pub public_items: middle::privacy::PublicItems,
     pub ty_cx: ty::ctxt,
     pub reachable: NodeSet,
+    pub name: String,
 }
 
+
 /// Run the resolution, typechecking, region checking and other
 /// miscellaneous analysis passes on the crate. Return various
 /// structures carrying the results of the analysis.
 pub fn phase_3_run_analysis_passes(sess: Session,
                                    krate: &ast::Crate,
-                                   ast_map: syntax::ast_map::Map) -> CrateAnalysis {
-
+                                   ast_map: syntax::ast_map::Map,
+                                   name: String) -> CrateAnalysis {
     let time_passes = sess.time_passes();
 
     time(time_passes, "external crate/lib resolution", (), |_|
@@ -398,6 +422,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
         exported_items: exported_items,
         public_items: public_items,
         reachable: reachable_map,
+        name: name,
     }
 }
 
@@ -426,8 +451,7 @@ pub struct CrateTranslation {
 /// Run the translation phase to LLVM, after which the AST and analysis can
 /// be discarded.
 pub fn phase_4_translate_to_llvm(krate: ast::Crate,
-                                 analysis: CrateAnalysis,
-                                 outputs: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
+                                 analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
     let time_passes = analysis.ty_cx.sess.time_passes();
 
     time(time_passes, "resolving dependency formats", (), |_|
@@ -435,7 +459,7 @@ pub fn phase_4_translate_to_llvm(krate: ast::Crate,
 
     // Option dance to work around the lack of stack once closures.
     time(time_passes, "translation", (krate, analysis), |(krate, analysis)|
-         trans::base::trans_crate(krate, analysis, outputs))
+         trans::base::trans_crate(krate, analysis))
 }
 
 /// Run LLVM itself, producing a bitcode file, assembly file or object file
@@ -473,7 +497,7 @@ pub fn phase_6_link_output(sess: &Session,
          link::link_binary(sess,
                            trans,
                            outputs,
-                           &trans.link.crateid));
+                           trans.link.crate_name.as_slice()));
 }
 
 pub fn stop_after_phase_3(sess: &Session) -> bool {
@@ -514,9 +538,7 @@ pub fn stop_after_phase_5(sess: &Session) -> bool {
 fn write_out_deps(sess: &Session,
                   input: &Input,
                   outputs: &OutputFilenames,
-                  krate: &ast::Crate) {
-    let id = link::find_crate_id(krate.attrs.as_slice(),
-                                 outputs.out_filestem.as_slice());
+                  id: &str) {
 
     let mut out_filenames = Vec::new();
     for output_type in sess.opts.output_types.iter() {
@@ -524,7 +546,8 @@ fn write_out_deps(sess: &Session,
         match *output_type {
             link::OutputTypeExe => {
                 for output in sess.crate_types.borrow().iter() {
-                    let p = link::filename_for_input(sess, *output, &id, &file);
+                    let p = link::filename_for_input(sess, *output,
+                                                     id, &file);
                     out_filenames.push(p);
                 }
             }
@@ -591,7 +614,7 @@ fn post(&self,
         match node {
             pprust::NodeItem(item) => {
                 try!(pp::space(&mut s.s));
-                s.synth_comment(item.id.to_str())
+                s.synth_comment(item.id.to_string())
             }
             pprust::NodeBlock(blk) => {
                 try!(pp::space(&mut s.s));
@@ -599,7 +622,7 @@ fn post(&self,
             }
             pprust::NodeExpr(expr) => {
                 try!(pp::space(&mut s.s));
-                try!(s.synth_comment(expr.id.to_str()));
+                try!(s.synth_comment(expr.id.to_string()));
                 s.pclose()
             }
             pprust::NodePat(pat) => {
@@ -633,7 +656,7 @@ fn post(&self,
                 try!(pp::word(&mut s.s, "as"));
                 try!(pp::space(&mut s.s));
                 try!(pp::word(&mut s.s,
-                              ppaux::ty_to_str(
+                              ppaux::ty_to_string(
                                   tcx,
                                   ty::expr_ty(tcx, expr)).as_slice()));
                 s.pclose()
@@ -643,19 +666,38 @@ fn post(&self,
     }
 }
 
+fn gather_flowgraph_variants(sess: &Session) -> Vec<borrowck_dot::Variant> {
+    let print_loans   = config::FLOWGRAPH_PRINT_LOANS;
+    let print_moves   = config::FLOWGRAPH_PRINT_MOVES;
+    let print_assigns = config::FLOWGRAPH_PRINT_ASSIGNS;
+    let print_all     = config::FLOWGRAPH_PRINT_ALL;
+    let opt = |print_which| sess.debugging_opt(print_which);
+    let mut variants = Vec::new();
+    if opt(print_all) || opt(print_loans) {
+        variants.push(borrowck_dot::Loans);
+    }
+    if opt(print_all) || opt(print_moves) {
+        variants.push(borrowck_dot::Moves);
+    }
+    if opt(print_all) || opt(print_assigns) {
+        variants.push(borrowck_dot::Assigns);
+    }
+    variants
+}
+
 pub fn pretty_print_input(sess: Session,
                           cfg: ast::CrateConfig,
                           input: &Input,
                           ppm: PpMode,
                           ofile: Option<Path>) {
     let krate = phase_1_parse_input(&sess, cfg, input);
-    let id = link::find_crate_id(krate.attrs.as_slice(),
-                                 input.filestem().as_slice());
+    let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(), input);
 
     let (krate, ast_map, is_expanded) = match ppm {
         PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
             let (krate, ast_map)
-                = match phase_2_configure_and_expand(&sess, krate, &id) {
+                = match phase_2_configure_and_expand(&sess, krate,
+                                                     id.as_slice()) {
                     None => return,
                     Some(p) => p,
                 };
@@ -695,7 +737,7 @@ pub fn pretty_print_input(sess: Session,
         }
         PpmTyped => {
             let ast_map = ast_map.expect("--pretty=typed missing ast_map");
-            let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
+            let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map, id);
             let annotation = TypedAnnotation {
                 analysis: analysis
             };
@@ -714,10 +756,17 @@ pub fn pretty_print_input(sess: Session,
                 sess.fatal(format!("--pretty flowgraph couldn't find id: {}",
                                    nodeid).as_slice())
             });
-            let block = match node {
-                syntax::ast_map::NodeBlock(block) => block,
-                _ => {
-                    let message = format!("--pretty=flowgraph needs block, got {:?}",
+            let code = blocks::Code::from_node(node);
+            match code {
+                Some(code) => {
+                    let variants = gather_flowgraph_variants(&sess);
+                    let analysis = phase_3_run_analysis_passes(sess, &krate,
+                                                               ast_map, id);
+                    print_flowgraph(variants, analysis, code, out)
+                }
+                None => {
+                    let message = format!("--pretty=flowgraph needs \
+                                           block, fn, or method; got {:?}",
                                           node);
 
                     // point to what was found, if there's an
@@ -727,9 +776,7 @@ pub fn pretty_print_input(sess: Session,
                         None => sess.fatal(message.as_slice())
                     }
                 }
-            };
-            let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
-            print_flowgraph(analysis, block, out)
+            }
         }
         _ => {
             pprust::print_crate(sess.codemap(),
@@ -745,17 +792,52 @@ pub fn pretty_print_input(sess: Session,
 
 }
 
-fn print_flowgraph<W:io::Writer>(analysis: CrateAnalysis,
-                                 block: ast::P<ast::Block>,
+fn print_flowgraph<W:io::Writer>(variants: Vec<borrowck_dot::Variant>,
+                                 analysis: CrateAnalysis,
+                                 code: blocks::Code,
                                  mut out: W) -> io::IoResult<()> {
     let ty_cx = &analysis.ty_cx;
-    let cfg = cfg::CFG::new(ty_cx, &*block);
-    let lcfg = LabelledCFG { ast_map: &ty_cx.map,
-                             cfg: &cfg,
-                             name: format!("block{}", block.id), };
+    let cfg = match code {
+        blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
+        blocks::FnLikeCode(fn_like) => cfg::CFG::new(ty_cx, fn_like.body()),
+    };
     debug!("cfg: {:?}", cfg);
-    let r = dot::render(&lcfg, &mut out);
-    return expand_err_details(r);
+
+    match code {
+        _ if variants.len() == 0 => {
+            let lcfg = LabelledCFG {
+                ast_map: &ty_cx.map,
+                cfg: &cfg,
+                name: format!("node_{}", code.id()),
+            };
+            let r = dot::render(&lcfg, &mut out);
+            return expand_err_details(r);
+        }
+        blocks::BlockCode(_) => {
+            ty_cx.sess.err("--pretty flowgraph with -Z flowgraph-print \
+                            annotations requires fn-like node id.");
+            return Ok(())
+        }
+        blocks::FnLikeCode(fn_like) => {
+            let fn_parts = FnPartsWithCFG::from_fn_like(&fn_like, &cfg);
+            let (bccx, analysis_data) =
+                borrowck::build_borrowck_dataflow_data_for_fn(ty_cx, fn_parts);
+
+            let lcfg = LabelledCFG {
+                ast_map: &ty_cx.map,
+                cfg: &cfg,
+                name: format!("node_{}", code.id()),
+            };
+            let lcfg = borrowck_dot::DataflowLabeller {
+                inner: lcfg,
+                variants: variants,
+                borrowck_ctxt: &bccx,
+                analysis_data: &analysis_data,
+            };
+            let r = dot::render(&lcfg, &mut out);
+            return expand_err_details(r);
+        }
+    }
 
     fn expand_err_details(r: io::IoResult<()>) -> io::IoResult<()> {
         r.map_err(|ioerr| {
@@ -845,6 +927,11 @@ pub fn collect_crate_types(session: &Session,
     }).collect()
 }
 
+pub fn collect_crate_metadata(session: &Session,
+                              _attrs: &[ast::Attribute]) -> Vec<String> {
+    session.opts.cg.metadata.clone()
+}
+
 pub struct OutputFilenames {
     pub out_directory: Path,
     pub out_filestem: String,
@@ -893,14 +980,22 @@ pub fn build_output_filenames(input: &Input,
                 None => Path::new(".")
             };
 
-            let mut stem = input.filestem();
+            // If a crate name is present, we use it as the link name
+            let stem = sess.opts.crate_name.clone().or_else(|| {
+                attr::find_crate_name(attrs).map(|n| n.get().to_string())
+            }).or_else(|| {
+                // NB: this clause can be removed once #[crate_id] is no longer
+                // deprecated.
+                //
+                // Also note that this will be warned about later so we don't
+                // warn about it here.
+                use syntax::crateid::CrateId;
+                attrs.iter().find(|at| at.check_name("crate_id"))
+                     .and_then(|at| at.value_str())
+                     .and_then(|s| from_str::<CrateId>(s.get()))
+                     .map(|id| id.name)
+            }).unwrap_or(input.filestem());
 
-            // If a crateid is present, we use it as the link name
-            let crateid = attr::find_crateid(attrs);
-            match crateid {
-                None => {}
-                Some(crateid) => stem = crateid.name.to_string(),
-            }
             OutputFilenames {
                 out_directory: dirpath,
                 out_filestem: stem,
index 87c0a2708395756800683198baed2dc757eb57c1..e850b71dda8cca9266632398d1234a1069977dd2 100644 (file)
@@ -26,6 +26,7 @@
 use syntax::ast;
 use syntax::parse;
 use syntax::diagnostic::Emitter;
+use syntax::diagnostics;
 
 use getopts;
 
@@ -49,8 +50,24 @@ fn run_compiler(args: &[String]) {
         Some(matches) => matches,
         None => return
     };
-    let sopts = config::build_session_options(&matches);
 
+    let descriptions = diagnostics::registry::Registry::new(super::DIAGNOSTICS);
+    match matches.opt_str("explain") {
+        Some(ref code) => {
+            match descriptions.find_description(code.as_slice()) {
+                Some(ref description) => {
+                    println!("{}", description);
+                }
+                None => {
+                    early_error(format!("no extended information for {}", code).as_slice());
+                }
+            }
+            return;
+        },
+        None => ()
+    }
+
+    let sopts = config::build_session_options(&matches);
     let (input, input_file_path) = match matches.free.len() {
         0u => {
             if sopts.describe_lints {
@@ -75,7 +92,7 @@ fn run_compiler(args: &[String]) {
         _ => early_error("multiple input filenames provided")
     };
 
-    let sess = build_session(sopts, input_file_path);
+    let sess = build_session(sopts, input_file_path, descriptions);
     let cfg = config::build_configuration(&sess);
     let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
     let ofile = matches.opt_str("o").map(|o| Path::new(o));
@@ -251,7 +268,7 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
         match getopts::getopts(args.as_slice(), config::optgroups().as_slice()) {
             Ok(m) => m,
             Err(f) => {
-                early_error(f.to_str().as_slice());
+                early_error(f.to_string().as_slice());
             }
         };
 
@@ -275,7 +292,7 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
     }
 
     if cg_flags.contains(&"passes=list".to_string()) {
-        unsafe { ::lib::llvm::llvm::LLVMRustPrintPasses(); }
+        unsafe { ::llvm::LLVMRustPrintPasses(); }
         return None;
     }
 
@@ -294,28 +311,26 @@ fn print_crate_info(sess: &Session,
                     odir: &Option<Path>,
                     ofile: &Option<Path>)
                     -> bool {
-    let (crate_id, crate_name, crate_file_name) = sess.opts.print_metas;
+    let (crate_name, crate_file_name) = sess.opts.print_metas;
     // these nasty nested conditions are to avoid doing extra work
-    if crate_id || crate_name || crate_file_name {
+    if crate_name || crate_file_name {
         let attrs = parse_crate_attrs(sess, input);
         let t_outputs = driver::build_output_filenames(input,
                                                        odir,
                                                        ofile,
                                                        attrs.as_slice(),
                                                        sess);
-        let id = link::find_crate_id(attrs.as_slice(),
-                                     t_outputs.out_filestem.as_slice());
+        let id = link::find_crate_name(Some(sess), attrs.as_slice(), input);
 
-        if crate_id {
-            println!("{}", id.to_str());
-        }
         if crate_name {
-            println!("{}", id.name);
+            println!("{}", id);
         }
         if crate_file_name {
             let crate_types = driver::collect_crate_types(sess, attrs.as_slice());
+            let metadata = driver::collect_crate_metadata(sess, attrs.as_slice());
+            *sess.crate_metadata.borrow_mut() = metadata;
             for &style in crate_types.iter() {
-                let fname = link::filename_for_input(sess, style, &id,
+                let fname = link::filename_for_input(sess, style, id.as_slice(),
                                                      &t_outputs.with_extension(""));
                 println!("{}", fname.filename_display());
             }
@@ -385,11 +400,16 @@ fn parse_crate_attrs(sess: &Session, input: &Input) ->
 }
 
 pub fn early_error(msg: &str) -> ! {
-    let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto);
-    emitter.emit(None, msg, diagnostic::Fatal);
+    let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
+    emitter.emit(None, msg, None, diagnostic::Fatal);
     fail!(diagnostic::FatalError);
 }
 
+pub fn early_warn(msg: &str) {
+    let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
+    emitter.emit(None, msg, None, diagnostic::Warning);
+}
+
 pub fn list_metadata(sess: &Session, path: &Path,
                      out: &mut io::Writer) -> io::IoResult<()> {
     metadata::loader::list_file_metadata(sess.targ_cfg.os, path, out)
@@ -426,7 +446,7 @@ fn monitor(f: proc():Send) {
         Err(value) => {
             // Task failed without emitting a fatal diagnostic
             if !value.is::<diagnostic::FatalError>() {
-                let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto);
+                let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
 
                 // a .span_bug or .bug call has already printed what
                 // it wants to print.
@@ -434,6 +454,7 @@ fn monitor(f: proc():Send) {
                     emitter.emit(
                         None,
                         "unexpected failure",
+                        None,
                         diagnostic::Bug);
                 }
 
@@ -444,16 +465,17 @@ fn monitor(f: proc():Send) {
                     "run with `RUST_BACKTRACE=1` for a backtrace".to_string(),
                 ];
                 for note in xs.iter() {
-                    emitter.emit(None, note.as_slice(), diagnostic::Note)
+                    emitter.emit(None, note.as_slice(), None, diagnostic::Note)
                 }
 
-                match r.read_to_str() {
+                match r.read_to_string() {
                     Ok(s) => println!("{}", s),
                     Err(e) => {
                         emitter.emit(None,
                                      format!("failed to read internal \
                                               stderr: {}",
                                              e).as_slice(),
+                                     None,
                                      diagnostic::Error)
                     }
                 }
index 07366f34c4e03d7018c1821d408645025f59ccee..313b2bd6bf0d46e7c1db8e5ee77c81a50d870b36 100644 (file)
@@ -20,6 +20,7 @@
 use syntax::ast::NodeId;
 use syntax::codemap::Span;
 use syntax::diagnostic;
+use syntax::diagnostics;
 use syntax::parse;
 use syntax::parse::token;
 use syntax::parse::ParseSess;
@@ -28,7 +29,8 @@
 use std::os;
 use std::cell::{Cell, RefCell};
 
-
+// Represents the data associated with a compilation
+// session for a single crate.
 pub struct Session {
     pub targ_cfg: config::Config,
     pub opts: config::Options,
@@ -47,6 +49,7 @@ pub struct Session {
     pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
     pub node_id: Cell<ast::NodeId>,
     pub crate_types: RefCell<Vec<config::CrateType>>,
+    pub crate_metadata: RefCell<Vec<String>>,
     pub features: front::feature_gate::Features,
 
     /// The maximum recursion limit for potentially infinitely recursive
@@ -64,6 +67,9 @@ pub fn fatal(&self, msg: &str) -> ! {
     pub fn span_err(&self, sp: Span, msg: &str) {
         self.diagnostic().span_err(sp, msg)
     }
+    pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
+        self.diagnostic().span_err_with_code(sp, msg, code)
+    }
     pub fn err(&self, msg: &str) {
         self.diagnostic().handler().err(msg)
     }
@@ -196,11 +202,12 @@ pub fn host_filesearch<'a>(&'a self) -> filesearch::FileSearch<'a> {
 }
 
 pub fn build_session(sopts: config::Options,
-                     local_crate_source_file: Option<Path>)
+                     local_crate_source_file: Option<Path>,
+                     registry: diagnostics::registry::Registry)
                      -> Session {
     let codemap = codemap::CodeMap::new();
     let diagnostic_handler =
-        diagnostic::default_handler(sopts.color);
+        diagnostic::default_handler(sopts.color, Some(registry));
     let span_diagnostic_handler =
         diagnostic::mk_span_handler(diagnostic_handler, codemap);
 
@@ -243,6 +250,7 @@ pub fn build_session_(sopts: config::Options,
         lints: RefCell::new(NodeMap::new()),
         node_id: Cell::new(1),
         crate_types: RefCell::new(Vec::new()),
+        crate_metadata: RefCell::new(Vec::new()),
         features: front::feature_gate::Features::new(),
         recursion_limit: Cell::new(64),
     };
index 2fa0ab9072c226f3ef566ba0cab6e37c5d4187e1..0c39cf350a613c02b06e57deacc1f6ede7cfb872 100644 (file)
@@ -14,6 +14,8 @@
 
 use std::gc::{Gc, GC};
 
+/// A folder that strips out items that do not belong in the current
+/// configuration.
 struct Context<'a> {
     in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool,
 }
@@ -41,6 +43,9 @@ fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
     fn fold_expr(&mut self, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
         fold_expr(self, expr)
     }
+    fn fold_mac(&mut self, mac: &ast::Mac) -> ast::Mac {
+        fold::fold_mac(mac, self)
+    }
 }
 
 pub fn strip_items(krate: ast::Crate,
@@ -109,12 +114,12 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
                 .map(|x| *x).collect();
             ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
         }
-        ast::ItemTrait(ref a, b, ref c, ref methods) => {
+        ast::ItemTrait(ref a, ref b, ref c, ref methods) => {
             let methods = methods.iter()
                                  .filter(|m| trait_method_in_cfg(cx, *m) )
                                  .map(|x| (*x).clone())
                                  .collect();
-            ast::ItemTrait((*a).clone(), b, (*c).clone(), methods)
+            ast::ItemTrait((*a).clone(), (*b).clone(), (*c).clone(), methods)
         }
         ast::ItemStruct(ref def, ref generics) => {
             ast::ItemStruct(fold_struct(cx, &**def), generics.clone())
index 931f0312f579c809686a3e7d76c223c06e7acbd1..8b92166388d8608aadec35fbca6e4934948c3794 100644 (file)
@@ -66,6 +66,8 @@
 
     ("quad_precision_float", Removed),
 
+    ("rustc_diagnostic_macros", Active),
+
     // A temporary feature gate used to enable parser extensions needed
     // to bootstrap fix for #5723.
     ("issue_5723_bootstrap", Active),
@@ -93,6 +95,7 @@ pub struct Features {
     pub default_type_params: Cell<bool>,
     pub issue_5723_bootstrap: Cell<bool>,
     pub overloaded_calls: Cell<bool>,
+    pub rustc_diagnostic_macros: Cell<bool>
 }
 
 impl Features {
@@ -101,6 +104,7 @@ pub fn new() -> Features {
             default_type_params: Cell::new(false),
             issue_5723_bootstrap: Cell::new(false),
             overloaded_calls: Cell::new(false),
+            rustc_diagnostic_macros: Cell::new(false)
         }
     }
 }
@@ -425,4 +429,5 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
     sess.features.default_type_params.set(cx.has_feature("default_type_params"));
     sess.features.issue_5723_bootstrap.set(cx.has_feature("issue_5723_bootstrap"));
     sess.features.overloaded_calls.set(cx.has_feature("overloaded_calls"));
+    sess.features.rustc_diagnostic_macros.set(cx.has_feature("rustc_diagnostic_macros"));
 }
index 54ba9db570e6366af279777b1d4cdee4b96e4a11..351c9a6b771672c6506c4c95f04d1419a8c71b87 100644 (file)
@@ -25,8 +25,6 @@
 use std::mem;
 use std::gc::{Gc, GC};
 
-pub static VERSION: &'static str = "0.11.0";
-
 pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
                                -> ast::Crate {
     if use_std(&krate) {
@@ -60,24 +58,12 @@ struct StandardLibraryInjector<'a> {
     sess: &'a Session,
 }
 
-pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
-    match option_env!("CFG_DISABLE_INJECT_STD_VERSION") {
-        Some("1") => None,
-        _ => {
-            Some((token::intern_and_get_ident(format!("{}#{}",
-                                                      krate,
-                                                      VERSION).as_slice()),
-                  ast::CookedStr))
-        }
-    }
-}
-
 impl<'a> fold::Folder for StandardLibraryInjector<'a> {
     fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         let mut vis = vec!(ast::ViewItem {
             node: ast::ViewItemExternCrate(token::str_to_ident("std"),
-                                         with_version("std"),
-                                         ast::DUMMY_NODE_ID),
+                                           None,
+                                           ast::DUMMY_NODE_ID),
             attrs: vec!(
                 attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
                         InternedString::new("phase"),
@@ -95,8 +81,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         if use_start(&krate) && any_exe {
             vis.push(ast::ViewItem {
                 node: ast::ViewItemExternCrate(token::str_to_ident("native"),
-                                             with_version("native"),
-                                             ast::DUMMY_NODE_ID),
+                                               None,
+                                               ast::DUMMY_NODE_ID),
                 attrs: Vec::new(),
                 vis: ast::Inherited,
                 span: DUMMY_SP
index d33b76ae08c5ede9b9b1d9329beb5d3c86e02624..0860d111a9ef04a2f254bbf2de4b615856651cd2 100644 (file)
@@ -15,7 +15,6 @@
 
 use driver::session::Session;
 use front::config;
-use front::std_inject::with_version;
 
 use std::cell::RefCell;
 use std::gc::{Gc, GC};
@@ -154,7 +153,7 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate)
         ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
                              ExpansionConfig {
                                  deriving_hash_type_parameter: false,
-                                 crate_id: from_str("test").unwrap(),
+                                 crate_name: "test".to_string(),
                              }),
         path: RefCell::new(Vec::new()),
         testfns: RefCell::new(Vec::new()),
@@ -298,9 +297,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
                                         ast::DUMMY_NODE_ID))),
          ast::Public)
     } else {
-        (ast::ViewItemExternCrate(id_test,
-                               with_version("test"),
-                               ast::DUMMY_NODE_ID),
+        (ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
          ast::Inherited)
     };
     ast::ViewItem {
@@ -350,7 +347,7 @@ pub fn main() {
         span: DUMMY_SP,
      };
 
-    debug!("Synthetic test module:\n{}\n", pprust::item_to_str(&item));
+    debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
 
     box(GC) item
 }
@@ -395,8 +392,8 @@ fn mk_tests(cx: &TestCtxt) -> Gc<ast::Item> {
 }
 
 fn is_test_crate(krate: &ast::Crate) -> bool {
-    match attr::find_crateid(krate.attrs.as_slice()) {
-        Some(ref s) if "test" == s.name.as_slice() => true,
+    match attr::find_crate_name(krate.attrs.as_slice()) {
+        Some(ref s) if "test" == s.get().as_slice() => true,
         _ => false
     }
 }
index 729eb908e3943be911df2c82cf1a159e4fb02494..92d1c176a1b92c8b28d8ef2faf7b2b56d6a6c811 100644 (file)
@@ -18,7 +18,7 @@
 
 */
 
-#![crate_id = "rustc#0.11.0"]
+#![crate_name = "rustc"]
 #![experimental]
 #![comment = "The Rust compiler"]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-      html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+      html_root_url = "http://doc.rust-lang.org/master/")]
 
 #![allow(deprecated)]
 #![feature(macro_rules, globs, struct_variant, managed_boxes, quote)]
 #![feature(default_type_params, phase, unsafe_destructor)]
 
+#![allow(unknown_features)] // NOTE: Remove after next snapshot
+#![feature(rustc_diagnostic_macros)]
+
 extern crate arena;
 extern crate debug;
 extern crate flate;
 extern crate getopts;
 extern crate graphviz;
 extern crate libc;
+extern crate llvm = "rustc_llvm";
+extern crate rustc_back = "rustc_back";
 extern crate serialize;
-extern crate syntax;
 extern crate time;
 #[phase(plugin, link)] extern crate log;
+#[phase(plugin, link)] extern crate syntax;
+
+mod diagnostics;
+
+pub mod back {
+    pub use rustc_back::abi;
+    pub use rustc_back::archive;
+    pub use rustc_back::arm;
+    pub use rustc_back::mips;
+    pub use rustc_back::mipsel;
+    pub use rustc_back::rpath;
+    pub use rustc_back::svh;
+    pub use rustc_back::target_strs;
+    pub use rustc_back::x86;
+    pub use rustc_back::x86_64;
+
+    pub mod link;
+    pub mod lto;
+
+}
 
 pub mod middle {
     pub mod def;
@@ -91,21 +115,6 @@ pub mod front {
     pub mod show_span;
 }
 
-pub mod back {
-    pub mod abi;
-    pub mod archive;
-    pub mod arm;
-    pub mod link;
-    pub mod lto;
-    pub mod mips;
-    pub mod mipsel;
-    pub mod rpath;
-    pub mod svh;
-    pub mod target_strs;
-    pub mod x86;
-    pub mod x86_64;
-}
-
 pub mod metadata;
 
 pub mod driver;
@@ -115,18 +124,20 @@ pub mod back {
 pub mod lint;
 
 pub mod util {
+    pub use rustc_back::fs;
+    pub use rustc_back::sha2;
+
     pub mod common;
     pub mod ppaux;
-    pub mod sha2;
     pub mod nodemap;
-    pub mod fs;
 }
 
 pub mod lib {
-    pub mod llvm;
-    pub mod llvmdeps;
+    pub use llvm;
 }
 
+__build_diagnostic_array!(DIAGNOSTICS)
+
 // A private module so that macro-expanded idents like
 // `::rustc::lint::Lint` will also work in `rustc` itself.
 //
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
deleted file mode 100644 (file)
index d07e744..0000000
+++ /dev/null
@@ -1,1983 +0,0 @@
-// Copyright 2012-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.
-
-#![allow(non_uppercase_pattern_statics)]
-#![allow(non_camel_case_types)]
-#![allow(non_snake_case_functions)]
-#![allow(dead_code)]
-
-use std::c_str::ToCStr;
-use std::cell::RefCell;
-use std::collections::HashMap;
-use libc::{c_uint, c_ushort, c_void, free, uint64_t};
-use std::str::raw::from_c_str;
-
-use middle::trans::type_::Type;
-
-pub type Opcode = u32;
-pub type Bool = c_uint;
-
-pub static True: Bool = 1 as Bool;
-pub static False: Bool = 0 as Bool;
-
-// Consts for the LLVM CallConv type, pre-cast to uint.
-
-#[deriving(PartialEq)]
-pub enum CallConv {
-    CCallConv = 0,
-    FastCallConv = 8,
-    ColdCallConv = 9,
-    X86StdcallCallConv = 64,
-    X86FastcallCallConv = 65,
-    X86_64_Win64 = 79,
-}
-
-pub enum Visibility {
-    LLVMDefaultVisibility = 0,
-    HiddenVisibility = 1,
-    ProtectedVisibility = 2,
-}
-
-// This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
-// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
-// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
-// they've been removed in upstream LLVM commit r203866.
-pub enum Linkage {
-    ExternalLinkage = 0,
-    AvailableExternallyLinkage = 1,
-    LinkOnceAnyLinkage = 2,
-    LinkOnceODRLinkage = 3,
-    WeakAnyLinkage = 5,
-    WeakODRLinkage = 6,
-    AppendingLinkage = 7,
-    InternalLinkage = 8,
-    PrivateLinkage = 9,
-    ExternalWeakLinkage = 12,
-    CommonLinkage = 14,
-}
-
-#[deriving(Clone)]
-pub enum Attribute {
-    ZExtAttribute = 1 << 0,
-    SExtAttribute = 1 << 1,
-    NoReturnAttribute = 1 << 2,
-    InRegAttribute = 1 << 3,
-    StructRetAttribute = 1 << 4,
-    NoUnwindAttribute = 1 << 5,
-    NoAliasAttribute = 1 << 6,
-    ByValAttribute = 1 << 7,
-    NestAttribute = 1 << 8,
-    ReadNoneAttribute = 1 << 9,
-    ReadOnlyAttribute = 1 << 10,
-    NoInlineAttribute = 1 << 11,
-    AlwaysInlineAttribute = 1 << 12,
-    OptimizeForSizeAttribute = 1 << 13,
-    StackProtectAttribute = 1 << 14,
-    StackProtectReqAttribute = 1 << 15,
-    AlignmentAttribute = 31 << 16,
-    NoCaptureAttribute = 1 << 21,
-    NoRedZoneAttribute = 1 << 22,
-    NoImplicitFloatAttribute = 1 << 23,
-    NakedAttribute = 1 << 24,
-    InlineHintAttribute = 1 << 25,
-    StackAttribute = 7 << 26,
-    ReturnsTwiceAttribute = 1 << 29,
-    UWTableAttribute = 1 << 30,
-    NonLazyBindAttribute = 1 << 31,
-}
-
-#[repr(u64)]
-pub enum OtherAttribute {
-    // The following are not really exposed in
-    // the LLVM c api so instead to add these
-    // we call a wrapper function in RustWrapper
-    // that uses the C++ api.
-    SanitizeAddressAttribute = 1 << 32,
-    MinSizeAttribute = 1 << 33,
-    NoDuplicateAttribute = 1 << 34,
-    StackProtectStrongAttribute = 1 << 35,
-    SanitizeThreadAttribute = 1 << 36,
-    SanitizeMemoryAttribute = 1 << 37,
-    NoBuiltinAttribute = 1 << 38,
-    ReturnedAttribute = 1 << 39,
-    ColdAttribute = 1 << 40,
-    BuiltinAttribute = 1 << 41,
-    OptimizeNoneAttribute = 1 << 42,
-    InAllocaAttribute = 1 << 43,
-    NonNullAttribute = 1 << 44,
-}
-
-#[repr(C)]
-pub enum AttributeSet {
-    ReturnIndex = 0,
-    FunctionIndex = !0
-}
-
-// enum for the LLVM IntPredicate type
-pub enum IntPredicate {
-    IntEQ = 32,
-    IntNE = 33,
-    IntUGT = 34,
-    IntUGE = 35,
-    IntULT = 36,
-    IntULE = 37,
-    IntSGT = 38,
-    IntSGE = 39,
-    IntSLT = 40,
-    IntSLE = 41,
-}
-
-// enum for the LLVM RealPredicate type
-pub enum RealPredicate {
-    RealPredicateFalse = 0,
-    RealOEQ = 1,
-    RealOGT = 2,
-    RealOGE = 3,
-    RealOLT = 4,
-    RealOLE = 5,
-    RealONE = 6,
-    RealORD = 7,
-    RealUNO = 8,
-    RealUEQ = 9,
-    RealUGT = 10,
-    RealUGE = 11,
-    RealULT = 12,
-    RealULE = 13,
-    RealUNE = 14,
-    RealPredicateTrue = 15,
-}
-
-// The LLVM TypeKind type - must stay in sync with the def of
-// LLVMTypeKind in llvm/include/llvm-c/Core.h
-#[deriving(PartialEq)]
-#[repr(C)]
-pub enum TypeKind {
-    Void      = 0,
-    Half      = 1,
-    Float     = 2,
-    Double    = 3,
-    X86_FP80  = 4,
-    FP128     = 5,
-    PPC_FP128 = 6,
-    Label     = 7,
-    Integer   = 8,
-    Function  = 9,
-    Struct    = 10,
-    Array     = 11,
-    Pointer   = 12,
-    Vector    = 13,
-    Metadata  = 14,
-    X86_MMX   = 15,
-}
-
-#[repr(C)]
-pub enum AtomicBinOp {
-    Xchg = 0,
-    Add  = 1,
-    Sub  = 2,
-    And  = 3,
-    Nand = 4,
-    Or   = 5,
-    Xor  = 6,
-    Max  = 7,
-    Min  = 8,
-    UMax = 9,
-    UMin = 10,
-}
-
-#[repr(C)]
-pub enum AtomicOrdering {
-    NotAtomic = 0,
-    Unordered = 1,
-    Monotonic = 2,
-    // Consume = 3,  // Not specified yet.
-    Acquire = 4,
-    Release = 5,
-    AcquireRelease = 6,
-    SequentiallyConsistent = 7
-}
-
-// Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
-#[repr(C)]
-pub enum FileType {
-    AssemblyFile = 0,
-    ObjectFile = 1
-}
-
-pub enum Metadata {
-    MD_dbg = 0,
-    MD_tbaa = 1,
-    MD_prof = 2,
-    MD_fpmath = 3,
-    MD_range = 4,
-    MD_tbaa_struct = 5
-}
-
-// Inline Asm Dialect
-pub enum AsmDialect {
-    AD_ATT   = 0,
-    AD_Intel = 1
-}
-
-#[deriving(PartialEq)]
-#[repr(C)]
-pub enum CodeGenOptLevel {
-    CodeGenLevelNone = 0,
-    CodeGenLevelLess = 1,
-    CodeGenLevelDefault = 2,
-    CodeGenLevelAggressive = 3,
-}
-
-#[repr(C)]
-pub enum RelocMode {
-    RelocDefault = 0,
-    RelocStatic = 1,
-    RelocPIC = 2,
-    RelocDynamicNoPic = 3,
-}
-
-#[repr(C)]
-pub enum CodeGenModel {
-    CodeModelDefault = 0,
-    CodeModelJITDefault = 1,
-    CodeModelSmall = 2,
-    CodeModelKernel = 3,
-    CodeModelMedium = 4,
-    CodeModelLarge = 5,
-}
-
-// Opaque pointer types
-pub enum Module_opaque {}
-pub type ModuleRef = *mut Module_opaque;
-pub enum Context_opaque {}
-pub type ContextRef = *mut Context_opaque;
-pub enum Type_opaque {}
-pub type TypeRef = *mut Type_opaque;
-pub enum Value_opaque {}
-pub type ValueRef = *mut Value_opaque;
-pub enum BasicBlock_opaque {}
-pub type BasicBlockRef = *mut BasicBlock_opaque;
-pub enum Builder_opaque {}
-pub type BuilderRef = *mut Builder_opaque;
-pub enum ExecutionEngine_opaque {}
-pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
-pub enum MemoryBuffer_opaque {}
-pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
-pub enum PassManager_opaque {}
-pub type PassManagerRef = *mut PassManager_opaque;
-pub enum PassManagerBuilder_opaque {}
-pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
-pub enum Use_opaque {}
-pub type UseRef = *mut Use_opaque;
-pub enum TargetData_opaque {}
-pub type TargetDataRef = *mut TargetData_opaque;
-pub enum ObjectFile_opaque {}
-pub type ObjectFileRef = *mut ObjectFile_opaque;
-pub enum SectionIterator_opaque {}
-pub type SectionIteratorRef = *mut SectionIterator_opaque;
-pub enum Pass_opaque {}
-pub type PassRef = *mut Pass_opaque;
-pub enum TargetMachine_opaque {}
-pub type TargetMachineRef = *mut TargetMachine_opaque;
-pub enum Archive_opaque {}
-pub type ArchiveRef = *mut Archive_opaque;
-
-pub mod debuginfo {
-    use super::{ValueRef};
-
-    pub enum DIBuilder_opaque {}
-    pub type DIBuilderRef = *mut DIBuilder_opaque;
-
-    pub type DIDescriptor = ValueRef;
-    pub type DIScope = DIDescriptor;
-    pub type DILocation = DIDescriptor;
-    pub type DIFile = DIScope;
-    pub type DILexicalBlock = DIScope;
-    pub type DISubprogram = DIScope;
-    pub type DIType = DIDescriptor;
-    pub type DIBasicType = DIType;
-    pub type DIDerivedType = DIType;
-    pub type DICompositeType = DIDerivedType;
-    pub type DIVariable = DIDescriptor;
-    pub type DIGlobalVariable = DIDescriptor;
-    pub type DIArray = DIDescriptor;
-    pub type DISubrange = DIDescriptor;
-
-    pub enum DIDescriptorFlags {
-      FlagPrivate            = 1 << 0,
-      FlagProtected          = 1 << 1,
-      FlagFwdDecl            = 1 << 2,
-      FlagAppleBlock         = 1 << 3,
-      FlagBlockByrefStruct   = 1 << 4,
-      FlagVirtual            = 1 << 5,
-      FlagArtificial         = 1 << 6,
-      FlagExplicit           = 1 << 7,
-      FlagPrototyped         = 1 << 8,
-      FlagObjcClassComplete  = 1 << 9,
-      FlagObjectPointer      = 1 << 10,
-      FlagVector             = 1 << 11,
-      FlagStaticMember       = 1 << 12
-    }
-}
-
-pub mod llvm {
-    use super::{AtomicBinOp, AtomicOrdering, BasicBlockRef, ExecutionEngineRef};
-    use super::{Bool, BuilderRef, ContextRef, MemoryBufferRef, ModuleRef};
-    use super::{ObjectFileRef, Opcode, PassManagerRef, PassManagerBuilderRef};
-    use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef};
-    use super::{ValueRef, TargetMachineRef, FileType, ArchiveRef};
-    use super::{CodeGenModel, RelocMode, CodeGenOptLevel};
-    use super::debuginfo::*;
-    use libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong,
-               size_t, uint64_t};
-
-    // Link to our native llvm bindings (things that we need to use the C++ api
-    // for) and because llvm is written in C++ we need to link against libstdc++
-    //
-    // You'll probably notice that there is an omission of all LLVM libraries
-    // from this location. This is because the set of LLVM libraries that we
-    // link to is mostly defined by LLVM, and the `llvm-config` tool is used to
-    // figure out the exact set of libraries. To do this, the build system
-    // generates an llvmdeps.rs file next to this one which will be
-    // automatically updated whenever LLVM is updated to include an up-to-date
-    // set of the libraries we need to link to LLVM for.
-    #[link(name = "rustllvm", kind = "static")]
-    extern {
-        /* Create and destroy contexts. */
-        pub fn LLVMContextCreate() -> ContextRef;
-        pub fn LLVMContextDispose(C: ContextRef);
-        pub fn LLVMGetMDKindIDInContext(C: ContextRef,
-                                        Name: *const c_char,
-                                        SLen: c_uint)
-                                        -> c_uint;
-
-        /* Create and destroy modules. */
-        pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char,
-                                                 C: ContextRef)
-                                                 -> ModuleRef;
-        pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
-        pub fn LLVMDisposeModule(M: ModuleRef);
-
-        /** Data layout. See Module::getDataLayout. */
-        pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char;
-        pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char);
-
-        /** Target triple. See Module::getTargetTriple. */
-        pub fn LLVMGetTarget(M: ModuleRef) -> *const c_char;
-        pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char);
-
-        /** See Module::dump. */
-        pub fn LLVMDumpModule(M: ModuleRef);
-
-        /** See Module::setModuleInlineAsm. */
-        pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
-
-        /** See llvm::LLVMTypeKind::getTypeID. */
-        pub fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
-
-        /** See llvm::LLVMType::getContext. */
-        pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
-
-        /* Operations on integer types */
-        pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint)
-                                    -> TypeRef;
-
-        pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
-
-        /* Operations on real types */
-        pub fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
-
-        /* Operations on function types */
-        pub fn LLVMFunctionType(ReturnType: TypeRef,
-                                ParamTypes: *const TypeRef,
-                                ParamCount: c_uint,
-                                IsVarArg: Bool)
-                                -> TypeRef;
-        pub fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
-        pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
-        pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
-        pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *const TypeRef);
-
-        /* Operations on struct types */
-        pub fn LLVMStructTypeInContext(C: ContextRef,
-                                       ElementTypes: *const TypeRef,
-                                       ElementCount: c_uint,
-                                       Packed: Bool)
-                                       -> TypeRef;
-        pub fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
-        pub fn LLVMGetStructElementTypes(StructTy: TypeRef,
-                                         Dest: *mut TypeRef);
-        pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
-
-        /* Operations on array, pointer, and vector types (sequence types) */
-        pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
-        pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint)
-                               -> TypeRef;
-        pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint)
-                              -> TypeRef;
-
-        pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
-        pub fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
-        pub fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
-        pub fn LLVMGetPointerToGlobal(EE: ExecutionEngineRef, V: ValueRef)
-                                      -> *const ();
-        pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
-
-        /* Operations on other types */
-        pub fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
-        pub fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
-
-        /* Operations on all values */
-        pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
-        pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
-        pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
-        pub fn LLVMDumpValue(Val: ValueRef);
-        pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
-        pub fn LLVMHasMetadata(Val: ValueRef) -> c_int;
-        pub fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
-        pub fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
-
-        /* Operations on Uses */
-        pub fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
-        pub fn LLVMGetNextUse(U: UseRef) -> UseRef;
-        pub fn LLVMGetUser(U: UseRef) -> ValueRef;
-        pub fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
-
-        /* Operations on Users */
-        pub fn LLVMGetNumOperands(Val: ValueRef) -> c_int;
-        pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
-        pub fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
-
-        /* Operations on constants of any type */
-        pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
-        /* all zeroes */
-        pub fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
-        pub fn LLVMConstICmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstFCmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
-                             -> ValueRef;
-        /* only for int/vector */
-        pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
-        pub fn LLVMIsConstant(Val: ValueRef) -> Bool;
-        pub fn LLVMIsNull(Val: ValueRef) -> Bool;
-        pub fn LLVMIsUndef(Val: ValueRef) -> Bool;
-        pub fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
-
-        /* Operations on metadata */
-        pub fn LLVMMDStringInContext(C: ContextRef,
-                                     Str: *const c_char,
-                                     SLen: c_uint)
-                                     -> ValueRef;
-        pub fn LLVMMDNodeInContext(C: ContextRef,
-                                   Vals: *const ValueRef,
-                                   Count: c_uint)
-                                   -> ValueRef;
-        pub fn LLVMAddNamedMetadataOperand(M: ModuleRef,
-                                           Str: *const c_char,
-                                           Val: ValueRef);
-
-        /* Operations on scalar constants */
-        pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool)
-                            -> ValueRef;
-        pub fn LLVMConstIntOfString(IntTy: TypeRef, Text: *const c_char, Radix: u8)
-                                    -> ValueRef;
-        pub fn LLVMConstIntOfStringAndSize(IntTy: TypeRef,
-                                           Text: *const c_char,
-                                           SLen: c_uint,
-                                           Radix: u8)
-                                           -> ValueRef;
-        pub fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
-        pub fn LLVMConstRealOfString(RealTy: TypeRef, Text: *const c_char)
-                                     -> ValueRef;
-        pub fn LLVMConstRealOfStringAndSize(RealTy: TypeRef,
-                                            Text: *const c_char,
-                                            SLen: c_uint)
-                                            -> ValueRef;
-        pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
-        pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
-
-
-        /* Operations on composite constants */
-        pub fn LLVMConstStringInContext(C: ContextRef,
-                                        Str: *const c_char,
-                                        Length: c_uint,
-                                        DontNullTerminate: Bool)
-                                        -> ValueRef;
-        pub fn LLVMConstStructInContext(C: ContextRef,
-                                        ConstantVals: *const ValueRef,
-                                        Count: c_uint,
-                                        Packed: Bool)
-                                        -> ValueRef;
-
-        pub fn LLVMConstArray(ElementTy: TypeRef,
-                              ConstantVals: *const ValueRef,
-                              Length: c_uint)
-                              -> ValueRef;
-        pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint)
-                               -> ValueRef;
-
-        /* Constant expressions */
-        pub fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
-        pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
-        pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
-        pub fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
-        pub fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
-        pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
-        pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
-        pub fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                            -> ValueRef;
-        pub fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                               -> ValueRef;
-        pub fn LLVMConstNUWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                               -> ValueRef;
-        pub fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                            -> ValueRef;
-        pub fn LLVMConstNSWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                               -> ValueRef;
-        pub fn LLVMConstNUWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                               -> ValueRef;
-        pub fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                            -> ValueRef;
-        pub fn LLVMConstNSWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                               -> ValueRef;
-        pub fn LLVMConstNUWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                               -> ValueRef;
-        pub fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstExactSDiv(LHSConstant: ValueRef,
-                                  RHSConstant: ValueRef)
-                                  -> ValueRef;
-        pub fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                            -> ValueRef;
-        pub fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                           -> ValueRef;
-        pub fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                            -> ValueRef;
-        pub fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                            -> ValueRef;
-        pub fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
-                             -> ValueRef;
-        pub fn LLVMConstGEP(ConstantVal: ValueRef,
-                            ConstantIndices: *const ValueRef,
-                            NumIndices: c_uint)
-                            -> ValueRef;
-        pub fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
-                                    ConstantIndices: *const ValueRef,
-                                    NumIndices: c_uint)
-                                    -> ValueRef;
-        pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef)
-                              -> ValueRef;
-        pub fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef)
-                             -> ValueRef;
-        pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef)
-                             -> ValueRef;
-        pub fn LLVMConstFPTrunc(ConstantVal: ValueRef, ToType: TypeRef)
-                                -> ValueRef;
-        pub fn LLVMConstFPExt(ConstantVal: ValueRef, ToType: TypeRef)
-                              -> ValueRef;
-        pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef)
-                               -> ValueRef;
-        pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef)
-                               -> ValueRef;
-        pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef)
-                               -> ValueRef;
-        pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef)
-                               -> ValueRef;
-        pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef)
-                                 -> ValueRef;
-        pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef)
-                                 -> ValueRef;
-        pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef)
-                                -> ValueRef;
-        pub fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
-                                      -> ValueRef;
-        pub fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
-                                      -> ValueRef;
-        pub fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
-                                       -> ValueRef;
-        pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef)
-                                    -> ValueRef;
-        pub fn LLVMConstIntCast(ConstantVal: ValueRef,
-                                ToType: TypeRef,
-                                isSigned: Bool)
-                                -> ValueRef;
-        pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef)
-                               -> ValueRef;
-        pub fn LLVMConstSelect(ConstantCondition: ValueRef,
-                               ConstantIfTrue: ValueRef,
-                               ConstantIfFalse: ValueRef)
-                               -> ValueRef;
-        pub fn LLVMConstExtractElement(VectorConstant: ValueRef,
-                                       IndexConstant: ValueRef)
-                                       -> ValueRef;
-        pub fn LLVMConstInsertElement(VectorConstant: ValueRef,
-                                      ElementValueConstant: ValueRef,
-                                      IndexConstant: ValueRef)
-                                      -> ValueRef;
-        pub fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
-                                      VectorBConstant: ValueRef,
-                                      MaskConstant: ValueRef)
-                                      -> ValueRef;
-        pub fn LLVMConstExtractValue(AggConstant: ValueRef,
-                                     IdxList: *const c_uint,
-                                     NumIdx: c_uint)
-                                     -> ValueRef;
-        pub fn LLVMConstInsertValue(AggConstant: ValueRef,
-                                    ElementValueConstant: ValueRef,
-                                    IdxList: *const c_uint,
-                                    NumIdx: c_uint)
-                                    -> ValueRef;
-        pub fn LLVMConstInlineAsm(Ty: TypeRef,
-                                  AsmString: *const c_char,
-                                  Constraints: *const c_char,
-                                  HasSideEffects: Bool,
-                                  IsAlignStack: Bool)
-                                  -> ValueRef;
-        pub fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
-
-
-
-        /* Operations on global variables, functions, and aliases (globals) */
-        pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
-        pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
-        pub fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
-        pub fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
-        pub fn LLVMGetSection(Global: ValueRef) -> *const c_char;
-        pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char);
-        pub fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
-        pub fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
-        pub fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
-        pub fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
-
-
-        /* Operations on global variables */
-        pub fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMAddGlobalInAddressSpace(M: ModuleRef,
-                                           Ty: TypeRef,
-                                           Name: *const c_char,
-                                           AddressSpace: c_uint)
-                                           -> ValueRef;
-        pub fn LLVMGetNamedGlobal(M: ModuleRef, Name: *const c_char) -> ValueRef;
-        pub fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
-        pub fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
-        pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
-        pub fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
-        pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
-        pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
-        pub fn LLVMSetInitializer(GlobalVar: ValueRef,
-                                         ConstantVal: ValueRef);
-        pub fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
-        pub fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
-        pub fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
-        pub fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
-
-        /* Operations on aliases */
-        pub fn LLVMAddAlias(M: ModuleRef,
-                            Ty: TypeRef,
-                            Aliasee: ValueRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-
-        /* Operations on functions */
-        pub fn LLVMAddFunction(M: ModuleRef,
-                               Name: *const c_char,
-                               FunctionTy: TypeRef)
-                               -> ValueRef;
-        pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
-        pub fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
-        pub fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
-        pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
-        pub fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
-        pub fn LLVMDeleteFunction(Fn: ValueRef);
-        pub fn LLVMGetOrInsertFunction(M: ModuleRef,
-                                       Name: *const c_char,
-                                       FunctionTy: TypeRef)
-                                       -> ValueRef;
-        pub fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
-        pub fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
-        pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
-        pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
-        pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
-        pub fn LLVMAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: uint64_t);
-        pub fn LLVMAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
-        pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
-        pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
-
-        /* Operations on parameters */
-        pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
-        pub fn LLVMGetParams(Fn: ValueRef, Params: *const ValueRef);
-        pub fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
-        pub fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
-        pub fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
-        pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
-        pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
-        pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
-        pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
-        pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
-        pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
-        pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
-
-        /* Operations on basic blocks */
-        pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
-        pub fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
-        pub fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
-        pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
-        pub fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
-        pub fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *const ValueRef);
-        pub fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-        pub fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-        pub fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
-        pub fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
-        pub fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-
-        pub fn LLVMAppendBasicBlockInContext(C: ContextRef,
-                                             Fn: ValueRef,
-                                             Name: *const c_char)
-                                             -> BasicBlockRef;
-        pub fn LLVMInsertBasicBlockInContext(C: ContextRef,
-                                             BB: BasicBlockRef,
-                                             Name: *const c_char)
-                                             -> BasicBlockRef;
-        pub fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
-
-        pub fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef,
-                                       MoveAfter: BasicBlockRef);
-
-        pub fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef,
-                                        MoveBefore: BasicBlockRef);
-
-        /* Operations on instructions */
-        pub fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
-        pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
-        pub fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
-        pub fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
-        pub fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
-        pub fn LLVMInstructionEraseFromParent(Inst: ValueRef);
-
-        /* Operations on call sites */
-        pub fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
-        pub fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
-        pub fn LLVMAddInstrAttribute(Instr: ValueRef,
-                                     index: c_uint,
-                                     IA: c_uint);
-        pub fn LLVMRemoveInstrAttribute(Instr: ValueRef,
-                                        index: c_uint,
-                                        IA: c_uint);
-        pub fn LLVMSetInstrParamAlignment(Instr: ValueRef,
-                                          index: c_uint,
-                                          align: c_uint);
-        pub fn LLVMAddCallSiteAttribute(Instr: ValueRef,
-                                        index: c_uint,
-                                        Val: uint64_t);
-
-        /* Operations on call instructions (only) */
-        pub fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
-        pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
-
-        /* Operations on load/store instructions (only) */
-        pub fn LLVMGetVolatile(MemoryAccessInst: ValueRef) -> Bool;
-        pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool);
-
-        /* Operations on phi nodes */
-        pub fn LLVMAddIncoming(PhiNode: ValueRef,
-                               IncomingValues: *const ValueRef,
-                               IncomingBlocks: *const BasicBlockRef,
-                               Count: c_uint);
-        pub fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
-        pub fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint)
-                                    -> ValueRef;
-        pub fn LLVMGetIncomingBlock(PhiNode: ValueRef, Index: c_uint)
-                                    -> BasicBlockRef;
-
-        /* Instruction builders */
-        pub fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
-        pub fn LLVMPositionBuilder(Builder: BuilderRef,
-                                   Block: BasicBlockRef,
-                                   Instr: ValueRef);
-        pub fn LLVMPositionBuilderBefore(Builder: BuilderRef,
-                                         Instr: ValueRef);
-        pub fn LLVMPositionBuilderAtEnd(Builder: BuilderRef,
-                                        Block: BasicBlockRef);
-        pub fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
-        pub fn LLVMClearInsertionPosition(Builder: BuilderRef);
-        pub fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
-        pub fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
-                                             Instr: ValueRef,
-                                             Name: *const c_char);
-        pub fn LLVMDisposeBuilder(Builder: BuilderRef);
-        pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef);
-
-        /* Metadata */
-        pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
-        pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
-        pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
-
-        /* Terminators */
-        pub fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
-        pub fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
-        pub fn LLVMBuildAggregateRet(B: BuilderRef,
-                                     RetVals: *const ValueRef,
-                                     N: c_uint)
-                                     -> ValueRef;
-        pub fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
-        pub fn LLVMBuildCondBr(B: BuilderRef,
-                               If: ValueRef,
-                               Then: BasicBlockRef,
-                               Else: BasicBlockRef)
-                               -> ValueRef;
-        pub fn LLVMBuildSwitch(B: BuilderRef,
-                               V: ValueRef,
-                               Else: BasicBlockRef,
-                               NumCases: c_uint)
-                               -> ValueRef;
-        pub fn LLVMBuildIndirectBr(B: BuilderRef,
-                                   Addr: ValueRef,
-                                   NumDests: c_uint)
-                                   -> ValueRef;
-        pub fn LLVMBuildInvoke(B: BuilderRef,
-                               Fn: ValueRef,
-                               Args: *const ValueRef,
-                               NumArgs: c_uint,
-                               Then: BasicBlockRef,
-                               Catch: BasicBlockRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildLandingPad(B: BuilderRef,
-                                   Ty: TypeRef,
-                                   PersFn: ValueRef,
-                                   NumClauses: c_uint,
-                                   Name: *const c_char)
-                                   -> ValueRef;
-        pub fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
-        pub fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
-
-        /* Add a case to the switch instruction */
-        pub fn LLVMAddCase(Switch: ValueRef,
-                           OnVal: ValueRef,
-                           Dest: BasicBlockRef);
-
-        /* Add a destination to the indirectbr instruction */
-        pub fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
-
-        /* Add a clause to the landing pad instruction */
-        pub fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
-
-        /* Set the cleanup on a landing pad instruction */
-        pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
-
-        /* Arithmetic */
-        pub fn LLVMBuildAdd(B: BuilderRef,
-                            LHS: ValueRef,
-                            RHS: ValueRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-        pub fn LLVMBuildNSWAdd(B: BuilderRef,
-                               LHS: ValueRef,
-                               RHS: ValueRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildNUWAdd(B: BuilderRef,
-                               LHS: ValueRef,
-                               RHS: ValueRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildFAdd(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildSub(B: BuilderRef,
-                            LHS: ValueRef,
-                            RHS: ValueRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-        pub fn LLVMBuildNSWSub(B: BuilderRef,
-                               LHS: ValueRef,
-                               RHS: ValueRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildNUWSub(B: BuilderRef,
-                               LHS: ValueRef,
-                               RHS: ValueRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildFSub(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildMul(B: BuilderRef,
-                            LHS: ValueRef,
-                            RHS: ValueRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-        pub fn LLVMBuildNSWMul(B: BuilderRef,
-                               LHS: ValueRef,
-                               RHS: ValueRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildNUWMul(B: BuilderRef,
-                               LHS: ValueRef,
-                               RHS: ValueRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildFMul(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildUDiv(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildSDiv(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildExactSDiv(B: BuilderRef,
-                                  LHS: ValueRef,
-                                  RHS: ValueRef,
-                                  Name: *const c_char)
-                                  -> ValueRef;
-        pub fn LLVMBuildFDiv(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildURem(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildSRem(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildFRem(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildShl(B: BuilderRef,
-                            LHS: ValueRef,
-                            RHS: ValueRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-        pub fn LLVMBuildLShr(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildAShr(B: BuilderRef,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildAnd(B: BuilderRef,
-                            LHS: ValueRef,
-                            RHS: ValueRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-        pub fn LLVMBuildOr(B: BuilderRef,
-                           LHS: ValueRef,
-                           RHS: ValueRef,
-                           Name: *const c_char)
-                           -> ValueRef;
-        pub fn LLVMBuildXor(B: BuilderRef,
-                            LHS: ValueRef,
-                            RHS: ValueRef,
-                            Name: *const c_char)
-                            -> ValueRef;
-        pub fn LLVMBuildBinOp(B: BuilderRef,
-                              Op: Opcode,
-                              LHS: ValueRef,
-                              RHS: ValueRef,
-                              Name: *const c_char)
-                              -> ValueRef;
-        pub fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                            -> ValueRef;
-        pub fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *const c_char)
-                            -> ValueRef;
-
-        /* Memory */
-        pub fn LLVMBuildMalloc(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildArrayMalloc(B: BuilderRef,
-                                    Ty: TypeRef,
-                                    Val: ValueRef,
-                                    Name: *const c_char)
-                                    -> ValueRef;
-        pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildArrayAlloca(B: BuilderRef,
-                                    Ty: TypeRef,
-                                    Val: ValueRef,
-                                    Name: *const c_char)
-                                    -> ValueRef;
-        pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
-        pub fn LLVMBuildLoad(B: BuilderRef,
-                             PointerVal: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-
-        pub fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef)
-                              -> ValueRef;
-
-        pub fn LLVMBuildGEP(B: BuilderRef,
-                            Pointer: ValueRef,
-                            Indices: *const ValueRef,
-                            NumIndices: c_uint,
-                            Name: *const c_char)
-                            -> ValueRef;
-        pub fn LLVMBuildInBoundsGEP(B: BuilderRef,
-                                    Pointer: ValueRef,
-                                    Indices: *const ValueRef,
-                                    NumIndices: c_uint,
-                                    Name: *const c_char)
-                                    -> ValueRef;
-        pub fn LLVMBuildStructGEP(B: BuilderRef,
-                                  Pointer: ValueRef,
-                                  Idx: c_uint,
-                                  Name: *const c_char)
-                                  -> ValueRef;
-        pub fn LLVMBuildGlobalString(B: BuilderRef,
-                                     Str: *const c_char,
-                                     Name: *const c_char)
-                                     -> ValueRef;
-        pub fn LLVMBuildGlobalStringPtr(B: BuilderRef,
-                                        Str: *const c_char,
-                                        Name: *const c_char)
-                                        -> ValueRef;
-
-        /* Casts */
-        pub fn LLVMBuildTrunc(B: BuilderRef,
-                              Val: ValueRef,
-                              DestTy: TypeRef,
-                              Name: *const c_char)
-                              -> ValueRef;
-        pub fn LLVMBuildZExt(B: BuilderRef,
-                             Val: ValueRef,
-                             DestTy: TypeRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildSExt(B: BuilderRef,
-                             Val: ValueRef,
-                             DestTy: TypeRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildFPToUI(B: BuilderRef,
-                               Val: ValueRef,
-                               DestTy: TypeRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildFPToSI(B: BuilderRef,
-                               Val: ValueRef,
-                               DestTy: TypeRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildUIToFP(B: BuilderRef,
-                               Val: ValueRef,
-                               DestTy: TypeRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildSIToFP(B: BuilderRef,
-                               Val: ValueRef,
-                               DestTy: TypeRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildFPTrunc(B: BuilderRef,
-                                Val: ValueRef,
-                                DestTy: TypeRef,
-                                Name: *const c_char)
-                                -> ValueRef;
-        pub fn LLVMBuildFPExt(B: BuilderRef,
-                              Val: ValueRef,
-                              DestTy: TypeRef,
-                              Name: *const c_char)
-                              -> ValueRef;
-        pub fn LLVMBuildPtrToInt(B: BuilderRef,
-                                 Val: ValueRef,
-                                 DestTy: TypeRef,
-                                 Name: *const c_char)
-                                 -> ValueRef;
-        pub fn LLVMBuildIntToPtr(B: BuilderRef,
-                                 Val: ValueRef,
-                                 DestTy: TypeRef,
-                                 Name: *const c_char)
-                                 -> ValueRef;
-        pub fn LLVMBuildBitCast(B: BuilderRef,
-                                Val: ValueRef,
-                                DestTy: TypeRef,
-                                Name: *const c_char)
-                                -> ValueRef;
-        pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
-                                      Val: ValueRef,
-                                      DestTy: TypeRef,
-                                      Name: *const c_char)
-                                      -> ValueRef;
-        pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
-                                      Val: ValueRef,
-                                      DestTy: TypeRef,
-                                      Name: *const c_char)
-                                      -> ValueRef;
-        pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
-                                       Val: ValueRef,
-                                       DestTy: TypeRef,
-                                       Name: *const c_char)
-                                       -> ValueRef;
-        pub fn LLVMBuildCast(B: BuilderRef,
-                             Op: Opcode,
-                             Val: ValueRef,
-                             DestTy: TypeRef,
-                             Name: *const c_char) -> ValueRef;
-        pub fn LLVMBuildPointerCast(B: BuilderRef,
-                                    Val: ValueRef,
-                                    DestTy: TypeRef,
-                                    Name: *const c_char)
-                                    -> ValueRef;
-        pub fn LLVMBuildIntCast(B: BuilderRef,
-                                Val: ValueRef,
-                                DestTy: TypeRef,
-                                Name: *const c_char)
-                                -> ValueRef;
-        pub fn LLVMBuildFPCast(B: BuilderRef,
-                               Val: ValueRef,
-                               DestTy: TypeRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-
-        /* Comparisons */
-        pub fn LLVMBuildICmp(B: BuilderRef,
-                             Op: c_uint,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildFCmp(B: BuilderRef,
-                             Op: c_uint,
-                             LHS: ValueRef,
-                             RHS: ValueRef,
-                             Name: *const c_char)
-                             -> ValueRef;
-
-        /* Miscellaneous instructions */
-        pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
-                            -> ValueRef;
-        pub fn LLVMBuildCall(B: BuilderRef,
-                             Fn: ValueRef,
-                             Args: *const ValueRef,
-                             NumArgs: c_uint,
-                             Name: *const c_char)
-                             -> ValueRef;
-        pub fn LLVMBuildSelect(B: BuilderRef,
-                               If: ValueRef,
-                               Then: ValueRef,
-                               Else: ValueRef,
-                               Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildVAArg(B: BuilderRef,
-                              list: ValueRef,
-                              Ty: TypeRef,
-                              Name: *const c_char)
-                              -> ValueRef;
-        pub fn LLVMBuildExtractElement(B: BuilderRef,
-                                       VecVal: ValueRef,
-                                       Index: ValueRef,
-                                       Name: *const c_char)
-                                       -> ValueRef;
-        pub fn LLVMBuildInsertElement(B: BuilderRef,
-                                      VecVal: ValueRef,
-                                      EltVal: ValueRef,
-                                      Index: ValueRef,
-                                      Name: *const c_char)
-                                      -> ValueRef;
-        pub fn LLVMBuildShuffleVector(B: BuilderRef,
-                                      V1: ValueRef,
-                                      V2: ValueRef,
-                                      Mask: ValueRef,
-                                      Name: *const c_char)
-                                      -> ValueRef;
-        pub fn LLVMBuildExtractValue(B: BuilderRef,
-                                     AggVal: ValueRef,
-                                     Index: c_uint,
-                                     Name: *const c_char)
-                                     -> ValueRef;
-        pub fn LLVMBuildInsertValue(B: BuilderRef,
-                                    AggVal: ValueRef,
-                                    EltVal: ValueRef,
-                                    Index: c_uint,
-                                    Name: *const c_char)
-                                    -> ValueRef;
-
-        pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
-                               -> ValueRef;
-        pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
-                                  -> ValueRef;
-        pub fn LLVMBuildPtrDiff(B: BuilderRef,
-                                LHS: ValueRef,
-                                RHS: ValueRef,
-                                Name: *const c_char)
-                                -> ValueRef;
-
-        /* Atomic Operations */
-        pub fn LLVMBuildAtomicLoad(B: BuilderRef,
-                                   PointerVal: ValueRef,
-                                   Name: *const c_char,
-                                   Order: AtomicOrdering,
-                                   Alignment: c_uint)
-                                   -> ValueRef;
-
-        pub fn LLVMBuildAtomicStore(B: BuilderRef,
-                                    Val: ValueRef,
-                                    Ptr: ValueRef,
-                                    Order: AtomicOrdering,
-                                    Alignment: c_uint)
-                                    -> ValueRef;
-
-        pub fn LLVMBuildAtomicCmpXchg(B: BuilderRef,
-                                      LHS: ValueRef,
-                                      CMP: ValueRef,
-                                      RHS: ValueRef,
-                                      Order: AtomicOrdering,
-                                      FailureOrder: AtomicOrdering)
-                                      -> ValueRef;
-        pub fn LLVMBuildAtomicRMW(B: BuilderRef,
-                                  Op: AtomicBinOp,
-                                  LHS: ValueRef,
-                                  RHS: ValueRef,
-                                  Order: AtomicOrdering,
-                                  SingleThreaded: Bool)
-                                  -> ValueRef;
-
-        pub fn LLVMBuildAtomicFence(B: BuilderRef, Order: AtomicOrdering);
-
-
-        /* Selected entries from the downcasts. */
-        pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
-        pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef;
-
-        /** Writes a module to the specified path. Returns 0 on success. */
-        pub fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *const c_char) -> c_int;
-
-        /** Creates target data from a target layout string. */
-        pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef;
-        /// Adds the target data to the given pass manager. The pass manager
-        /// references the target data only weakly.
-        pub fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
-        /** Number of bytes clobbered when doing a Store to *T. */
-        pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
-                                   -> c_ulonglong;
-
-        /** Number of bytes clobbered when doing a Store to *T. */
-        pub fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
-                                    -> c_ulonglong;
-
-        /** Distance between successive elements in an array of T.
-        Includes ABI padding. */
-        pub fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_uint;
-
-        /** Returns the preferred alignment of a type. */
-        pub fn LLVMPreferredAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-                                            -> c_uint;
-        /** Returns the minimum alignment of a type. */
-        pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-                                      -> c_uint;
-
-        /// Computes the byte offset of the indexed struct element for a
-        /// target.
-        pub fn LLVMOffsetOfElement(TD: TargetDataRef,
-                                   StructTy: TypeRef,
-                                   Element: c_uint)
-                                   -> c_ulonglong;
-
-        /**
-         * Returns the minimum alignment of a type when part of a call frame.
-         */
-        pub fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-                                            -> c_uint;
-
-        /** Disposes target data. */
-        pub fn LLVMDisposeTargetData(TD: TargetDataRef);
-
-        /** Creates a pass manager. */
-        pub fn LLVMCreatePassManager() -> PassManagerRef;
-
-        /** Creates a function-by-function pass manager */
-        pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef)
-                                                      -> PassManagerRef;
-
-        /** Disposes a pass manager. */
-        pub fn LLVMDisposePassManager(PM: PassManagerRef);
-
-        /** Runs a pass manager on a module. */
-        pub fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
-
-        /** Runs the function passes on the provided function. */
-        pub fn LLVMRunFunctionPassManager(FPM: PassManagerRef, F: ValueRef)
-                                          -> Bool;
-
-        /** Initializes all the function passes scheduled in the manager */
-        pub fn LLVMInitializeFunctionPassManager(FPM: PassManagerRef) -> Bool;
-
-        /** Finalizes all the function passes scheduled in the manager */
-        pub fn LLVMFinalizeFunctionPassManager(FPM: PassManagerRef) -> Bool;
-
-        pub fn LLVMInitializePasses();
-
-        /** Adds a verification pass. */
-        pub fn LLVMAddVerifierPass(PM: PassManagerRef);
-
-        pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
-        pub fn LLVMAddIPSCCPPass(PM: PassManagerRef);
-        pub fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
-        pub fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
-        pub fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
-        pub fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
-        pub fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
-        pub fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
-        pub fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
-        pub fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
-        pub fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
-        pub fn LLVMAddReassociatePass(PM: PassManagerRef);
-        pub fn LLVMAddLoopRotatePass(PM: PassManagerRef);
-        pub fn LLVMAddLICMPass(PM: PassManagerRef);
-        pub fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
-        pub fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
-        pub fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
-        pub fn LLVMAddGVNPass(PM: PassManagerRef);
-        pub fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
-        pub fn LLVMAddSCCPPass(PM: PassManagerRef);
-        pub fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
-        pub fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
-        pub fn LLVMAddConstantMergePass(PM: PassManagerRef);
-        pub fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
-        pub fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
-        pub fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
-        pub fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
-        pub fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
-        pub fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
-        pub fn LLVMAddPruneEHPass(PM: PassManagerRef);
-        pub fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
-        pub fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
-        pub fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
-        pub fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
-        pub fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
-
-        pub fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
-        pub fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
-        pub fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
-                                                 OptimizationLevel: c_uint);
-        pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
-                                                  Value: Bool);
-        pub fn LLVMPassManagerBuilderSetDisableUnitAtATime(
-            PMB: PassManagerBuilderRef,
-            Value: Bool);
-        pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(
-            PMB: PassManagerBuilderRef,
-            Value: Bool);
-        pub fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls(
-            PMB: PassManagerBuilderRef,
-            Value: Bool);
-        pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(
-            PMB: PassManagerBuilderRef,
-            threshold: c_uint);
-        pub fn LLVMPassManagerBuilderPopulateModulePassManager(
-            PMB: PassManagerBuilderRef,
-            PM: PassManagerRef);
-
-        pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(
-            PMB: PassManagerBuilderRef,
-            PM: PassManagerRef);
-        pub fn LLVMPassManagerBuilderPopulateLTOPassManager(
-            PMB: PassManagerBuilderRef,
-            PM: PassManagerRef,
-            Internalize: Bool,
-            RunInliner: Bool);
-
-        /** Destroys a memory buffer. */
-        pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
-
-
-        /* Stuff that's in rustllvm/ because it's not upstream yet. */
-
-        /** Opens an object file. */
-        pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
-        /** Closes an object file. */
-        pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
-
-        /** Enumerates the sections in an object file. */
-        pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
-        /** Destroys a section iterator. */
-        pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
-        /** Returns true if the section iterator is at the end of the section
-            list: */
-        pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
-                                          SI: SectionIteratorRef)
-                                          -> Bool;
-        /** Moves the section iterator to point to the next section. */
-        pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
-        /** Returns the current section size. */
-        pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
-        /** Returns the current section contents as a string buffer. */
-        pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char;
-
-        /** Reads the given file and returns it as a memory buffer. Use
-            LLVMDisposeMemoryBuffer() to get rid of it. */
-        pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char)
-            -> MemoryBufferRef;
-        /** Borrows the contents of the memory buffer (doesn't copy it) */
-        pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *const c_char,
-                                                     InputDataLength: size_t,
-                                                     BufferName: *const c_char,
-                                                     RequiresNull: Bool)
-            -> MemoryBufferRef;
-        pub fn LLVMCreateMemoryBufferWithMemoryRangeCopy(InputData: *const c_char,
-                                                         InputDataLength: size_t,
-                                                         BufferName: *const c_char)
-            -> MemoryBufferRef;
-
-        pub fn LLVMIsMultithreaded() -> Bool;
-        pub fn LLVMStartMultithreaded() -> Bool;
-
-        /** Returns a string describing the last error caused by an LLVMRust*
-            call. */
-        pub fn LLVMRustGetLastError() -> *const c_char;
-
-        /// Print the pass timings since static dtors aren't picking them up.
-        pub fn LLVMRustPrintPassTimings();
-
-        pub fn LLVMStructCreateNamed(C: ContextRef, Name: *const c_char) -> TypeRef;
-
-        pub fn LLVMStructSetBody(StructTy: TypeRef,
-                                 ElementTypes: *const TypeRef,
-                                 ElementCount: c_uint,
-                                 Packed: Bool);
-
-        pub fn LLVMConstNamedStruct(S: TypeRef,
-                                    ConstantVals: *const ValueRef,
-                                    Count: c_uint)
-                                    -> ValueRef;
-
-        /** Enables LLVM debug output. */
-        pub fn LLVMSetDebug(Enabled: c_int);
-
-        /** Prepares inline assembly. */
-        pub fn LLVMInlineAsm(Ty: TypeRef,
-                             AsmString: *const c_char,
-                             Constraints: *const c_char,
-                             SideEffects: Bool,
-                             AlignStack: Bool,
-                             Dialect: c_uint)
-                             -> ValueRef;
-
-        pub static LLVMRustDebugMetadataVersion: u32;
-
-        pub fn LLVMRustAddModuleFlag(M: ModuleRef,
-                                     name: *const c_char,
-                                     value: u32);
-
-        pub fn LLVMDIBuilderCreate(M: ModuleRef) -> DIBuilderRef;
-
-        pub fn LLVMDIBuilderDispose(Builder: DIBuilderRef);
-
-        pub fn LLVMDIBuilderFinalize(Builder: DIBuilderRef);
-
-        pub fn LLVMDIBuilderCreateCompileUnit(Builder: DIBuilderRef,
-                                              Lang: c_uint,
-                                              File: *const c_char,
-                                              Dir: *const c_char,
-                                              Producer: *const c_char,
-                                              isOptimized: bool,
-                                              Flags: *const c_char,
-                                              RuntimeVer: c_uint,
-                                              SplitName: *const c_char);
-
-        pub fn LLVMDIBuilderCreateFile(Builder: DIBuilderRef,
-                                       Filename: *const c_char,
-                                       Directory: *const c_char)
-                                       -> DIFile;
-
-        pub fn LLVMDIBuilderCreateSubroutineType(Builder: DIBuilderRef,
-                                                 File: DIFile,
-                                                 ParameterTypes: DIArray)
-                                                 -> DICompositeType;
-
-        pub fn LLVMDIBuilderCreateFunction(Builder: DIBuilderRef,
-                                           Scope: DIDescriptor,
-                                           Name: *const c_char,
-                                           LinkageName: *const c_char,
-                                           File: DIFile,
-                                           LineNo: c_uint,
-                                           Ty: DIType,
-                                           isLocalToUnit: bool,
-                                           isDefinition: bool,
-                                           ScopeLine: c_uint,
-                                           Flags: c_uint,
-                                           isOptimized: bool,
-                                           Fn: ValueRef,
-                                           TParam: ValueRef,
-                                           Decl: ValueRef)
-                                           -> DISubprogram;
-
-        pub fn LLVMDIBuilderCreateBasicType(Builder: DIBuilderRef,
-                                            Name: *const c_char,
-                                            SizeInBits: c_ulonglong,
-                                            AlignInBits: c_ulonglong,
-                                            Encoding: c_uint)
-                                            -> DIBasicType;
-
-        pub fn LLVMDIBuilderCreatePointerType(Builder: DIBuilderRef,
-                                              PointeeTy: DIType,
-                                              SizeInBits: c_ulonglong,
-                                              AlignInBits: c_ulonglong,
-                                              Name: *const c_char)
-                                              -> DIDerivedType;
-
-        pub fn LLVMDIBuilderCreateStructType(Builder: DIBuilderRef,
-                                             Scope: DIDescriptor,
-                                             Name: *const c_char,
-                                             File: DIFile,
-                                             LineNumber: c_uint,
-                                             SizeInBits: c_ulonglong,
-                                             AlignInBits: c_ulonglong,
-                                             Flags: c_uint,
-                                             DerivedFrom: DIType,
-                                             Elements: DIArray,
-                                             RunTimeLang: c_uint,
-                                             VTableHolder: ValueRef,
-                                             UniqueId: *const c_char)
-                                             -> DICompositeType;
-
-        pub fn LLVMDIBuilderCreateMemberType(Builder: DIBuilderRef,
-                                             Scope: DIDescriptor,
-                                             Name: *const c_char,
-                                             File: DIFile,
-                                             LineNo: c_uint,
-                                             SizeInBits: c_ulonglong,
-                                             AlignInBits: c_ulonglong,
-                                             OffsetInBits: c_ulonglong,
-                                             Flags: c_uint,
-                                             Ty: DIType)
-                                             -> DIDerivedType;
-
-        pub fn LLVMDIBuilderCreateLexicalBlock(Builder: DIBuilderRef,
-                                               Scope: DIDescriptor,
-                                               File: DIFile,
-                                               Line: c_uint,
-                                               Col: c_uint,
-                                               Discriminator: c_uint)
-                                               -> DILexicalBlock;
-
-        pub fn LLVMDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
-                                                 Context: DIDescriptor,
-                                                 Name: *const c_char,
-                                                 LinkageName: *const c_char,
-                                                 File: DIFile,
-                                                 LineNo: c_uint,
-                                                 Ty: DIType,
-                                                 isLocalToUnit: bool,
-                                                 Val: ValueRef,
-                                                 Decl: ValueRef)
-                                                 -> DIGlobalVariable;
-
-        pub fn LLVMDIBuilderCreateLocalVariable(Builder: DIBuilderRef,
-                                                Tag: c_uint,
-                                                Scope: DIDescriptor,
-                                                Name: *const c_char,
-                                                File: DIFile,
-                                                LineNo: c_uint,
-                                                Ty: DIType,
-                                                AlwaysPreserve: bool,
-                                                Flags: c_uint,
-                                                ArgNo: c_uint)
-                                                -> DIVariable;
-
-        pub fn LLVMDIBuilderCreateArrayType(Builder: DIBuilderRef,
-                                            Size: c_ulonglong,
-                                            AlignInBits: c_ulonglong,
-                                            Ty: DIType,
-                                            Subscripts: DIArray)
-                                            -> DIType;
-
-        pub fn LLVMDIBuilderCreateVectorType(Builder: DIBuilderRef,
-                                             Size: c_ulonglong,
-                                             AlignInBits: c_ulonglong,
-                                             Ty: DIType,
-                                             Subscripts: DIArray)
-                                             -> DIType;
-
-        pub fn LLVMDIBuilderGetOrCreateSubrange(Builder: DIBuilderRef,
-                                                Lo: c_longlong,
-                                                Count: c_longlong)
-                                                -> DISubrange;
-
-        pub fn LLVMDIBuilderGetOrCreateArray(Builder: DIBuilderRef,
-                                             Ptr: *const DIDescriptor,
-                                             Count: c_uint)
-                                             -> DIArray;
-
-        pub fn LLVMDIBuilderInsertDeclareAtEnd(Builder: DIBuilderRef,
-                                               Val: ValueRef,
-                                               VarInfo: DIVariable,
-                                               InsertAtEnd: BasicBlockRef)
-                                               -> ValueRef;
-
-        pub fn LLVMDIBuilderInsertDeclareBefore(Builder: DIBuilderRef,
-                                                Val: ValueRef,
-                                                VarInfo: DIVariable,
-                                                InsertBefore: ValueRef)
-                                                -> ValueRef;
-
-        pub fn LLVMDIBuilderCreateEnumerator(Builder: DIBuilderRef,
-                                             Name: *const c_char,
-                                             Val: c_ulonglong)
-                                             -> ValueRef;
-
-        pub fn LLVMDIBuilderCreateEnumerationType(Builder: DIBuilderRef,
-                                                  Scope: ValueRef,
-                                                  Name: *const c_char,
-                                                  File: ValueRef,
-                                                  LineNumber: c_uint,
-                                                  SizeInBits: c_ulonglong,
-                                                  AlignInBits: c_ulonglong,
-                                                  Elements: ValueRef,
-                                                  ClassType: ValueRef)
-                                                  -> ValueRef;
-
-        pub fn LLVMDIBuilderCreateUnionType(Builder: DIBuilderRef,
-                                            Scope: ValueRef,
-                                            Name: *const c_char,
-                                            File: ValueRef,
-                                            LineNumber: c_uint,
-                                            SizeInBits: c_ulonglong,
-                                            AlignInBits: c_ulonglong,
-                                            Flags: c_uint,
-                                            Elements: ValueRef,
-                                            RunTimeLang: c_uint,
-                                            UniqueId: *const c_char)
-                                            -> ValueRef;
-
-        pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
-
-        pub fn LLVMDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef,
-                                                        Scope: ValueRef,
-                                                        Name: *const c_char,
-                                                        Ty: ValueRef,
-                                                        File: ValueRef,
-                                                        LineNo: c_uint,
-                                                        ColumnNo: c_uint)
-                                                        -> ValueRef;
-
-        pub fn LLVMDIBuilderCreateOpDeref(IntType: TypeRef) -> ValueRef;
-
-        pub fn LLVMDIBuilderCreateOpPlus(IntType: TypeRef) -> ValueRef;
-
-        pub fn LLVMDIBuilderCreateComplexVariable(Builder: DIBuilderRef,
-            Tag: c_uint,
-            Scope: ValueRef,
-            Name: *const c_char,
-            File: ValueRef,
-            LineNo: c_uint,
-            Ty: ValueRef,
-            AddrOps: *const ValueRef,
-            AddrOpsCount: c_uint,
-            ArgNo: c_uint)
-            -> ValueRef;
-
-        pub fn LLVMDIBuilderCreateNameSpace(Builder: DIBuilderRef,
-                                            Scope: ValueRef,
-                                            Name: *const c_char,
-                                            File: ValueRef,
-                                            LineNo: c_uint)
-                                            -> ValueRef;
-
-        pub fn LLVMDICompositeTypeSetTypeArray(CompositeType: ValueRef, TypeArray: ValueRef);
-        pub fn LLVMTypeToString(Type: TypeRef) -> *const c_char;
-        pub fn LLVMValueToString(value_ref: ValueRef) -> *const c_char;
-
-        pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
-
-        pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
-
-        pub fn LLVMInitializeX86TargetInfo();
-        pub fn LLVMInitializeX86Target();
-        pub fn LLVMInitializeX86TargetMC();
-        pub fn LLVMInitializeX86AsmPrinter();
-        pub fn LLVMInitializeX86AsmParser();
-        pub fn LLVMInitializeARMTargetInfo();
-        pub fn LLVMInitializeARMTarget();
-        pub fn LLVMInitializeARMTargetMC();
-        pub fn LLVMInitializeARMAsmPrinter();
-        pub fn LLVMInitializeARMAsmParser();
-        pub fn LLVMInitializeMipsTargetInfo();
-        pub fn LLVMInitializeMipsTarget();
-        pub fn LLVMInitializeMipsTargetMC();
-        pub fn LLVMInitializeMipsAsmPrinter();
-        pub fn LLVMInitializeMipsAsmParser();
-
-        pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: *const c_char) -> bool;
-        pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
-                                           CPU: *const c_char,
-                                           Features: *const c_char,
-                                           Model: CodeGenModel,
-                                           Reloc: RelocMode,
-                                           Level: CodeGenOptLevel,
-                                           EnableSegstk: bool,
-                                           UseSoftFP: bool,
-                                           NoFramePointerElim: bool,
-                                           FunctionSections: bool,
-                                           DataSections: bool) -> TargetMachineRef;
-        pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
-        pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef,
-                                         PM: PassManagerRef,
-                                         M: ModuleRef);
-        pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
-                                             M: ModuleRef,
-                                             DisableSimplifyLibCalls: bool);
-        pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef,
-                                      DisableSimplifyLibCalls: bool);
-        pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef);
-        pub fn LLVMRustWriteOutputFile(T: TargetMachineRef,
-                                       PM: PassManagerRef,
-                                       M: ModuleRef,
-                                       Output: *const c_char,
-                                       FileType: FileType) -> bool;
-        pub fn LLVMRustPrintModule(PM: PassManagerRef,
-                                   M: ModuleRef,
-                                   Output: *const c_char);
-        pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
-        pub fn LLVMRustPrintPasses();
-        pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char);
-        pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef,
-                                           AddLifetimes: bool);
-        pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef,
-                                             bc: *const c_char,
-                                             len: size_t) -> bool;
-        pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
-                                          syms: *const *const c_char,
-                                          len: size_t);
-        pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
-
-        pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef;
-        pub fn LLVMRustArchiveReadSection(AR: ArchiveRef, name: *const c_char,
-                                          out_len: *mut size_t) -> *const c_char;
-        pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
-
-        pub fn LLVMRustSetDLLExportStorageClass(V: ValueRef);
-        pub fn LLVMVersionMajor() -> c_int;
-        pub fn LLVMVersionMinor() -> c_int;
-
-        pub fn LLVMRustGetSectionName(SI: SectionIteratorRef,
-                                      data: *mut *const c_char) -> c_int;
-    }
-}
-
-pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
-    unsafe {
-        llvm::LLVMSetInstructionCallConv(instr, cc as c_uint);
-    }
-}
-pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
-    unsafe {
-        llvm::LLVMSetFunctionCallConv(fn_, cc as c_uint);
-    }
-}
-pub fn SetLinkage(global: ValueRef, link: Linkage) {
-    unsafe {
-        llvm::LLVMSetLinkage(global, link as c_uint);
-    }
-}
-
-pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) {
-    unsafe {
-        llvm::LLVMSetUnnamedAddr(global, unnamed as Bool);
-    }
-}
-
-pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
-    unsafe {
-        llvm::LLVMSetThreadLocal(global, is_thread_local as Bool);
-    }
-}
-
-pub fn ConstICmp(pred: IntPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
-    unsafe {
-        llvm::LLVMConstICmp(pred as c_ushort, v1, v2)
-    }
-}
-pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
-    unsafe {
-        llvm::LLVMConstFCmp(pred as c_ushort, v1, v2)
-    }
-}
-
-pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
-    unsafe {
-        llvm::LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr as uint64_t)
-    }
-}
-/* Memory-managed object interface to type handles. */
-
-pub struct TypeNames {
-    named_types: RefCell<HashMap<String, TypeRef>>,
-}
-
-impl TypeNames {
-    pub fn new() -> TypeNames {
-        TypeNames {
-            named_types: RefCell::new(HashMap::new())
-        }
-    }
-
-    pub fn associate_type(&self, s: &str, t: &Type) {
-        assert!(self.named_types.borrow_mut().insert(s.to_string(),
-                                                     t.to_ref()));
-    }
-
-    pub fn find_type(&self, s: &str) -> Option<Type> {
-        self.named_types.borrow().find_equiv(&s).map(|x| Type::from_ref(*x))
-    }
-
-    pub fn type_to_str(&self, ty: Type) -> String {
-        unsafe {
-            let s = llvm::LLVMTypeToString(ty.to_ref());
-            let ret = from_c_str(s);
-            free(s as *mut c_void);
-            ret.to_string()
-        }
-    }
-
-    pub fn types_to_str(&self, tys: &[Type]) -> String {
-        let strs: Vec<String> = tys.iter().map(|t| self.type_to_str(*t)).collect();
-        format!("[{}]", strs.connect(","))
-    }
-
-    pub fn val_to_str(&self, val: ValueRef) -> String {
-        unsafe {
-            let s = llvm::LLVMValueToString(val);
-            let ret = from_c_str(s);
-            free(s as *mut c_void);
-            ret.to_string()
-        }
-    }
-}
-
-/* Memory-managed interface to target data. */
-
-pub struct TargetData {
-    pub lltd: TargetDataRef
-}
-
-impl Drop for TargetData {
-    fn drop(&mut self) {
-        unsafe {
-            llvm::LLVMDisposeTargetData(self.lltd);
-        }
-    }
-}
-
-pub fn mk_target_data(string_rep: &str) -> TargetData {
-    TargetData {
-        lltd: string_rep.with_c_str(|buf| {
-            unsafe { llvm::LLVMCreateTargetData(buf) }
-        })
-    }
-}
-
-/* Memory-managed interface to object files. */
-
-pub struct ObjectFile {
-    pub llof: ObjectFileRef,
-}
-
-impl ObjectFile {
-    // This will take ownership of llmb
-    pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
-        unsafe {
-            let llof = llvm::LLVMCreateObjectFile(llmb);
-            if llof as int == 0 {
-                // LLVMCreateObjectFile took ownership of llmb
-                return None
-            }
-
-            Some(ObjectFile {
-                llof: llof,
-            })
-        }
-    }
-}
-
-impl Drop for ObjectFile {
-    fn drop(&mut self) {
-        unsafe {
-            llvm::LLVMDisposeObjectFile(self.llof);
-        }
-    }
-}
-
-/* Memory-managed interface to section iterators. */
-
-pub struct SectionIter {
-    pub llsi: SectionIteratorRef
-}
-
-impl Drop for SectionIter {
-    fn drop(&mut self) {
-        unsafe {
-            llvm::LLVMDisposeSectionIterator(self.llsi);
-        }
-    }
-}
-
-pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter {
-    unsafe {
-        SectionIter {
-            llsi: llvm::LLVMGetSections(llof)
-        }
-    }
-}
diff --git a/src/librustc/lib/llvmdeps.rs b/src/librustc/lib/llvmdeps.rs
new file mode 100644 (file)
index 0000000..05e5e58
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// WARNING: THIS IS A GENERATED FILE, DO NOT MODIFY
+//          take a look at src/etc/mklldeps.py if you're interested
+
+#[cfg(target_arch = "x86_64", target_os = "linux")]
+#[link(name = "LLVMInstrumentation", kind = "static")]
+#[link(name = "LLVMInterpreter", kind = "static")]
+#[link(name = "LLVMMCJIT", kind = "static")]
+#[link(name = "LLVMRuntimeDyld", kind = "static")]
+#[link(name = "LLVMJIT", kind = "static")]
+#[link(name = "LLVMExecutionEngine", kind = "static")]
+#[link(name = "LLVMAsmParser", kind = "static")]
+#[link(name = "LLVMLinker", kind = "static")]
+#[link(name = "LLVMBitWriter", kind = "static")]
+#[link(name = "LLVMipo", kind = "static")]
+#[link(name = "LLVMVectorize", kind = "static")]
+#[link(name = "LLVMMipsDisassembler", kind = "static")]
+#[link(name = "LLVMMipsCodeGen", kind = "static")]
+#[link(name = "LLVMMipsAsmParser", kind = "static")]
+#[link(name = "LLVMMipsDesc", kind = "static")]
+#[link(name = "LLVMMipsInfo", kind = "static")]
+#[link(name = "LLVMMipsAsmPrinter", kind = "static")]
+#[link(name = "LLVMARMDisassembler", kind = "static")]
+#[link(name = "LLVMARMCodeGen", kind = "static")]
+#[link(name = "LLVMARMAsmParser", kind = "static")]
+#[link(name = "LLVMARMDesc", kind = "static")]
+#[link(name = "LLVMARMInfo", kind = "static")]
+#[link(name = "LLVMARMAsmPrinter", kind = "static")]
+#[link(name = "LLVMX86Disassembler", kind = "static")]
+#[link(name = "LLVMX86AsmParser", kind = "static")]
+#[link(name = "LLVMX86CodeGen", kind = "static")]
+#[link(name = "LLVMSelectionDAG", kind = "static")]
+#[link(name = "LLVMAsmPrinter", kind = "static")]
+#[link(name = "LLVMMCParser", kind = "static")]
+#[link(name = "LLVMCodeGen", kind = "static")]
+#[link(name = "LLVMScalarOpts", kind = "static")]
+#[link(name = "LLVMInstCombine", kind = "static")]
+#[link(name = "LLVMTransformUtils", kind = "static")]
+#[link(name = "LLVMipa", kind = "static")]
+#[link(name = "LLVMAnalysis", kind = "static")]
+#[link(name = "LLVMTarget", kind = "static")]
+#[link(name = "LLVMX86Desc", kind = "static")]
+#[link(name = "LLVMX86Info", kind = "static")]
+#[link(name = "LLVMX86AsmPrinter", kind = "static")]
+#[link(name = "LLVMMC", kind = "static")]
+#[link(name = "LLVMObject", kind = "static")]
+#[link(name = "LLVMBitReader", kind = "static")]
+#[link(name = "LLVMCore", kind = "static")]
+#[link(name = "LLVMX86Utils", kind = "static")]
+#[link(name = "LLVMSupport", kind = "static")]
+#[link(name = "pthread")]
+#[link(name = "dl")]
+#[link(name = "m")]
+#[link(name = "stdc++")]
+extern {}
index a8f778934ae47e21c28b9b3c016d5326598bd1ea..62236d753ad26e8dc80ad4b8ac08fae63ce3710b 100644 (file)
 use middle::typeck::astconv::ast_ty_to_ty;
 use middle::typeck::infer;
 use middle::{typeck, ty, def, pat_util, stability};
-use util::ppaux::{ty_to_str};
+use util::ppaux::{ty_to_string};
 use util::nodemap::NodeSet;
 use lint::{Context, LintPass, LintArray};
 
 use std::cmp;
 use std::collections::HashMap;
-use std::i16;
-use std::i32;
-use std::i64;
-use std::i8;
-use std::u16;
-use std::u32;
-use std::u64;
-use std::u8;
+use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
 use std::gc::Gc;
 use syntax::abi;
 use syntax::ast_map;
@@ -214,7 +207,21 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                                          "literal out of range for its type");
                         }
                     },
-
+                    ty::ty_float(t) => {
+                        let (min, max) = float_ty_range(t);
+                        let lit_val: f64 = match lit.node {
+                            ast::LitFloat(ref v, _) |
+                            ast::LitFloatUnsuffixed(ref v) => match from_str(v.get()) {
+                                Some(f) => f,
+                                None => return
+                            },
+                            _ => fail!()
+                        };
+                        if lit_val < min || lit_val > max {
+                            cx.span_lint(TYPE_OVERFLOW, e.span,
+                                         "literal out of range for its type");
+                        }
+                    },
                     _ => ()
                 };
             },
@@ -265,6 +272,13 @@ fn uint_ty_range(uint_ty: ast::UintTy) -> (u64, u64) {
             }
         }
 
+        fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) {
+            match float_ty {
+                ast::TyF32  => (f32::MIN_VALUE as f64, f32::MAX_VALUE as f64),
+                ast::TyF64  => (f64::MIN_VALUE,        f64::MAX_VALUE)
+            }
+        }
+
         fn check_limits(tcx: &ty::ctxt, binop: ast::BinOp,
                         l: &ast::Expr, r: &ast::Expr) -> bool {
             let (lit, expr, swap) = match (&l.node, &r.node) {
@@ -412,14 +426,14 @@ fn check_heap_type(&self, cx: &Context, span: Span, ty: ty::t) {
         });
 
         if n_uniq > 0 {
-            let s = ty_to_str(cx.tcx, ty);
+            let s = ty_to_string(cx.tcx, ty);
             let m = format!("type uses owned (Box type) pointers: {}", s);
             cx.span_lint(OWNED_HEAP_MEMORY, span, m.as_slice());
             cx.span_lint(HEAP_MEMORY, span, m.as_slice());
         }
 
         if n_box > 0 {
-            let s = ty_to_str(cx.tcx, ty);
+            let s = ty_to_string(cx.tcx, ty);
             let m = format!("type uses managed (@ type) pointers: {}", s);
             cx.span_lint(MANAGED_HEAP_MEMORY, span, m.as_slice());
             cx.span_lint(HEAP_MEMORY, span, m.as_slice());
@@ -540,7 +554,7 @@ fn get_lints(&self) -> LintArray {
     }
 
     fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
-        static ATTRIBUTE_WHITELIST: &'static [&'static str] = &'static [
+        static ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
             // FIXME: #14408 whitelist docs since rustdoc looks at them
             "doc",
 
@@ -574,13 +588,13 @@ fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
             "unstable",
         ];
 
-        static CRATE_ATTRS: &'static [&'static str] = &'static [
+        static CRATE_ATTRS: &'static [&'static str] = &[
+            "crate_name",
             "crate_type",
             "feature",
             "no_start",
             "no_main",
             "no_std",
-            "crate_id",
             "desc",
             "comment",
             "license",
@@ -669,22 +683,13 @@ fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
                 if ast_util::is_local(did) {
                     match cx.tcx.map.get(did.node) {
                         ast_map::NodeItem(it) => {
-                            if attr::contains_name(it.attrs.as_slice(),
-                                                   "must_use") {
-                                cx.span_lint(UNUSED_MUST_USE, s.span,
-                                             "unused result which must be used");
-                                warned = true;
-                            }
+                            warned |= check_must_use(cx, it.attrs.as_slice(), s.span);
                         }
                         _ => {}
                     }
                 } else {
                     csearch::get_item_attrs(&cx.sess().cstore, did, |attrs| {
-                        if attr::contains_name(attrs.as_slice(), "must_use") {
-                            cx.span_lint(UNUSED_MUST_USE, s.span,
-                                         "unused result which must be used");
-                            warned = true;
-                        }
+                        warned |= check_must_use(cx, attrs.as_slice(), s.span);
                     });
                 }
             }
@@ -693,6 +698,25 @@ fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
         if !warned {
             cx.span_lint(UNUSED_RESULT, s.span, "unused result");
         }
+
+        fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
+            for attr in attrs.iter() {
+                if attr.check_name("must_use") {
+                    let mut msg = "unused result which must be used".to_string();
+                    // check for #[must_use="..."]
+                    match attr.value_str() {
+                        None => {}
+                        Some(s) => {
+                            msg.push_str(": ");
+                            msg.push_str(s.get());
+                        }
+                    }
+                    cx.span_lint(UNUSED_MUST_USE, sp, msg.as_slice());
+                    return true;
+                }
+            }
+            false
+        }
     }
 }
 
@@ -734,6 +758,11 @@ fn check_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
             }
         }
 
+        let has_extern_repr = it.attrs.iter().fold(attr::ReprAny, |acc, attr| {
+            attr::find_repr_attr(cx.tcx.sess.diagnostic(), attr, acc)
+        }) == attr::ReprExtern;
+        if has_extern_repr { return }
+
         match it.node {
             ast::ItemTy(..) | ast::ItemStruct(..) => {
                 check_case(cx, "type", it.ident, it.span)
@@ -1114,7 +1143,7 @@ fn check_unused_mut_pat(&self, cx: &Context, pats: &[Gc<ast::Pat>]) {
                 match mode {
                     ast::BindByValue(ast::MutMutable) => {
                         if !token::get_ident(ident).get().starts_with("_") {
-                            mutables.insert_or_update_with(ident.name as uint,
+                            mutables.insert_or_update_with(ident.name.uint(),
                                 vec!(id), |_, old| { old.push(id); });
                         }
                     }
index 79fbd73c23d3cbdbcffeef0ed299fcc604440657..61aaf068c1098bd06ce1e6e9c9433542bfc7e2a7 100644 (file)
@@ -666,7 +666,7 @@ pub fn check_crate(tcx: &ty::ctxt,
         for &(lint, span, ref msg) in v.iter() {
             tcx.sess.span_bug(span,
                               format!("unprocessed lint {} at {}: {}",
-                                      lint.as_str(), tcx.map.node_to_str(*id), *msg).as_slice())
+                                      lint.as_str(), tcx.map.node_to_string(*id), *msg).as_slice())
         }
     }
 
index 9e1d272f5da2e2ec8c4beb3a129dfe2a628b48d3..cdeecf3a080fe2f26fadafe77e2b673d17bb38fe 100644 (file)
@@ -11,7 +11,6 @@
 #![allow(non_camel_case_types)]
 
 use std::mem;
-use syntax::crateid::CrateId;
 use back::svh::Svh;
 
 // EBML enum definitions and utils shared by the encoder and decoder
@@ -71,9 +70,9 @@
 pub static tag_crate_dep: uint = 0x19;
 
 pub static tag_crate_hash: uint = 0x1a;
-pub static tag_crate_crateid: uint = 0x1b;
+pub static tag_crate_crate_name: uint = 0x1b;
 
-pub static tag_crate_dep_crateid: uint = 0x1d;
+pub static tag_crate_dep_crate_name: uint = 0x1d;
 pub static tag_crate_dep_hash: uint = 0x1e;
 
 pub static tag_mod_impl: uint = 0x1f;
@@ -215,7 +214,7 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
 
 #[deriving(Clone, Show)]
 pub struct LinkMeta {
-    pub crateid: CrateId,
+    pub crate_name: String,
     pub crate_hash: Svh,
 }
 
index 218fc31f62356efd2b709ac16d86c2a3f81f4a5e..2314b3f74e3c4e07048f103de06b76c0226f33e5 100644 (file)
@@ -12,7 +12,6 @@
 
 //! Validates all used crates and extern libraries and loads their metadata
 
-use back::link;
 use back::svh::Svh;
 use driver::session::Session;
 use driver::{driver, config};
@@ -33,7 +32,6 @@
 use syntax::diagnostic::SpanHandler;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
-use syntax::crateid::CrateId;
 use syntax::visit;
 
 struct Env<'a> {
@@ -69,7 +67,7 @@ fn visit_item(&mut self, a: &ast::Item, _: ()) {
 fn dump_crates(cstore: &CStore) {
     debug!("resolved crates:");
     cstore.iter_crate_data_origins(|_, data, opt_source| {
-        debug!("crate_id: {}", data.crate_id());
+        debug!("  name: {}", data.name());
         debug!("  cnum: {}", data.cnum);
         debug!("  hash: {}", data.hash());
         opt_source.map(|cs| {
@@ -83,20 +81,17 @@ fn dump_crates(cstore: &CStore) {
 fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
     let mut map = HashMap::new();
     cstore.iter_crate_data(|cnum, data| {
-        let crateid = data.crate_id();
-        let key = (crateid.name.clone(), crateid.path.clone());
-        map.find_or_insert_with(key, |_| Vec::new()).push(cnum);
+        map.find_or_insert_with(data.name(), |_| Vec::new()).push(cnum);
     });
 
-    for ((name, _), dupes) in map.move_iter() {
+    for (name, dupes) in map.move_iter() {
         if dupes.len() == 1 { continue }
         diag.handler().warn(
-            format!("using multiple versions of crate `{}`",
-                    name).as_slice());
+            format!("using multiple versions of crate `{}`", name).as_slice());
         for dupe in dupes.move_iter() {
             let data = cstore.get_crate_data(dupe);
             diag.span_note(data.span, "used here");
-            loader::note_crateid_attr(diag, &data.crate_id());
+            loader::note_crate_name(diag, data.name().as_slice());
         }
     }
 }
@@ -129,7 +124,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
             let (cnum, _, _) = resolve_crate(e,
                                              &None,
                                              info.ident.as_slice(),
-                                             &info.crate_id,
+                                             info.name.as_slice(),
                                              None,
                                              i.span);
             e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
@@ -140,7 +135,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
 
 struct CrateInfo {
     ident: String,
-    crate_id: CrateId,
+    name: String,
     id: ast::NodeId,
     should_link: bool,
 }
@@ -151,22 +146,18 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
             let ident = token::get_ident(ident);
             debug!("resolving extern crate stmt. ident: {:?} path_opt: {:?}",
                    ident, path_opt);
-            let crate_id = match *path_opt {
+            let name = match *path_opt {
                 Some((ref path_str, _)) => {
-                    let crateid: Option<CrateId> = from_str(path_str.get());
-                    match crateid {
-                        None => {
-                            e.sess.span_err(i.span, "malformed crate id");
-                            return None
-                        }
-                        Some(id) => id
-                    }
+                    let name = path_str.get().to_string();
+                    validate_crate_name(Some(e.sess), name.as_slice(),
+                                        Some(i.span));
+                    name
                 }
-                None => from_str(ident.get().to_str().as_slice()).unwrap()
+                None => ident.get().to_string(),
             };
             Some(CrateInfo {
                 ident: ident.get().to_string(),
-                crate_id: crate_id,
+                name: name,
                 id: id,
                 should_link: should_link(i),
             })
@@ -175,6 +166,28 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
     }
 }
 
+pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
+    let err = |s: &str| {
+        match (sp, sess) {
+            (_, None) => fail!("{}", s),
+            (Some(sp), Some(sess)) => sess.span_err(sp, s),
+            (None, Some(sess)) => sess.err(s),
+        }
+    };
+    if s.len() == 0 {
+        err("crate name must not be empty");
+    }
+    for c in s.chars() {
+        if c.is_alphanumeric() { continue }
+        if c == '_' || c == '-' { continue }
+        err(format!("invalid character `{}` in crate name: `{}`", c, s).as_slice());
+    }
+    match sess {
+        Some(sess) => sess.abort_if_errors(),
+        None => {}
+    }
+}
+
 fn visit_item(e: &Env, i: &ast::Item) {
     match i.node {
         ast::ItemForeignMod(ref fm) => {
@@ -263,17 +276,36 @@ fn visit_item(e: &Env, i: &ast::Item) {
     }
 }
 
-fn existing_match(e: &Env, crate_id: &CrateId,
+fn existing_match(e: &Env, name: &str,
                   hash: Option<&Svh>) -> Option<ast::CrateNum> {
     let mut ret = None;
     e.sess.cstore.iter_crate_data(|cnum, data| {
-        let other_id = data.crate_id();
-        if crate_id.matches(&other_id) {
-            let other_hash = data.hash();
-            match hash {
-                Some(hash) if *hash != other_hash => {}
-                Some(..) | None => { ret = Some(cnum); }
+        if data.name().as_slice() != name { return }
+
+        match hash {
+            Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }
+            Some(..) => return,
+            None => {}
+        }
+
+        // When the hash is None we're dealing with a top-level dependency in
+        // which case we may have a specification on the command line for this
+        // library. Even though an upstream library may have loaded something of
+        // the same name, we have to make sure it was loaded from the exact same
+        // location as well.
+        let source = e.sess.cstore.get_used_crate_source(cnum).unwrap();
+        let dylib = source.dylib.as_ref().map(|p| p.as_vec());
+        let rlib = source.rlib.as_ref().map(|p| p.as_vec());
+        match e.sess.opts.externs.find_equiv(&name) {
+            Some(locs) => {
+                let found = locs.iter().any(|l| {
+                    Some(l.as_bytes()) == dylib || Some(l.as_bytes()) == rlib
+                });
+                if found {
+                    ret = Some(cnum);
+                }
             }
+            None => ret = Some(cnum),
         }
     });
     return ret;
@@ -282,7 +314,7 @@ fn existing_match(e: &Env, crate_id: &CrateId,
 fn register_crate<'a>(e: &mut Env,
                   root: &Option<CratePaths>,
                   ident: &str,
-                  crate_id: &CrateId,
+                  name: &str,
                   span: Span,
                   lib: loader::Library)
                         -> (ast::CrateNum, Rc<cstore::crate_metadata>,
@@ -309,7 +341,7 @@ fn register_crate<'a>(e: &mut Env,
     let loader::Library{ dylib, rlib, metadata } = lib;
 
     let cmeta = Rc::new( cstore::crate_metadata {
-        name: crate_id.name.to_string(),
+        name: name.to_string(),
         data: metadata,
         cnum_map: cnum_map,
         cnum: cnum,
@@ -330,20 +362,18 @@ fn register_crate<'a>(e: &mut Env,
 fn resolve_crate<'a>(e: &mut Env,
                  root: &Option<CratePaths>,
                  ident: &str,
-                 crate_id: &CrateId,
+                 name: &str,
                  hash: Option<&Svh>,
                  span: Span)
                      -> (ast::CrateNum, Rc<cstore::crate_metadata>,
                          cstore::CrateSource) {
-    match existing_match(e, crate_id, hash) {
+    match existing_match(e, name, hash) {
         None => {
-            let id_hash = link::crate_id_hash(crate_id);
             let mut load_ctxt = loader::Context {
                 sess: e.sess,
                 span: span,
                 ident: ident,
-                crate_id: crate_id,
-                id_hash: id_hash.as_slice(),
+                crate_name: name,
                 hash: hash.map(|a| &*a),
                 filesearch: e.sess.target_filesearch(),
                 os: e.sess.targ_cfg.os,
@@ -351,9 +381,10 @@ fn resolve_crate<'a>(e: &mut Env,
                 root: root,
                 rejected_via_hash: vec!(),
                 rejected_via_triple: vec!(),
+                should_match_name: true,
             };
             let library = load_ctxt.load_library_crate();
-            register_crate(e, root, ident, crate_id, span, library)
+            register_crate(e, root, ident, name, span, library)
         }
         Some(cnum) => (cnum,
                        e.sess.cstore.get_crate_data(cnum),
@@ -370,10 +401,10 @@ fn resolve_crate_deps(e: &mut Env,
     // The map from crate numbers in the crate we're resolving to local crate
     // numbers
     decoder::get_crate_deps(cdata).iter().map(|dep| {
-        debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
+        debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
         let (local_cnum, _, _) = resolve_crate(e, root,
-                                               dep.crate_id.name.as_slice(),
-                                               &dep.crate_id,
+                                               dep.name.as_slice(),
+                                               dep.name.as_slice(),
                                                Some(&dep.hash),
                                                span);
         (dep.cnum, local_cnum)
@@ -399,14 +430,12 @@ pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata
         let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
         let is_cross = target_triple != driver::host_triple();
         let mut should_link = info.should_link && !is_cross;
-        let id_hash = link::crate_id_hash(&info.crate_id);
         let os = config::get_os(driver::host_triple()).unwrap();
         let mut load_ctxt = loader::Context {
             sess: self.env.sess,
             span: krate.span,
             ident: info.ident.as_slice(),
-            crate_id: &info.crate_id,
-            id_hash: id_hash.as_slice(),
+            crate_name: info.name.as_slice(),
             hash: None,
             filesearch: self.env.sess.host_filesearch(),
             triple: driver::host_triple(),
@@ -414,9 +443,10 @@ pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata
             root: &None,
             rejected_via_hash: vec!(),
             rejected_via_triple: vec!(),
+            should_match_name: true,
         };
         let library = match load_ctxt.maybe_load_library_crate() {
-            Some (l) => l,
+            Some(l) => l,
             None if is_cross => {
                 // try loading from target crates (only valid if there are
                 // no syntax extensions)
@@ -443,15 +473,24 @@ pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata
         let registrar = decoder::get_plugin_registrar_fn(library.metadata.as_slice()).map(|id| {
             decoder::get_symbol(library.metadata.as_slice(), id)
         });
+        if library.dylib.is_none() && registrar.is_some() {
+            let message = format!("plugin crate `{}` only found in rlib format, \
+                                   but must be available in dylib format",
+                                  info.ident);
+            self.env.sess.span_err(krate.span, message.as_slice());
+            // No need to abort because the loading code will just ignore this
+            // empty dylib.
+        }
         let pc = PluginMetadata {
             lib: library.dylib.clone(),
             macros: macros,
             registrar_symbol: registrar,
         };
-        if should_link && existing_match(&self.env, &info.crate_id, None).is_none() {
+        if should_link && existing_match(&self.env, info.name.as_slice(),
+                                         None).is_none() {
             // register crate now to avoid double-reading metadata
             register_crate(&mut self.env, &None, info.ident.as_slice(),
-                           &info.crate_id, krate.span, library);
+                           info.name.as_slice(), krate.span, library);
         }
         pc
     }
index 846f879104f64f7ba559e62815d7b025d65b024e..5dafb7a661dfd0c7755ca8281400aafa8cddcff4 100644 (file)
@@ -22,7 +22,6 @@
 use std::rc::Rc;
 use std::collections::HashMap;
 use syntax::ast;
-use syntax::crateid::CrateId;
 use syntax::codemap::Span;
 use syntax::parse::token::IdentInterner;
 
@@ -197,7 +196,7 @@ pub fn get_used_libraries<'a>(&'a self)
     }
 
     pub fn add_used_link_args(&self, args: &str) {
-        for s in args.split(' ') {
+        for s in args.split(' ').filter(|s| !s.is_empty()) {
             self.used_link_args.borrow_mut().push(s.to_string());
         }
     }
@@ -220,7 +219,7 @@ pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
 
 impl crate_metadata {
     pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
-    pub fn crate_id(&self) -> CrateId { decoder::get_crate_id(self.data()) }
+    pub fn name(&self) -> String { decoder::get_crate_name(self.data()) }
     pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
 }
 
index 78a29b52bdf5bc45974f05b5adf5bfe4ffc7d88b..cc41223688ee0b9eab8f8ff7f3c6caaff54d262d 100644 (file)
@@ -46,7 +46,6 @@
 use syntax::print::pprust;
 use syntax::ast;
 use syntax::codemap;
-use syntax::crateid::CrateId;
 
 pub type Cmd<'a> = &'a crate_metadata;
 
@@ -165,19 +164,6 @@ fn item_visibility(item: ebml::Doc) -> ast::Visibility {
     }
 }
 
-fn item_sized(item: ebml::Doc) -> ast::Sized {
-    match reader::maybe_get_doc(item, tag_items_data_item_sized) {
-        None => ast::StaticSize,
-        Some(sized_doc) => {
-            match reader::doc_as_u8(sized_doc) as char {
-                'd' => ast::DynSize,
-                's' => ast::StaticSize,
-                _ => fail!("unknown sized-ness character")
-            }
-        }
-    }
-}
-
 fn item_method_sort(item: ebml::Doc) -> char {
     let mut ret = 'r';
     reader::tagged_docs(item, tag_item_trait_method_sort, |doc| {
@@ -337,7 +323,7 @@ fn item_name(intr: &IdentInterner, item: ebml::Doc) -> ast::Ident {
     let string = name.as_str_slice();
     match intr.find_equiv(&string) {
         None => token::str_to_ident(string),
-        Some(val) => ast::Ident::new(val as ast::Name),
+        Some(val) => ast::Ident::new(val),
     }
 }
 
@@ -394,7 +380,6 @@ pub fn get_trait_def(cdata: Cmd,
     let tp_defs = item_ty_param_defs(item_doc, tcx, cdata,
                                      tag_items_data_item_ty_param_bounds);
     let rp_defs = item_region_param_defs(item_doc, cdata);
-    let sized = item_sized(item_doc);
     let mut bounds = ty::empty_builtin_bounds();
     // Collect the builtin bounds from the encoded supertraits.
     // FIXME(#8559): They should be encoded directly.
@@ -406,12 +391,6 @@ pub fn get_trait_def(cdata: Cmd,
         });
         true
     });
-    // Turn sized into a bound, FIXME(#8559).
-    if sized == ast::StaticSize {
-        tcx.lang_items.to_builtin_kind(tcx.lang_items.sized_trait().unwrap()).map(|bound| {
-            bounds.add(bound);
-        });
-    }
 
     ty::TraitDef {
         generics: ty::Generics {types: tp_defs,
@@ -760,10 +739,11 @@ fn get_mutability(ch: u8) -> ast::Mutability {
     let explicit_self_kind = string.as_bytes()[0];
     match explicit_self_kind as char {
         's' => ast::SelfStatic,
-        'v' => ast::SelfValue,
-        '~' => ast::SelfUniq,
+        'v' => ast::SelfValue(special_idents::self_),
+        '~' => ast::SelfUniq(special_idents::self_),
         // FIXME(#4846) expl. region
-        '&' => ast::SelfRegion(None, get_mutability(string.as_bytes()[1])),
+        '&' => ast::SelfRegion(None, get_mutability(string.as_bytes()[1]),
+                               special_idents::self_),
         _ => fail!("unknown self type code: `{}`", explicit_self_kind as char)
     }
 }
@@ -1088,7 +1068,7 @@ fn list_crate_attributes(md: ebml::Doc, hash: &Svh,
 
     let r = get_attributes(md);
     for attr in r.iter() {
-        try!(write!(out, "{}\n", pprust::attribute_to_str(attr)));
+        try!(write!(out, "{}\n", pprust::attribute_to_string(attr)));
     }
 
     write!(out, "\n\n")
@@ -1101,7 +1081,7 @@ pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
 #[deriving(Clone)]
 pub struct CrateDep {
     pub cnum: ast::CrateNum,
-    pub crate_id: CrateId,
+    pub name: String,
     pub hash: Svh,
 }
 
@@ -1115,13 +1095,11 @@ fn docstr(doc: ebml::Doc, tag_: uint) -> String {
         d.as_str_slice().to_string()
     }
     reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
-        let crate_id =
-            from_str(docstr(depdoc,
-                            tag_crate_dep_crateid).as_slice()).unwrap();
+        let name = docstr(depdoc, tag_crate_dep_crate_name);
         let hash = Svh::new(docstr(depdoc, tag_crate_dep_hash).as_slice());
         deps.push(CrateDep {
             cnum: crate_num,
-            crate_id: crate_id,
+            name: name,
             hash: hash,
         });
         crate_num += 1;
@@ -1133,7 +1111,7 @@ fn docstr(doc: ebml::Doc, tag_: uint) -> String {
 fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
     try!(write!(out, "=External Dependencies=\n"));
     for dep in get_crate_deps(data).iter() {
-        try!(write!(out, "{} {}-{}\n", dep.cnum, dep.crate_id, dep.hash));
+        try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
     }
     try!(write!(out, "\n"));
     Ok(())
@@ -1152,23 +1130,21 @@ pub fn get_crate_hash(data: &[u8]) -> Svh {
     Svh::new(hashdoc.as_str_slice())
 }
 
-pub fn maybe_get_crate_id(data: &[u8]) -> Option<CrateId> {
+pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
     let cratedoc = ebml::Doc::new(data);
-    reader::maybe_get_doc(cratedoc, tag_crate_crateid).map(|doc| {
-        from_str(doc.as_str_slice()).unwrap()
+    reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
+        doc.as_str_slice().to_string()
     })
 }
 
-pub fn get_crate_triple(data: &[u8]) -> String {
+pub fn get_crate_triple(data: &[u8]) -> Option<String> {
     let cratedoc = ebml::Doc::new(data);
     let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
-    triple_doc.expect("No triple in crate").as_str().to_string()
+    triple_doc.map(|s| s.as_str().to_string())
 }
 
-pub fn get_crate_id(data: &[u8]) -> CrateId {
-    let cratedoc = ebml::Doc::new(data);
-    let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);
-    from_str(hashdoc.as_str_slice()).unwrap()
+pub fn get_crate_name(data: &[u8]) -> String {
+    maybe_get_crate_name(data).expect("no crate name in crate")
 }
 
 pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
index 6eb7c5a4310e6f9cb61abc55001000ae275839cc..6cb0ab51ca10d074f3e09a39f8131777a9434588 100644 (file)
 use syntax::ast_map;
 use syntax::ast_util::*;
 use syntax::ast_util;
-use syntax::attr::AttrMetaMethods;
 use syntax::attr;
-use syntax::crateid::CrateId;
+use syntax::attr::AttrMetaMethods;
 use syntax::diagnostic::SpanHandler;
-use syntax::parse::token::InternedString;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::visit::Visitor;
@@ -103,7 +101,7 @@ fn encode_impl_type_basename(ebml_w: &mut Encoder, name: Ident) {
 }
 
 pub fn encode_def_id(ebml_w: &mut Encoder, id: DefId) {
-    ebml_w.wr_tagged_str(tag_def_id, def_to_str(id).as_slice());
+    ebml_w.wr_tagged_str(tag_def_id, def_to_string(id).as_slice());
 }
 
 #[deriving(Clone)]
@@ -118,7 +116,7 @@ fn encode_trait_ref(ebml_w: &mut Encoder,
                     tag: uint) {
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
@@ -143,7 +141,7 @@ fn encode_family(ebml_w: &mut Encoder, c: char) {
     ebml_w.end_tag();
 }
 
-pub fn def_to_str(did: DefId) -> String {
+pub fn def_to_string(did: DefId) -> String {
     format!("{}:{}", did.krate, did.node)
 }
 
@@ -153,7 +151,7 @@ fn encode_ty_type_param_defs(ebml_w: &mut Encoder,
                              tag: uint) {
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
@@ -174,7 +172,7 @@ fn encode_region_param_defs(ebml_w: &mut Encoder,
         ebml_w.end_tag();
 
         ebml_w.wr_tagged_str(tag_region_param_def_def_id,
-                             def_to_str(param.def_id).as_slice());
+                             def_to_string(param.def_id).as_slice());
 
         ebml_w.wr_tagged_u64(tag_region_param_def_space,
                              param.space.to_uint() as u64);
@@ -206,7 +204,7 @@ fn encode_bounds_and_type(ebml_w: &mut Encoder,
 
 fn encode_variant_id(ebml_w: &mut Encoder, vid: DefId) {
     ebml_w.start_tag(tag_items_data_item_variant);
-    let s = def_to_str(vid);
+    let s = def_to_string(vid);
     ebml_w.writer.write(s.as_bytes());
     ebml_w.end_tag();
 }
@@ -216,7 +214,7 @@ pub fn write_type(ecx: &EncodeContext,
                   typ: ty::t) {
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
@@ -238,7 +236,7 @@ fn encode_method_fty(ecx: &EncodeContext,
 
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
@@ -268,14 +266,14 @@ fn encode_disr_val(_: &EncodeContext,
                    ebml_w: &mut Encoder,
                    disr_val: ty::Disr) {
     ebml_w.start_tag(tag_disr_val);
-    let s = disr_val.to_str();
+    let s = disr_val.to_string();
     ebml_w.writer.write(s.as_bytes());
     ebml_w.end_tag();
 }
 
 fn encode_parent_item(ebml_w: &mut Encoder, id: DefId) {
     ebml_w.start_tag(tag_items_data_parent_item);
-    let s = def_to_str(id);
+    let s = def_to_string(id);
     ebml_w.writer.write(s.as_bytes());
     ebml_w.end_tag();
 }
@@ -293,7 +291,7 @@ fn encode_struct_fields(ebml_w: &mut Encoder,
         encode_struct_field_family(ebml_w, f.vis);
         encode_def_id(ebml_w, f.id);
         ebml_w.start_tag(tag_item_field_origin);
-        let s = def_to_str(origin);
+        let s = def_to_string(origin);
         ebml_w.writer.write(s.as_bytes());
         ebml_w.end_tag();
         ebml_w.end_tag();
@@ -384,7 +382,7 @@ fn encode_reexported_static_method(ebml_w: &mut Encoder,
             exp.name, token::get_ident(method_ident));
     ebml_w.start_tag(tag_items_data_item_reexport);
     ebml_w.start_tag(tag_items_data_item_reexport_def_id);
-    ebml_w.wr_str(def_to_str(method_def_id).as_slice());
+    ebml_w.wr_str(def_to_string(method_def_id).as_slice());
     ebml_w.end_tag();
     ebml_w.start_tag(tag_items_data_item_reexport_name);
     ebml_w.wr_str(format!("{}::{}",
@@ -531,7 +529,7 @@ fn encode_reexports(ecx: &EncodeContext,
                        id);
                 ebml_w.start_tag(tag_items_data_item_reexport);
                 ebml_w.start_tag(tag_items_data_item_reexport_def_id);
-                ebml_w.wr_str(def_to_str(exp.def_id).as_slice());
+                ebml_w.wr_str(def_to_string(exp.def_id).as_slice());
                 ebml_w.end_tag();
                 ebml_w.start_tag(tag_items_data_item_reexport_name);
                 ebml_w.wr_str(exp.name.as_slice());
@@ -564,12 +562,12 @@ fn encode_info_for_mod(ecx: &EncodeContext,
     // Encode info about all the module children.
     for item in md.items.iter() {
         ebml_w.start_tag(tag_mod_child);
-        ebml_w.wr_str(def_to_str(local_def(item.id)).as_slice());
+        ebml_w.wr_str(def_to_string(local_def(item.id)).as_slice());
         ebml_w.end_tag();
 
         each_auxiliary_node_id(*item, |auxiliary_node_id| {
             ebml_w.start_tag(tag_mod_child);
-            ebml_w.wr_str(def_to_str(local_def(
+            ebml_w.wr_str(def_to_string(local_def(
                         auxiliary_node_id)).as_slice());
             ebml_w.end_tag();
             true
@@ -581,10 +579,10 @@ fn encode_info_for_mod(ecx: &EncodeContext,
                 debug!("(encoding info for module) ... encoding impl {} \
                         ({:?}/{:?})",
                         token::get_ident(ident),
-                        did, ecx.tcx.map.node_to_str(did));
+                        did, ecx.tcx.map.node_to_string(did));
 
                 ebml_w.start_tag(tag_mod_impl);
-                ebml_w.wr_str(def_to_str(local_def(did)).as_slice());
+                ebml_w.wr_str(def_to_string(local_def(did)).as_slice());
                 ebml_w.end_tag();
             }
             _ => {}
@@ -630,10 +628,10 @@ fn encode_explicit_self(ebml_w: &mut Encoder, explicit_self: ast::ExplicitSelf_)
 
     // Encode the base self type.
     match explicit_self {
-        SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); }
-        SelfValue  => { ebml_w.writer.write(&[ 'v' as u8 ]); }
-        SelfUniq   => { ebml_w.writer.write(&[ '~' as u8 ]); }
-        SelfRegion(_, m) => {
+        SelfStatic   => { ebml_w.writer.write(&[ 's' as u8 ]); }
+        SelfValue(_) => { ebml_w.writer.write(&[ 'v' as u8 ]); }
+        SelfUniq(_)  => { ebml_w.writer.write(&[ '~' as u8 ]); }
+        SelfRegion(_, m, _) => {
             // FIXME(#4846) encode custom lifetime
             ebml_w.writer.write(&['&' as u8]);
             encode_mutability(ebml_w, m);
@@ -661,7 +659,7 @@ fn encode_provided_source(ebml_w: &mut Encoder,
                           source_opt: Option<DefId>) {
     for source in source_opt.iter() {
         ebml_w.start_tag(tag_item_method_provided_source);
-        let s = def_to_str(*source);
+        let s = def_to_string(*source);
         ebml_w.writer.write(s.as_bytes());
         ebml_w.end_tag();
     }
@@ -695,6 +693,10 @@ fn encode_info_for_struct(ecx: &EncodeContext,
         encode_name(ebml_w, nm);
         encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
         encode_def_id(ebml_w, local_def(id));
+
+        let stab = stability::lookup(ecx.tcx, field.id);
+        encode_stability(ebml_w, stab);
+
         ebml_w.end_tag();
     }
     index
@@ -797,7 +799,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
         } else {
             encode_symbol(ecx, ebml_w, m.def_id.node);
         }
-        encode_method_argument_names(ebml_w, &*ast_method.decl);
+        encode_method_argument_names(ebml_w, method_fn_decl(&*ast_method));
     }
 
     ebml_w.end_tag();
@@ -883,16 +885,6 @@ fn encode_extension_implementations(ecx: &EncodeContext,
     }
 }
 
-fn encode_sized(ebml_w: &mut Encoder, sized: Sized) {
-    ebml_w.start_tag(tag_items_data_item_sized);
-    let ch = match sized {
-        DynSize => 'd',
-        StaticSize => 's',
-    };
-    ebml_w.wr_str(str::from_char(ch).as_slice());
-    ebml_w.end_tag();
-}
-
 fn encode_stability(ebml_w: &mut Encoder, stab_opt: Option<attr::Stability>) {
     stab_opt.map(|stab| {
         ebml_w.start_tag(tag_items_data_item_stability);
@@ -918,7 +910,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
     }
 
     debug!("encoding info for item at {}",
-           tcx.sess.codemap().span_to_str(item.span));
+           tcx.sess.codemap().span_to_string(item.span));
 
     let def_id = local_def(item.id);
     let stab = stability::lookup(tcx, ast_util::local_def(item.id));
@@ -989,7 +981,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         // Encode all the items in this module.
         for foreign_item in fm.items.iter() {
             ebml_w.start_tag(tag_mod_child);
-            ebml_w.wr_str(def_to_str(local_def(foreign_item.id)).as_slice());
+            ebml_w.wr_str(def_to_string(local_def(foreign_item.id)).as_slice());
             ebml_w.end_tag();
         }
         encode_visibility(ebml_w, vis);
@@ -1113,7 +1105,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         }
         for &method_def_id in methods.iter() {
             ebml_w.start_tag(tag_item_impl_method);
-            let s = def_to_str(method_def_id);
+            let s = def_to_string(method_def_id);
             ebml_w.writer.write(s.as_bytes());
             ebml_w.end_tag();
         }
@@ -1151,7 +1143,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                                    ast_method)
         }
       }
-      ItemTrait(_, sized, ref super_traits, ref ms) => {
+      ItemTrait(_, _, ref super_traits, ref ms) => {
         add_to_index(item, ebml_w, index);
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, def_id);
@@ -1165,9 +1157,6 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
         encode_name(ebml_w, item.ident.name);
         encode_attributes(ebml_w, item.attrs.as_slice());
-        // When we fix the rest of the supertrait nastiness (FIXME(#8559)), we
-        // should no longer need this ugly little hack either.
-        encode_sized(ebml_w, sized);
         encode_visibility(ebml_w, vis);
         encode_stability(ebml_w, stab);
         for &method_def_id in ty::trait_method_def_ids(tcx, def_id).iter() {
@@ -1176,7 +1165,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
             ebml_w.end_tag();
 
             ebml_w.start_tag(tag_mod_child);
-            ebml_w.wr_str(def_to_str(method_def_id).as_slice());
+            ebml_w.wr_str(def_to_string(method_def_id).as_slice());
             ebml_w.end_tag();
         }
         encode_path(ebml_w, path.clone());
@@ -1252,7 +1241,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                     encode_method_sort(ebml_w, 'p');
                     encode_inlined_item(ecx, ebml_w,
                                         IIMethodRef(def_id, true, &*m));
-                    encode_method_argument_names(ebml_w, &*m.decl);
+                    encode_method_argument_names(ebml_w, method_fn_decl(m));
                 }
             }
 
@@ -1329,7 +1318,7 @@ fn my_visit_foreign_item(ni: &ForeignItem,
     // See above
     let ecx: &EncodeContext = unsafe { mem::transmute(ecx_ptr) };
     debug!("writing foreign item {}::{}",
-            ecx.tcx.map.path_to_str(ni.id),
+            ecx.tcx.map.path_to_string(ni.id),
             token::get_ident(ni.ident));
 
     let mut ebml_w = unsafe {
@@ -1494,35 +1483,6 @@ fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
     ebml_w.end_tag();
 }
 
-// So there's a special crate attribute called 'crate_id' which defines the
-// metadata that Rust cares about for linking crates. If the user didn't
-// provide it we will throw it in anyway with a default value.
-fn synthesize_crate_attrs(ecx: &EncodeContext,
-                          krate: &Crate) -> Vec<Attribute> {
-
-    fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
-        assert!(!ecx.link_meta.crateid.name.is_empty());
-
-        attr::mk_attr_inner(attr::mk_attr_id(),
-            attr::mk_name_value_item_str(
-                InternedString::new("crate_id"),
-                token::intern_and_get_ident(ecx.link_meta
-                                               .crateid
-                                               .to_str()
-                                               .as_slice())))
-    }
-
-    let mut attrs = Vec::new();
-    for attr in krate.attrs.iter() {
-        if !attr.check_name("crate_id") {
-            attrs.push(*attr);
-        }
-    }
-    attrs.push(synthesize_crateid_attr(ecx));
-
-    attrs
-}
-
 fn encode_crate_deps(ebml_w: &mut Encoder, cstore: &cstore::CStore) {
     fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
         // Pull the cnums and name,vers,hash out of cstore
@@ -1530,8 +1490,8 @@ fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
         cstore.iter_crate_data(|key, val| {
             let dep = decoder::CrateDep {
                 cnum: key,
-                crate_id: decoder::get_crate_id(val.data()),
-                hash: decoder::get_crate_hash(val.data())
+                name: decoder::get_crate_name(val.data()),
+                hash: decoder::get_crate_hash(val.data()),
             };
             deps.push(dep);
         });
@@ -1628,37 +1588,25 @@ fn encode_plugin_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
     }
 }
 
-struct MacroDefVisitor<'a, 'b, 'c> {
-    ecx: &'a EncodeContext<'b>,
-    ebml_w: &'a mut Encoder<'c>
-}
-
-impl<'a, 'b, 'c> Visitor<()> for MacroDefVisitor<'a, 'b, 'c> {
-    fn visit_item(&mut self, item: &Item, _: ()) {
-        match item.node {
-            ItemMac(..) => {
-                let def = self.ecx.tcx.sess.codemap().span_to_snippet(item.span)
-                    .expect("Unable to find source for macro");
-                self.ebml_w.start_tag(tag_macro_def);
-                self.ebml_w.wr_str(def.as_slice());
-                self.ebml_w.end_tag();
-            }
-            _ => {}
-        }
-        visit::walk_item(self, item, ());
-    }
+/// Given a span, write the text of that span into the output stream
+/// as an exported macro
+fn encode_macro_def(ecx: &EncodeContext,
+                    ebml_w: &mut Encoder,
+                    span: &syntax::codemap::Span) {
+    let def = ecx.tcx.sess.codemap().span_to_snippet(*span)
+        .expect("Unable to find source for macro");
+    ebml_w.start_tag(tag_macro_def);
+    ebml_w.wr_str(def.as_slice());
+    ebml_w.end_tag();
 }
 
-fn encode_macro_defs<'a>(ecx: &'a EncodeContext,
-                         krate: &Crate,
-                         ebml_w: &'a mut Encoder) {
+/// Serialize the text of the exported macros
+fn encode_macro_defs(ecx: &EncodeContext,
+                     krate: &Crate,
+                     ebml_w: &mut Encoder) {
     ebml_w.start_tag(tag_exported_macros);
-    {
-        let mut visitor = MacroDefVisitor {
-            ecx: ecx,
-            ebml_w: ebml_w,
-        };
-        visit::walk_crate(&mut visitor, krate, ());
+    for span in krate.exported_macros.iter() {
+        encode_macro_def(ecx, ebml_w, span);
     }
     ebml_w.end_tag();
 }
@@ -1724,12 +1672,12 @@ fn encode_misc_info(ecx: &EncodeContext,
     ebml_w.start_tag(tag_misc_info_crate_items);
     for &item in krate.module.items.iter() {
         ebml_w.start_tag(tag_mod_child);
-        ebml_w.wr_str(def_to_str(local_def(item.id)).as_slice());
+        ebml_w.wr_str(def_to_string(local_def(item.id)).as_slice());
         ebml_w.end_tag();
 
         each_auxiliary_node_id(item, |auxiliary_node_id| {
             ebml_w.start_tag(tag_mod_child);
-            ebml_w.wr_str(def_to_str(local_def(
+            ebml_w.wr_str(def_to_string(local_def(
                         auxiliary_node_id)).as_slice());
             ebml_w.end_tag();
             true
@@ -1766,8 +1714,8 @@ fn encode_reachable_extern_fns(ecx: &EncodeContext, ebml_w: &mut Encoder) {
 fn encode_crate_dep(ebml_w: &mut Encoder,
                     dep: decoder::CrateDep) {
     ebml_w.start_tag(tag_crate_dep);
-    ebml_w.start_tag(tag_crate_dep_crateid);
-    ebml_w.writer.write(dep.crate_id.to_str().as_bytes());
+    ebml_w.start_tag(tag_crate_dep_crate_name);
+    ebml_w.writer.write(dep.name.as_bytes());
     ebml_w.end_tag();
     ebml_w.start_tag(tag_crate_dep_hash);
     ebml_w.writer.write(dep.hash.as_str().as_bytes());
@@ -1781,9 +1729,9 @@ fn encode_hash(ebml_w: &mut Encoder, hash: &Svh) {
     ebml_w.end_tag();
 }
 
-fn encode_crate_id(ebml_w: &mut Encoder, crate_id: &CrateId) {
-    ebml_w.start_tag(tag_crate_crateid);
-    ebml_w.writer.write(crate_id.to_str().as_bytes());
+fn encode_crate_name(ebml_w: &mut Encoder, crate_name: &str) {
+    ebml_w.start_tag(tag_crate_crate_name);
+    ebml_w.writer.write(crate_name.as_bytes());
     ebml_w.end_tag();
 }
 
@@ -1880,7 +1828,7 @@ struct Stats {
 
     let mut ebml_w = writer::Encoder::new(wr);
 
-    encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid);
+    encode_crate_name(&mut ebml_w, ecx.link_meta.crate_name.as_slice());
     encode_crate_triple(&mut ebml_w,
                         tcx.sess
                            .targ_cfg
@@ -1891,8 +1839,7 @@ struct Stats {
     encode_dylib_dependency_formats(&mut ebml_w, &ecx);
 
     let mut i = ebml_w.writer.tell().unwrap();
-    let crate_attrs = synthesize_crate_attrs(&ecx, krate);
-    encode_attributes(&mut ebml_w, crate_attrs.as_slice());
+    encode_attributes(&mut ebml_w, krate.attrs.as_slice());
     stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;
 
     i = ebml_w.writer.tell().unwrap();
@@ -1971,7 +1918,7 @@ pub fn encoded_ty(tcx: &ty::ctxt, t: ty::t) -> String {
     let mut wr = MemWriter::new();
     tyencode::enc_ty(&mut wr, &tyencode::ctxt {
         diag: tcx.sess.diagnostic(),
-        ds: def_to_str,
+        ds: def_to_string,
         tcx: tcx,
         abbrevs: &RefCell::new(HashMap::new())
     }, t);
index ccab76ca6f012d641250ceaa8f369e953a793ff1..e7d52ef3b3d6cb1b54cb124e8207bfe39ba47802 100644 (file)
 // except according to those terms.
 
 //! Finds crate binaries and loads their metadata
-
-use back::archive::{ArchiveRO, METADATA_FILENAME};
+//!
+//! Might I be the first to welcome you to a world of platform differences,
+//! version requirements, dependency graphs, conficting desires, and fun! This
+//! is the major guts (along with metadata::creader) of the compiler for loading
+//! crates and resolving dependencies. Let's take a tour!
+//!
+//! # The problem
+//!
+//! Each invocation of the compiler is immediately concerned with one primary
+//! problem, to connect a set of crates to resolved crates on the filesystem.
+//! Concretely speaking, the compiler follows roughly these steps to get here:
+//!
+//! 1. Discover a set of `extern crate` statements.
+//! 2. Transform these directives into crate names. If the directive does not
+//!    have an explicit name, then the identifier is the name.
+//! 3. For each of these crate names, find a corresponding crate on the
+//!    filesystem.
+//!
+//! Sounds easy, right? Let's walk into some of the nuances.
+//!
+//! ## Transitive Dependencies
+//!
+//! Let's say we've got three crates: A, B, and C. A depends on B, and B depends
+//! on C. When we're compiling A, we primarily need to find and locate B, but we
+//! also end up needing to find and locate C as well.
+//!
+//! The reason for this is that any of B's types could be composed of C's types,
+//! any function in B could return a type from C, etc. To be able to guarantee
+//! that we can always typecheck/translate any function, we have to have
+//! complete knowledge of the whole ecosystem, not just our immediate
+//! dependencies.
+//!
+//! So now as part of the "find a corresponding crate on the filesystem" step
+//! above, this involves also finding all crates for *all upstream
+//! dependencies*. This includes all dependencies transitively.
+//!
+//! ## Rlibs and Dylibs
+//!
+//! The compiler has two forms of intermediate dependencies. These are dubbed
+//! rlibs and dylibs for the static and dynamic variants, respectively. An rlib
+//! is a rustc-defined file format (currently just an ar archive) while a dylib
+//! is a platform-defined dynamic library. Each library has a metadata somewhere
+//! inside of it.
+//!
+//! When translating a crate name to a crate on the filesystem, we all of a
+//! sudden need to take into account both rlibs and dylibs! Linkage later on may
+//! use either one of these files, as each has their pros/cons. The job of crate
+//! loading is to discover what's possible by finding all candidates.
+//!
+//! Most parts of this loading systems keep the dylib/rlib as just separate
+//! variables.
+//!
+//! ## Where to look?
+//!
+//! We can't exactly scan your whole hard drive when looking for dependencies,
+//! so we need to places to look. Currently the compiler will implicitly add the
+//! target lib search path ($prefix/lib/rustlib/$target/lib) to any compilation,
+//! and otherwise all -L flags are added to the search paths.
+//!
+//! ## What criterion to select on?
+//!
+//! This a pretty tricky area of loading crates. Given a file, how do we know
+//! whether it's the right crate? Currently, the rules look along these lines:
+//!
+//! 1. Does the filename match an rlib/dylib pattern? That is to say, does the
+//!    filename have the right prefix/suffix?
+//! 2. Does the filename have the right prefix for the crate name being queried?
+//!    This is filtering for files like `libfoo*.rlib` and such.
+//! 3. Is the file an actual rust library? This is done by loading the metadata
+//!    from the library and making sure it's actually there.
+//! 4. Does the name in the metadata agree with the name of the library?
+//! 5. Does the target in the metadata agree with the current target?
+//! 6. Does the SVH match? (more on this later)
+//!
+//! If the file answeres `yes` to all these questions, then the file is
+//! considered as being *candidate* for being accepted. It is illegal to have
+//! more than two candidates as the compiler has no method by which to resolve
+//! this conflict. Additionally, rlib/dylib candidates are considered
+//! separately.
+//!
+//! After all this has happened, we have 1 or two files as candidates. These
+//! represent the rlib/dylib file found for a library, and they're returned as
+//! being found.
+//!
+//! ### What about versions?
+//!
+//! A lot of effort has been put forth to remove versioning from the compiler.
+//! There have been forays in the past to have versioning baked in, but it was
+//! largely always deemed insufficient to the point that it was recognized that
+//! it's probably something the compiler shouldn't do anyway due to its
+//! complicated nature and the state of the half-baked solutions.
+//!
+//! With a departure from versioning, the primary criterion for loading crates
+//! is just the name of a crate. If we stopped here, it would imply that you
+//! could never link two crates of the same name from different sources
+//! together, which is clearly a bad state to be in.
+//!
+//! To resolve this problem, we come to the next section!
+//!
+//! # Expert Mode
+//!
+//! A number of flags have been added to the compiler to solve the "version
+//! problem" in the previous section, as well as generally enabling more
+//! powerful usage of the crate loading system of the compiler. The goal of
+//! these flags and options are to enable third-party tools to drive the
+//! compiler with prior knowledge about how the world should look.
+//!
+//! ## The `--extern` flag
+//!
+//! The compiler accepts a flag of this form a number of times:
+//!
+//! ```notrust
+//! --extern crate-name=path/to/the/crate.rlib
+//! ```
+//!
+//! This flag is basically the following letter to the compiler:
+//!
+//! > Dear rustc,
+//! >
+//! > When you are attempting to load the immediate dependency `crate-name`, I
+//! > would like you too assume that the library is located at
+//! > `path/to/the/crate.rlib`, and look nowhere else. Also, please do not
+//! > assume that the path I specified has the name `crate-name`.
+//!
+//! This flag basically overrides most matching logic except for validating that
+//! the file is indeed a rust library. The same `crate-name` can be specified
+//! twice to specify the rlib/dylib pair.
+//!
+//! ## Enabling "multiple versions"
+//!
+//! This basically boils down to the ability to specify arbitrary packages to
+//! the compiler. For example, if crate A wanted to use Bv1 and Bv2, then it
+//! would look something like:
+//!
+//! ```ignore
+//! extern crate b1;
+//! extern crate b2;
+//!
+//! fn main() {}
+//! ```
+//!
+//! and the compiler would be invoked as:
+//!
+//! ```notrust
+//! rustc a.rs --extern b1=path/to/libb1.rlib --extern b2=path/to/libb2.rlib
+//! ```
+//!
+//! In this scenario there are two crates named `b` and the compiler must be
+//! manually driven to be informed where each crate is.
+//!
+//! ## Frobbing symbols
+//!
+//! One of the immediate problems with linking the same library together twice
+//! in the same problem is dealing with duplicate symbols. The primary way to
+//! deal with this in rustc is to add hashes to the end of each symbol.
+//!
+//! In order to force hashes to change between versions of a library, if
+//! desired, the compiler exposes an option `-C metadata=foo`, which is used to
+//! initially seed each symbol hash. The string `foo` is prepended to each
+//! string-to-hash to ensure that symbols change over time.
+//!
+//! ## Loading transitive dependencies
+//!
+//! Dealing with same-named-but-distinct crates is not just a local problem, but
+//! one that also needs to be dealt with for transitive dependences. Note that
+//! in the letter above `--extern` flags only apply to the *local* set of
+//! dependencies, not the upstream transitive dependencies. Consider this
+//! dependency graph:
+//!
+//! ```notrust
+//! A.1   A.2
+//! |     |
+//! |     |
+//! B     C
+//!  \   /
+//!   \ /
+//!    D
+//! ```
+//!
+//! In this scenario, when we compile `D`, we need to be able to distinctly
+//! resolve `A.1` and `A.2`, but an `--extern` flag cannot apply to these
+//! transitive dependencies.
+//!
+//! Note that the key idea here is that `B` and `C` are both *already compiled*.
+//! That is, they have already resolved their dependencies. Due to unrelated
+//! technical reasons, when a library is compiled, it is only compatible with
+//! the *exact same* version of the upstream libraries it was compiled against.
+//! We use the "Strict Version Hash" to identify the exact copy of an upstream
+//! library.
+//!
+//! With this knowledge, we know that `B` and `C` will depend on `A` with
+//! different SVH values, so we crawl the normal `-L` paths looking for
+//! `liba*.rlib` and filter based on the contained SVH.
+//!
+//! In the end, this ends up not needing `--extern` to specify upstream
+//! transitive dependencies.
+//!
+//! # Wrapping up
+//!
+//! That's the general overview of loading crates in the compiler, but it's by
+//! no means all of the necessary details. Take a look at the rest of
+//! metadata::loader or metadata::creader for all the juicy details!
+
+use back::archive::{METADATA_FILENAME};
 use back::svh::Svh;
 use driver::session::Session;
-use lib::llvm::{False, llvm, ObjectFile, mk_section_iter};
+use llvm;
+use llvm::{False, ObjectFile, mk_section_iter};
+use llvm::archive_ro::ArchiveRO;
 use metadata::cstore::{MetadataBlob, MetadataVec, MetadataArchive};
 use metadata::decoder;
 use metadata::encoder;
 use syntax::abi;
 use syntax::codemap::Span;
 use syntax::diagnostic::SpanHandler;
-use syntax::crateid::CrateId;
-use syntax::attr::AttrMetaMethods;
 use util::fs;
 
 use std::c_str::ToCStr;
@@ -61,8 +263,7 @@ pub struct Context<'a> {
     pub sess: &'a Session,
     pub span: Span,
     pub ident: &'a str,
-    pub crate_id: &'a CrateId,
-    pub id_hash: &'a str,
+    pub crate_name: &'a str,
     pub hash: Option<&'a Svh>,
     pub triple: &'a str,
     pub os: abi::Os,
@@ -70,6 +271,7 @@ pub struct Context<'a> {
     pub root: &'a Option<CratePaths>,
     pub rejected_via_hash: Vec<CrateMismatch>,
     pub rejected_via_triple: Vec<CrateMismatch>,
+    pub should_match_name: bool,
 }
 
 pub struct Library {
@@ -167,19 +369,30 @@ pub fn report_load_errs(&mut self) {
     }
 
     fn find_library_crate(&mut self) -> Option<Library> {
+        // If an SVH is specified, then this is a transitive dependency that
+        // must be loaded via -L plus some filtering.
+        if self.hash.is_none() {
+            self.should_match_name = false;
+            match self.find_commandline_library() {
+                Some(l) => return Some(l),
+                None => {}
+            }
+            self.should_match_name = true;
+        }
+
         let dypair = self.dylibname();
 
         // want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
         let dylib_prefix = dypair.map(|(prefix, _)| {
-            format!("{}{}-", prefix, self.crate_id.name)
+            format!("{}{}", prefix, self.crate_name)
         });
-        let rlib_prefix = format!("lib{}-", self.crate_id.name);
+        let rlib_prefix = format!("lib{}", self.crate_name);
 
         let mut candidates = HashMap::new();
 
         // First, find all possible candidate rlibs and dylibs purely based on
         // the name of the files themselves. We're trying to match against an
-        // exact crate_id and a possibly an exact hash.
+        // exact crate name and a possibly an exact hash.
         //
         // During this step, we can filter all found libraries based on the
         // name and id found in the crate id (we ignore the path portion for
@@ -195,49 +408,32 @@ fn find_library_crate(&mut self) -> Option<Library> {
                 None => return FileDoesntMatch,
                 Some(file) => file,
             };
-            if file.starts_with(rlib_prefix.as_slice()) &&
+            let (hash, rlib) = if file.starts_with(rlib_prefix.as_slice()) &&
                     file.ends_with(".rlib") {
-                info!("rlib candidate: {}", path.display());
-                match self.try_match(file, rlib_prefix.as_slice(), ".rlib") {
-                    Some(hash) => {
-                        info!("rlib accepted, hash: {}", hash);
-                        let slot = candidates.find_or_insert_with(hash, |_| {
-                            (HashSet::new(), HashSet::new())
-                        });
-                        let (ref mut rlibs, _) = *slot;
-                        rlibs.insert(fs::realpath(path).unwrap());
-                        FileMatches
-                    }
-                    None => {
-                        info!("rlib rejected");
-                        FileDoesntMatch
-                    }
-                }
+                (file.slice(rlib_prefix.len(), file.len() - ".rlib".len()),
+                 true)
             } else if dypair.map_or(false, |(_, suffix)| {
                 file.starts_with(dylib_prefix.get_ref().as_slice()) &&
                 file.ends_with(suffix)
             }) {
                 let (_, suffix) = dypair.unwrap();
                 let dylib_prefix = dylib_prefix.get_ref().as_slice();
-                info!("dylib candidate: {}", path.display());
-                match self.try_match(file, dylib_prefix, suffix) {
-                    Some(hash) => {
-                        info!("dylib accepted, hash: {}", hash);
-                        let slot = candidates.find_or_insert_with(hash, |_| {
-                            (HashSet::new(), HashSet::new())
-                        });
-                        let (_, ref mut dylibs) = *slot;
-                        dylibs.insert(fs::realpath(path).unwrap());
-                        FileMatches
-                    }
-                    None => {
-                        info!("dylib rejected");
-                        FileDoesntMatch
-                    }
-                }
+                (file.slice(dylib_prefix.len(), file.len() - suffix.len()),
+                 false)
             } else {
-                FileDoesntMatch
+                return FileDoesntMatch
+            };
+            info!("lib candidate: {}", path.display());
+            let slot = candidates.find_or_insert_with(hash.to_string(), |_| {
+                (HashSet::new(), HashSet::new())
+            });
+            let (ref mut rlibs, ref mut dylibs) = *slot;
+            if rlib {
+                rlibs.insert(fs::realpath(path).unwrap());
+            } else {
+                dylibs.insert(fs::realpath(path).unwrap());
             }
+            FileMatches
         });
 
         // We have now collected all known libraries into a set of candidates
@@ -274,7 +470,7 @@ fn find_library_crate(&mut self) -> Option<Library> {
             _ => {
                 self.sess.span_err(self.span,
                     format!("multiple matching crates for `{}`",
-                            self.crate_id.name).as_slice());
+                            self.crate_name).as_slice());
                 self.sess.note("candidates:");
                 for lib in libraries.iter() {
                     match lib.dylib {
@@ -292,50 +488,14 @@ fn find_library_crate(&mut self) -> Option<Library> {
                         None => {}
                     }
                     let data = lib.metadata.as_slice();
-                    let crate_id = decoder::get_crate_id(data);
-                    note_crateid_attr(self.sess.diagnostic(), &crate_id);
+                    let name = decoder::get_crate_name(data);
+                    note_crate_name(self.sess.diagnostic(), name.as_slice());
                 }
                 None
             }
         }
     }
 
-    // Attempts to match the requested version of a library against the file
-    // specified. The prefix/suffix are specified (disambiguates between
-    // rlib/dylib).
-    //
-    // The return value is `None` if `file` doesn't look like a rust-generated
-    // library, or if a specific version was requested and it doesn't match the
-    // apparent file's version.
-    //
-    // If everything checks out, then `Some(hash)` is returned where `hash` is
-    // the listed hash in the filename itself.
-    fn try_match(&self, file: &str, prefix: &str, suffix: &str) -> Option<String>{
-        let middle = file.slice(prefix.len(), file.len() - suffix.len());
-        debug!("matching -- {}, middle: {}", file, middle);
-        let mut parts = middle.splitn('-', 1);
-        let hash = match parts.next() { Some(h) => h, None => return None };
-        debug!("matching -- {}, hash: {} (want {})", file, hash, self.id_hash);
-        let vers = match parts.next() { Some(v) => v, None => return None };
-        debug!("matching -- {}, vers: {} (want {})", file, vers,
-               self.crate_id.version);
-        match self.crate_id.version {
-            Some(ref version) if version.as_slice() != vers => return None,
-            Some(..) => {} // check the hash
-
-            // hash is irrelevant, no version specified
-            None => return Some(hash.to_string())
-        }
-        debug!("matching -- {}, vers ok", file);
-        // hashes in filenames are prefixes of the "true hash"
-        if self.id_hash == hash.as_slice() {
-            debug!("matching -- {}, hash ok", file);
-            Some(hash.to_string())
-        } else {
-            None
-        }
-    }
-
     // Attempts to extract *one* library from the set `m`. If the set has no
     // elements, `None` is returned. If the set has more than one element, then
     // the errors and notes are emitted about the set of libraries.
@@ -382,7 +542,7 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
                                    format!("multiple {} candidates for `{}` \
                                             found",
                                            flavor,
-                                           self.crate_id.name).as_slice());
+                                           self.crate_name).as_slice());
                 self.sess.span_note(self.span,
                                     format!(r"candidate #1: {}",
                                             ret.get_ref()
@@ -404,9 +564,11 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
     }
 
     fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
-        match decoder::maybe_get_crate_id(crate_data) {
-            Some(ref id) if self.crate_id.matches(id) => {}
-            _ => { info!("Rejecting via crate_id"); return false }
+        if self.should_match_name {
+            match decoder::maybe_get_crate_name(crate_data) {
+                Some(ref name) if self.crate_name == name.as_slice() => {}
+                _ => { info!("Rejecting via crate name"); return false }
+            }
         }
         let hash = match decoder::maybe_get_crate_hash(crate_data) {
             Some(hash) => hash, None => {
@@ -415,7 +577,10 @@ fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
             }
         };
 
-        let triple = decoder::get_crate_triple(crate_data);
+        let triple = match decoder::get_crate_triple(crate_data) {
+            None => { debug!("triple not present"); return false }
+            Some(t) => t,
+        };
         if triple.as_slice() != self.triple {
             info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
             self.rejected_via_triple.push(CrateMismatch {
@@ -456,10 +621,72 @@ fn dylibname(&self) -> Option<(&'static str, &'static str)> {
         }
     }
 
+    fn find_commandline_library(&mut self) -> Option<Library> {
+        let locs = match self.sess.opts.externs.find_equiv(&self.crate_name) {
+            Some(s) => s,
+            None => return None,
+        };
+
+        // First, filter out all libraries that look suspicious. We only accept
+        // files which actually exist that have the correct naming scheme for
+        // rlibs/dylibs.
+        let sess = self.sess;
+        let dylibname = self.dylibname();
+        let mut locs = locs.iter().map(|l| Path::new(l.as_slice())).filter(|loc| {
+            if !loc.exists() {
+                sess.err(format!("extern location does not exist: {}",
+                                 loc.display()).as_slice());
+                return false;
+            }
+            let file = loc.filename_str().unwrap();
+            if file.starts_with("lib") && file.ends_with(".rlib") {
+                return true
+            } else {
+                match dylibname {
+                    Some((prefix, suffix)) => {
+                        if file.starts_with(prefix) && file.ends_with(suffix) {
+                            return true
+                        }
+                    }
+                    None => {}
+                }
+            }
+            sess.err(format!("extern location is of an unknown type: {}",
+                             loc.display()).as_slice());
+            false
+        });
+
+        // Now that we have an itertor of good candidates, make sure there's at
+        // most one rlib and at most one dylib.
+        let mut rlibs = HashSet::new();
+        let mut dylibs = HashSet::new();
+        for loc in locs {
+            if loc.filename_str().unwrap().ends_with(".rlib") {
+                rlibs.insert(loc.clone());
+            } else {
+                dylibs.insert(loc.clone());
+            }
+        }
+
+        // Extract the rlib/dylib pair.
+        let mut metadata = None;
+        let rlib = self.extract_one(rlibs, "rlib", &mut metadata);
+        let dylib = self.extract_one(dylibs, "dylib", &mut metadata);
+
+        if rlib.is_none() && dylib.is_none() { return None }
+        match metadata {
+            Some(metadata) => Some(Library {
+                dylib: dylib,
+                rlib: rlib,
+                metadata: metadata,
+            }),
+            None => None,
+        }
+    }
 }
 
-pub fn note_crateid_attr(diag: &SpanHandler, crateid: &CrateId) {
-    diag.handler().note(format!("crate_id: {}", crateid.to_str()).as_slice());
+pub fn note_crate_name(diag: &SpanHandler, name: &str) {
+    diag.handler().note(format!("crate name: {}", name).as_slice());
 }
 
 impl ArchiveMetadata {
index 1f36c3850cf4b19ddd419b3694c7ee73eba3afe6..b207543398aaa2ec6b18df2ffbb1c74a754f39a1 100644 (file)
@@ -100,7 +100,7 @@ fn enc_vec_per_param_space<T>(w: &mut MemWriter,
                               op: |&mut MemWriter, &ctxt, &T|) {
     for &space in subst::ParamSpace::all().iter() {
         mywrite!(w, "[");
-        for t in v.get_vec(space).iter() {
+        for t in v.get_slice(space).iter() {
             op(w, cx, t);
         }
         mywrite!(w, "]");
index 19e7b9329b1ff218a9f25627766706e19732b98a..d58023a48756f00ebc3f8facec0c9e2536003dd7 100644 (file)
@@ -28,7 +28,7 @@
 use middle::subst::VecPerParamSpace;
 use middle::typeck::{MethodCall, MethodCallee, MethodOrigin};
 use middle::{ty, typeck};
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 use syntax::{ast, ast_map, ast_util, codemap, fold};
 use syntax::codemap::Span;
@@ -86,7 +86,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
         e::IIMethodRef(_, _, m) => m.id,
     };
     debug!("> Encoding inlined item: {} ({})",
-           ecx.tcx.map.path_to_str(id),
+           ecx.tcx.map.path_to_string(id),
            ebml_w.writer.tell());
 
     let ii = simplify_ast(ii);
@@ -99,7 +99,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
     ebml_w.end_tag();
 
     debug!("< Encoded inlined fn: {} ({})",
-           ecx.tcx.map.path_to_str(id),
+           ecx.tcx.map.path_to_string(id),
            ebml_w.writer.tell());
 }
 
@@ -119,7 +119,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
         debug!("> Decoding inlined fn: {}::?",
         {
             // Do an Option dance to use the path after it is moved below.
-            let s = ast_map::path_to_str(ast_map::Values(path.iter()));
+            let s = ast_map::path_to_string(ast_map::Values(path.iter()));
             path_as_str = Some(s);
             path_as_str.as_ref().map(|x| x.as_slice())
         });
@@ -136,7 +136,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
         let ident = match ii {
             ast::IIItem(i) => i.ident,
             ast::IIForeign(i) => i.ident,
-            ast::IIMethod(_, _, m) => m.ident,
+            ast::IIMethod(_, _, m) => ast_util::method_ident(&*m),
         };
         debug!("Fn named: {}", token::get_ident(ident));
         debug!("< Decoded inlined fn: {}::{}",
@@ -147,7 +147,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
         match ii {
           ast::IIItem(i) => {
             debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<",
-                   syntax::print::pprust::item_to_str(&*i));
+                   syntax::print::pprust::item_to_string(&*i));
           }
           _ => { }
         }
@@ -345,7 +345,9 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
         // HACK we're not dropping items.
         e::IIItemRef(i) => ast::IIItem(fold::noop_fold_item(i, &mut fld)
                                        .expect_one("expected one item")),
-        e::IIMethodRef(d, p, m) => ast::IIMethod(d, p, fold::noop_fold_method(m, &mut fld)),
+        e::IIMethodRef(d, p, m) => ast::IIMethod(d, p, fold::noop_fold_method(m, &mut fld)
+                                                 .expect_one(
+                "noop_fold_method must produce exactly one method")),
         e::IIForeignRef(i) => ast::IIForeign(fold::noop_fold_foreign_item(i, &mut fld))
     }
 }
@@ -387,7 +389,8 @@ fn renumber_and_map_ast(xcx: &ExtendedDecodeContext,
                 ast::IIItem(fld.fold_item(i).expect_one("expected one item"))
             }
             ast::IIMethod(d, is_provided, m) => {
-                ast::IIMethod(xcx.tr_def_id(d), is_provided, fld.fold_method(m))
+                ast::IIMethod(xcx.tr_def_id(d), is_provided, fld.fold_method(m)
+                              .expect_one("expected one method"))
             }
             ast::IIForeign(i) => ast::IIForeign(fld.fold_foreign_item(i))
         }
@@ -810,7 +813,7 @@ fn encode_vec_per_param_space<T>(ebml_w: &mut Encoder,
                                  v: &subst::VecPerParamSpace<T>,
                                  f: |&mut Encoder, &T|) {
     for &space in subst::ParamSpace::all().iter() {
-        ebml_w.emit_from_vec(v.get_vec(space).as_slice(),
+        ebml_w.emit_from_vec(v.get_slice(space),
                              |ebml_w, n| Ok(f(ebml_w, n))).unwrap();
     }
 }
@@ -826,7 +829,7 @@ impl<'a> get_ty_str_ctxt for e::EncodeContext<'a> {
     fn ty_str_ctxt<'a>(&'a self) -> tyencode::ctxt<'a> {
         tyencode::ctxt {
             diag: self.tcx.sess.diagnostic(),
-            ds: e::def_to_str,
+            ds: e::def_to_string,
             tcx: self.tcx,
             abbrevs: &self.type_abbrevs
         }
@@ -1391,7 +1394,7 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
                     c::tag_table_node_type => {
                         let ty = val_dsr.read_ty(xcx);
                         debug!("inserting ty for node {:?}: {}",
-                               id, ty_to_str(dcx.tcx, ty));
+                               id, ty_to_string(dcx.tcx, ty));
                         dcx.tcx.node_types.borrow_mut().insert(id as uint, ty);
                     }
                     c::tag_table_item_subst => {
@@ -1523,7 +1526,7 @@ fn test_basic() {
         fn foo() {}
     ));
 }
-
+/* NOTE: When there's a snapshot, update this (yay quasiquoter!)
 #[test]
 fn test_smalltalk() {
     let cx = mk_ctxt();
@@ -1531,6 +1534,7 @@ fn test_smalltalk() {
         fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
     ));
 }
+*/
 
 #[test]
 fn test_more() {
@@ -1561,7 +1565,7 @@ fn new_int_alist<B>() -> alist<int, B> {
     ).unwrap());
     match (item_out, item_exp) {
       (ast::IIItem(item_out), ast::IIItem(item_exp)) => {
-        assert!(pprust::item_to_str(item_out) == pprust::item_to_str(item_exp));
+        assert!(pprust::item_to_string(item_out) == pprust::item_to_string(item_exp));
       }
       _ => fail!()
     }
index df208b9cdc133f85f352a0a3a60dec63e8433968..db8ab8c83fbdc78ae18f20bdb60d96bb08ae431a 100644 (file)
@@ -351,7 +351,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                 "it".to_string()
             } else {
                 format!("`{}`",
-                        self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                        self.bccx.loan_path_to_string(&*old_loan.loan_path))
             };
 
             match (new_loan.kind, old_loan.kind) {
@@ -360,7 +360,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                         new_loan.span,
                         format!("cannot borrow `{}` as mutable \
                                 more than once at a time",
-                                self.bccx.loan_path_to_str(
+                                self.bccx.loan_path_to_string(
                                     &*new_loan.loan_path)).as_slice());
                 }
 
@@ -369,7 +369,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                         new_loan.span,
                         format!("closure requires unique access to `{}` \
                                 but {} is already borrowed",
-                                self.bccx.loan_path_to_str(&*new_loan.loan_path),
+                                self.bccx.loan_path_to_string(&*new_loan.loan_path),
                                 old_pronoun).as_slice());
                 }
 
@@ -378,7 +378,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                         new_loan.span,
                         format!("cannot borrow `{}` as {} because \
                                 previous closure requires unique access",
-                                self.bccx.loan_path_to_str(&*new_loan.loan_path),
+                                self.bccx.loan_path_to_string(&*new_loan.loan_path),
                                 new_loan.kind.to_user_str()).as_slice());
                 }
 
@@ -387,7 +387,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                         new_loan.span,
                         format!("cannot borrow `{}` as {} because \
                                 {} is also borrowed as {}",
-                                self.bccx.loan_path_to_str(&*new_loan.loan_path),
+                                self.bccx.loan_path_to_string(&*new_loan.loan_path),
                                 new_loan.kind.to_user_str(),
                                 old_pronoun,
                                 old_loan.kind.to_user_str()).as_slice());
@@ -399,7 +399,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                     self.bccx.span_note(
                         span,
                         format!("borrow occurs due to use of `{}` in closure",
-                                self.bccx.loan_path_to_str(
+                                self.bccx.loan_path_to_string(
                                     &*new_loan.loan_path)).as_slice());
                 }
                 _ => { }
@@ -410,7 +410,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                     format!("the mutable borrow prevents subsequent \
                             moves, borrows, or modification of `{0}` \
                             until the borrow ends",
-                            self.bccx.loan_path_to_str(
+                            self.bccx.loan_path_to_string(
                                 &*old_loan.loan_path))
                 }
 
@@ -418,14 +418,14 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                     format!("the immutable borrow prevents subsequent \
                             moves or mutable borrows of `{0}` \
                             until the borrow ends",
-                            self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                            self.bccx.loan_path_to_string(&*old_loan.loan_path))
                 }
 
                 ty::UniqueImmBorrow => {
                     format!("the unique capture prevents subsequent \
                             moves or borrows of `{0}` \
                             until the borrow ends",
-                            self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                            self.bccx.loan_path_to_string(&*old_loan.loan_path))
                 }
             };
 
@@ -433,7 +433,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                 euv::ClosureCapture(_) => {
                     format!("previous borrow of `{}` occurs here due to \
                             use in closure",
-                            self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                            self.bccx.loan_path_to_string(&*old_loan.loan_path))
                 }
 
                 euv::OverloadedOperator(..) |
@@ -442,7 +442,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                 euv::ClosureInvocation(..) |
                 euv::RefBinding(..) => {
                     format!("previous borrow of `{}` occurs here",
-                            self.bccx.loan_path_to_str(&*old_loan.loan_path))
+                            self.bccx.loan_path_to_string(&*old_loan.loan_path))
                 }
             };
 
@@ -518,12 +518,12 @@ fn check_for_copy_of_frozen_path(&self,
                 self.bccx.span_err(
                     span,
                     format!("cannot use `{}` because it was mutably borrowed",
-                            self.bccx.loan_path_to_str(copy_path).as_slice())
+                            self.bccx.loan_path_to_string(copy_path).as_slice())
                     .as_slice());
                 self.bccx.span_note(
                     loan_span,
                     format!("borrow of `{}` occurs here",
-                            self.bccx.loan_path_to_str(&*loan_path).as_slice())
+                            self.bccx.loan_path_to_string(&*loan_path).as_slice())
                     .as_slice());
             }
         }
@@ -543,19 +543,19 @@ fn check_for_move_of_borrowed_path(&self,
                 let err_message = match move_kind {
                     move_data::Captured =>
                         format!("cannot move `{}` into closure because it is borrowed",
-                                self.bccx.loan_path_to_str(move_path).as_slice()),
+                                self.bccx.loan_path_to_string(move_path).as_slice()),
                     move_data::Declared |
                     move_data::MoveExpr |
                     move_data::MovePat =>
                         format!("cannot move out of `{}` because it is borrowed",
-                                self.bccx.loan_path_to_str(move_path).as_slice())
+                                self.bccx.loan_path_to_string(move_path).as_slice())
                 };
 
                 self.bccx.span_err(span, err_message.as_slice());
                 self.bccx.span_note(
                     loan_span,
                     format!("borrow of `{}` occurs here",
-                            self.bccx.loan_path_to_str(&*loan_path).as_slice())
+                            self.bccx.loan_path_to_string(&*loan_path).as_slice())
                     .as_slice());
             }
         }
@@ -567,7 +567,7 @@ pub fn analyze_restrictions_on_use(&self,
                                        borrow_kind: ty::BorrowKind)
                                        -> UseError {
         debug!("analyze_restrictions_on_use(expr_id={:?}, use_path={})",
-               self.tcx().map.node_to_str(expr_id),
+               self.tcx().map.node_to_string(expr_id),
                use_path.repr(self.tcx()));
 
         let mut ret = UseOk;
@@ -690,15 +690,15 @@ fn check_assignment(&self,
                     assignment_span,
                     format!("cannot assign to {} {} `{}`",
                             assignee_cmt.mutbl.to_user_str(),
-                            self.bccx.cmt_to_str(&*assignee_cmt),
-                            self.bccx.loan_path_to_str(&*lp)).as_slice());
+                            self.bccx.cmt_to_string(&*assignee_cmt),
+                            self.bccx.loan_path_to_string(&*lp)).as_slice());
             }
             None => {
                 self.bccx.span_err(
                     assignment_span,
                     format!("cannot assign to {} {}",
                             assignee_cmt.mutbl.to_user_str(),
-                            self.bccx.cmt_to_str(&*assignee_cmt)).as_slice());
+                            self.bccx.cmt_to_string(&*assignee_cmt)).as_slice());
             }
         }
         return;
@@ -824,10 +824,10 @@ pub fn report_illegal_mutation(&self,
         self.bccx.span_err(
             span,
             format!("cannot assign to `{}` because it is borrowed",
-                    self.bccx.loan_path_to_str(loan_path)).as_slice());
+                    self.bccx.loan_path_to_string(loan_path)).as_slice());
         self.bccx.span_note(
             loan.span,
             format!("borrow of `{}` occurs here",
-                    self.bccx.loan_path_to_str(loan_path)).as_slice());
+                    self.bccx.loan_path_to_string(loan_path)).as_slice());
     }
 }
index f5c91f7b1b3bf4441e664ff0fd479486864b6d22..9876e12d5ccac539efb1d03ff7ba34ae4ad00cb8 100644 (file)
@@ -120,7 +120,7 @@ fn report_cannot_move_out_of(bccx: &BorrowckCtxt, move_from: mc::cmt) {
             bccx.span_err(
                 move_from.span,
                 format!("cannot move out of {}",
-                        bccx.cmt_to_str(&*move_from)).as_slice());
+                        bccx.cmt_to_string(&*move_from)).as_slice());
         }
 
         mc::cat_downcast(ref b) |
@@ -145,7 +145,7 @@ fn note_move_destination(bccx: &BorrowckCtxt,
                          move_to_span: codemap::Span,
                          pat_ident: &ast::Ident,
                          is_first_note: bool) {
-    let pat_name = pprust::ident_to_str(pat_ident);
+    let pat_name = pprust::ident_to_string(pat_ident);
     if is_first_note {
         bccx.span_note(
             move_to_span,
diff --git a/src/librustc/middle/borrowck/graphviz.rs b/src/librustc/middle/borrowck/graphviz.rs
new file mode 100644 (file)
index 0000000..e2ddb4a
--- /dev/null
@@ -0,0 +1,148 @@
+// 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.
+
+//! This module provides linkage between rustc::middle::graph and
+//! libgraphviz traits, specialized to attaching borrowck analysis
+//! data to rendered labels.
+
+/// For clarity, rename the graphviz crate locally to dot.
+use dot = graphviz;
+pub use middle::cfg::graphviz::{Node, Edge};
+use cfg_dot = middle::cfg::graphviz;
+
+use middle::borrowck;
+use middle::borrowck::{BorrowckCtxt, LoanPath};
+use middle::cfg::{CFGIndex};
+use middle::dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit};
+use middle::dataflow;
+
+use std::rc::Rc;
+use std::str;
+
+#[deriving(Show)]
+pub enum Variant {
+    Loans,
+    Moves,
+    Assigns,
+}
+
+impl Variant {
+    pub fn short_name(&self) -> &'static str {
+        match *self {
+            Loans   => "loans",
+            Moves   => "moves",
+            Assigns => "assigns",
+        }
+    }
+}
+
+pub struct DataflowLabeller<'a> {
+    pub inner: cfg_dot::LabelledCFG<'a>,
+    pub variants: Vec<Variant>,
+    pub borrowck_ctxt: &'a BorrowckCtxt<'a>,
+    pub analysis_data: &'a borrowck::AnalysisData<'a>,
+}
+
+impl<'a> DataflowLabeller<'a> {
+    fn dataflow_for(&self, e: EntryOrExit, n: &Node<'a>) -> String {
+        let id = n.val1().data.id;
+        debug!("dataflow_for({}, id={}) {}", e, id, self.variants);
+        let mut sets = "".to_string();
+        let mut seen_one = false;
+        for &variant in self.variants.iter() {
+            if seen_one { sets.push_str(" "); } else { seen_one = true; }
+            sets.push_str(variant.short_name());
+            sets.push_str(": ");
+            sets.push_str(self.dataflow_for_variant(e, n, variant).as_slice());
+        }
+        sets
+    }
+
+    fn dataflow_for_variant(&self, e: EntryOrExit, n: &Node, v: Variant) -> String {
+        let cfgidx = n.val0();
+        match v {
+            Loans   => self.dataflow_loans_for(e, cfgidx),
+            Moves   => self.dataflow_moves_for(e, cfgidx),
+            Assigns => self.dataflow_assigns_for(e, cfgidx),
+        }
+    }
+
+    fn build_set<O:DataFlowOperator>(&self,
+                                     e: EntryOrExit,
+                                     cfgidx: CFGIndex,
+                                     dfcx: &DataFlowContext<'a, O>,
+                                     to_lp: |uint| -> Rc<LoanPath>) -> String {
+        let mut saw_some = false;
+        let mut set = "{".to_string();
+        dfcx.each_bit_for_node(e, cfgidx, |index| {
+            let lp = to_lp(index);
+            if saw_some {
+                set.push_str(", ");
+            }
+            let loan_str = self.borrowck_ctxt.loan_path_to_string(&*lp);
+            set.push_str(loan_str.as_slice());
+            saw_some = true;
+            true
+        });
+        set.append("}")
+    }
+
+    fn dataflow_loans_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
+        let dfcx = &self.analysis_data.loans;
+        let loan_index_to_path = |loan_index| {
+            let all_loans = &self.analysis_data.all_loans;
+            all_loans.get(loan_index).loan_path()
+        };
+        self.build_set(e, cfgidx, dfcx, loan_index_to_path)
+    }
+
+    fn dataflow_moves_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
+        let dfcx = &self.analysis_data.move_data.dfcx_moves;
+        let move_index_to_path = |move_index| {
+            let move_data = &self.analysis_data.move_data.move_data;
+            let moves = move_data.moves.borrow();
+            let move = moves.get(move_index);
+            move_data.path_loan_path(move.path)
+        };
+        self.build_set(e, cfgidx, dfcx, move_index_to_path)
+    }
+
+    fn dataflow_assigns_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
+        let dfcx = &self.analysis_data.move_data.dfcx_assign;
+        let assign_index_to_path = |assign_index| {
+            let move_data = &self.analysis_data.move_data.move_data;
+            let assignments = move_data.var_assignments.borrow();
+            let assignment = assignments.get(assign_index);
+            move_data.path_loan_path(assignment.path)
+        };
+        self.build_set(e, cfgidx, dfcx, assign_index_to_path)
+    }
+}
+
+impl<'a> dot::Labeller<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a> {
+    fn graph_id(&'a self) -> dot::Id<'a> { self.inner.graph_id() }
+    fn node_id(&'a self, n: &Node<'a>) -> dot::Id<'a> { self.inner.node_id(n) }
+    fn node_label(&'a self, n: &Node<'a>) -> dot::LabelText<'a> {
+        let prefix = self.dataflow_for(dataflow::Entry, n);
+        let suffix = self.dataflow_for(dataflow::Exit, n);
+        let inner_label = self.inner.node_label(n);
+        inner_label
+            .prefix_line(dot::LabelStr(str::Owned(prefix)))
+            .suffix_line(dot::LabelStr(str::Owned(suffix)))
+    }
+    fn edge_label(&'a self, e: &Edge<'a>) -> dot::LabelText<'a> { self.inner.edge_label(e) }
+}
+
+impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a> {
+    fn nodes(&self) -> dot::Nodes<'a, Node<'a>> { self.inner.nodes() }
+    fn edges(&self) -> dot::Edges<'a, Edge<'a>> { self.inner.edges() }
+    fn source(&self, edge: &Edge<'a>) -> Node<'a> { self.inner.source(edge) }
+    fn target(&self, edge: &Edge<'a>) -> Node<'a> { self.inner.target(edge) }
+}
index 9ab3202b9096e5733d084b7a953c568e6b1250a7..77b3cfafa63afaa26d6f05fabd7052f212259d82 100644 (file)
@@ -28,6 +28,7 @@
 use std::string::String;
 use syntax::ast;
 use syntax::ast_map;
+use syntax::ast_map::blocks::{FnLikeNode, FnParts};
 use syntax::ast_util;
 use syntax::codemap::Span;
 use syntax::parse::token;
@@ -50,6 +51,8 @@ macro_rules! if_ok(
 
 pub mod gather_loans;
 
+pub mod graphviz;
+
 pub mod move_data;
 
 #[deriving(Clone)]
@@ -116,6 +119,13 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
     }
 }
 
+/// Collection of conclusions determined via borrow checker analyses.
+pub struct AnalysisData<'a> {
+    pub all_loans: Vec<Loan>,
+    pub loans: DataFlowContext<'a, LoanDataFlowOperator>,
+    pub move_data: move_data::FlowedMoveData<'a>,
+}
+
 fn borrowck_fn(this: &mut BorrowckCtxt,
                fk: &FnKind,
                decl: &ast::FnDecl,
@@ -123,18 +133,35 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
                sp: Span,
                id: ast::NodeId) {
     debug!("borrowck_fn(id={})", id);
+    let cfg = cfg::CFG::new(this.tcx, body);
+    let AnalysisData { all_loans,
+                       loans: loan_dfcx,
+                       move_data:flowed_moves } =
+        build_borrowck_dataflow_data(this, fk, decl, &cfg, body, sp, id);
+
+    check_loans::check_loans(this, &loan_dfcx, flowed_moves,
+                             all_loans.as_slice(), decl, body);
+
+    visit::walk_fn(this, fk, decl, body, sp, ());
+}
 
+fn build_borrowck_dataflow_data<'a>(this: &mut BorrowckCtxt<'a>,
+                                    fk: &FnKind,
+                                    decl: &ast::FnDecl,
+                                    cfg: &cfg::CFG,
+                                    body: &ast::Block,
+                                    sp: Span,
+                                    id: ast::NodeId) -> AnalysisData<'a> {
     // Check the body of fn items.
     let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
     let (all_loans, move_data) =
         gather_loans::gather_loans_in_fn(this, decl, body);
-    let cfg = cfg::CFG::new(this.tcx, body);
 
     let mut loan_dfcx =
         DataFlowContext::new(this.tcx,
                              "borrowck",
                              Some(decl),
-                             &cfg,
+                             cfg,
                              LoanDataFlowOperator,
                              id_range,
                              all_loans.len());
@@ -142,20 +169,57 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
         loan_dfcx.add_gen(loan.gen_scope, loan_idx);
         loan_dfcx.add_kill(loan.kill_scope, loan_idx);
     }
-    loan_dfcx.add_kills_from_flow_exits(&cfg);
-    loan_dfcx.propagate(&cfg, body);
+    loan_dfcx.add_kills_from_flow_exits(cfg);
+    loan_dfcx.propagate(cfg, body);
 
     let flowed_moves = move_data::FlowedMoveData::new(move_data,
                                                       this.tcx,
-                                                      &cfg,
+                                                      cfg,
                                                       id_range,
                                                       decl,
                                                       body);
 
-    check_loans::check_loans(this, &loan_dfcx, flowed_moves,
-                             all_loans.as_slice(), decl, body);
+    AnalysisData { all_loans: all_loans,
+                   loans: loan_dfcx,
+                   move_data:flowed_moves }
+}
 
-    visit::walk_fn(this, fk, decl, body, sp, ());
+/// This and a `ty::ctxt` is all you need to run the dataflow analyses
+/// used in the borrow checker.
+pub struct FnPartsWithCFG<'a> {
+    pub fn_parts: FnParts<'a>,
+    pub cfg:  &'a cfg::CFG,
+}
+
+impl<'a> FnPartsWithCFG<'a> {
+    pub fn from_fn_like(f: &'a FnLikeNode,
+                        g: &'a cfg::CFG) -> FnPartsWithCFG<'a> {
+        FnPartsWithCFG { fn_parts: f.to_fn_parts(), cfg: g }
+    }
+}
+
+/// Accessor for introspective clients inspecting `AnalysisData` and
+/// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
+pub fn build_borrowck_dataflow_data_for_fn<'a>(
+    tcx: &'a ty::ctxt,
+    input: FnPartsWithCFG<'a>) -> (BorrowckCtxt<'a>, AnalysisData<'a>) {
+
+    let mut bccx = BorrowckCtxt {
+        tcx: tcx,
+        stats: box(GC) BorrowStats {
+            loaned_paths_same: Cell::new(0),
+            loaned_paths_imm: Cell::new(0),
+            stable_paths: Cell::new(0),
+            guaranteed_paths: Cell::new(0),
+        }
+    };
+
+    let p = input.fn_parts;
+
+    let dataflow_data = build_borrowck_dataflow_data(
+        &mut bccx, &p.kind, p.decl, input.cfg, p.body, p.span, p.id);
+
+    (bccx, dataflow_data)
 }
 
 // ----------------------------------------------------------------------
@@ -198,6 +262,12 @@ pub struct Loan {
     cause: euv::LoanCause,
 }
 
+impl Loan {
+    pub fn loan_path(&self) -> Rc<LoanPath> {
+        self.loan_path.clone()
+    }
+}
+
 #[deriving(PartialEq, Eq, Hash)]
 pub enum LoanPath {
     LpVar(ast::NodeId),               // `x` in doc.rs
@@ -418,7 +488,7 @@ pub fn cat_pattern(&self,
     pub fn report(&self, err: BckError) {
         self.span_err(
             err.span,
-            self.bckerr_to_str(&err).as_slice());
+            self.bckerr_to_string(&err).as_slice());
         self.note_and_explain_bckerr(err);
     }
 
@@ -439,7 +509,7 @@ pub fn report_use_of_moved_value(&self,
                     use_span,
                     format!("{} of possibly uninitialized variable: `{}`",
                             verb,
-                            self.loan_path_to_str(lp)).as_slice());
+                            self.loan_path_to_string(lp)).as_slice());
             }
             _ => {
                 let partially = if lp == moved_lp {""} else {"partially "};
@@ -448,7 +518,7 @@ pub fn report_use_of_moved_value(&self,
                     format!("{} of {}moved value: `{}`",
                             verb,
                             partially,
-                            self.loan_path_to_str(lp)).as_slice());
+                            self.loan_path_to_string(lp)).as_slice());
             }
         }
 
@@ -472,7 +542,7 @@ pub fn report_use_of_moved_value(&self,
                 self.tcx.sess.span_note(
                     expr_span,
                     format!("`{}` moved here because it has type `{}`, which is {}",
-                            self.loan_path_to_str(moved_lp),
+                            self.loan_path_to_string(moved_lp),
                             expr_ty.user_string(self.tcx),
                             suggestion).as_slice());
             }
@@ -483,7 +553,7 @@ pub fn report_use_of_moved_value(&self,
                     format!("`{}` moved here because it has type `{}`, \
                              which is moved by default (use `ref` to \
                              override)",
-                            self.loan_path_to_str(moved_lp),
+                            self.loan_path_to_string(moved_lp),
                             pat_ty.user_string(self.tcx)).as_slice());
             }
 
@@ -506,7 +576,7 @@ pub fn report_use_of_moved_value(&self,
                     expr_span,
                     format!("`{}` moved into closure environment here because it \
                             has type `{}`, which is {}",
-                            self.loan_path_to_str(moved_lp),
+                            self.loan_path_to_string(moved_lp),
                             expr_ty.user_string(self.tcx),
                             suggestion).as_slice());
             }
@@ -536,7 +606,7 @@ pub fn report_reassigned_immutable_variable(&self,
         self.tcx.sess.span_err(
             span,
             format!("re-assignment of immutable variable `{}`",
-                    self.loan_path_to_str(lp)).as_slice());
+                    self.loan_path_to_string(lp)).as_slice());
         self.tcx.sess.span_note(assign.span, "prior assignment occurs here");
     }
 
@@ -552,20 +622,20 @@ pub fn span_end_note(&self, s: Span, m: &str) {
         self.tcx.sess.span_end_note(s, m);
     }
 
-    pub fn bckerr_to_str(&self, err: &BckError) -> String {
+    pub fn bckerr_to_string(&self, err: &BckError) -> String {
         match err.code {
             err_mutbl => {
                 let descr = match opt_loan_path(&err.cmt) {
                     None => {
                         format!("{} {}",
                                 err.cmt.mutbl.to_user_str(),
-                                self.cmt_to_str(&*err.cmt))
+                                self.cmt_to_string(&*err.cmt))
                     }
                     Some(lp) => {
                         format!("{} {} `{}`",
                                 err.cmt.mutbl.to_user_str(),
-                                self.cmt_to_str(&*err.cmt),
-                                self.loan_path_to_str(&*lp))
+                                self.cmt_to_string(&*err.cmt),
+                                self.loan_path_to_string(&*lp))
                     }
                 };
 
@@ -589,7 +659,7 @@ pub fn bckerr_to_str(&self, err: &BckError) -> String {
                 let msg = match opt_loan_path(&err.cmt) {
                     None => "borrowed value".to_string(),
                     Some(lp) => {
-                        format!("`{}`", self.loan_path_to_str(&*lp))
+                        format!("`{}`", self.loan_path_to_string(&*lp))
                     }
                 };
                 format!("{} does not live long enough", msg)
@@ -597,9 +667,9 @@ pub fn bckerr_to_str(&self, err: &BckError) -> String {
             err_borrowed_pointer_too_short(..) => {
                 let descr = match opt_loan_path(&err.cmt) {
                     Some(lp) => {
-                        format!("`{}`", self.loan_path_to_str(&*lp))
+                        format!("`{}`", self.loan_path_to_string(&*lp))
                     }
-                    None => self.cmt_to_str(&*err.cmt),
+                    None => self.cmt_to_string(&*err.cmt),
                 };
 
                 format!("lifetime of {} is too short to guarantee \
@@ -691,9 +761,9 @@ pub fn note_and_explain_bckerr(&self, err: BckError) {
             err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {
                 let descr = match opt_loan_path(&err.cmt) {
                     Some(lp) => {
-                        format!("`{}`", self.loan_path_to_str(&*lp))
+                        format!("`{}`", self.loan_path_to_string(&*lp))
                     }
-                    None => self.cmt_to_str(&*err.cmt),
+                    None => self.cmt_to_string(&*err.cmt),
                 };
                 note_and_explain_region(
                     self.tcx,
@@ -710,7 +780,7 @@ pub fn note_and_explain_bckerr(&self, err: BckError) {
         }
     }
 
-    pub fn append_loan_path_to_str(&self,
+    pub fn append_loan_path_to_string(&self,
                                    loan_path: &LoanPath,
                                    out: &mut String) {
         match *loan_path {
@@ -720,7 +790,7 @@ pub fn append_loan_path_to_str(&self,
             }
 
             LpExtend(ref lp_base, _, LpInterior(mc::InteriorField(fname))) => {
-                self.append_autoderefd_loan_path_to_str(&**lp_base, out);
+                self.append_autoderefd_loan_path_to_string(&**lp_base, out);
                 match fname {
                     mc::NamedField(fname) => {
                         out.push_char('.');
@@ -728,24 +798,24 @@ pub fn append_loan_path_to_str(&self,
                     }
                     mc::PositionalField(idx) => {
                         out.push_char('#'); // invent a notation here
-                        out.push_str(idx.to_str().as_slice());
+                        out.push_str(idx.to_string().as_slice());
                     }
                 }
             }
 
             LpExtend(ref lp_base, _, LpInterior(mc::InteriorElement(_))) => {
-                self.append_autoderefd_loan_path_to_str(&**lp_base, out);
+                self.append_autoderefd_loan_path_to_string(&**lp_base, out);
                 out.push_str("[..]");
             }
 
             LpExtend(ref lp_base, _, LpDeref(_)) => {
                 out.push_char('*');
-                self.append_loan_path_to_str(&**lp_base, out);
+                self.append_loan_path_to_string(&**lp_base, out);
             }
         }
     }
 
-    pub fn append_autoderefd_loan_path_to_str(&self,
+    pub fn append_autoderefd_loan_path_to_string(&self,
                                               loan_path: &LoanPath,
                                               out: &mut String) {
         match *loan_path {
@@ -753,23 +823,23 @@ pub fn append_autoderefd_loan_path_to_str(&self,
                 // For a path like `(*x).f` or `(*x)[3]`, autoderef
                 // rules would normally allow users to omit the `*x`.
                 // So just serialize such paths to `x.f` or x[3]` respectively.
-                self.append_autoderefd_loan_path_to_str(&**lp_base, out)
+                self.append_autoderefd_loan_path_to_string(&**lp_base, out)
             }
 
             LpVar(..) | LpUpvar(..) | LpExtend(_, _, LpInterior(..)) => {
-                self.append_loan_path_to_str(loan_path, out)
+                self.append_loan_path_to_string(loan_path, out)
             }
         }
     }
 
-    pub fn loan_path_to_str(&self, loan_path: &LoanPath) -> String {
+    pub fn loan_path_to_string(&self, loan_path: &LoanPath) -> String {
         let mut result = String::new();
-        self.append_loan_path_to_str(loan_path, &mut result);
+        self.append_loan_path_to_string(loan_path, &mut result);
         result
     }
 
-    pub fn cmt_to_str(&self, cmt: &mc::cmt_) -> String {
-        self.mc().cmt_to_str(cmt)
+    pub fn cmt_to_string(&self, cmt: &mc::cmt_) -> String {
+        self.mc().cmt_to_string(cmt)
     }
 }
 
@@ -815,11 +885,11 @@ impl Repr for LoanPath {
     fn repr(&self, tcx: &ty::ctxt) -> String {
         match self {
             &LpVar(id) => {
-                format!("$({})", tcx.map.node_to_str(id))
+                format!("$({})", tcx.map.node_to_string(id))
             }
 
             &LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => {
-                let s = tcx.map.node_to_str(var_id);
+                let s = tcx.map.node_to_string(var_id);
                 format!("$({} captured by id={})", s, closure_expr_id)
             }
 
index b61596908e60a5f93ea3307e463e44bd7fe42e98..a9c312fc0a455462e60dbc67953dc27aba9c6bfb 100644 (file)
@@ -189,7 +189,7 @@ pub fn new() -> MoveData {
         }
     }
 
-    fn path_loan_path(&self, index: MovePathIndex) -> Rc<LoanPath> {
+    pub fn path_loan_path(&self, index: MovePathIndex) -> Rc<LoanPath> {
         self.paths.borrow().get(index.get()).loan_path.clone()
     }
 
@@ -534,7 +534,7 @@ fn kill_moves(&self,
 impl<'a> FlowedMoveData<'a> {
     pub fn new(move_data: MoveData,
                tcx: &'a ty::ctxt,
-               cfg: &'a cfg::CFG,
+               cfg: &cfg::CFG,
                id_range: ast_util::IdRange,
                decl: &ast::FnDecl,
                body: &ast::Block)
index c33580d869b15ea7cc7381aa8232b5f0fc6cd9d3..e9bcdff070de1764d9e8d0c47ce0c03b913364b9 100644 (file)
@@ -64,7 +64,7 @@ fn node_label(&'a self, &(i, n): &Node<'a>) -> dot::LabelText<'a> {
         } else if n.data.id == ast::DUMMY_NODE_ID {
             dot::LabelStr("(dummy_node)".into_maybe_owned())
         } else {
-            let s = self.ast_map.node_to_str(n.data.id);
+            let s = self.ast_map.node_to_string(n.data.id);
             // left-aligns the lines
             let s = replace_newline_with_backslash_l(s);
             dot::EscStr(s.into_maybe_owned())
@@ -80,7 +80,7 @@ fn edge_label(&self, e: &Edge<'a>) -> dot::LabelText<'a> {
             } else {
                 put_one = true;
             }
-            let s = self.ast_map.node_to_str(node_id);
+            let s = self.ast_map.node_to_string(node_id);
             // left-aligns the lines
             let s = replace_newline_with_backslash_l(s);
             label = label.append(format!("exiting scope_{} {}",
@@ -117,3 +117,4 @@ fn edges(&self) -> dot::Edges<'a, Edge<'a>> { self.cfg.edges() }
     fn source(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) }
     fn target(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.target(edge) }
 }
+
index cf886702d863126f7373e17b7db64e8ac646cf8f..33bf6ceed4f2b848d9811072495d8b0d0dd47dad 100644 (file)
@@ -108,7 +108,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
                  .span_err(e.span,
                            format!("can not cast to `{}` in a constant \
                                     expression",
-                                   ppaux::ty_to_str(v.tcx, ety)).as_slice())
+                                   ppaux::ty_to_string(v.tcx, ety)).as_slice())
             }
           }
           ExprPath(ref pth) => {
index 8b5c7061a149faf4587ff9eecfd6a742ec6e5140..f31c247abd38c3c83935d0d5bad13221db1ffddf 100644 (file)
 use syntax::ast_util::{is_unguarded, walk_pat};
 use syntax::codemap::{Span, Spanned, DUMMY_SP};
 use syntax::owned_slice::OwnedSlice;
-use syntax::print::pprust::pat_to_str;
+use syntax::print::pprust::pat_to_string;
 use syntax::visit;
 use syntax::visit::{Visitor, FnKind};
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 struct Matrix(Vec<Vec<Gc<Pat>>>);
 
@@ -47,7 +47,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
         let &Matrix(ref m) = self;
         let pretty_printed_matrix: Vec<Vec<String>> = m.iter().map(|row| {
-            row.iter().map(|&pat| pat_to_str(pat)).collect::<Vec<String>>()
+            row.iter().map(|&pat| pat_to_string(pat)).collect::<Vec<String>>()
         }).collect();
 
         let column_count = m.iter().map(|row| row.len()).max().unwrap_or(0u);
@@ -147,7 +147,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
                    // We know the type is inhabited, so this must be wrong
                    cx.tcx.sess.span_err(ex.span, format!("non-exhaustive patterns: \
                                 type {} is non-empty",
-                                ty_to_str(cx.tcx, pat_ty)).as_slice());
+                                ty_to_string(cx.tcx, pat_ty)).as_slice());
                }
                // If the type *is* empty, it's vacuously exhaustive
                return;
@@ -194,7 +194,7 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {
 
             let v = vec!(*pat);
             match is_useful(cx, &seen, v.as_slice(), LeaveOutWitness) {
-                NotUseful => cx.tcx.sess.span_err(pat.span, "unreachable pattern"),
+                NotUseful => span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern"),
                 Useful => (),
                 UsefulWithWitness(_) => unreachable!()
             }
@@ -222,7 +222,8 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, m: &Matrix) {
                 [] => wild(),
                 _ => unreachable!()
             };
-            let msg = format!("non-exhaustive patterns: `{0}` not covered", pat_to_str(&*witness));
+            let msg = format!("non-exhaustive patterns: `{0}` not covered",
+                              pat_to_string(&*witness));
             cx.tcx.sess.span_err(sp, msg.as_slice());
         }
         NotUseful => {
@@ -283,13 +284,15 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
             };
             if is_structure {
                 let fields = ty::lookup_struct_fields(cx.tcx, vid);
-                let field_pats = fields.move_iter()
+                let field_pats: Vec<FieldPat> = fields.move_iter()
                     .zip(pats.iter())
+                    .filter(|&(_, pat)| pat.node != PatWild)
                     .map(|(field, pat)| FieldPat {
                         ident: Ident::new(field.name),
                         pat: pat.clone()
                     }).collect();
-                PatStruct(def_to_path(cx.tcx, vid), field_pats, false)
+                let has_more_fields = field_pats.len() < pats.len();
+                PatStruct(def_to_path(cx.tcx, vid), field_pats, has_more_fields)
             } else {
                 PatEnum(def_to_path(cx.tcx, vid), Some(pats))
             }
@@ -411,14 +414,7 @@ fn is_useful(cx: &MatchCheckCtxt, matrix @ &Matrix(ref rows): &Matrix,
         return NotUseful;
     }
     let real_pat = match rows.iter().find(|r| r.get(0).id != 0) {
-        Some(r) => {
-            match r.get(0).node {
-                // An arm of the form `ref x @ sub_pat` has type
-                // `sub_pat`, not `&sub_pat` as `x` itself does.
-                PatIdent(BindByRef(_), _, Some(sub)) => sub,
-                _ => *r.get(0)
-            }
-        }
+        Some(r) => raw_pat(*r.get(0)),
         None if v.len() == 0 => return NotUseful,
         None => v[0]
     };
@@ -563,6 +559,7 @@ pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor, ty: ty::t) ->
         ty::ty_rptr(_, ty::mt { ty: ty, .. }) => match ty::get(ty).sty {
             ty::ty_vec(_, None) => match *ctor {
                 Slice(length) => length,
+                ConstantValue(_) => 0u,
                 _ => unreachable!()
             },
             ty::ty_str => 0u,
@@ -677,8 +674,17 @@ pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
                 } else {
                     None
                 },
-                DefStruct(struct_id) => Some(struct_id),
-                _ => None
+                _ => {
+                    // Assume this is a struct.
+                    match ty::ty_to_def_id(node_id_to_type(cx.tcx, pat_id)) {
+                        None => {
+                            cx.tcx.sess.span_bug(pat_span,
+                                                 "struct pattern wasn't of a \
+                                                  type with a def ID?!")
+                        }
+                        Some(def_id) => Some(def_id),
+                    }
+                }
             };
             class_id.map(|variant_id| {
                 let struct_fields = ty::lookup_struct_fields(cx.tcx, variant_id);
@@ -775,7 +781,7 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
         Some(pat) => {
             let msg = format!(
                 "refutable pattern in {} binding: `{}` not covered",
-                name, pat_to_str(&*pat)
+                name, pat_to_string(&*pat)
             );
             cx.tcx.sess.span_err(loc.pat.span, msg.as_slice());
         },
@@ -797,7 +803,7 @@ fn check_fn(cx: &mut MatchCheckCtxt,
             Some(pat) => {
                 let msg = format!(
                     "refutable pattern in function argument: `{}` not covered",
-                    pat_to_str(&*pat)
+                    pat_to_string(&*pat)
                 );
                 cx.tcx.sess.span_err(input.pat.span, msg.as_slice());
             },
index 33949ee5b1644a91855be8f450873519abcc2328..1e948afb7018fe745ffc05f1e5db7dc33291e65d 100644 (file)
@@ -75,7 +75,7 @@ fn report_error(&self, span: Span, result: Option<String>) -> bool {
 impl<'a> Visitor<bool> for CheckStaticVisitor<'a> {
 
     fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
-        debug!("visit_item(item={})", pprust::item_to_str(i));
+        debug!("visit_item(item={})", pprust::item_to_string(i));
         match i.node {
             ast::ItemStatic(_, mutability, ref expr) => {
                 match mutability {
@@ -99,7 +99,7 @@ fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
     /// of a static item, this method does nothing but walking
     /// down through it.
     fn visit_expr(&mut self, e: &ast::Expr, is_const: bool) {
-        debug!("visit_expr(expr={})", pprust::expr_to_str(e));
+        debug!("visit_expr(expr={})", pprust::expr_to_string(e));
 
         if !is_const {
             return visit::walk_expr(self, e, is_const);
index 5ac85833e221eb3ccbcb47a23c47284ba2acf603..b28c0158584e6c96a06c054a5115ce14fa429d19 100644 (file)
@@ -28,6 +28,9 @@
 use syntax::print::{pp, pprust};
 use util::nodemap::NodeMap;
 
+#[deriving(Show)]
+pub enum EntryOrExit { Entry, Exit }
+
 #[deriving(Clone)]
 pub struct DataFlowContext<'a, O> {
     tcx: &'a ty::ctxt,
@@ -93,17 +96,18 @@ fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
 }
 
 impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
-    fn has_bitset(&self, n: ast::NodeId) -> bool {
+    fn has_bitset_for_nodeid(&self, n: ast::NodeId) -> bool {
         assert!(n != ast::DUMMY_NODE_ID);
         match self.nodeid_to_index.find(&n) {
             None => false,
-            Some(&cfgidx) => {
-                let node_id = cfgidx.node_id();
-                node_id < self.index_to_bitset.len() &&
-                    self.index_to_bitset.get(node_id).is_some()
-            }
+            Some(&cfgidx) => self.has_bitset_for_cfgidx(cfgidx),
         }
     }
+    fn has_bitset_for_cfgidx(&self, cfgidx: CFGIndex) -> bool {
+        let node_id = cfgidx.node_id();
+        node_id < self.index_to_bitset.len() &&
+            self.index_to_bitset.get(node_id).is_some()
+    }
     fn get_bitset_index(&self, cfgidx: CFGIndex) -> uint {
         let node_id = cfgidx.node_id();
         self.index_to_bitset.get(node_id).unwrap()
@@ -160,22 +164,22 @@ fn pre(&self,
             pprust::NodePat(pat) => pat.id
         };
 
-        if self.has_bitset(id) {
+        if self.has_bitset_for_nodeid(id) {
             let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
             let (start, end) = self.compute_id_range_frozen(cfgidx);
             let on_entry = self.on_entry.slice(start, end);
-            let entry_str = bits_to_str(on_entry);
+            let entry_str = bits_to_string(on_entry);
 
             let gens = self.gens.slice(start, end);
             let gens_str = if gens.iter().any(|&u| u != 0) {
-                format!(" gen: {}", bits_to_str(gens))
+                format!(" gen: {}", bits_to_string(gens))
             } else {
                 "".to_string()
             };
 
             let kills = self.kills.slice(start, end);
             let kills_str = if kills.iter().any(|&u| u != 0) {
-                format!(" kill: {}", bits_to_str(kills))
+                format!(" kill: {}", bits_to_string(kills))
             } else {
                 "".to_string()
             };
@@ -287,9 +291,9 @@ pub fn add_kill(&mut self, id: ast::NodeId, bit: uint) {
     }
 
     fn apply_gen_kill(&mut self, cfgidx: CFGIndex, bits: &mut [uint]) {
-        //! Applies the gen and kill sets for `id` to `bits`
+        //! Applies the gen and kill sets for `cfgidx` to `bits`
         debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
-               self.analysis_name, cfgidx, mut_bits_to_str(bits));
+               self.analysis_name, cfgidx, mut_bits_to_string(bits));
         let (start, end) = self.compute_id_range(cfgidx);
         let gens = self.gens.slice(start, end);
         bitwise(bits, gens, &Union);
@@ -297,7 +301,22 @@ fn apply_gen_kill(&mut self, cfgidx: CFGIndex, bits: &mut [uint]) {
         bitwise(bits, kills, &Subtract);
 
         debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [after]",
-               self.analysis_name, cfgidx, mut_bits_to_str(bits));
+               self.analysis_name, cfgidx, mut_bits_to_string(bits));
+    }
+
+    fn apply_gen_kill_frozen(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
+        //! Applies the gen and kill sets for `cfgidx` to `bits`
+        //! Only useful after `propagate()` has been called.
+        debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
+               self.analysis_name, cfgidx, mut_bits_to_string(bits));
+        let (start, end) = self.compute_id_range_frozen(cfgidx);
+        let gens = self.gens.slice(start, end);
+        bitwise(bits, gens, &Union);
+        let kills = self.kills.slice(start, end);
+        bitwise(bits, kills, &Subtract);
+
+        debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [after]",
+               self.analysis_name, cfgidx, mut_bits_to_string(bits));
     }
 
     fn compute_id_range_frozen(&self, cfgidx: CFGIndex) -> (uint, uint) {
@@ -327,28 +346,52 @@ pub fn each_bit_on_entry_frozen(&self,
                                     -> bool {
         //! Iterates through each bit that is set on entry to `id`.
         //! Only useful after `propagate()` has been called.
-        if !self.has_bitset(id) {
+        if !self.has_bitset_for_nodeid(id) {
             return true;
         }
         let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
+        self.each_bit_for_node(Entry, cfgidx, f)
+    }
+
+    pub fn each_bit_for_node(&self,
+                             e: EntryOrExit,
+                             cfgidx: CFGIndex,
+                             f: |uint| -> bool)
+                             -> bool {
+        //! Iterates through each bit that is set on entry/exit to `cfgidx`.
+        //! Only useful after `propagate()` has been called.
+        if !self.has_bitset_for_cfgidx(cfgidx) {
+            return true;
+        }
         let (start, end) = self.compute_id_range_frozen(cfgidx);
         let on_entry = self.on_entry.slice(start, end);
-        debug!("{:s} each_bit_on_entry_frozen(id={:?}, on_entry={})",
-               self.analysis_name, id, bits_to_str(on_entry));
-        self.each_bit(on_entry, f)
+        let temp_bits;
+        let slice = match e {
+            Entry => on_entry,
+            Exit => {
+                let mut t = on_entry.to_owned();
+                self.apply_gen_kill_frozen(cfgidx, t.as_mut_slice());
+                temp_bits = t;
+                temp_bits.as_slice()
+            }
+        };
+        debug!("{:s} each_bit_for_node({}, cfgidx={}) bits={}",
+               self.analysis_name, e, cfgidx, bits_to_string(slice));
+        self.each_bit(slice, f)
     }
 
     pub fn each_gen_bit_frozen(&self, id: ast::NodeId, f: |uint| -> bool)
                                -> bool {
         //! Iterates through each bit in the gen set for `id`.
-        if !self.has_bitset(id) {
+        //! Only useful after `propagate()` has been called.
+        if !self.has_bitset_for_nodeid(id) {
             return true;
         }
         let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
         let (start, end) = self.compute_id_range_frozen(cfgidx);
         let gens = self.gens.slice(start, end);
         debug!("{:s} each_gen_bit(id={:?}, gens={})",
-               self.analysis_name, id, bits_to_str(gens));
+               self.analysis_name, id, bits_to_string(gens));
         self.each_bit(gens, f)
     }
 
@@ -426,10 +469,10 @@ pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) {
             if changed {
                 let bits = self.kills.mut_slice(start, end);
                 debug!("{:s} add_kills_from_flow_exits flow_exit={} bits={} [before]",
-                       self.analysis_name, flow_exit, mut_bits_to_str(bits));
+                       self.analysis_name, flow_exit, mut_bits_to_string(bits));
                 bits.copy_from(orig_kills.as_slice());
                 debug!("{:s} add_kills_from_flow_exits flow_exit={} bits={} [after]",
-                       self.analysis_name, flow_exit, mut_bits_to_str(bits));
+                       self.analysis_name, flow_exit, mut_bits_to_string(bits));
             }
             true
         });
@@ -483,10 +526,10 @@ fn walk_cfg(&mut self,
                 cfg: &cfg::CFG,
                 in_out: &mut [uint]) {
         debug!("DataFlowContext::walk_cfg(in_out={}) {:s}",
-               bits_to_str(in_out), self.dfcx.analysis_name);
+               bits_to_string(in_out), self.dfcx.analysis_name);
         cfg.graph.each_node(|node_index, node| {
             debug!("DataFlowContext::walk_cfg idx={} id={} begin in_out={}",
-                   node_index, node.data.id, bits_to_str(in_out));
+                   node_index, node.data.id, bits_to_string(in_out));
 
             let (start, end) = self.dfcx.compute_id_range(node_index);
 
@@ -526,7 +569,7 @@ fn propagate_bits_into_entry_set_for(&mut self,
         let source = edge.source();
         let cfgidx = edge.target();
         debug!("{:s} propagate_bits_into_entry_set_for(pred_bits={}, {} to {})",
-               self.dfcx.analysis_name, bits_to_str(pred_bits), source, cfgidx);
+               self.dfcx.analysis_name, bits_to_string(pred_bits), source, cfgidx);
         let (start, end) = self.dfcx.compute_id_range(cfgidx);
         let changed = {
             // (scoping mutable borrow of self.dfcx.on_entry)
@@ -536,17 +579,17 @@ fn propagate_bits_into_entry_set_for(&mut self,
         if changed {
             debug!("{:s} changed entry set for {:?} to {}",
                    self.dfcx.analysis_name, cfgidx,
-                   bits_to_str(self.dfcx.on_entry.slice(start, end)));
+                   bits_to_string(self.dfcx.on_entry.slice(start, end)));
             self.changed = true;
         }
     }
 }
 
-fn mut_bits_to_str(words: &mut [uint]) -> String {
-    bits_to_str(words)
+fn mut_bits_to_string(words: &mut [uint]) -> String {
+    bits_to_string(words)
 }
 
-fn bits_to_str(words: &[uint]) -> String {
+fn bits_to_string(words: &[uint]) -> String {
     let mut result = String::new();
     let mut sep = '[';
 
@@ -582,7 +625,7 @@ fn bitwise<Op:BitwiseOperator>(out_vec: &mut [uint],
 
 fn set_bit(words: &mut [uint], bit: uint) -> bool {
     debug!("set_bit: words={} bit={}",
-           mut_bits_to_str(words), bit_str(bit));
+           mut_bits_to_string(words), bit_str(bit));
     let word = bit / uint::BITS;
     let bit_in_word = bit % uint::BITS;
     let bit_mask = 1 << bit_in_word;
index 70db3e964abb3273cc2f4d078a3c809b1c7fdad0..d84c62f744edc21b4c49f1be1c03ce6f1ba6d4fc 100644 (file)
@@ -22,6 +22,7 @@
 use std::collections::HashSet;
 use syntax::ast;
 use syntax::ast_map;
+use syntax::ast_util;
 use syntax::ast_util::{local_def, is_local};
 use syntax::attr::AttrMetaMethods;
 use syntax::attr;
@@ -141,16 +142,25 @@ fn handle_field_access(&mut self, lhs: &ast::Expr, name: &ast::Ident) {
     }
 
     fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[ast::FieldPat]) {
-        match self.tcx.def_map.borrow().get(&lhs.id) {
-            &def::DefStruct(id) | &def::DefVariant(_, id, _) => {
-                let fields = ty::lookup_struct_fields(self.tcx, id);
-                for pat in pats.iter() {
-                    let field_id = fields.iter()
-                        .find(|field| field.name == pat.ident.name).unwrap().id;
-                    self.live_symbols.insert(field_id.node);
+        let id = match self.tcx.def_map.borrow().get(&lhs.id) {
+            &def::DefVariant(_, id, _) => id,
+            _ => {
+                match ty::ty_to_def_id(ty::node_id_to_type(self.tcx,
+                                                           lhs.id)) {
+                    None => {
+                        self.tcx.sess.span_bug(lhs.span,
+                                               "struct pattern wasn't of a \
+                                                type with a def ID?!")
+                    }
+                    Some(def_id) => def_id,
                 }
             }
-            _ => ()
+        };
+        let fields = ty::lookup_struct_fields(self.tcx, id);
+        for pat in pats.iter() {
+            let field_id = fields.iter()
+                .find(|field| field.name == pat.ident.name).unwrap().id;
+            self.live_symbols.insert(field_id.node);
         }
     }
 
@@ -203,7 +213,7 @@ fn visit_node(&mut self, node: &ast_map::Node) {
                 visit::walk_trait_method(self, &*trait_method, ctxt);
             }
             ast_map::NodeMethod(method) => {
-                visit::walk_block(self, &*method.body, ctxt);
+                visit::walk_block(self, ast_util::method_body(&*method), ctxt);
             }
             ast_map::NodeForeignItem(foreign_item) => {
                 visit::walk_foreign_item(self, &*foreign_item, ctxt);
@@ -511,7 +521,8 @@ fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
     // Overwrite so that we don't warn the trait method itself.
     fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
         match *trait_method {
-            ast::Provided(ref method) => visit::walk_block(self, &*method.body, ()),
+            ast::Provided(ref method) => visit::walk_block(self,
+                                                           ast_util::method_body(&**method), ()),
             ast::Required(_) => ()
         }
     }
index 2333b329996401dc20c4596fbaa68b459a18d525..415135a2d048f04ff4bb8ec38207b35fa03d7279 100644 (file)
@@ -17,6 +17,7 @@
 use util::ppaux;
 
 use syntax::ast;
+use syntax::ast_util;
 use syntax::codemap::Span;
 use syntax::visit;
 use syntax::visit::Visitor;
@@ -68,7 +69,7 @@ fn check_str_index(&mut self, e: &ast::Expr) {
             _ => return
         };
         debug!("effect: checking index with base type {}",
-                ppaux::ty_to_str(self.tcx, base_type));
+                ppaux::ty_to_string(self.tcx, base_type));
         match ty::get(base_type).sty {
             ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
                 ty::ty_str => {
@@ -94,7 +95,7 @@ fn visit_fn(&mut self, fn_kind: &visit::FnKind, fn_decl: &ast::FnDecl,
             visit::FkItemFn(_, _, fn_style, _) =>
                 (true, fn_style == ast::UnsafeFn),
             visit::FkMethod(_, _, method) =>
-                (true, method.fn_style == ast::UnsafeFn),
+                (true, ast_util::method_fn_style(method) == ast::UnsafeFn),
             _ => (false, false),
         };
 
@@ -147,7 +148,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
                 let method_call = MethodCall::expr(expr.id);
                 let base_type = self.tcx.method_map.borrow().get(&method_call).ty;
                 debug!("effect: method call case, base type is {}",
-                       ppaux::ty_to_str(self.tcx, base_type));
+                       ppaux::ty_to_string(self.tcx, base_type));
                 if type_is_unsafe_function(base_type) {
                     self.require_unsafe(expr.span,
                                         "invocation of unsafe method")
@@ -156,7 +157,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
             ast::ExprCall(base, _) => {
                 let base_type = ty::node_id_to_type(self.tcx, base.id);
                 debug!("effect: call case, base type is {}",
-                       ppaux::ty_to_str(self.tcx, base_type));
+                       ppaux::ty_to_string(self.tcx, base_type));
                 if type_is_unsafe_function(base_type) {
                     self.require_unsafe(expr.span, "call to unsafe function")
                 }
@@ -164,7 +165,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
             ast::ExprUnary(ast::UnDeref, base) => {
                 let base_type = ty::node_id_to_type(self.tcx, base.id);
                 debug!("effect: unary case, base type is {}",
-                        ppaux::ty_to_str(self.tcx, base_type));
+                        ppaux::ty_to_string(self.tcx, base_type));
                 match ty::get(base_type).sty {
                     ty::ty_ptr(_) => {
                         self.require_unsafe(expr.span,
index b1f9b0bff9fd280310337dbb60df83a213b9c17f..78eeb26997d5148a2d74d6986d57e5a34db08ae5 100644 (file)
@@ -207,12 +207,12 @@ pub fn next_adjacent(&self, edge: EdgeIndex, dir: Direction) -> EdgeIndex {
 
     pub fn each_node<'a>(&'a self, f: |NodeIndex, &'a Node<N>| -> bool) -> bool {
         //! Iterates over all edges defined in the graph.
-        self.nodes.iter().enumerate().advance(|(i, node)| f(NodeIndex(i), node))
+        self.nodes.iter().enumerate().all(|(i, node)| f(NodeIndex(i), node))
     }
 
     pub fn each_edge<'a>(&'a self, f: |EdgeIndex, &'a Edge<E>| -> bool) -> bool {
         //! Iterates over all edges defined in the graph
-        self.edges.iter().enumerate().advance(|(i, edge)| f(EdgeIndex(i), edge))
+        self.edges.iter().enumerate().all(|(i, edge)| f(EdgeIndex(i), edge))
     }
 
     pub fn each_outgoing_edge<'a>(&'a self,
index a7154e78bc58612d7243430bd2aa3a106be75ac1..d432ced5226cee32781cfffea24c12d9eedfa8d8 100644 (file)
 use middle::ty;
 use middle::typeck::{MethodCall, NoAdjustment};
 use middle::typeck;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
 use util::ppaux::UserString;
 
 use syntax::ast::*;
 use syntax::attr;
 use syntax::codemap::Span;
-use syntax::print::pprust::{expr_to_str, ident_to_str};
+use syntax::print::pprust::{expr_to_string, ident_to_string};
 use syntax::{visit};
 use syntax::visit::Visitor;
 
@@ -126,7 +126,7 @@ fn check_impl_of_trait(cx: &mut Context, it: &Item, trait_ref: &TraitRef, self_t
         cx.tcx.sess.span_err(self_type.span,
             format!("the type `{}', which does not fulfill `{}`, cannot implement this \
                     trait",
-                    ty_to_str(cx.tcx, self_ty),
+                    ty_to_string(cx.tcx, self_ty),
                     missing.user_string(cx.tcx)).as_slice());
         cx.tcx.sess.span_note(self_type.span,
             format!("types implementing this trait must fulfill `{}`",
@@ -246,7 +246,7 @@ fn check_fn(
 }
 
 pub fn check_expr(cx: &mut Context, e: &Expr) {
-    debug!("kind::check_expr({})", expr_to_str(e));
+    debug!("kind::check_expr({})", expr_to_string(e));
 
     // Handle any kind bounds on type parameters
     check_bounds_on_type_parameters(cx, e);
@@ -492,7 +492,7 @@ pub fn check_typaram_bounds(cx: &Context,
             sp,
             format!("instantiating a type parameter with an incompatible type \
                      `{}`, which does not fulfill `{}`",
-                    ty_to_str(cx.tcx, ty),
+                    ty_to_string(cx.tcx, ty),
                     missing.user_string(cx.tcx)).as_slice());
     });
 }
@@ -509,14 +509,14 @@ pub fn check_freevar_bounds(cx: &Context, sp: Span, ty: ty::t,
                 format!("cannot implicitly borrow variable of type `{}` in a \
                          bounded stack closure (implicit reference does not \
                          fulfill `{}`)",
-                        ty_to_str(cx.tcx, rty),
+                        ty_to_string(cx.tcx, rty),
                         missing.user_string(cx.tcx)).as_slice())
             }
             None => {
                 cx.tcx.sess.span_err(sp,
                 format!("cannot capture variable of type `{}`, which does \
                          not fulfill `{}`, in a bounded closure",
-                        ty_to_str(cx.tcx, ty),
+                        ty_to_string(cx.tcx, ty),
                         missing.user_string(cx.tcx)).as_slice())
             }
         }
@@ -533,20 +533,20 @@ pub fn check_trait_cast_bounds(cx: &Context, sp: Span, ty: ty::t,
         cx.tcx.sess.span_err(sp,
             format!("cannot pack type `{}`, which does not fulfill \
                      `{}`, as a trait bounded by {}",
-                    ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx),
+                    ty_to_string(cx.tcx, ty), missing.user_string(cx.tcx),
                     bounds.user_string(cx.tcx)).as_slice());
     });
 }
 
 fn check_copy(cx: &Context, ty: ty::t, sp: Span, reason: &str) {
     debug!("type_contents({})={}",
-           ty_to_str(cx.tcx, ty),
-           ty::type_contents(cx.tcx, ty).to_str());
+           ty_to_string(cx.tcx, ty),
+           ty::type_contents(cx.tcx, ty).to_string());
     if ty::type_moves_by_default(cx.tcx, ty) {
         cx.tcx.sess.span_err(
             sp,
             format!("copying a value of non-copyable type `{}`",
-                    ty_to_str(cx.tcx, ty)).as_slice());
+                    ty_to_string(cx.tcx, ty)).as_slice());
         cx.tcx.sess.span_note(sp, format!("{}", reason).as_slice());
     }
 }
@@ -558,7 +558,7 @@ pub fn check_static(tcx: &ty::ctxt, ty: ty::t, sp: Span) -> bool {
             tcx.sess.span_err(sp,
                 format!("value may contain references; \
                          add `'static` bound to `{}`",
-                        ty_to_str(tcx, ty)).as_slice());
+                        ty_to_string(tcx, ty)).as_slice());
           }
           _ => {
             tcx.sess.span_err(sp, "value may contain references");
@@ -643,7 +643,7 @@ pub fn check_cast_for_escaping_regions(
             //         source_span,
             //         format!("source contains reference with lifetime \
             //               not found in the target type `{}`",
-            //              ty_to_str(cx.tcx, target_ty)));
+            //              ty_to_string(cx.tcx, target_ty)));
             //     note_and_explain_region(
             //         cx.tcx, "source data is only valid for ", r, "");
             // }
@@ -683,7 +683,7 @@ fn check_sized(tcx: &ty::ctxt, ty: ty::t, name: String, sp: Span) {
                           format!("variable `{}` has dynamically sized type \
                                    `{}`",
                                   name,
-                                  ty_to_str(tcx, ty)).as_slice());
+                                  ty_to_string(tcx, ty)).as_slice());
     }
 }
 
@@ -691,7 +691,7 @@ fn check_sized(tcx: &ty::ctxt, ty: ty::t, name: String, sp: Span) {
 fn check_pat(cx: &mut Context, pat: &Pat) {
     let var_name = match pat.node {
         PatWild => Some("_".to_string()),
-        PatIdent(_, ref path1, _) => Some(ident_to_str(&path1.node).to_string()),
+        PatIdent(_, ref path1, _) => Some(ident_to_string(&path1.node).to_string()),
         _ => None
     };
 
@@ -702,7 +702,7 @@ fn check_pat(cx: &mut Context, pat: &Pat) {
             match ty {
                 Some(ty) => {
                     debug!("kind: checking sized-ness of variable {}: {}",
-                           name, ty_to_str(cx.tcx, *ty));
+                           name, ty_to_string(cx.tcx, *ty));
                     check_sized(cx.tcx, *ty, name, pat.span);
                 }
                 None => {} // extern fn args
index 186a737a56ba34f6cd0833d10d5894a050797f0a..1a1d47b254770bd87293fea411963c95af53abc0 100644 (file)
@@ -234,6 +234,7 @@ pub fn collect_language_items(krate: &ast::Crate,
     ShlTraitLangItem,                "shl",                     shl_trait;
     ShrTraitLangItem,                "shr",                     shr_trait;
     IndexTraitLangItem,              "index",                   index_trait;
+    IndexMutTraitLangItem,           "index_mut",               index_mut_trait;
 
     UnsafeTypeLangItem,              "unsafe",                  unsafe_type;
 
index d48f7f541f0da016d1c85cfe980a529656c89031..79742d3173434cd5bafcef3173eccbbbc4f80d5c 100644 (file)
 use syntax::codemap::{BytePos, original_sp, Span};
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
-use syntax::print::pprust::{expr_to_str, block_to_str};
+use syntax::print::pprust::{expr_to_string, block_to_string};
 use syntax::{visit, ast_util};
 use syntax::visit::{Visitor, FnKind};
 
@@ -152,17 +152,17 @@ enum LiveNodeKind {
     ExitNode
 }
 
-fn live_node_kind_to_str(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
+fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
     let cm = cx.sess.codemap();
     match lnk {
         FreeVarNode(s) => {
-            format!("Free var node [{}]", cm.span_to_str(s))
+            format!("Free var node [{}]", cm.span_to_string(s))
         }
         ExprNode(s) => {
-            format!("Expr node [{}]", cm.span_to_str(s))
+            format!("Expr node [{}]", cm.span_to_string(s))
         }
         VarDefNode(s) => {
-            format!("Var def node [{}]", cm.span_to_str(s))
+            format!("Var def node [{}]", cm.span_to_string(s))
         }
         ExitNode => "Exit node".to_string(),
     }
@@ -272,8 +272,8 @@ fn add_live_node(&mut self, lnk: LiveNodeKind) -> LiveNode {
         self.lnks.push(lnk);
         self.num_live_nodes += 1;
 
-        debug!("{} is of kind {}", ln.to_str(),
-               live_node_kind_to_str(lnk, self.tcx));
+        debug!("{} is of kind {}", ln.to_string(),
+               live_node_kind_to_string(lnk, self.tcx));
 
         ln
     }
@@ -282,7 +282,7 @@ fn add_live_node_for_node(&mut self, node_id: NodeId, lnk: LiveNodeKind) {
         let ln = self.add_live_node(lnk);
         self.live_node_map.insert(node_id, ln);
 
-        debug!("{} is node {}", ln.to_str(), node_id);
+        debug!("{} is node {}", ln.to_string(), node_id);
     }
 
     fn add_variable(&mut self, vk: VarKind) -> Variable {
@@ -297,7 +297,7 @@ fn add_variable(&mut self, vk: VarKind) -> Variable {
             ImplicitRet => {}
         }
 
-        debug!("{} is {:?}", v.to_str(), vk);
+        debug!("{} is {:?}", v.to_string(), vk);
 
         v
     }
@@ -317,7 +317,7 @@ fn variable(&self, node_id: NodeId, span: Span) -> Variable {
     fn variable_name(&self, var: Variable) -> String {
         match self.var_kinds.get(var.get()) {
             &Local(LocalInfo { ident: nm, .. }) | &Arg(_, nm) => {
-                token::get_ident(nm).get().to_str()
+                token::get_ident(nm).get().to_string()
             },
             &ImplicitRet => "<implicit-ret>".to_string()
         }
@@ -675,7 +675,7 @@ fn write_vars(&self,
         for var_idx in range(0u, self.ir.num_vars) {
             let idx = node_base_idx + var_idx;
             if test(idx).is_valid() {
-                try!(write!(wr, " {}", Variable(var_idx).to_str()));
+                try!(write!(wr, " {}", Variable(var_idx).to_string()));
             }
         }
         Ok(())
@@ -717,7 +717,7 @@ fn ln_str(&self, ln: LiveNode) -> String {
             self.write_vars(wr, ln, |idx| self.users.get(idx).reader);
             write!(wr, "  writes");
             self.write_vars(wr, ln, |idx| self.users.get(idx).writer);
-            write!(wr, "  precedes {}]", self.successors.get(ln.get()).to_str());
+            write!(wr, "  precedes {}]", self.successors.get(ln.get()).to_string());
         }
         str::from_utf8(wr.unwrap().as_slice()).unwrap().to_string()
     }
@@ -766,7 +766,7 @@ fn merge_from_succ(&mut self,
         });
 
         debug!("merge_from_succ(ln={}, succ={}, first_merge={}, changed={})",
-               ln.to_str(), self.ln_str(succ_ln), first_merge, changed);
+               ln.to_string(), self.ln_str(succ_ln), first_merge, changed);
         return changed;
 
         fn copy_if_invalid(src: LiveNode, dst: &mut LiveNode) -> bool {
@@ -787,14 +787,14 @@ fn define(&mut self, writer: LiveNode, var: Variable) {
         self.users.get_mut(idx).reader = invalid_node();
         self.users.get_mut(idx).writer = invalid_node();
 
-        debug!("{} defines {} (idx={}): {}", writer.to_str(), var.to_str(),
+        debug!("{} defines {} (idx={}): {}", writer.to_string(), var.to_string(),
                idx, self.ln_str(writer));
     }
 
     // Either read, write, or both depending on the acc bitset
     fn acc(&mut self, ln: LiveNode, var: Variable, acc: uint) {
         debug!("{} accesses[{:x}] {}: {}",
-               ln.to_str(), acc, var.to_str(), self.ln_str(ln));
+               ln.to_string(), acc, var.to_string(), self.ln_str(ln));
 
         let idx = self.idx(ln, var);
         let user = self.users.get_mut(idx);
@@ -822,7 +822,7 @@ fn compute(&mut self, decl: &FnDecl, body: &Block) -> LiveNode {
         // effectively a return---this only occurs in `for` loops,
         // where the body is really a closure.
 
-        debug!("compute: using id for block, {}", block_to_str(body));
+        debug!("compute: using id for block, {}", block_to_string(body));
 
         let exit_ln = self.s.exit_ln;
         let entry_ln: LiveNode =
@@ -837,7 +837,7 @@ fn compute(&mut self, decl: &FnDecl, body: &Block) -> LiveNode {
                    }
                    body.id
                },
-               entry_ln.to_str());
+               entry_ln.to_string());
 
         entry_ln
     }
@@ -928,7 +928,7 @@ fn propagate_through_opt_expr(&mut self,
 
     fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
                               -> LiveNode {
-        debug!("propagate_through_expr: {}", expr_to_str(expr));
+        debug!("propagate_through_expr: {}", expr_to_string(expr));
 
         match expr.node {
           // Interesting cases with control flow or which gen/kill
@@ -942,7 +942,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
           }
 
           ExprFnBlock(_, ref blk) | ExprProc(_, ref blk) => {
-              debug!("{} is an ExprFnBlock or ExprProc", expr_to_str(expr));
+              debug!("{} is an ExprFnBlock or ExprProc", expr_to_string(expr));
 
               /*
               The next-node for a break is the successor of the entire
@@ -1314,7 +1314,7 @@ fn propagate_through_loop(&mut self,
             first_merge = false;
         }
         debug!("propagate_through_loop: using id for loop body {} {}",
-               expr.id, block_to_str(body));
+               expr.id, block_to_string(body));
 
         let cond_ln = self.propagate_through_opt_expr(cond, ln);
         let body_ln = self.with_loop_nodes(expr.id, succ, ln, |this| {
@@ -1458,6 +1458,8 @@ fn check_ret(&self,
                         },
                     _ => false
                 };
+                self.ir.tcx.sess.span_err(
+                    sp, "not all control paths return a value");
                 if ends_with_stmt {
                     let last_stmt = body.stmts.last().unwrap();
                     let original_span = original_sp(last_stmt.span, sp);
@@ -1469,8 +1471,6 @@ fn check_ret(&self,
                     self.ir.tcx.sess.span_note(
                         span_semicolon, "consider removing this semicolon:");
                 }
-                self.ir.tcx.sess.span_err(
-                    sp, "not all control paths return a value");
            }
         }
     }
index 54cca082e0de86950a10f7c26aeb8672369b6ae4..33ab2ed3632405adaa0fa90286535f4ae84cb4fa 100644 (file)
@@ -66,7 +66,7 @@
 use middle::ty;
 use middle::typeck;
 use util::nodemap::NodeMap;
-use util::ppaux::{ty_to_str, Repr};
+use util::ppaux::{ty_to_string, Repr};
 
 use syntax::ast::{MutImmutable, MutMutable};
 use syntax::ast;
@@ -217,7 +217,7 @@ pub fn deref_kind(tcx: &ty::ctxt, t: ty::t) -> deref_kind {
       None => {
         tcx.sess.bug(
             format!("deref_cat() invoked on non-derefable type {}",
-                    ty_to_str(tcx, t)).as_slice());
+                    ty_to_string(tcx, t)).as_slice());
       }
     }
 }
@@ -443,10 +443,6 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt> {
           }
 
           ast::ExprIndex(ref base, _) => {
-            if self.typer.is_method_call(expr.id) {
-                return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty));
-            }
-
             let base_cmt = if_ok!(self.cat_expr(&**base));
             Ok(self.cat_index(expr, base_cmt, 0))
           }
@@ -759,7 +755,7 @@ fn cat_deref_common<N:ast_node>(&self,
 
     pub fn cat_index<N:ast_node>(&self,
                                  elt: &N,
-                                 base_cmt: cmt,
+                                 mut base_cmt: cmt,
                                  derefs: uint)
                                  -> cmt {
         //! Creates a cmt for an indexing operation (`[]`); this
@@ -793,14 +789,26 @@ pub fn cat_index<N:ast_node>(&self,
         //! - `derefs`: the deref number to be used for
         //!   the implicit index deref, if any (see above)
 
-        let element_ty = match ty::array_element_ty(base_cmt.ty) {
-          Some(ref mt) => mt.ty,
-          None => {
-            self.tcx().sess.span_bug(
-                elt.span(),
-                format!("Explicit index of non-index type `{}`",
-                        base_cmt.ty.repr(self.tcx())).as_slice());
-          }
+        let method_call = typeck::MethodCall::expr(elt.id());
+        let method_ty = self.typer.node_method_ty(method_call);
+
+        let element_ty = match method_ty {
+            Some(method_ty) => {
+                let ref_ty = ty::ty_fn_ret(method_ty);
+                base_cmt = self.cat_rvalue_node(elt.id(), elt.span(), ref_ty);
+                *ty::ty_fn_args(method_ty).get(0)
+            }
+            None => {
+                match ty::array_element_ty(base_cmt.ty) {
+                    Some(ref mt) => mt.ty,
+                    None => {
+                        self.tcx().sess.span_bug(
+                            elt.span(),
+                            format!("Explicit index of non-index type `{}`",
+                                    base_cmt.ty.repr(self.tcx())).as_slice());
+                    }
+                }
+            }
         };
 
         return match deref_kind(self.tcx(), base_cmt.ty) {
@@ -972,7 +980,7 @@ pub fn cat_pattern(&self,
         // get the type of the *subpattern* and use that.
 
         debug!("cat_pattern: id={} pat={} cmt={}",
-               pat.id, pprust::pat_to_str(pat),
+               pat.id, pprust::pat_to_string(pat),
                cmt.repr(self.tcx()));
 
         op(self, cmt.clone(), pat);
@@ -1097,7 +1105,7 @@ pub fn cat_pattern(&self,
         Ok(())
     }
 
-    pub fn cmt_to_str(&self, cmt: &cmt_) -> String {
+    pub fn cmt_to_string(&self, cmt: &cmt_) -> String {
         match cmt.cat {
           cat_static_item => {
               "static item".to_string()
@@ -1143,10 +1151,10 @@ pub fn cmt_to_str(&self, cmt: &cmt_) -> String {
               "captured outer variable".to_string()
           }
           cat_discr(ref cmt, _) => {
-            self.cmt_to_str(&**cmt)
+            self.cmt_to_string(&**cmt)
           }
           cat_downcast(ref cmt) => {
-            self.cmt_to_str(&**cmt)
+            self.cmt_to_string(&**cmt)
           }
         }
     }
@@ -1303,7 +1311,7 @@ impl Repr for InteriorKind {
     fn repr(&self, _tcx: &ty::ctxt) -> String {
         match *self {
             InteriorField(NamedField(fld)) => {
-                token::get_name(fld).get().to_str()
+                token::get_name(fld).get().to_string()
             }
             InteriorField(PositionalField(i)) => format!("#{:?}", i),
             InteriorElement(_) => "[]".to_string(),
index 76e962a3bc4da6a1894def5f64c29b5c0b374072..580e7b2db57c294a772070b04eba0189916541db 100644 (file)
@@ -26,6 +26,7 @@
 
 use syntax::ast;
 use syntax::ast_map;
+use syntax::ast_util;
 use syntax::ast_util::{is_local, local_def};
 use syntax::attr;
 use syntax::codemap::Span;
@@ -263,10 +264,10 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
 
                 if public_ty || public_trait {
                     for method in methods.iter() {
-                        let meth_public = match method.explicit_self.node {
+                        let meth_public = match ast_util::method_explicit_self(&**method).node {
                             ast::SelfStatic => public_ty,
                             _ => true,
-                        } && method.vis == ast::Public;
+                        } && ast_util::method_vis(&**method) == ast::Public;
                         if meth_public || tr.is_some() {
                             self.exported_items.insert(method.id);
                         }
@@ -375,7 +376,7 @@ enum FieldName {
 impl<'a> PrivacyVisitor<'a> {
     // used when debugging
     fn nodestr(&self, id: ast::NodeId) -> String {
-        self.tcx.map.node_to_str(id).to_string()
+        self.tcx.map.node_to_string(id).to_string()
     }
 
     // Determines whether the given definition is public from the point of view
@@ -423,7 +424,7 @@ fn def_privacy(&self, did: ast::DefId) -> PrivacyResult {
         }
 
         debug!("privacy - local {} not public all the way down",
-               self.tcx.map.node_to_str(did.node));
+               self.tcx.map.node_to_string(did.node));
         // return quickly for things in the same module
         if self.parents.find(&did.node) == self.parents.find(&self.curitem) {
             debug!("privacy - same parent, we're done here");
@@ -456,8 +457,8 @@ fn def_privacy(&self, did: ast::DefId) -> PrivacyResult {
                     let imp = self.tcx.map.get_parent_did(closest_private_id);
                     match ty::impl_trait_ref(self.tcx, imp) {
                         Some(..) => return Allowable,
-                        _ if m.vis == ast::Public => return Allowable,
-                        _ => m.vis
+                        _ if ast_util::method_vis(&**m) == ast::Public => return Allowable,
+                        _ => ast_util::method_vis(&**m)
                     }
                 }
                 Some(ast_map::NodeTraitMethod(_)) => {
@@ -1078,7 +1079,7 @@ fn check_sane_privacy(&self, item: &ast::Item) {
                                 "visibility qualifiers have no effect on trait \
                                  impls");
                 for m in methods.iter() {
-                    check_inherited(m.span, m.vis, "");
+                    check_inherited(m.span, ast_util::method_vis(&**m), "");
                 }
             }
 
@@ -1110,7 +1111,7 @@ fn check_sane_privacy(&self, item: &ast::Item) {
                 for m in methods.iter() {
                     match *m {
                         ast::Provided(ref m) => {
-                            check_inherited(m.span, m.vis,
+                            check_inherited(m.span, ast_util::method_vis(&**m),
                                             "unnecessary visibility");
                         }
                         ast::Required(ref m) => {
@@ -1148,7 +1149,7 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
         match item.node {
             ast::ItemImpl(_, _, _, ref methods) => {
                 for m in methods.iter() {
-                    check_inherited(tcx, m.span, m.vis);
+                    check_inherited(tcx, m.span, ast_util::method_vis(&**m));
                 }
             }
             ast::ItemForeignMod(ref fm) => {
@@ -1174,7 +1175,7 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
                     match *m {
                         ast::Required(..) => {}
                         ast::Provided(ref m) => check_inherited(tcx, m.span,
-                                                                m.vis),
+                                                                ast_util::method_vis(&**m)),
                     }
                 }
             }
@@ -1344,7 +1345,7 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
                     for method in methods.iter() {
-                        if method.explicit_self.node == ast::SelfStatic &&
+                        if ast_util::method_explicit_self(&**method).node == ast::SelfStatic &&
                             self.exported_items.contains(&method.id) {
                             found_pub_static = true;
                             visit::walk_method_helper(self, &**method, ());
index 682dcb2b709f396ff8bdfb1b8a61689002137838..d9324574da73f78a4afd9de153ac5c026831c1b3 100644 (file)
@@ -68,7 +68,7 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
 fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
                            impl_src: ast::DefId) -> bool {
     if attributes_specify_inlining(method.attrs.as_slice()) ||
-        generics_require_inlining(&method.generics) {
+        generics_require_inlining(ast_util::method_generics(&*method)) {
         return true
     }
     if is_local(impl_src) {
@@ -200,7 +200,7 @@ fn def_id_represents_local_inlined_item(&self, def_id: ast::DefId) -> bool {
                 }
             }
             Some(ast_map::NodeMethod(method)) => {
-                if generics_require_inlining(&method.generics) ||
+                if generics_require_inlining(ast_util::method_generics(&*method)) ||
                         attributes_specify_inlining(method.attrs.as_slice()) {
                     true
                 } else {
@@ -316,14 +316,14 @@ fn propagate_node(&mut self, node: &ast_map::Node,
                         // Keep going, nothing to get exported
                     }
                     ast::Provided(ref method) => {
-                        visit::walk_block(self, &*method.body, ())
+                        visit::walk_block(self, ast_util::method_body(&**method), ())
                     }
                 }
             }
             ast_map::NodeMethod(method) => {
                 let did = self.tcx.map.get_parent_did(search_item);
                 if method_might_be_inlined(self.tcx, &*method, did) {
-                    visit::walk_block(self, &*method.body, ())
+                    visit::walk_block(self, ast_util::method_body(&*method), ())
                 }
             }
             // Nothing to recurse on for these
@@ -336,7 +336,7 @@ fn propagate_node(&mut self, node: &ast_map::Node,
                     .bug(format!("found unexpected thingy in worklist: {}",
                                  self.tcx
                                      .map
-                                     .node_to_str(search_item)).as_slice())
+                                     .node_to_string(search_item)).as_slice())
             }
         }
     }
index 3b59736e292b51c2b4681367cb1fa660b931906f..df4d3b7efe432ea6ffada1db2c3bac9569f4bc8e 100644 (file)
@@ -821,7 +821,7 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
                                body.id={}, \
                                cx.parent={})",
            id,
-           visitor.sess.codemap().span_to_str(sp),
+           visitor.sess.codemap().span_to_string(sp),
            body.id,
            cx.parent);
 
index b7b4618a7904619a97f34eacd6d26a0efe1a2b0f..6c6ac81b985303ba6b3dd38eb8a67bf8841953e5 100644 (file)
 
 use syntax::ast::*;
 use syntax::ast;
+use syntax::ast_util;
 use syntax::ast_util::{local_def};
 use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
 use syntax::ext::mtwt;
+use syntax::parse::token::special_names;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::codemap::{Span, DUMMY_SP, Pos};
@@ -307,7 +309,7 @@ enum BareIdentifierPatternResolution {
 #[deriving(PartialEq)]
 enum DuplicateCheckingMode {
     ForbidDuplicateModules,
-    ForbidDuplicateTypes,
+    ForbidDuplicateTypesAndModules,
     ForbidDuplicateValues,
     ForbidDuplicateTypesAndValues,
     OverwriteDuplicates
@@ -790,12 +792,11 @@ fn intern(&mut self, string: &str, primitive_type: PrimTy) {
 }
 
 
-fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
+fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
     match ns {
-        NoError     => "",
-        ModuleError => "module",
-        TypeError   => "type",
-        ValueError  => "value",
+        NoError                 => "",
+        ModuleError | TypeError => "type or module",
+        ValueError              => "value",
     }
 }
 
@@ -831,9 +832,9 @@ struct Resolver<'a> {
     current_self_type: Option<Ty>,
 
     // The ident for the keyword "self".
-    self_ident: Ident,
+    self_name: Name,
     // The ident for the non-keyword "Self".
-    type_self_ident: Ident,
+    type_self_name: Name,
 
     // The idents for the primitive types.
     primitive_type_table: PrimitiveTypeTable,
@@ -927,8 +928,8 @@ fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
             current_trait_ref: None,
             current_self_type: None,
 
-            self_ident: special_idents::self_,
-            type_self_ident: special_idents::type_self,
+            self_name: special_names::self_,
+            type_self_name: special_names::type_self,
 
             primitive_type_table: PrimitiveTypeTable::new(),
 
@@ -1033,9 +1034,12 @@ fn add_child(&self,
                         }
                         Some(TypeNS)
                     }
-                    ForbidDuplicateTypes => {
+                    ForbidDuplicateTypesAndModules => {
                         match child.def_for_namespace(TypeNS) {
-                            Some(DefMod(_)) | None => {}
+                            None => {}
+                            Some(_) if child.get_module_if_available()
+                                            .map(|m| m.kind.get()) ==
+                                       Some(ImplModuleKind) => {}
                             Some(_) => duplicate_type = TypeError
                         }
                         Some(TypeNS)
@@ -1069,14 +1073,14 @@ fn add_child(&self,
                     let ns = ns.unwrap();
                     self.resolve_error(sp,
                         format!("duplicate definition of {} `{}`",
-                             namespace_error_to_str(duplicate_type),
+                             namespace_error_to_string(duplicate_type),
                              token::get_ident(name)).as_slice());
                     {
                         let r = child.span_for_namespace(ns);
                         for sp in r.iter() {
                             self.session.span_note(*sp,
                                  format!("first definition of {} `{}` here",
-                                      namespace_error_to_str(duplicate_type),
+                                      namespace_error_to_string(duplicate_type),
                                       token::get_ident(name)).as_slice());
                         }
                     }
@@ -1177,7 +1181,10 @@ fn build_reduced_graph_for_item(&mut self,
             // These items live in the type namespace.
             ItemTy(..) => {
                 let name_bindings =
-                    self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
+                    self.add_child(ident,
+                                   parent.clone(),
+                                   ForbidDuplicateTypesAndModules,
+                                   sp);
 
                 name_bindings.define_type
                     (DefTy(local_def(item.id)), sp, is_public);
@@ -1186,7 +1193,10 @@ fn build_reduced_graph_for_item(&mut self,
 
             ItemEnum(ref enum_definition, _) => {
                 let name_bindings =
-                    self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
+                    self.add_child(ident,
+                                   parent.clone(),
+                                   ForbidDuplicateTypesAndModules,
+                                   sp);
 
                 name_bindings.define_type
                     (DefTy(local_def(item.id)), sp, is_public);
@@ -1206,7 +1216,7 @@ fn build_reduced_graph_for_item(&mut self,
                 // Adding to both Type and Value namespaces or just Type?
                 let (forbid, ctor_id) = match struct_def.ctor_id {
                     Some(ctor_id)   => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
-                    None            => (ForbidDuplicateTypes, None)
+                    None            => (ForbidDuplicateTypesAndModules, None)
                 };
 
                 let name_bindings = self.add_child(ident, parent.clone(), forbid, sp);
@@ -1289,20 +1299,20 @@ fn build_reduced_graph_for_item(&mut self,
                         // For each method...
                         for method in methods.iter() {
                             // Add the method to the module.
-                            let ident = method.ident;
+                            let ident = ast_util::method_ident(&**method);
                             let method_name_bindings =
                                 self.add_child(ident,
                                                new_parent.clone(),
                                                ForbidDuplicateValues,
                                                method.span);
-                            let def = match method.explicit_self.node {
+                            let def = match ast_util::method_explicit_self(&**method).node {
                                 SelfStatic => {
                                     // Static methods become
                                     // `def_static_method`s.
                                     DefStaticMethod(local_def(method.id),
                                                       FromImpl(local_def(
                                                         item.id)),
-                                                      method.fn_style)
+                                                    ast_util::method_fn_style(&**method))
                                 }
                                 _ => {
                                     // Non-static methods become
@@ -1311,7 +1321,7 @@ fn build_reduced_graph_for_item(&mut self,
                                 }
                             };
 
-                            let is_public = method.vis == ast::Public;
+                            let is_public = ast_util::method_vis(&**method) == ast::Public;
                             method_name_bindings.define_value(def,
                                                               method.span,
                                                               is_public);
@@ -1327,7 +1337,10 @@ fn build_reduced_graph_for_item(&mut self,
 
             ItemTrait(_, _, _, ref methods) => {
                 let name_bindings =
-                    self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
+                    self.add_child(ident,
+                                   parent.clone(),
+                                   ForbidDuplicateTypesAndModules,
+                                   sp);
 
                 // Add all the methods within to a new module.
                 let parent_link = self.get_parent_link(parent.clone(), ident);
@@ -1497,7 +1510,7 @@ fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
                                                               false,
                                                               true));
                     debug!("(build reduced graph for item) found extern `{}`",
-                            self.module_to_str(&*external_module));
+                            self.module_to_string(&*external_module));
                     parent.module().external_module_children.borrow_mut()
                                    .insert(name.name, external_module.clone());
                     self.build_reduced_graph_for_external_crate(external_module);
@@ -1851,7 +1864,7 @@ fn build_reduced_graph_for_external_crate_def(&mut self,
     /// Builds the reduced graph rooted at the given external module.
     fn populate_external_module(&mut self, module: Rc<Module>) {
         debug!("(populating external module) attempting to populate {}",
-               self.module_to_str(&*module));
+               self.module_to_string(&*module));
 
         let def_id = match module.def_id.get() {
             None => {
@@ -1919,7 +1932,7 @@ fn build_import_directive(&mut self,
             SingleImport(target, _) => {
                 debug!("(building import directive) building import \
                         directive: {}::{}",
-                       self.idents_to_str(module_.imports.borrow().last().unwrap()
+                       self.idents_to_string(module_.imports.borrow().last().unwrap()
                                                  .module_path.as_slice()),
                        token::get_ident(target));
 
@@ -1992,7 +2005,7 @@ fn resolve_imports(&mut self) {
     /// submodules.
     fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
         debug!("(resolving imports for module subtree) resolving {}",
-               self.module_to_str(&*module_));
+               self.module_to_string(&*module_));
         let orig_module = replace(&mut self.current_module, module_.clone());
         self.resolve_imports_for_module(module_.clone());
         self.current_module = orig_module;
@@ -2019,7 +2032,7 @@ fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
         if module.all_imports_resolved() {
             debug!("(resolving imports for module) all imports resolved for \
                    {}",
-                   self.module_to_str(&*module));
+                   self.module_to_string(&*module));
             return;
         }
 
@@ -2036,7 +2049,7 @@ fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
                         None => (import_directive.span, String::new())
                     };
                     let msg = format!("unresolved import `{}`{}",
-                                      self.import_path_to_str(
+                                      self.import_path_to_string(
                                           import_directive.module_path
                                                           .as_slice(),
                                           import_directive.subclass),
@@ -2052,7 +2065,7 @@ fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
         }
     }
 
-    fn idents_to_str(&self, idents: &[Ident]) -> String {
+    fn idents_to_string(&self, idents: &[Ident]) -> String {
         let mut first = true;
         let mut result = String::new();
         for ident in idents.iter() {
@@ -2066,15 +2079,15 @@ fn idents_to_str(&self, idents: &[Ident]) -> String {
         result
     }
 
-    fn path_idents_to_str(&self, path: &Path) -> String {
+    fn path_idents_to_string(&self, path: &Path) -> String {
         let identifiers: Vec<ast::Ident> = path.segments
                                              .iter()
                                              .map(|seg| seg.identifier)
                                              .collect();
-        self.idents_to_str(identifiers.as_slice())
+        self.idents_to_string(identifiers.as_slice())
     }
 
-    fn import_directive_subclass_to_str(&mut self,
+    fn import_directive_subclass_to_string(&mut self,
                                         subclass: ImportDirectiveSubclass)
                                         -> String {
         match subclass {
@@ -2085,16 +2098,16 @@ fn import_directive_subclass_to_str(&mut self,
         }
     }
 
-    fn import_path_to_str(&mut self,
+    fn import_path_to_string(&mut self,
                           idents: &[Ident],
                           subclass: ImportDirectiveSubclass)
                           -> String {
         if idents.is_empty() {
-            self.import_directive_subclass_to_str(subclass)
+            self.import_directive_subclass_to_string(subclass)
         } else {
             (format!("{}::{}",
-                     self.idents_to_str(idents),
-                     self.import_directive_subclass_to_str(
+                     self.idents_to_string(idents),
+                     self.import_directive_subclass_to_string(
                          subclass))).to_string()
         }
     }
@@ -2113,8 +2126,8 @@ fn resolve_import_for_module(&mut self,
 
         debug!("(resolving import for module) resolving import `{}::...` in \
                 `{}`",
-               self.idents_to_str(module_path.as_slice()),
-               self.module_to_str(&*module_));
+               self.idents_to_string(module_path.as_slice()),
+               self.module_to_string(&*module_));
 
         // First, resolve the module path for the directive, if necessary.
         let container = if module_path.len() == 0 {
@@ -2220,9 +2233,9 @@ fn resolve_single_import(&mut self,
         debug!("(resolving single import) resolving `{}` = `{}::{}` from \
                 `{}` id {}, last private {:?}",
                token::get_ident(target),
-               self.module_to_str(&*containing_module),
+               self.module_to_string(&*containing_module),
                token::get_ident(source),
-               self.module_to_str(module_),
+               self.module_to_string(module_),
                directive.id,
                lp);
 
@@ -2409,7 +2422,7 @@ fn get_binding(this: &mut Resolver,
         if value_result.is_unbound() && type_result.is_unbound() {
             let msg = format!("There is no `{}` in `{}`",
                               token::get_ident(source),
-                              self.module_to_str(&*containing_module));
+                              self.module_to_string(&*containing_module));
             return Failed(Some((directive.span, msg)));
         }
         let value_used_public = value_used_reexport || value_used_public;
@@ -2483,7 +2496,7 @@ fn resolve_glob_import(&mut self,
             debug!("(resolving glob import) writing module resolution \
                     {:?} into `{}`",
                    target_import_resolution.type_target.is_none(),
-                   self.module_to_str(module_));
+                   self.module_to_string(module_));
 
             if !target_import_resolution.is_public {
                 debug!("(resolving glob import) nevermind, just kidding");
@@ -2579,9 +2592,9 @@ fn merge_import_resolution(&mut self,
 
         debug!("(resolving glob import) writing resolution `{}` in `{}` \
                to `{}`",
-               token::get_name(name).get().to_str(),
-               self.module_to_str(&*containing_module),
-               self.module_to_str(module_));
+               token::get_name(name).get().to_string(),
+               self.module_to_string(&*containing_module),
+               self.module_to_string(module_));
 
         // Merge the child item into the import resolution.
         if name_bindings.defined_in_public_namespace(ValueNS) {
@@ -2641,7 +2654,7 @@ fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                               false) {
                 Failed(None) => {
                     let segment_name = token::get_ident(name);
-                    let module_name = self.module_to_str(&*search_module);
+                    let module_name = self.module_to_string(&*search_module);
                     let mut span = span;
                     let msg = if "???" == module_name.as_slice() {
                         span.hi = span.lo + Pos::from_uint(segment_name.get().len());
@@ -2649,10 +2662,10 @@ fn search_parent_externals(needle: Name, module: &Rc<Module>)
                         match search_parent_externals(name.name,
                                                      &self.current_module) {
                             Some(module) => {
-                                let path_str = self.idents_to_str(module_path);
-                                let target_mod_str = self.module_to_str(&*module);
+                                let path_str = self.idents_to_string(module_path);
+                                let target_mod_str = self.module_to_string(&*module);
                                 let current_mod_str =
-                                    self.module_to_str(&*self.current_module);
+                                    self.module_to_string(&*self.current_module);
 
                                 let prefix = if target_mod_str == current_mod_str {
                                     "self::".to_string()
@@ -2760,8 +2773,8 @@ fn resolve_module_path(&mut self,
 
         debug!("(resolving module path for import) processing `{}` rooted at \
                `{}`",
-               self.idents_to_str(module_path),
-               self.module_to_str(&*module_));
+               self.idents_to_string(module_path),
+               self.module_to_string(&*module_));
 
         // Resolve the module prefix, if any.
         let module_prefix_result = self.resolve_module_prefix(module_.clone(),
@@ -2772,7 +2785,7 @@ fn resolve_module_path(&mut self,
         let last_private;
         match module_prefix_result {
             Failed(None) => {
-                let mpath = self.idents_to_str(module_path);
+                let mpath = self.idents_to_string(module_path);
                 let mpath = mpath.as_slice();
                 match mpath.rfind(':') {
                     Some(idx) => {
@@ -2854,7 +2867,7 @@ fn resolve_item_in_lexical_scope(&mut self,
                 namespace {:?} in `{}`",
                token::get_ident(name),
                namespace,
-               self.module_to_str(&*module_));
+               self.module_to_string(&*module_));
 
         // The current module node is handled specially. First, check for
         // its immediate children.
@@ -3087,7 +3100,7 @@ fn resolve_module_prefix(&mut self,
                 break
             }
             debug!("(resolving module prefix) resolving `super` at {}",
-                   self.module_to_str(&*containing_module));
+                   self.module_to_string(&*containing_module));
             match self.get_nearest_normal_module_parent(containing_module) {
                 None => return Failed(None),
                 Some(new_module) => {
@@ -3098,7 +3111,7 @@ fn resolve_module_prefix(&mut self,
         }
 
         debug!("(resolving module prefix) finished resolving prefix at {}",
-               self.module_to_str(&*containing_module));
+               self.module_to_string(&*containing_module));
 
         return Success(PrefixFound(containing_module, i));
     }
@@ -3118,7 +3131,7 @@ fn resolve_name_in_module(&mut self,
                               -> ResolveResult<(Target, bool)> {
         debug!("(resolving name in module) resolving `{}` in `{}`",
                token::get_name(name).get(),
-               self.module_to_str(&*module_));
+               self.module_to_string(&*module_));
 
         // First, check the direct children of the module.
         self.populate_module_if_necessary(&module_);
@@ -3251,19 +3264,19 @@ fn record_exports_for_module_subtree(&mut self,
                 // OK. Continue.
                 debug!("(recording exports for module subtree) recording \
                         exports for local module `{}`",
-                       self.module_to_str(&*module_));
+                       self.module_to_string(&*module_));
             }
             None => {
                 // Record exports for the root module.
                 debug!("(recording exports for module subtree) recording \
                         exports for root module `{}`",
-                       self.module_to_str(&*module_));
+                       self.module_to_string(&*module_));
             }
             Some(_) => {
                 // Bail out.
                 debug!("(recording exports for module subtree) not recording \
                         exports for `{}`",
-                       self.module_to_str(&*module_));
+                       self.module_to_string(&*module_));
                 return;
             }
         }
@@ -3379,7 +3392,7 @@ fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
                     None => {
                         debug!("!!! (with scope) didn't find `{}` in `{}`",
                                token::get_ident(name),
-                               self.module_to_str(&*orig_module));
+                               self.module_to_string(&*orig_module));
                     }
                     Some(name_bindings) => {
                         match (*name_bindings).get_module_if_available() {
@@ -3387,7 +3400,7 @@ fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
                                 debug!("!!! (with scope) didn't find module \
                                         for `{}` in `{}`",
                                        token::get_ident(name),
-                                       self.module_to_str(&*orig_module));
+                                       self.module_to_string(&*orig_module));
                             }
                             Some(module_) => {
                                 self.current_module = module_;
@@ -3587,6 +3600,7 @@ fn resolve_item(&mut self, item: &Item) {
                                                                item.id,
                                                                ItemRibKind),
                                              |this| {
+                    this.resolve_type_parameters(&generics.ty_params);
                     visit::walk_item(this, item, ());
                 });
             }
@@ -3612,12 +3626,12 @@ fn resolve_item(&mut self, item: &Item) {
                                             methods.as_slice());
             }
 
-            ItemTrait(ref generics, _, ref traits, ref methods) => {
+            ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
                 // Create a new rib for the self type.
                 let self_type_rib = Rib::new(ItemRibKind);
 
-                // plain insert (no renaming)
-                let name = self.type_self_ident.name;
+                // plain insert (no renaming, types are not currently hygienic....)
+                let name = self.type_self_name;
                 self_type_rib.bindings.borrow_mut()
                              .insert(name, DlDef(DefSelfTy(item.id)));
                 self.type_ribs.borrow_mut().push(self_type_rib);
@@ -3634,6 +3648,12 @@ fn resolve_item(&mut self, item: &Item) {
                     for trt in traits.iter() {
                         this.resolve_trait_reference(item.id, trt, TraitDerivation);
                     }
+                    match unbound {
+                        &Some(ast::TraitTyParamBound(ref tpb)) => {
+                            this.resolve_trait_reference(item.id, tpb, TraitDerivation);
+                        }
+                        _ => {}
+                    }
 
                     for method in (*methods).iter() {
                         // Create a new rib for the method-specific type
@@ -3845,11 +3865,15 @@ fn resolve_function(&mut self,
     }
 
     fn resolve_type_parameters(&mut self,
-                                   type_parameters: &OwnedSlice<TyParam>) {
+                               type_parameters: &OwnedSlice<TyParam>) {
         for type_parameter in type_parameters.iter() {
             for bound in type_parameter.bounds.iter() {
                 self.resolve_type_parameter_bound(type_parameter.id, bound);
             }
+            match &type_parameter.unbound {
+                &Some(ref unbound) => self.resolve_type_parameter_bound(type_parameter.id, unbound),
+                &None => {}
+            }
             match type_parameter.default {
                 Some(ref ty) => self.resolve_type(&**ty),
                 None => {}
@@ -3876,12 +3900,12 @@ fn resolve_type_parameter_bound(&mut self,
     }
 
     fn resolve_trait_reference(&mut self,
-                                   id: NodeId,
-                                   trait_reference: &TraitRef,
-                                   reference_type: TraitReferenceType) {
+                               id: NodeId,
+                               trait_reference: &TraitRef,
+                               reference_type: TraitReferenceType) {
         match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
             None => {
-                let path_str = self.path_idents_to_str(&trait_reference.path);
+                let path_str = self.path_idents_to_string(&trait_reference.path);
                 let usage_str = match reference_type {
                     TraitBoundingTypeParameter => "bound type parameter with",
                     TraitImplementation        => "implement",
@@ -3900,7 +3924,7 @@ fn resolve_trait_reference(&mut self,
                     (def, _) => {
                         self.resolve_error(trait_reference.path.span,
                                            format!("`{}` is not a trait",
-                                                   self.path_idents_to_str(
+                                                   self.path_idents_to_string(
                                                         &trait_reference.path)));
 
                         // If it's a typedef, give a note
@@ -3948,7 +3972,7 @@ fn resolve_struct(&mut self,
                                                             .identifier),
                                        def);
                                 debug!("(resolving struct) writing resolution for `{}` (id {})",
-                                       this.path_idents_to_str(path),
+                                       this.path_idents_to_string(path),
                                        path_id);
                                 this.record_def(path_id, (def, lp));
                             }
@@ -3980,13 +4004,15 @@ fn resolve_struct(&mut self,
     fn resolve_method(&mut self,
                       rib_kind: RibKind,
                       method: &Method) {
-        let method_generics = &method.generics;
+        let method_generics = ast_util::method_generics(method);
         let type_parameters = HasTypeParameters(method_generics,
                                                 FnSpace,
                                                 method.id,
                                                 rib_kind);
 
-        self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
+        self.resolve_function(rib_kind, Some(ast_util::method_fn_decl(method)),
+                              type_parameters,
+                              ast_util::method_body(method));
     }
 
     fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
@@ -4057,10 +4083,10 @@ fn resolve_implementation(&mut self,
     fn check_trait_method(&self, method: &Method) {
         // If there is a TraitRef in scope for an impl, then the method must be in the trait.
         for &(did, ref trait_ref) in self.current_trait_ref.iter() {
-            let method_name = method.ident.name;
+            let method_name = ast_util::method_ident(method).name;
 
             if self.method_map.borrow().find(&(method_name, did)).is_none() {
-                let path_str = self.path_idents_to_str(&trait_ref.path);
+                let path_str = self.path_idents_to_string(&trait_ref.path);
                 self.resolve_error(method.span,
                                     format!("method `{}` is not a member of trait `{}`",
                                             token::get_name(method_name),
@@ -4270,13 +4296,13 @@ fn resolve_type(&mut self, ty: &Ty) {
                         // Write the result into the def map.
                         debug!("(resolving type) writing resolution for `{}` \
                                 (id {})",
-                               self.path_idents_to_str(path),
+                               self.path_idents_to_string(path),
                                path_id);
                         self.record_def(path_id, def);
                     }
                     None => {
                         let msg = format!("use of undeclared type name `{}`",
-                                          self.path_idents_to_str(path));
+                                          self.path_idents_to_string(path));
                         self.resolve_error(ty.span, msg.as_slice());
                     }
                 }
@@ -4470,24 +4496,14 @@ struct or enum variant",
 
                 PatStruct(ref path, _, _) => {
                     match self.resolve_path(pat_id, path, TypeNS, false) {
-                        Some((DefTy(class_id), lp))
-                                if self.structs.contains_key(&class_id) => {
-                            let class_def = DefStruct(class_id);
-                            self.record_def(pattern.id, (class_def, lp));
-                        }
-                        Some(definition @ (DefStruct(class_id), _)) => {
-                            assert!(self.structs.contains_key(&class_id));
-                            self.record_def(pattern.id, definition);
-                        }
-                        Some(definition @ (DefVariant(_, variant_id, _), _))
-                                if self.structs.contains_key(&variant_id) => {
+                        Some(definition) => {
                             self.record_def(pattern.id, definition);
                         }
                         result => {
                             debug!("(resolving pattern) didn't find struct \
                                     def: {:?}", result);
                             let msg = format!("`{}` does not name a structure",
-                                              self.path_idents_to_str(path));
+                                              self.path_idents_to_string(path));
                             self.resolve_error(path.span, msg.as_slice());
                         }
                     }
@@ -4717,7 +4733,7 @@ fn resolve_module_relative_path(&mut self,
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared module `{}`",
-                                          self.idents_to_str(
+                                          self.idents_to_string(
                                                module_path_idents.as_slice()));
                         (path.span, msg)
                     }
@@ -4793,7 +4809,7 @@ fn resolve_crate_relative_path(&mut self,
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared module `::{}`",
-                                          self.idents_to_str(
+                                          self.idents_to_string(
                                                module_path_idents.as_slice()));
                         (path.span, msg)
                     }
@@ -4998,7 +5014,7 @@ fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
         match get_module(self, path.span, ident_path.as_slice()) {
             Some(module) => match module.children.borrow().find(&name) {
                 Some(binding) => {
-                    let p_str = self.path_idents_to_str(&path);
+                    let p_str = self.path_idents_to_string(&path);
                     match binding.def_for_namespace(ValueNS) {
                         Some(DefStaticMethod(_, provenance, _)) => {
                             match provenance {
@@ -5020,7 +5036,7 @@ fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
         let method_map = self.method_map.borrow();
         match self.current_trait_ref {
             Some((did, ref trait_ref)) => {
-                let path_str = self.path_idents_to_str(&trait_ref.path);
+                let path_str = self.path_idents_to_string(&trait_ref.path);
 
                 match method_map.find(&(name, did)) {
                     Some(&SelfStatic) => return StaticTraitMethod(path_str),
@@ -5093,7 +5109,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                     Some(def) => {
                         // Write the result into the def map.
                         debug!("(resolving expr) resolved `{}`",
-                               self.path_idents_to_str(path));
+                               self.path_idents_to_string(path));
 
                         // First-class methods are not supported yet; error
                         // out here.
@@ -5113,7 +5129,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                         self.record_def(expr.id, def);
                     }
                     None => {
-                        let wrong_name = self.path_idents_to_str(path);
+                        let wrong_name = self.path_idents_to_string(path);
                         // Be helpful if the name refers to a struct
                         // (The pattern matching def_tys where the id is in self.structs
                         // matches on regular structs while excluding tuple- and enum-like
@@ -5136,7 +5152,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                             }
                             _ => {
                                 let mut method_scope = false;
-                                self.value_ribs.borrow().iter().rev().advance(|rib| {
+                                self.value_ribs.borrow().iter().rev().all(|rib| {
                                     let res = match *rib {
                                         Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
                                         Rib { bindings: _, kind: ItemRibKind } => false,
@@ -5147,8 +5163,8 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                     false // Stop advancing
                                 });
 
-                                if method_scope && token::get_name(self.self_ident.name).get()
-                                                                        == wrong_name.as_slice() {
+                                if method_scope && token::get_name(self.self_name).get()
+                                                                   == wrong_name.as_slice() {
                                         self.resolve_error(
                                             expr.span,
                                             "`self` is not available \
@@ -5200,22 +5216,16 @@ fn resolve_expr(&mut self, expr: &Expr) {
             }
 
             ExprStruct(ref path, _, _) => {
-                // Resolve the path to the structure it goes to.
+                // Resolve the path to the structure it goes to. We don't
+                // check to ensure that the path is actually a structure; that
+                // is checked later during typeck.
                 match self.resolve_path(expr.id, path, TypeNS, false) {
-                    Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
-                            if self.structs.contains_key(&class_id) => {
-                        let class_def = DefStruct(class_id);
-                        self.record_def(expr.id, (class_def, lp));
-                    }
-                    Some(definition @ (DefVariant(_, class_id, _), _))
-                            if self.structs.contains_key(&class_id) => {
-                        self.record_def(expr.id, definition);
-                    }
+                    Some(definition) => self.record_def(expr.id, definition),
                     result => {
                         debug!("(resolving expression) didn't find struct \
                                 def: {:?}", result);
                         let msg = format!("`{}` does not name a structure",
-                                          self.path_idents_to_str(path));
+                                          self.path_idents_to_string(path));
                         self.resolve_error(path.span, msg.as_slice());
                     }
                 }
@@ -5515,7 +5525,7 @@ fn finalize_import(&mut self, id: NodeId, span: Span) {
     //
 
     /// A somewhat inefficient routine to obtain the name of a module.
-    fn module_to_str(&self, module: &Module) -> String {
+    fn module_to_string(&self, module: &Module) -> String {
         let mut idents = Vec::new();
 
         fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
@@ -5526,6 +5536,7 @@ fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
                     collect_mod(idents, &*module.upgrade().unwrap());
                 }
                 BlockParentLink(ref module, _) => {
+                    // danger, shouldn't be ident?
                     idents.push(special_idents::opaque);
                     collect_mod(idents, &*module.upgrade().unwrap());
                 }
@@ -5536,14 +5547,14 @@ fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
         if idents.len() == 0 {
             return "???".to_string();
         }
-        self.idents_to_str(idents.move_iter().rev()
+        self.idents_to_string(idents.move_iter().rev()
                                  .collect::<Vec<ast::Ident>>()
                                  .as_slice())
     }
 
     #[allow(dead_code)]   // useful for debugging
     fn dump_module(&mut self, module_: Rc<Module>) {
-        debug!("Dump of module `{}`:", self.module_to_str(&*module_));
+        debug!("Dump of module `{}`:", self.module_to_string(&*module_));
 
         debug!("Children:");
         self.populate_module_if_necessary(&module_);
index 8ff5331cec2319dca978cf60064224f0dddde9c4..1c85413a8d8eb7a02f401790aa209e8620210036 100644 (file)
@@ -24,7 +24,7 @@
 use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
-use syntax::print::pprust::{lifetime_to_str};
+use syntax::print::pprust::{lifetime_to_string};
 use syntax::visit;
 use syntax::visit::Visitor;
 use util::nodemap::NodeMap;
@@ -372,7 +372,7 @@ fn insert_lifetime(&mut self,
         }
 
         debug!("lifetime_ref={} id={} resolved to {:?}",
-                lifetime_to_str(lifetime_ref),
+                lifetime_to_string(lifetime_ref),
                 lifetime_ref.id,
                 def);
         self.named_region_map.insert(lifetime_ref.id, def);
index bdb7d30339d66f010f0ba8e170dffe17dcaafe4b..a492b4ab9525e193ef67e9dced2af4aa342d8db7 100644 (file)
@@ -51,7 +51,7 @@
 use syntax::parse::token::{get_ident,keywords};
 use syntax::visit;
 use syntax::visit::Visitor;
-use syntax::print::pprust::{path_to_str,ty_to_str};
+use syntax::print::pprust::{path_to_string,ty_to_string};
 
 use middle::save::span_utils::SpanUtils;
 use middle::save::recorder::Recorder;
@@ -108,7 +108,7 @@ fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> {
         if spans.len() < path.segments.len() {
             error!("Mis-calculated spans for path '{}'. \
                     Found {} spans, expected {}. Found spans:",
-                   path_to_str(path), spans.len(), path.segments.len());
+                   path_to_string(path), spans.len(), path.segments.len());
             for s in spans.iter() {
                 let loc = self.sess.codemap().lookup_char_pos(s.lo);
                 error!("    '{}' in {}, line {}",
@@ -126,7 +126,7 @@ fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> {
             let sub_path = ast::Path{span: *span, // span for the last segment
                                      global: path.global,
                                      segments: segs};
-            let qualname = path_to_str(&sub_path);
+            let qualname = path_to_string(&sub_path);
             result.push((*span, qualname));
             segs = sub_path.segments;
         }
@@ -249,7 +249,7 @@ fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str, e:DxrVisi
             self.collecting = false;
             let span_utils = self.span;
             for &(id, ref p, _, _) in self.collected_paths.iter() {
-                let typ = ppaux::ty_to_str(&self.analysis.ty_cx,
+                let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
                     *self.analysis.ty_cx.node_types.borrow().get(&(id as uint)));
                 // get the span only for the name of the variable (I hope the path is only ever a
                 // variable name, but who knows?)
@@ -257,7 +257,7 @@ fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str, e:DxrVisi
                                     span_utils.span_for_last_ident(p.span),
                                     id,
                                     qualname,
-                                    path_to_str(p).as_slice(),
+                                    path_to_string(p).as_slice(),
                                     typ.as_slice());
             }
             self.collected_paths.clear();
@@ -280,7 +280,7 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
                     match item.node {
                         ast::ItemImpl(_, _, ty, _) => {
                             let mut result = String::from_str("<");
-                            result.push_str(ty_to_str(&*ty).as_slice());
+                            result.push_str(ty_to_string(&*ty).as_slice());
 
                             match ty::trait_of_method(&self.analysis.ty_cx,
                                                       ast_util::local_def(method.id)) {
@@ -333,7 +333,7 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
             },
         };
 
-        qualname.push_str(get_ident(method.ident).get());
+        qualname.push_str(get_ident(ast_util::method_ident(&*method)).get());
         let qualname = qualname.as_slice();
 
         // record the decl for this def (if it has one)
@@ -349,17 +349,18 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
                             decl_id,
                             scope_id);
 
-        self.process_formals(&method.decl.inputs, qualname, e);
+        let m_decl = ast_util::method_fn_decl(&*method);
+        self.process_formals(&m_decl.inputs, qualname, e);
 
         // walk arg and return types
-        for arg in method.decl.inputs.iter() {
+        for arg in m_decl.inputs.iter() {
             self.visit_ty(&*arg.ty, e);
         }
-        self.visit_ty(&*method.decl.output, e);
+        self.visit_ty(m_decl.output, e);
         // walk the fn body
-        self.visit_block(&*method.body, DxrVisitorEnv::new_nested(method.id));
+        self.visit_block(ast_util::method_body(&*method), DxrVisitorEnv::new_nested(method.id));
 
-        self.process_generic_params(&method.generics,
+        self.process_generic_params(ast_util::method_generics(&*method),
                                     method.span,
                                     qualname,
                                     method.id,
@@ -400,7 +401,7 @@ fn process_struct_field_def(&mut self,
             ast::NamedField(ident, _) => {
                 let name = get_ident(ident);
                 let qualname = format!("{}::{}", qualname, name);
-                let typ = ppaux::ty_to_str(&self.analysis.ty_cx,
+                let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
                     *self.analysis.ty_cx.node_types.borrow().get(&(field.node.id as uint)));
                 match self.span.sub_span_before_token(field.span, token::COLON) {
                     Some(sub_span) => self.fmt.field_str(field.span,
@@ -452,7 +453,7 @@ fn process_fn(&mut self,
                   decl: ast::P<ast::FnDecl>,
                   ty_params: &ast::Generics,
                   body: ast::P<ast::Block>) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Fn);
         self.fmt.fn_str(item.span,
@@ -482,7 +483,7 @@ fn process_static(&mut self,
                       mt: ast::Mutability,
                       expr: &ast::Expr)
     {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         // If the variable is immutable, save the initialising expression.
         let value = match mt {
@@ -497,7 +498,7 @@ fn process_static(&mut self,
                             get_ident(item.ident).get(),
                             qualname.as_slice(),
                             value.as_slice(),
-                            ty_to_str(&*typ).as_slice(),
+                            ty_to_string(&*typ).as_slice(),
                             e.cur_scope);
 
         // walk type and init value
@@ -510,7 +511,7 @@ fn process_struct(&mut self,
                       e: DxrVisitorEnv,
                       def: &ast::StructDef,
                       ty_params: &ast::Generics) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let ctor_id = match def.ctor_id {
             Some(node_id) => node_id,
@@ -538,7 +539,7 @@ fn process_enum(&mut self,
                     e: DxrVisitorEnv,
                     enum_definition: &ast::EnumDef,
                     ty_params: &ast::Generics) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
         match self.span.sub_span_after_keyword(item.span, keywords::Enum) {
             Some(sub_span) => self.fmt.enum_str(item.span,
                                                 Some(sub_span),
@@ -639,7 +640,7 @@ fn process_trait(&mut self,
                      generics: &ast::Generics,
                      trait_refs: &Vec<ast::TraitRef>,
                      methods: &Vec<ast::TraitMethod>) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
         self.fmt.trait_str(item.span,
@@ -678,7 +679,7 @@ fn process_mod(&mut self,
                    item: &ast::Item,  // The module in question, represented as an item.
                    e: DxrVisitorEnv,
                    m: &ast::Mod) {
-        let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+        let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let cm = self.sess.codemap();
         let filename = cm.span_to_filename(m.inner);
@@ -971,8 +972,8 @@ fn visit_item(&mut self, item:&ast::Item, e: DxrVisitorEnv) {
                 self.process_trait(item, e, generics, trait_refs, methods),
             ast::ItemMod(ref m) => self.process_mod(item, e, m),
             ast::ItemTy(ty, ref ty_params) => {
-                let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
-                let value = ty_to_str(&*ty);
+                let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
+                let value = ty_to_string(&*ty);
                 let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
                 self.fmt.typedef_str(item.span,
                                      sub_span,
@@ -1231,7 +1232,7 @@ fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
                     return
                 }
 
-                let id = String::from_str("$").append(ex.id.to_str().as_slice());
+                let id = String::from_str("$").append(ex.id.to_string().as_slice());
                 self.process_formals(&decl.inputs, id.as_slice(), e);
 
                 // walk arg and return types
@@ -1288,7 +1289,7 @@ fn visit_arm(&mut self, arm: &ast::Arm, e: DxrVisitorEnv) {
                 def::DefBinding(id, _)  => self.fmt.variable_str(p.span,
                                                                  sub_span,
                                                                  id,
-                                                                 path_to_str(p).as_slice(),
+                                                                 path_to_string(p).as_slice(),
                                                                  value.as_slice(),
                                                                  ""),
                 def::DefVariant(_,id,_) => self.fmt.ref_str(ref_kind,
@@ -1331,7 +1332,7 @@ fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) {
         for &(id, ref p, ref immut, _) in self.collected_paths.iter() {
             let value = if *immut { value.to_owned() } else { "<mutable>".to_owned() };
             let types = self.analysis.ty_cx.node_types.borrow();
-            let typ = ppaux::ty_to_str(&self.analysis.ty_cx, *types.get(&(id as uint)));
+            let typ = ppaux::ty_to_string(&self.analysis.ty_cx, *types.get(&(id as uint)));
             // Get the span only for the name of the variable (I hope the path
             // is only ever a variable name, but who knows?).
             let sub_span = self.span.span_for_last_ident(p.span);
@@ -1339,7 +1340,7 @@ fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) {
             self.fmt.variable_str(p.span,
                                   sub_span,
                                   id,
-                                  path_to_str(p).as_slice(),
+                                  path_to_string(p).as_slice(),
                                   value.as_slice(),
                                   typ.as_slice());
         }
@@ -1373,15 +1374,15 @@ pub fn process_crate(sess: &Session,
         return;
     }
 
-    let (cratename, crateid) = match attr::find_crateid(krate.attrs.as_slice()) {
-        Some(crateid) => (crateid.name.clone(), crateid.to_str()),
+    let cratename = match attr::find_crate_name(krate.attrs.as_slice()) {
+        Some(name) => name.get().to_string(),
         None => {
             info!("Could not find crate name, using 'unknown_crate'");
-            (String::from_str("unknown_crate"),"unknown_crate".to_owned())
+            String::from_str("unknown_crate")
         },
     };
 
-    info!("Dumping crate {} ({})", cratename, crateid);
+    info!("Dumping crate {}", cratename);
 
     // find a path to dump our data to
     let mut root_path = match os::getenv("DXR_RUST_TEMP_FOLDER") {
index fd76d6d37d10d932709447f110e8c9a6e992c599..7869aec1683c20c115814223a1e706ecb478b516 100644 (file)
@@ -252,7 +252,7 @@ pub fn variable_str(&mut self,
         // the local case they can be overridden in one block and there is no nice way
         // to refer to such a scope in english, so we just hack it by appending the
         // variable def's node id
-        let qualname = String::from_str(name).append("$").append(id.to_str().as_slice());
+        let qualname = String::from_str(name).append("$").append(id.to_string().as_slice());
         self.check_and_record(Variable,
                               span,
                               sub_span,
index ac17bd07503521212b46b40f71055095d86649e3..a3fa5a5f85ba4cd5237d3d43d37ebb49bffbd148 100644 (file)
 use util::nodemap::{NodeMap, DefIdMap};
 use syntax::codemap::Span;
 use syntax::{attr, visit};
+use syntax::ast;
 use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
 use syntax::ast::{Item, Required, Provided, TraitMethod, TypeMethod, Method};
-use syntax::ast::{Generics, StructDef, Ident};
+use syntax::ast::{Generics, StructDef, StructField, Ident};
 use syntax::ast_util::is_local;
 use syntax::attr::Stability;
 use syntax::visit::{FnKind, FkMethod, Visitor};
@@ -91,6 +92,11 @@ fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics,
         s.ctor_id.map(|id| self.annotate(id, &[], parent.clone()));
         visit::walk_struct_def(self, s, parent)
     }
+
+    fn visit_struct_field(&mut self, s: &StructField, parent: Option<Stability>) {
+        let stab = self.annotate(s.node.id, s.node.attrs.as_slice(), parent);
+        visit::walk_struct_field(self, s, stab)
+    }
 }
 
 impl Index {
@@ -102,8 +108,8 @@ pub fn build(krate: &Crate) -> Index {
                 extern_cache: DefIdMap::new()
             }
         };
-        visit::walk_crate(&mut annotator, krate,
-                          attr::find_stability(krate.attrs.as_slice()));
+        let stab = annotator.annotate(ast::CRATE_NODE_ID, krate.attrs.as_slice(), None);
+        visit::walk_crate(&mut annotator, krate, stab);
         annotator.index
     }
 }
index 0cd3b6e7d79184ee8dd9f1f737e278ae0d7cba6e..4684bd3532ec13ebb9daedfbb227b958c0da7031 100644 (file)
@@ -15,7 +15,6 @@
 use middle::ty_fold::{TypeFoldable, TypeFolder};
 use util::ppaux::Repr;
 
-use std::iter::Chain;
 use std::mem;
 use std::raw;
 use std::slice::{Items, MutItems};
@@ -191,8 +190,8 @@ pub fn mut_regions<'a>(&'a mut self) -> &'a mut VecPerParamSpace<ty::Region> {
     }
 
     pub fn with_method_from(self, substs: &Substs) -> Substs {
-        self.with_method((*substs.types.get_vec(FnSpace)).clone(),
-                         (*substs.regions().get_vec(FnSpace)).clone())
+        self.with_method(Vec::from_slice(substs.types.get_slice(FnSpace)),
+                         Vec::from_slice(substs.regions().get_slice(FnSpace)))
     }
 
     pub fn with_method(self,
@@ -261,13 +260,44 @@ pub fn from_uint(u: uint) -> ParamSpace {
  */
 #[deriving(PartialEq, Eq, Clone, Hash, Encodable, Decodable)]
 pub struct VecPerParamSpace<T> {
-    vecs: (Vec<T>, Vec<T>, Vec<T>)
+    // This was originally represented as a tuple with one Vec<T> for
+    // each variant of ParamSpace, and that remains the abstraction
+    // that it provides to its clients.
+    //
+    // Here is how the representation corresponds to the abstraction
+    // i.e. the "abstraction function" AF:
+    //
+    // AF(self) = (self.content.slice_to(self.type_limit),
+    //             self.content.slice(self.type_limit, self.self_limit),
+    //             self.content.slice_from(self.self_limit))
+    type_limit: uint,
+    self_limit: uint,
+    content: Vec<T>,
+}
+
+impl<T:Clone> VecPerParamSpace<T> {
+    pub fn push_all(&mut self, space: ParamSpace, values: &[T]) {
+        // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
+        for t in values.iter() {
+            self.push(space, t.clone());
+        }
+    }
 }
 
 impl<T> VecPerParamSpace<T> {
+    fn limits(&self, space: ParamSpace) -> (uint, uint) {
+        match space {
+            TypeSpace => (0, self.type_limit),
+            SelfSpace => (self.type_limit, self.self_limit),
+            FnSpace => (self.self_limit, self.content.len()),
+        }
+    }
+
     pub fn empty() -> VecPerParamSpace<T> {
         VecPerParamSpace {
-            vecs: (Vec::new(), Vec::new(), Vec::new())
+            type_limit: 0,
+            self_limit: 0,
+            content: Vec::new()
         }
     }
 
@@ -276,8 +306,15 @@ pub fn params_from_type(types: Vec<T>) -> VecPerParamSpace<T> {
     }
 
     pub fn new(t: Vec<T>, s: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
+        let type_limit = t.len();
+        let self_limit = t.len() + s.len();
+        let mut content = t;
+        content.push_all_move(s);
+        content.push_all_move(f);
         VecPerParamSpace {
-            vecs: (t, s, f)
+            type_limit: type_limit,
+            self_limit: self_limit,
+            content: content,
         }
     }
 
@@ -289,55 +326,98 @@ pub fn sort(t: Vec<T>, space: |&T| -> ParamSpace) -> VecPerParamSpace<T> {
         result
     }
 
+    /// Appends `value` to the vector associated with `space`.
+    ///
+    /// Unlike the `push` method in `Vec`, this should not be assumed
+    /// to be a cheap operation (even when amortized over many calls).
     pub fn push(&mut self, space: ParamSpace, value: T) {
-        self.get_mut_vec(space).push(value);
+        let (_, limit) = self.limits(space);
+        match space {
+            TypeSpace => { self.type_limit += 1; self.self_limit += 1; }
+            SelfSpace => { self.self_limit += 1; }
+            FnSpace   => {}
+        }
+        self.content.insert(limit, value);
+    }
+
+    pub fn pop(&mut self, space: ParamSpace) -> Option<T> {
+        let (start, limit) = self.limits(space);
+        if start == limit {
+            None
+        } else {
+            match space {
+                TypeSpace => { self.type_limit -= 1; self.self_limit -= 1; }
+                SelfSpace => { self.self_limit -= 1; }
+                FnSpace   => {}
+            }
+            self.content.remove(limit - 1)
+        }
+    }
+
+    pub fn truncate(&mut self, space: ParamSpace, len: uint) {
+        // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
+        while self.len(space) > len {
+            self.pop(space);
+        }
+    }
+
+    pub fn replace(&mut self, space: ParamSpace, elems: Vec<T>) {
+        // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
+        self.truncate(space, 0);
+        for t in elems.move_iter() {
+            self.push(space, t);
+        }
     }
 
     pub fn get_self<'a>(&'a self) -> Option<&'a T> {
-        let v = self.get_vec(SelfSpace);
+        let v = self.get_slice(SelfSpace);
         assert!(v.len() <= 1);
-        if v.len() == 0 { None } else { Some(v.get(0)) }
+        if v.len() == 0 { None } else { Some(&v[0]) }
     }
 
     pub fn len(&self, space: ParamSpace) -> uint {
-        self.get_vec(space).len()
+        self.get_slice(space).len()
+    }
+
+    pub fn is_empty_in(&self, space: ParamSpace) -> bool {
+        self.len(space) == 0
     }
 
-    pub fn get_vec<'a>(&'a self, space: ParamSpace) -> &'a Vec<T> {
-        self.vecs.get(space as uint).unwrap()
+    pub fn get_slice<'a>(&'a self, space: ParamSpace) -> &'a [T] {
+        let (start, limit) = self.limits(space);
+        self.content.slice(start, limit)
     }
 
-    pub fn get_mut_vec<'a>(&'a mut self, space: ParamSpace) -> &'a mut Vec<T> {
-        self.vecs.get_mut(space as uint).unwrap()
+    fn get_mut_slice<'a>(&'a mut self, space: ParamSpace) -> &'a mut [T] {
+        let (start, limit) = self.limits(space);
+        self.content.mut_slice(start, limit)
     }
 
     pub fn opt_get<'a>(&'a self,
                        space: ParamSpace,
                        index: uint)
                        -> Option<&'a T> {
-        let v = self.get_vec(space);
-        if index < v.len() { Some(v.get(index)) } else { None }
+        let v = self.get_slice(space);
+        if index < v.len() { Some(&v[index]) } else { None }
     }
 
     pub fn get<'a>(&'a self, space: ParamSpace, index: uint) -> &'a T {
-        self.get_vec(space).get(index)
+        &self.get_slice(space)[index]
     }
 
     pub fn get_mut<'a>(&'a mut self,
                        space: ParamSpace,
                        index: uint) -> &'a mut T {
-        self.get_mut_vec(space).get_mut(index)
+        &mut self.get_mut_slice(space)[index]
     }
 
-    pub fn iter<'a>(&'a self) -> Chain<Items<'a,T>,
-                                       Chain<Items<'a,T>,
-                                             Items<'a,T>>> {
-        let (ref r, ref s, ref f) = self.vecs;
-        r.iter().chain(s.iter().chain(f.iter()))
+    pub fn iter<'a>(&'a self) -> Items<'a,T> {
+        self.content.iter()
     }
 
-    pub fn all_vecs(&self, pred: |&Vec<T>| -> bool) -> bool {
-        self.vecs.iter().all(pred)
+    pub fn all_vecs(&self, pred: |&[T]| -> bool) -> bool {
+        let spaces = [TypeSpace, SelfSpace, FnSpace];
+        spaces.iter().all(|&space| { pred(self.get_slice(space)) })
     }
 
     pub fn all(&self, pred: |&T| -> bool) -> bool {
@@ -353,9 +433,13 @@ pub fn is_empty(&self) -> bool {
     }
 
     pub fn map<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
-        VecPerParamSpace::new(self.vecs.ref0().iter().map(|p| pred(p)).collect(),
-                              self.vecs.ref1().iter().map(|p| pred(p)).collect(),
-                              self.vecs.ref2().iter().map(|p| pred(p)).collect())
+        // FIXME (#15418): this could avoid allocating the intermediate
+        // Vec's, but note that the values of type_limit and self_limit
+        // also need to be kept in sync during construction.
+        VecPerParamSpace::new(
+            self.get_slice(TypeSpace).iter().map(|p| pred(p)).collect(),
+            self.get_slice(SelfSpace).iter().map(|p| pred(p)).collect(),
+            self.get_slice(FnSpace).iter().map(|p| pred(p)).collect())
     }
 
     pub fn map_rev<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
@@ -368,29 +452,46 @@ pub fn map_rev<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
          * can be run to a fixed point
          */
 
-        let mut fns: Vec<U> = self.vecs.ref2().iter().rev().map(|p| pred(p)).collect();
+        let mut fns: Vec<U> = self.get_slice(FnSpace).iter().rev().map(|p| pred(p)).collect();
 
         // NB: Calling foo.rev().map().rev() causes the calls to map
         // to occur in the wrong order. This was somewhat surprising
         // to me, though it makes total sense.
         fns.reverse();
 
-        let mut selfs: Vec<U> = self.vecs.ref1().iter().rev().map(|p| pred(p)).collect();
+        let mut selfs: Vec<U> = self.get_slice(SelfSpace).iter().rev().map(|p| pred(p)).collect();
         selfs.reverse();
-        let mut tys: Vec<U> = self.vecs.ref0().iter().rev().map(|p| pred(p)).collect();
+        let mut tys: Vec<U> = self.get_slice(TypeSpace).iter().rev().map(|p| pred(p)).collect();
         tys.reverse();
         VecPerParamSpace::new(tys, selfs, fns)
     }
 
     pub fn split(self) -> (Vec<T>, Vec<T>, Vec<T>) {
-        self.vecs
+        // FIXME (#15418): this does two traversals when in principle
+        // one would suffice.  i.e. change to use `move_iter`.
+        let VecPerParamSpace { type_limit, self_limit, content } = self;
+        let mut i = 0;
+        let (prefix, fn_vec) = content.partition(|_| {
+            let on_left = i < self_limit;
+            i += 1;
+            on_left
+        });
+
+        let mut i = 0;
+        let (type_vec, self_vec) = prefix.partition(|_| {
+            let on_left = i < type_limit;
+            i += 1;
+            on_left
+        });
+
+        (type_vec, self_vec, fn_vec)
     }
 
     pub fn with_vec(mut self, space: ParamSpace, vec: Vec<T>)
                     -> VecPerParamSpace<T>
     {
-        assert!(self.get_vec(space).is_empty());
-        *self.get_mut_vec(space) = vec;
+        assert!(self.is_empty_in(space));
+        self.replace(space, vec);
         self
     }
 }
index 2f8918acb30bc30d8700ed3b954338b3ad36b037..958d2cd3774315fa4da1a53a44b2e2e7c00a6e86 100644 (file)
 
 use back::abi;
 use driver::config::FullDebugInfo;
-use lib::llvm::{llvm, ValueRef, BasicBlockRef};
+use llvm;
+use llvm::{ValueRef, BasicBlockRef};
 use middle::const_eval;
 use middle::def;
 use middle::check_match;
 use middle::trans::debuginfo;
 use middle::ty;
 use util::common::indenter;
-use util::ppaux::{Repr, vec_map_to_str};
+use util::ppaux::{Repr, vec_map_to_string};
 
 use std;
 use std::collections::HashMap;
@@ -409,30 +410,29 @@ fn expand_nested_bindings<'a, 'b>(
            bcx.to_str(),
            m.repr(bcx.tcx()),
            col,
-           bcx.val_to_str(val));
+           bcx.val_to_string(val));
     let _indenter = indenter();
 
     m.iter().map(|br| {
-        match br.pats.get(col).node {
-            ast::PatIdent(_, ref path1, Some(inner)) => {
-                let pats = Vec::from_slice(br.pats.slice(0u, col))
-                           .append((vec!(inner))
-                                   .append(br.pats.slice(col + 1u, br.pats.len())).as_slice());
-
-                let mut bound_ptrs = br.bound_ptrs.clone();
-                bound_ptrs.push((path1.node, val));
-                Match {
-                    pats: pats,
-                    data: &*br.data,
-                    bound_ptrs: bound_ptrs
-                }
-            }
-            _ => Match {
-                pats: br.pats.clone(),
-                data: &*br.data,
-                bound_ptrs: br.bound_ptrs.clone()
+        let mut bound_ptrs = br.bound_ptrs.clone();
+        let mut pat = *br.pats.get(col);
+        loop {
+            pat = match pat.node {
+                ast::PatIdent(_, ref path, Some(inner)) => {
+                    bound_ptrs.push((path.node, val));
+                    inner.clone()
+                },
+                _ => break
             }
         }
+
+        let mut pats = br.pats.clone();
+        *pats.get_mut(col) = pat;
+        Match {
+            pats: pats,
+            data: &*br.data,
+            bound_ptrs: bound_ptrs
+        }
     }).collect()
 }
 
@@ -450,7 +450,7 @@ fn enter_match<'a, 'b>(
            bcx.to_str(),
            m.repr(bcx.tcx()),
            col,
-           bcx.val_to_str(val));
+           bcx.val_to_string(val));
     let _indenter = indenter();
 
     m.iter().filter_map(|br| {
@@ -486,7 +486,7 @@ fn enter_default<'a, 'b>(
            bcx.to_str(),
            m.repr(bcx.tcx()),
            col,
-           bcx.val_to_str(val));
+           bcx.val_to_string(val));
     let _indenter = indenter();
 
     // Collect all of the matches that can match against anything.
@@ -542,7 +542,7 @@ fn enter_opt<'a, 'b>(
            m.repr(bcx.tcx()),
            *opt,
            col,
-           bcx.val_to_str(val));
+           bcx.val_to_string(val));
     let _indenter = indenter();
 
     let ctor = match opt {
@@ -781,9 +781,9 @@ fn extract_vec_elems<'a>(
 // matches should fit that sort of pattern or NONE (however, some of the
 // matches may be wildcards like _ or identifiers).
 macro_rules! any_pat (
-    ($m:expr, $pattern:pat) => (
+    ($m:expr, $col:expr, $pattern:pat) => (
         ($m).iter().any(|br| {
-            match br.pats.get(col).node {
+            match br.pats.get($col).node {
                 $pattern => true,
                 _ => false
             }
@@ -792,11 +792,11 @@ macro_rules! any_pat (
 )
 
 fn any_uniq_pat(m: &[Match], col: uint) -> bool {
-    any_pat!(m, ast::PatBox(_))
+    any_pat!(m, col, ast::PatBox(_))
 }
 
 fn any_region_pat(m: &[Match], col: uint) -> bool {
-    any_pat!(m, ast::PatRegion(_))
+    any_pat!(m, col, ast::PatRegion(_))
 }
 
 fn any_irrefutable_adt_pat(bcx: &Block, m: &[Match], col: uint) -> bool {
@@ -804,12 +804,19 @@ fn any_irrefutable_adt_pat(bcx: &Block, m: &[Match], col: uint) -> bool {
         let pat = *br.pats.get(col);
         match pat.node {
             ast::PatTup(_) => true,
-            ast::PatEnum(..) | ast::PatIdent(_, _, None) | ast::PatStruct(..) =>
+            ast::PatStruct(..) => {
+                match bcx.tcx().def_map.borrow().find(&pat.id) {
+                    Some(&def::DefVariant(..)) => false,
+                    _ => true,
+                }
+            }
+            ast::PatEnum(..) | ast::PatIdent(_, _, None) => {
                 match bcx.tcx().def_map.borrow().find(&pat.id) {
                     Some(&def::DefFn(..)) |
                     Some(&def::DefStruct(..)) => true,
                     _ => false
-                },
+                }
+            }
             _ => false
         }
     })
@@ -916,7 +923,7 @@ fn compare_str<'a>(cx: &'a Block<'a>,
         let did = langcall(cx,
                            None,
                            format!("comparison of `{}`",
-                                   cx.ty_to_str(rhs_t)).as_slice(),
+                                   cx.ty_to_string(rhs_t)).as_slice(),
                            StrEqFnLangItem);
         callee::trans_lang_call(cx, did, [lhs, rhs], None)
     }
@@ -947,8 +954,8 @@ fn compare_str<'a>(cx: &'a Block<'a>,
     }
 }
 
-fn insert_lllocals<'a>(mut bcx: &'a Block<'a>,
-                       bindings_map: &BindingsMap)
+fn insert_lllocals<'a>(mut bcx: &'a Block<'a>, bindings_map: &BindingsMap,
+                       cs: Option<cleanup::ScopeId>)
                        -> &'a Block<'a> {
     /*!
      * For each binding in `data.bindings_map`, adds an appropriate entry into
@@ -975,10 +982,14 @@ fn insert_lllocals<'a>(mut bcx: &'a Block<'a>,
         };
 
         let datum = Datum::new(llval, binding_info.ty, Lvalue);
+        match cs {
+            Some(cs) => bcx.fcx.schedule_drop_and_zero_mem(cs, llval, binding_info.ty),
+            _ => {}
+        }
 
         debug!("binding {:?} to {}",
                binding_info.id,
-               bcx.val_to_str(llval));
+               bcx.val_to_string(llval));
         bcx.fcx.lllocals.borrow_mut().insert(binding_info.id, datum);
 
         if bcx.sess().opts.debuginfo == FullDebugInfo {
@@ -1001,12 +1012,12 @@ fn compile_guard<'a, 'b>(
                  -> &'b Block<'b> {
     debug!("compile_guard(bcx={}, guard_expr={}, m={}, vals={})",
            bcx.to_str(),
-           bcx.expr_to_str(guard_expr),
+           bcx.expr_to_string(guard_expr),
            m.repr(bcx.tcx()),
-           vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
+           vec_map_to_string(vals, |v| bcx.val_to_string(*v)));
     let _indenter = indenter();
 
-    let mut bcx = insert_lllocals(bcx, &data.bindings_map);
+    let mut bcx = insert_lllocals(bcx, &data.bindings_map, None);
 
     let val = unpack_datum!(bcx, expr::trans(bcx, guard_expr));
     let val = val.to_llbool(bcx);
@@ -1040,7 +1051,7 @@ fn compile_submatch<'a, 'b>(
     debug!("compile_submatch(bcx={}, m={}, vals={})",
            bcx.to_str(),
            m.repr(bcx.tcx()),
-           vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
+           vec_map_to_string(vals, |v| bcx.val_to_string(*v)));
     let _indenter = indenter();
     let _icx = push_ctxt("match::compile_submatch");
     let mut bcx = bcx;
@@ -1145,7 +1156,7 @@ fn compile_submatch_continue<'a, 'b>(
     debug!("options={:?}", opts);
     let mut kind = no_branch;
     let mut test_val = val;
-    debug!("test_val={}", bcx.val_to_str(test_val));
+    debug!("test_val={}", bcx.val_to_string(test_val));
     if opts.len() > 0u {
         match *opts.get(0) {
             var(_, ref repr, _) => {
@@ -1460,9 +1471,11 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>,
     for arm_data in arm_datas.iter() {
         let mut bcx = arm_data.bodycx;
 
-        // insert bindings into the lllocals map
-        bcx = insert_lllocals(bcx, &arm_data.bindings_map);
+        // insert bindings into the lllocals map and add cleanups
+        let cs = fcx.push_custom_cleanup_scope();
+        bcx = insert_lllocals(bcx, &arm_data.bindings_map, Some(cleanup::CustomScope(cs)));
         bcx = expr::trans_into(bcx, &*arm_data.arm.body, dest);
+        bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, cs);
         arm_cxs.push(bcx);
     }
 
index d21ee37f2912ef11d570f57ff104810dbc455de9..3ee61b1d6759668beaf3423c0fb3edfe1abc59df 100644 (file)
@@ -48,7 +48,7 @@
 use libc::c_ulonglong;
 use std::rc::Rc;
 
-use lib::llvm::{ValueRef, True, IntEQ, IntNE};
+use llvm::{ValueRef, True, IntEQ, IntNE};
 use middle::subst;
 use middle::subst::Subst;
 use middle::trans::_match;
@@ -63,7 +63,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::attr::IntType;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 type Hint = attr::ReprAttr;
 
@@ -111,7 +111,7 @@ pub enum Repr {
     StructWrappedNullablePointer {
         pub nonnull: Struct,
         pub nndiscr: Disr,
-        pub ptrfield: uint,
+        pub ptrfield: PointerField,
         pub nullfields: Vec<ty::t>,
     }
 }
@@ -135,7 +135,7 @@ pub fn represent_node(bcx: &Block, node: ast::NodeId) -> Rc<Repr> {
 
 /// Decides how to represent a given type.
 pub fn represent_type(cx: &CrateContext, t: ty::t) -> Rc<Repr> {
-    debug!("Representing: {}", ty_to_str(cx.tcx(), t));
+    debug!("Representing: {}", ty_to_string(cx.tcx(), t));
     match cx.adt_reprs.borrow().find(&t) {
         Some(repr) => return repr.clone(),
         None => {}
@@ -211,24 +211,21 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr {
                 let mut discr = 0;
                 while discr < 2 {
                     if cases.get(1 - discr).is_zerolen(cx) {
+                        let st = mk_struct(cx, cases.get(discr).tys.as_slice(), false);
                         match cases.get(discr).find_ptr() {
+                            Some(ThinPointer(_)) if st.fields.len() == 1 => {
+                                return RawNullablePointer {
+                                    nndiscr: discr as Disr,
+                                    nnty: *st.fields.get(0),
+                                    nullfields: cases.get(1 - discr).tys.clone()
+                                };
+                            }
                             Some(ptrfield) => {
-                                let st = mk_struct(cx, cases.get(discr).tys.as_slice(),
-                                                   false);
-
-                                return if st.fields.len() == 1 {
-                                    RawNullablePointer {
-                                        nndiscr: discr as Disr,
-                                        nnty: *st.fields.get(0),
-                                        nullfields: cases.get(1 - discr).tys.clone()
-                                    }
-                                } else {
-                                    StructWrappedNullablePointer {
-                                        nndiscr: discr as Disr,
-                                        nonnull: st,
-                                        ptrfield: ptrfield,
-                                        nullfields: cases.get(1 - discr).tys.clone()
-                                    }
+                                return StructWrappedNullablePointer {
+                                    nndiscr: discr as Disr,
+                                    nonnull: st,
+                                    ptrfield: ptrfield,
+                                    nullfields: cases.get(1 - discr).tys.clone()
                                 };
                             }
                             None => { }
@@ -283,23 +280,67 @@ pub fn is_ffi_safe(tcx: &ty::ctxt, def_id: ast::DefId) -> bool {
 }
 
 // this should probably all be in ty
-struct Case { discr: Disr, tys: Vec<ty::t> }
+struct Case {
+    discr: Disr,
+    tys: Vec<ty::t>
+}
+
+
+#[deriving(Show)]
+pub enum PointerField {
+    ThinPointer(uint),
+    FatPointer(uint, uint)
+}
+
 impl Case {
     fn is_zerolen(&self, cx: &CrateContext) -> bool {
         mk_struct(cx, self.tys.as_slice(), false).size == 0
     }
-    fn find_ptr(&self) -> Option<uint> {
-        self.tys.iter().position(|&ty| {
+    fn find_ptr(&self) -> Option<PointerField> {
+        use back::abi::{fn_field_code, slice_elt_base, trt_field_box};
+
+        for (i, &ty) in self.tys.iter().enumerate() {
             match ty::get(ty).sty {
-                ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
-                    ty::ty_vec(_, None) | ty::ty_str| ty::ty_trait(..) => false,
-                    _ => true,
+                // &T/&mut T could either be a thin or fat pointer depending on T
+                ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty {
+                    // &[T] and &str are a pointer and length pair
+                    ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i, slice_elt_base)),
+
+                    // &Trait/&mut Trait are a pair of pointers: the actual object and a vtable
+                    ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
+
+                    // Any other &T/&mut T is just a pointer
+                    _ => return Some(ThinPointer(i))
+                },
+
+                // Box<T> could either be a thin or fat pointer depending on T
+                ty::ty_uniq(t) => match ty::get(t).sty {
+                    // Box<[T]>/Box<str> might be FatPointer in a post DST world
+                    ty::ty_vec(_, None) | ty::ty_str => continue,
+
+                    // Box<Trait> is a pair of pointers: the actual object and a vtable
+                    ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
+
+                    // Any other Box<T> is just a pointer
+                    _ => return Some(ThinPointer(i))
                 },
-                ty::ty_box(..) | ty::ty_bare_fn(..) => true,
-                // Is that everything?  Would closures or slices qualify?
-                _ => false
+
+                // Gc<T> is just a pointer
+                ty::ty_box(..) => return Some(ThinPointer(i)),
+
+                // Functions are just pointers
+                ty::ty_bare_fn(..) => return Some(ThinPointer(i)),
+
+                // Closures are a pair of pointers: the code and environment
+                ty::ty_closure(..) => return Some(FatPointer(i, fn_field_code)),
+
+                // Anything else is not a pointer
+                _ => continue
+
             }
-        })
+        }
+
+        None
     }
 }
 
@@ -552,8 +593,8 @@ pub fn trans_get_discr(bcx: &Block, r: &Repr, scrutinee: ValueRef, cast_to: Opti
             val = ICmp(bcx, cmp, Load(bcx, scrutinee), C_null(llptrty));
             signed = false;
         }
-        StructWrappedNullablePointer { nonnull: ref nonnull, nndiscr, ptrfield, .. } => {
-            val = struct_wrapped_nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee);
+        StructWrappedNullablePointer { nndiscr, ptrfield, .. } => {
+            val = struct_wrapped_nullable_bitdiscr(bcx, nndiscr, ptrfield, scrutinee);
             signed = false;
         }
     }
@@ -563,12 +604,15 @@ pub fn trans_get_discr(bcx: &Block, r: &Repr, scrutinee: ValueRef, cast_to: Opti
     }
 }
 
-fn struct_wrapped_nullable_bitdiscr(bcx: &Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uint,
+fn struct_wrapped_nullable_bitdiscr(bcx: &Block, nndiscr: Disr, ptrfield: PointerField,
                                     scrutinee: ValueRef) -> ValueRef {
-    let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield]));
+    let llptrptr = match ptrfield {
+        ThinPointer(field) => GEPi(bcx, scrutinee, [0, field]),
+        FatPointer(field, pair) => GEPi(bcx, scrutinee, [0, field, pair])
+    };
+    let llptr = Load(bcx, llptrptr);
     let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
-    let llptrty = type_of::type_of(bcx.ccx(), *nonnull.fields.get(ptrfield));
-    ICmp(bcx, cmp, llptr, C_null(llptrty))
+    ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)))
 }
 
 /// Helper for cases where the discriminant is simply loaded.
@@ -618,7 +662,7 @@ pub fn trans_case<'a>(bcx: &'a Block<'a>, r: &Repr, discr: Disr)
         RawNullablePointer { .. } |
         StructWrappedNullablePointer { .. } => {
             assert!(discr == 0 || discr == 1);
-            _match::single_result(Result::new(bcx, C_i1(bcx.ccx(), discr != 0)))
+            _match::single_result(Result::new(bcx, C_bool(bcx.ccx(), discr != 0)))
         }
     }
 }
@@ -641,7 +685,7 @@ pub fn trans_start_init(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) {
         }
         Univariant(ref st, true) => {
             assert_eq!(discr, 0);
-            Store(bcx, C_bool(bcx.ccx(), true),
+            Store(bcx, C_u8(bcx.ccx(), 1),
                   GEPi(bcx, val, [0, st.fields.len() - 1]))
         }
         Univariant(..) => {
@@ -655,9 +699,15 @@ pub fn trans_start_init(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) {
         }
         StructWrappedNullablePointer { nonnull: ref nonnull, nndiscr, ptrfield, .. } => {
             if discr != nndiscr {
-                let llptrptr = GEPi(bcx, val, [0, ptrfield]);
-                let llptrty = type_of::type_of(bcx.ccx(),
-                                               *nonnull.fields.get(ptrfield));
+                let (llptrptr, llptrty) = match ptrfield {
+                    ThinPointer(field) =>
+                        (GEPi(bcx, val, [0, field]),
+                         type_of::type_of(bcx.ccx(), *nonnull.fields.get(field))),
+                    FatPointer(field, pair) => {
+                        let v = GEPi(bcx, val, [0, field, pair]);
+                        (v, val_ty(v).element_type())
+                    }
+                };
                 Store(bcx, C_null(llptrty), llptrptr)
             }
         }
@@ -925,7 +975,11 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef)
             }
         }
         StructWrappedNullablePointer { nndiscr, ptrfield, .. } => {
-            if is_null(const_struct_field(ccx, val, ptrfield)) {
+            let (idx, sub_idx) = match ptrfield {
+                ThinPointer(field) => (field, None),
+                FatPointer(field, pair) => (field, Some(pair))
+            };
+            if is_null(const_struct_field(ccx, val, idx, sub_idx)) {
                 /* subtraction as uint is ok because nndiscr is either 0 or 1 */
                 (1 - nndiscr) as Disr
             } else {
@@ -946,18 +1000,18 @@ pub fn const_get_field(ccx: &CrateContext, r: &Repr, val: ValueRef,
                        _discr: Disr, ix: uint) -> ValueRef {
     match *r {
         CEnum(..) => ccx.sess().bug("element access in C-like enum const"),
-        Univariant(..) => const_struct_field(ccx, val, ix),
-        General(..) => const_struct_field(ccx, val, ix + 1),
+        Univariant(..) => const_struct_field(ccx, val, ix, None),
+        General(..) => const_struct_field(ccx, val, ix + 1, None),
         RawNullablePointer { .. } => {
             assert_eq!(ix, 0);
             val
         }
-        StructWrappedNullablePointer{ .. } => const_struct_field(ccx, val, ix)
+        StructWrappedNullablePointer{ .. } => const_struct_field(ccx, val, ix, None)
     }
 }
 
 /// Extract field of struct-like const, skipping our alignment padding.
-fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: uint)
+fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: uint, sub_idx: Option<uint>)
     -> ValueRef {
     // Get the ix-th non-undef element of the struct.
     let mut real_ix = 0; // actual position in the struct
@@ -965,7 +1019,10 @@ fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: uint)
     let mut field;
     loop {
         loop {
-            field = const_get_elt(ccx, val, [real_ix]);
+            field = match sub_idx {
+                Some(si) => const_get_elt(ccx, val, [real_ix, si as u32]),
+                None => const_get_elt(ccx, val, [real_ix])
+            };
             if !is_undef(field) {
                 break;
             }
index 81bb50a83afdfbc7fec850d8936109985aaad837..9760ef07a40e463aa4bb7b5d1aabee8a92a4c1ff 100644 (file)
@@ -12,7 +12,7 @@
 # Translation of inline assembly.
 */
 
-use lib;
+use llvm;
 use middle::trans::build::*;
 use middle::trans::callee;
 use middle::trans::common::*;
@@ -99,8 +99,8 @@ pub fn trans_inline_asm<'a>(bcx: &'a Block<'a>, ia: &ast::InlineAsm)
     };
 
     let dialect = match ia.dialect {
-        ast::AsmAtt   => lib::llvm::AD_ATT,
-        ast::AsmIntel => lib::llvm::AD_Intel
+        ast::AsmAtt   => llvm::AD_ATT,
+        ast::AsmIntel => llvm::AD_Intel
     };
 
     let r = ia.asm.get().with_c_str(|a| {
index 75271804b7911b32be2380cbfffc9d8015e824dc..6bcc9b9b745b7f5e438842de8b7bbcb9774c4a6e 100644 (file)
 use driver::config;
 use driver::config::{NoDebugInfo, FullDebugInfo};
 use driver::session::Session;
-use driver::driver::OutputFilenames;
 use driver::driver::{CrateAnalysis, CrateTranslation};
-use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
-use lib::llvm::{llvm, Vector};
-use lib;
+use llvm;
+use llvm::{ModuleRef, ValueRef, BasicBlockRef};
+use llvm::{Vector};
 use metadata::{csearch, encoder, loader};
 use lint;
 use middle::astencode;
@@ -72,7 +71,7 @@
 use middle::ty;
 use middle::typeck;
 use util::common::indenter;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
 use util::sha2::Sha256;
 use util::nodemap::NodeMap;
 
@@ -173,7 +172,7 @@ fn drop(&mut self) {
 }
 
 // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
-fn decl_fn(ccx: &CrateContext, name: &str, cc: lib::llvm::CallConv,
+fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
            ty: Type, output: ty::t) -> ValueRef {
 
     let llfn: ValueRef = name.with_c_str(|buf| {
@@ -187,16 +186,16 @@ fn decl_fn(ccx: &CrateContext, name: &str, cc: lib::llvm::CallConv,
         ty::ty_bot => {
             unsafe {
                 llvm::LLVMAddFunctionAttribute(llfn,
-                                               lib::llvm::FunctionIndex as c_uint,
-                                               lib::llvm::NoReturnAttribute as uint64_t)
+                                               llvm::FunctionIndex as c_uint,
+                                               llvm::NoReturnAttribute as uint64_t)
             }
         }
         _ => {}
     }
 
-    lib::llvm::SetFunctionCallConv(llfn, cc);
+    llvm::SetFunctionCallConv(llfn, cc);
     // Function addresses in Rust are never significant, allowing functions to be merged.
-    lib::llvm::SetUnnamedAddr(llfn, true);
+    llvm::SetUnnamedAddr(llfn, true);
 
     if ccx.is_split_stack_supported() {
         set_split_stack(llfn);
@@ -210,14 +209,14 @@ pub fn decl_cdecl_fn(ccx: &CrateContext,
                      name: &str,
                      ty: Type,
                      output: ty::t) -> ValueRef {
-    decl_fn(ccx, name, lib::llvm::CCallConv, ty, output)
+    decl_fn(ccx, name, llvm::CCallConv, ty, output)
 }
 
 // only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
 pub fn get_extern_fn(ccx: &CrateContext,
                      externs: &mut ExternMap,
                      name: &str,
-                     cc: lib::llvm::CallConv,
+                     cc: llvm::CallConv,
                      ty: Type,
                      output: ty::t)
                      -> ValueRef {
@@ -254,7 +253,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
     };
 
     let llfty = type_of_rust_fn(ccx, has_env, inputs.as_slice(), output);
-    let llfn = decl_fn(ccx, name, lib::llvm::CCallConv, llfty, output);
+    let llfn = decl_fn(ccx, name, llvm::CCallConv, llfty, output);
     let attrs = get_fn_llvm_attributes(ccx, fn_ty);
     for &(idx, attr) in attrs.iter() {
         unsafe {
@@ -267,7 +266,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
 
 pub fn decl_internal_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
     let llfn = decl_rust_fn(ccx, fn_ty, name);
-    lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
+    llvm::SetLinkage(llfn, llvm::InternalLinkage);
     llfn
 }
 
@@ -302,7 +301,7 @@ fn require_alloc_fn(bcx: &Block, info_ty: ty::t, it: LangItem) -> ast::DefId {
         Ok(id) => id,
         Err(s) => {
             bcx.sess().fatal(format!("allocation of `{}` {}",
-                                     bcx.ty_to_str(info_ty),
+                                     bcx.ty_to_string(info_ty),
                                      s).as_slice());
         }
     }
@@ -376,26 +375,26 @@ pub fn get_tydesc(ccx: &CrateContext, t: ty::t) -> Rc<tydesc_info> {
 
 #[allow(dead_code)] // useful
 pub fn set_optimize_for_size(f: ValueRef) {
-    lib::llvm::SetFunctionAttribute(f, lib::llvm::OptimizeForSizeAttribute)
+    llvm::SetFunctionAttribute(f, llvm::OptimizeForSizeAttribute)
 }
 
 pub fn set_no_inline(f: ValueRef) {
-    lib::llvm::SetFunctionAttribute(f, lib::llvm::NoInlineAttribute)
+    llvm::SetFunctionAttribute(f, llvm::NoInlineAttribute)
 }
 
 #[allow(dead_code)] // useful
 pub fn set_no_unwind(f: ValueRef) {
-    lib::llvm::SetFunctionAttribute(f, lib::llvm::NoUnwindAttribute)
+    llvm::SetFunctionAttribute(f, llvm::NoUnwindAttribute)
 }
 
 // Tell LLVM to emit the information necessary to unwind the stack for the
 // function f.
 pub fn set_uwtable(f: ValueRef) {
-    lib::llvm::SetFunctionAttribute(f, lib::llvm::UWTableAttribute)
+    llvm::SetFunctionAttribute(f, llvm::UWTableAttribute)
 }
 
 pub fn set_inline_hint(f: ValueRef) {
-    lib::llvm::SetFunctionAttribute(f, lib::llvm::InlineHintAttribute)
+    llvm::SetFunctionAttribute(f, llvm::InlineHintAttribute)
 }
 
 pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
@@ -416,25 +415,25 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
     if contains_name(attrs, "cold") {
         unsafe {
             llvm::LLVMAddFunctionAttribute(llfn,
-                                           lib::llvm::FunctionIndex as c_uint,
-                                           lib::llvm::ColdAttribute as uint64_t)
+                                           llvm::FunctionIndex as c_uint,
+                                           llvm::ColdAttribute as uint64_t)
         }
     }
 }
 
 pub fn set_always_inline(f: ValueRef) {
-    lib::llvm::SetFunctionAttribute(f, lib::llvm::AlwaysInlineAttribute)
+    llvm::SetFunctionAttribute(f, llvm::AlwaysInlineAttribute)
 }
 
 pub fn set_split_stack(f: ValueRef) {
     "split-stack".with_c_str(|buf| {
-        unsafe { llvm::LLVMAddFunctionAttrString(f, lib::llvm::FunctionIndex as c_uint, buf); }
+        unsafe { llvm::LLVMAddFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
     })
 }
 
 pub fn unset_split_stack(f: ValueRef) {
     "split-stack".with_c_str(|buf| {
-        unsafe { llvm::LLVMRemoveFunctionAttrString(f, lib::llvm::FunctionIndex as c_uint, buf); }
+        unsafe { llvm::LLVMRemoveFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
     })
 }
 
@@ -480,7 +479,7 @@ pub fn get_res_dtor(ccx: &CrateContext,
         get_extern_fn(ccx,
                       &mut *ccx.externs.borrow_mut(),
                       name.as_slice(),
-                      lib::llvm::CCallConv,
+                      llvm::CCallConv,
                       llty,
                       dtor_ty)
     }
@@ -539,44 +538,44 @@ fn die(cx: &Block) -> ! {
         // We don't need to do actual comparisons for nil.
         // () == () holds but () < () does not.
         match op {
-          ast::BiEq | ast::BiLe | ast::BiGe => return C_i1(cx.ccx(), true),
-          ast::BiNe | ast::BiLt | ast::BiGt => return C_i1(cx.ccx(), false),
+          ast::BiEq | ast::BiLe | ast::BiGe => return C_bool(cx.ccx(), true),
+          ast::BiNe | ast::BiLt | ast::BiGt => return C_bool(cx.ccx(), false),
           // refinements would be nice
           _ => die(cx)
         }
       }
       floating_point => {
         let cmp = match op {
-          ast::BiEq => lib::llvm::RealOEQ,
-          ast::BiNe => lib::llvm::RealUNE,
-          ast::BiLt => lib::llvm::RealOLT,
-          ast::BiLe => lib::llvm::RealOLE,
-          ast::BiGt => lib::llvm::RealOGT,
-          ast::BiGe => lib::llvm::RealOGE,
+          ast::BiEq => llvm::RealOEQ,
+          ast::BiNe => llvm::RealUNE,
+          ast::BiLt => llvm::RealOLT,
+          ast::BiLe => llvm::RealOLE,
+          ast::BiGt => llvm::RealOGT,
+          ast::BiGe => llvm::RealOGE,
           _ => die(cx)
         };
         return FCmp(cx, cmp, lhs, rhs);
       }
       signed_int => {
         let cmp = match op {
-          ast::BiEq => lib::llvm::IntEQ,
-          ast::BiNe => lib::llvm::IntNE,
-          ast::BiLt => lib::llvm::IntSLT,
-          ast::BiLe => lib::llvm::IntSLE,
-          ast::BiGt => lib::llvm::IntSGT,
-          ast::BiGe => lib::llvm::IntSGE,
+          ast::BiEq => llvm::IntEQ,
+          ast::BiNe => llvm::IntNE,
+          ast::BiLt => llvm::IntSLT,
+          ast::BiLe => llvm::IntSLE,
+          ast::BiGt => llvm::IntSGT,
+          ast::BiGe => llvm::IntSGE,
           _ => die(cx)
         };
         return ICmp(cx, cmp, lhs, rhs);
       }
       unsigned_int => {
         let cmp = match op {
-          ast::BiEq => lib::llvm::IntEQ,
-          ast::BiNe => lib::llvm::IntNE,
-          ast::BiLt => lib::llvm::IntULT,
-          ast::BiLe => lib::llvm::IntULE,
-          ast::BiGt => lib::llvm::IntUGT,
-          ast::BiGe => lib::llvm::IntUGE,
+          ast::BiEq => llvm::IntEQ,
+          ast::BiNe => llvm::IntNE,
+          ast::BiLt => llvm::IntULT,
+          ast::BiLe => llvm::IntULE,
+          ast::BiGt => llvm::IntUGT,
+          ast::BiGe => llvm::IntUGE,
           _ => die(cx)
         };
         return ICmp(cx, cmp, lhs, rhs);
@@ -603,12 +602,12 @@ pub fn compare_simd_types(
         },
         ty::ty_uint(_) | ty::ty_int(_) => {
             let cmp = match op {
-                ast::BiEq => lib::llvm::IntEQ,
-                ast::BiNe => lib::llvm::IntNE,
-                ast::BiLt => lib::llvm::IntSLT,
-                ast::BiLe => lib::llvm::IntSLE,
-                ast::BiGt => lib::llvm::IntSGT,
-                ast::BiGe => lib::llvm::IntSGE,
+                ast::BiEq => llvm::IntEQ,
+                ast::BiNe => llvm::IntNE,
+                ast::BiLt => llvm::IntSLT,
+                ast::BiLe => llvm::IntSLE,
+                ast::BiGt => llvm::IntSGT,
+                ast::BiGe => llvm::IntSGE,
                 _ => cx.sess().bug("compare_simd_types: must be a comparison operator"),
             };
             let return_ty = Type::vector(&type_of(cx.ccx(), t), size as u64);
@@ -707,7 +706,7 @@ fn iter_variant<'r,
                       let variant_cx =
                           fcx.new_temp_block(
                               format!("enum-iter-variant-{}",
-                                      variant.disr_val.to_str().as_slice())
+                                      variant.disr_val.to_string().as_slice())
                                      .as_slice());
                       match adt::trans_case(cx, &*repr, variant.disr_val) {
                           _match::single_result(r) => {
@@ -802,15 +801,15 @@ pub fn fail_if_zero_or_overflows<'a>(
     let (is_zero, is_signed) = match ty::get(rhs_t).sty {
         ty::ty_int(t) => {
             let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false);
-            (ICmp(cx, lib::llvm::IntEQ, rhs, zero), true)
+            (ICmp(cx, llvm::IntEQ, rhs, zero), true)
         }
         ty::ty_uint(t) => {
             let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false);
-            (ICmp(cx, lib::llvm::IntEQ, rhs, zero), false)
+            (ICmp(cx, llvm::IntEQ, rhs, zero), false)
         }
         _ => {
             cx.sess().bug(format!("fail-if-zero on unexpected type: {}",
-                                  ty_to_str(cx.tcx(), rhs_t)).as_slice());
+                                  ty_to_string(cx.tcx(), rhs_t)).as_slice());
         }
     };
     let bcx = with_cond(cx, is_zero, |bcx| {
@@ -842,10 +841,10 @@ pub fn fail_if_zero_or_overflows<'a>(
             }
             _ => unreachable!(),
         };
-        let minus_one = ICmp(bcx, lib::llvm::IntEQ, rhs,
+        let minus_one = ICmp(bcx, llvm::IntEQ, rhs,
                              C_integral(llty, -1, false));
         with_cond(bcx, minus_one, |bcx| {
-            let is_min = ICmp(bcx, lib::llvm::IntEQ, lhs,
+            let is_min = ICmp(bcx, llvm::IntEQ, lhs,
                               C_integral(llty, min, true));
             with_cond(bcx, is_min, |bcx| {
                 controlflow::trans_fail(bcx, span,
@@ -863,9 +862,12 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
         ty::ty_bare_fn(ref fn_ty) => {
             match fn_ty.abi.for_target(ccx.sess().targ_cfg.os,
                                        ccx.sess().targ_cfg.arch) {
-                Some(Rust) | Some(RustIntrinsic) => {
+                Some(Rust) => {
                     get_extern_rust_fn(ccx, t, name.as_slice(), did)
                 }
+                Some(RustIntrinsic) => {
+                    ccx.sess().bug("unexpected intrinsic in trans_external_path")
+                }
                 Some(..) | None => {
                     foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
                                                       name.as_slice(), None)
@@ -904,7 +906,7 @@ pub fn invoke<'a>(
             debug!("invoke at ???");
         }
         Some(id) => {
-            debug!("invoke at {}", bcx.tcx().map.node_to_str(id));
+            debug!("invoke at {}", bcx.tcx().map.node_to_string(id));
         }
     }
 
@@ -959,10 +961,42 @@ pub fn need_invoke(bcx: &Block) -> bool {
 
 pub fn load_if_immediate(cx: &Block, v: ValueRef, t: ty::t) -> ValueRef {
     let _icx = push_ctxt("load_if_immediate");
-    if type_is_immediate(cx.ccx(), t) { return Load(cx, v); }
+    if type_is_immediate(cx.ccx(), t) { return load_ty(cx, v, t); }
     return v;
 }
 
+pub fn load_ty(cx: &Block, ptr: ValueRef, t: ty::t) -> ValueRef {
+    /*!
+     * Helper for loading values from memory. Does the necessary conversion if
+     * the in-memory type differs from the type used for SSA values. Also
+     * handles various special cases where the type gives us better information
+     * about what we are loading.
+     */
+    if type_is_zero_size(cx.ccx(), t) {
+        C_undef(type_of::type_of(cx.ccx(), t))
+    } else if ty::type_is_bool(t) {
+        Trunc(cx, LoadRangeAssert(cx, ptr, 0, 2, llvm::False), Type::i1(cx.ccx()))
+    } else if ty::type_is_char(t) {
+        // a char is a unicode codepoint, and so takes values from 0
+        // to 0x10FFFF inclusive only.
+        LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False)
+    } else {
+        Load(cx, ptr)
+    }
+}
+
+pub fn store_ty(cx: &Block, v: ValueRef, dst: ValueRef, t: ty::t) {
+    /*!
+     * Helper for storing values in memory. Does the necessary conversion if
+     * the in-memory type differs from the type used for SSA values.
+     */
+    if ty::type_is_bool(t) {
+        Store(cx, ZExt(cx, v, Type::i8(cx.ccx())), dst);
+    } else {
+        Store(cx, v, dst);
+    };
+}
+
 pub fn ignore_lhs(_bcx: &Block, local: &ast::Local) -> bool {
     match local.pat.node {
         ast::PatWild => true, _ => false
@@ -1014,7 +1048,7 @@ pub fn call_memcpy(cx: &Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef,
     let dst_ptr = PointerCast(cx, dst, Type::i8p(ccx));
     let size = IntCast(cx, n_bytes, ccx.int_type);
     let align = C_i32(ccx, align as i32);
-    let volatile = C_i1(ccx, false);
+    let volatile = C_bool(ccx, false);
     Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile], []);
 }
 
@@ -1059,7 +1093,7 @@ fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
     let llzeroval = C_u8(ccx, 0);
     let size = machine::llsize_of(ccx, ty);
     let align = C_i32(ccx, llalign_of_min(ccx, ty) as i32);
-    let volatile = C_i1(ccx, false);
+    let volatile = C_bool(ccx, false);
     b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], []);
 }
 
@@ -1113,8 +1147,7 @@ pub fn make_return_pointer(fcx: &FunctionContext, output_type: ty::t)
             llvm::LLVMGetParam(fcx.llfn, 0)
         } else {
             let lloutputtype = type_of::type_of(fcx.ccx, output_type);
-            let bcx = fcx.entry_bcx.borrow().clone().unwrap();
-            Alloca(bcx, lloutputtype, "__make_return_pointer")
+            AllocaFcx(fcx, lloutputtype, "__make_return_pointer")
         }
     }
 }
@@ -1143,7 +1176,7 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
            if id == -1 {
                "".to_string()
            } else {
-               ccx.tcx.map.path_to_str(id).to_string()
+               ccx.tcx.map.path_to_string(id).to_string()
            },
            id, param_substs.repr(ccx.tcx()));
 
@@ -1155,7 +1188,6 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
           llfn: llfndecl,
           llenv: None,
           llretptr: Cell::new(None),
-          entry_bcx: RefCell::new(None),
           alloca_insert_pt: Cell::new(None),
           llreturn: Cell::new(None),
           personality: Cell::new(None),
@@ -1185,11 +1217,9 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
 /// and allocating space for the return pointer.
 pub fn init_function<'a>(fcx: &'a FunctionContext<'a>,
                          skip_retptr: bool,
-                         output_type: ty::t) {
+                         output_type: ty::t) -> &'a Block<'a> {
     let entry_bcx = fcx.new_temp_block("entry-block");
 
-    *fcx.entry_bcx.borrow_mut() = Some(entry_bcx);
-
     // Use a dummy instruction as the insertion point for all allocas.
     // This is later removed in FunctionContext::cleanup.
     fcx.alloca_insert_pt.set(Some(unsafe {
@@ -1211,6 +1241,8 @@ pub fn init_function<'a>(fcx: &'a FunctionContext<'a>,
             fcx.llretptr.set(Some(make_return_pointer(fcx, substd_output_type)));
         }
     }
+
+    entry_bcx
 }
 
 // NB: must keep 4 fns in sync:
@@ -1285,9 +1317,14 @@ fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>,
 // Ties up the llstaticallocas -> llloadenv -> lltop edges,
 // and builds the return block.
 pub fn finish_fn<'a>(fcx: &'a FunctionContext<'a>,
-                     last_bcx: &'a Block<'a>) {
+                     last_bcx: &'a Block<'a>,
+                     retty: ty::t) {
     let _icx = push_ctxt("finish_fn");
 
+    // This shouldn't need to recompute the return type,
+    // as new_fn_ctxt did it already.
+    let substd_retty = retty.substp(fcx.ccx.tcx(), fcx.param_substs);
+
     let ret_cx = match fcx.llreturn.get() {
         Some(llreturn) => {
             if !last_bcx.terminated.get() {
@@ -1297,13 +1334,13 @@ pub fn finish_fn<'a>(fcx: &'a FunctionContext<'a>,
         }
         None => last_bcx
     };
-    build_return_block(fcx, ret_cx);
+    build_return_block(fcx, ret_cx, substd_retty);
     debuginfo::clear_source_location(fcx);
     fcx.cleanup();
 }
 
 // Builds the return block for a function.
-pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
+pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block, retty: ty::t) {
     // Return the value if this function immediate; otherwise, return void.
     if fcx.llretptr.get().is_none() || fcx.caller_expects_out_pointer {
         return RetVoid(ret_cx);
@@ -1321,13 +1358,16 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
                 retptr.erase_from_parent();
             }
 
-            retval
+            if ty::type_is_bool(retty) {
+                Trunc(ret_cx, retval, Type::i1(fcx.ccx))
+            } else {
+                retval
+            }
         }
         // Otherwise, load the return value from the ret slot
-        None => Load(ret_cx, fcx.llretptr.get().unwrap())
+        None => load_ty(ret_cx, fcx.llretptr.get().unwrap(), retty)
     };
 
-
     Ret(ret_cx, retval);
 }
 
@@ -1365,15 +1405,11 @@ pub fn trans_closure(ccx: &CrateContext,
                           param_substs,
                           Some(body.span),
                           &arena);
-    init_function(&fcx, false, output_type);
+    let mut bcx = init_function(&fcx, false, output_type);
 
     // cleanup scope for the incoming arguments
     let arg_scope = fcx.push_custom_cleanup_scope();
 
-    // Create the first basic block in the function and keep a handle on it to
-    //  pass to finish_fn later.
-    let bcx_top = fcx.entry_bcx.borrow().clone().unwrap();
-    let mut bcx = bcx_top;
     let block_ty = node_id_type(bcx, body.id);
 
     // Set up arguments to the function.
@@ -1429,7 +1465,7 @@ pub fn trans_closure(ccx: &CrateContext,
     }
 
     // Insert the mandatory first few basic blocks before lltop.
-    finish_fn(&fcx, bcx);
+    finish_fn(&fcx, bcx, output_type);
 }
 
 // trans_fn: creates an LLVM function corresponding to a source language
@@ -1441,7 +1477,7 @@ pub fn trans_fn(ccx: &CrateContext,
                 param_substs: &param_substs,
                 id: ast::NodeId,
                 attrs: &[ast::Attribute]) {
-    let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_str(id).to_string());
+    let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_string(id).to_string());
     debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx()));
     let _icx = push_ctxt("trans_fn");
     let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx(), id));
@@ -1494,20 +1530,18 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
         _ => ccx.sess().bug(
             format!("trans_enum_variant_or_tuple_like_struct: \
                      unexpected ctor return type {}",
-                    ty_to_str(ccx.tcx(), ctor_ty)).as_slice())
+                    ty_to_string(ccx.tcx(), ctor_ty)).as_slice())
     };
 
     let arena = TypedArena::new();
     let fcx = new_fn_ctxt(ccx, llfndecl, ctor_id, false, result_ty,
                           param_substs, None, &arena);
-    init_function(&fcx, false, result_ty);
+    let bcx = init_function(&fcx, false, result_ty);
 
     let arg_tys = ty::ty_fn_args(ctor_ty);
 
     let arg_datums = create_datums_for_fn_args(&fcx, arg_tys.as_slice());
 
-    let bcx = fcx.entry_bcx.borrow().clone().unwrap();
-
     if !type_is_zero_size(fcx.ccx, result_ty) {
         let repr = adt::represent_type(ccx, result_ty);
         adt::trans_start_init(bcx, &*repr, fcx.llretptr.get().unwrap(), disr);
@@ -1521,7 +1555,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
         }
     }
 
-    finish_fn(&fcx, bcx);
+    finish_fn(&fcx, bcx, result_ty);
 }
 
 fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef,
@@ -1721,7 +1755,7 @@ fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: String, node_id: ast::N
     ccx.item_symbols.borrow_mut().insert(node_id, sym);
 
     if !ccx.reachable.contains(&node_id) {
-        lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
+        llvm::SetLinkage(llfn, llvm::InternalLinkage);
     }
 
     // The stack exhaustion lang item shouldn't have a split stack because
@@ -1730,10 +1764,10 @@ fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: String, node_id: ast::N
     let def = ast_util::local_def(node_id);
     if ccx.tcx.lang_items.stack_exhausted() == Some(def) {
         unset_split_stack(llfn);
-        lib::llvm::SetLinkage(llfn, lib::llvm::ExternalLinkage);
+        llvm::SetLinkage(llfn, llvm::ExternalLinkage);
     }
     if ccx.tcx.lang_items.eh_personality() == Some(def) {
-        lib::llvm::SetLinkage(llfn, lib::llvm::ExternalLinkage);
+        llvm::SetLinkage(llfn, llvm::ExternalLinkage);
     }
 
 
@@ -1750,9 +1784,9 @@ fn register_fn(ccx: &CrateContext,
                -> ValueRef {
     match ty::get(node_type).sty {
         ty::ty_bare_fn(ref f) => {
-            assert!(f.abi == Rust || f.abi == RustIntrinsic);
+            assert!(f.abi == Rust);
         }
-        _ => fail!("expected bare rust fn or an intrinsic")
+        _ => fail!("expected bare rust fn")
     };
 
     let llfn = decl_rust_fn(ccx, node_type, sym.as_slice());
@@ -1780,13 +1814,13 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
     // implications directly to the call instruction. Right now,
     // the only attribute we need to worry about is `sret`.
     if type_of::return_uses_outptr(ccx, ret_ty) {
-        attrs.push((1, lib::llvm::StructRetAttribute as u64));
+        attrs.push((1, llvm::StructRetAttribute as u64));
 
         // The outptr can be noalias and nocapture because it's entirely
         // invisible to the program. We can also mark it as nonnull
-        attrs.push((1, lib::llvm::NoAliasAttribute as u64));
-        attrs.push((1, lib::llvm::NoCaptureAttribute as u64));
-        attrs.push((1, lib::llvm::NonNullAttribute as u64));
+        attrs.push((1, llvm::NoAliasAttribute as u64));
+        attrs.push((1, llvm::NoCaptureAttribute as u64));
+        attrs.push((1, llvm::NonNullAttribute as u64));
 
         // Add one more since there's an outptr
         first_arg_offset += 1;
@@ -1800,7 +1834,7 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
                 ty::ty_str | ty::ty_vec(..) | ty::ty_trait(..) => true, _ => false
             } => {}
             ty::ty_uniq(_) => {
-                attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NoAliasAttribute as u64));
+                attrs.push((llvm::ReturnIndex as uint, llvm::NoAliasAttribute as u64));
             }
             _ => {}
         }
@@ -1813,14 +1847,14 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
                 ty::ty_str | ty::ty_vec(..) | ty::ty_trait(..) => true, _ => false
             } => {}
             ty::ty_uniq(_) | ty::ty_rptr(_, _) => {
-                attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NonNullAttribute as u64));
+                attrs.push((llvm::ReturnIndex as uint, llvm::NonNullAttribute as u64));
             }
             _ => {}
         }
 
         match ty::get(ret_ty).sty {
             ty::ty_bool => {
-                attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::ZExtAttribute as u64));
+                attrs.push((llvm::ReturnIndex as uint, llvm::ZExtAttribute as u64));
             }
             _ => {}
         }
@@ -1833,25 +1867,25 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
                 // For non-immediate arguments the callee gets its own copy of
                 // the value on the stack, so there are no aliases. It's also
                 // program-invisible so can't possibly capture
-                attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
-                attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
-                attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+                attrs.push((idx, llvm::NoAliasAttribute as u64));
+                attrs.push((idx, llvm::NoCaptureAttribute as u64));
+                attrs.push((idx, llvm::NonNullAttribute as u64));
             }
             ty::ty_bool => {
-                attrs.push((idx, lib::llvm::ZExtAttribute as u64));
+                attrs.push((idx, llvm::ZExtAttribute as u64));
             }
             // `~` pointer parameters never alias because ownership is transferred
             ty::ty_uniq(_) => {
-                attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
-                attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+                attrs.push((idx, llvm::NoAliasAttribute as u64));
+                attrs.push((idx, llvm::NonNullAttribute as u64));
             }
             // `&mut` pointer parameters never alias other parameters, or mutable global data
             ty::ty_rptr(b, mt) if mt.mutbl == ast::MutMutable => {
-                attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
-                attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+                attrs.push((idx, llvm::NoAliasAttribute as u64));
+                attrs.push((idx, llvm::NonNullAttribute as u64));
                 match b {
                     ReLateBound(_, BrAnon(_)) => {
-                        attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
+                        attrs.push((idx, llvm::NoCaptureAttribute as u64));
                     }
                     _ => {}
                 }
@@ -1859,12 +1893,12 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) -> Vec<(uint, u6
             // When a reference in an argument has no named lifetime, it's impossible for that
             // reference to escape this function (returned or stored beyond the call by a closure).
             ty::ty_rptr(ReLateBound(_, BrAnon(_)), _) => {
-                attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
-                attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+                attrs.push((idx, llvm::NoCaptureAttribute as u64));
+                attrs.push((idx, llvm::NonNullAttribute as u64));
             }
             // & pointer parameters are never null
             ty::ty_rptr(_, _) => {
-                attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+                attrs.push((idx, llvm::NonNullAttribute as u64));
             }
             _ => ()
         }
@@ -1878,7 +1912,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext,
                           sp: Span,
                           sym: String,
                           node_id: ast::NodeId,
-                          cc: lib::llvm::CallConv,
+                          cc: llvm::CallConv,
                           llfty: Type) -> ValueRef {
     debug!("register_fn_llvmty id={} sym={}", node_id, sym);
 
@@ -1979,7 +2013,7 @@ fn exported_name(ccx: &CrateContext, id: ast::NodeId,
         _ => ccx.tcx.map.with_path(id, |mut path| {
             if attr::contains_name(attrs, "no_mangle") {
                 // Don't mangle
-                path.last().unwrap().to_str()
+                path.last().unwrap().to_string()
             } else {
                 match weak_lang_items::link_name(attrs) {
                     Some(name) => name.get().to_string(),
@@ -2039,7 +2073,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                         });
 
                         if !ccx.reachable.contains(&id) {
-                            lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
+                            llvm::SetLinkage(g, llvm::InternalLinkage);
                         }
 
                         // Apply the `unnamed_addr` attribute if
@@ -2047,7 +2081,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                         if !ast_util::static_has_significant_address(
                                 mutbl,
                                 i.attrs.as_slice()) {
-                            lib::llvm::SetUnnamedAddr(g, true);
+                            llvm::SetUnnamedAddr(g, true);
 
                             // This is a curious case where we must make
                             // all of these statics inlineable. If a
@@ -2069,7 +2103,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 
                         if attr::contains_name(i.attrs.as_slice(),
                                                "thread_local") {
-                            lib::llvm::set_thread_local(g, true);
+                            llvm::set_thread_local(g, true);
                         }
 
                         if !inlineable {
@@ -2207,7 +2241,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
     // linkage b/c that doesn't quite make sense. Otherwise items can
     // have internal linkage if they're not reachable.
     if !foreign && !ccx.reachable.contains(&id) {
-        lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage);
+        llvm::SetLinkage(val, llvm::InternalLinkage);
     }
 
     ccx.item_vals.borrow_mut().insert(id, val);
@@ -2270,8 +2304,9 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
                      }.as_slice());
     let llmeta = C_bytes(cx, compressed.as_slice());
     let llconst = C_struct(cx, [llmeta], false);
-    let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,
-                       cx.link_meta.crateid.version_or_default(), cx.link_meta.crate_hash);
+    let name = format!("rust_metadata_{}_{}",
+                       cx.link_meta.crate_name,
+                       cx.link_meta.crate_hash);
     let llglobal = name.with_c_str(|buf| {
         unsafe {
             llvm::LLVMAddGlobal(cx.metadata_llmod, val_ty(llconst).to_ref(), buf)
@@ -2288,9 +2323,8 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
 }
 
 pub fn trans_crate(krate: ast::Crate,
-                   analysis: CrateAnalysis,
-                   output: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
-    let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, .. } = analysis;
+                   analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
+    let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
 
     // Before we touch LLVM, make sure that multithreading is enabled.
     unsafe {
@@ -2310,8 +2344,7 @@ pub fn trans_crate(krate: ast::Crate,
         }
     }
 
-    let link_meta = link::build_link_meta(&krate,
-                                          output.out_filestem.as_slice());
+    let link_meta = link::build_link_meta(&tcx.sess, &krate, name);
 
     // Append ".rs" to crate name as LLVM module identifier.
     //
@@ -2321,7 +2354,7 @@ pub fn trans_crate(krate: ast::Crate,
     // crashes if the module identifier is same as other symbols
     // such as a function name in the module.
     // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
-    let mut llmod_id = link_meta.crateid.name.clone();
+    let mut llmod_id = link_meta.crate_name.clone();
     llmod_id.push_str(".rs");
 
     let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
index 303ad5fbce2ce25283fc13cd4820f60e9121297f..13b8ed4df6b82a9b4b933a8ce2f5c6ce11803314 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use lib::llvm::{llvm, BasicBlockRef};
+use llvm;
+use llvm::{BasicBlockRef};
 use middle::trans::value::{Users, Value};
 use std::iter::{Filter, Map};
 
index e1c02f543bf9e7c4ee2046012efeeeb5ce3c69cc..995ad16b59f5b303c159b15af5f34329f1d4773c 100644 (file)
 #![allow(dead_code)] // FFI wrappers
 #![allow(non_snake_case_functions)]
 
-use lib::llvm::llvm;
-use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
-use lib::llvm::{Opcode, IntPredicate, RealPredicate};
-use lib::llvm::{ValueRef, BasicBlockRef};
-use lib;
+use llvm;
+use llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
+use llvm::{Opcode, IntPredicate, RealPredicate};
+use llvm::{ValueRef, BasicBlockRef};
 use middle::trans::common::*;
 use syntax::codemap::Span;
 
@@ -97,7 +96,7 @@ pub fn Switch(cx: &Block, v: ValueRef, else_: BasicBlockRef, num_cases: uint)
 
 pub fn AddCase(s: ValueRef, on_val: ValueRef, dest: BasicBlockRef) {
     unsafe {
-        if llvm::LLVMIsUndef(s) == lib::llvm::True { return; }
+        if llvm::LLVMIsUndef(s) == llvm::True { return; }
         llvm::LLVMAddCase(s, on_val, dest);
     }
 }
@@ -122,8 +121,8 @@ pub fn Invoke(cx: &Block,
     check_not_terminated(cx);
     terminate(cx, "Invoke");
     debug!("Invoke({} with arguments ({}))",
-           cx.val_to_str(fn_),
-           args.iter().map(|a| cx.val_to_str(*a)).collect::<Vec<String>>().connect(", "));
+           cx.val_to_string(fn_),
+           args.iter().map(|a| cx.val_to_string(*a)).collect::<Vec<String>>().connect(", "));
     B(cx).invoke(fn_, args, then, catch, attributes)
 }
 
@@ -350,7 +349,7 @@ pub fn Load(cx: &Block, pointer_val: ValueRef) -> ValueRef {
         let ccx = cx.fcx.ccx;
         if cx.unreachable.get() {
             let ty = val_ty(pointer_val);
-            let eltty = if ty.kind() == lib::llvm::Array {
+            let eltty = if ty.kind() == llvm::Array {
                 ty.element_type()
             } else {
                 ccx.int_type
@@ -382,11 +381,11 @@ pub fn AtomicLoad(cx: &Block, pointer_val: ValueRef, order: AtomicOrdering) -> V
 
 
 pub fn LoadRangeAssert(cx: &Block, pointer_val: ValueRef, lo: c_ulonglong,
-                       hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
+                       hi: c_ulonglong, signed: llvm::Bool) -> ValueRef {
     if cx.unreachable.get() {
         let ccx = cx.fcx.ccx;
         let ty = val_ty(pointer_val);
-        let eltty = if ty.kind() == lib::llvm::Array {
+        let eltty = if ty.kind() == llvm::Array {
             ty.element_type()
         } else {
             ccx.int_type
@@ -647,7 +646,7 @@ pub fn Phi(cx: &Block, ty: Type, vals: &[ValueRef],
 
 pub fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
     unsafe {
-        if llvm::LLVMIsUndef(phi) == lib::llvm::True { return; }
+        if llvm::LLVMIsUndef(phi) == llvm::True { return; }
         llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
     }
 }
@@ -656,7 +655,7 @@ pub fn _UndefReturn(cx: &Block, fn_: ValueRef) -> ValueRef {
     unsafe {
         let ccx = cx.fcx.ccx;
         let ty = val_ty(fn_);
-        let retty = if ty.kind() == lib::llvm::Integer {
+        let retty = if ty.kind() == llvm::Integer {
             ty.return_type()
         } else {
             ccx.int_type
index a9c1adac3d7cf01e07c3926d4706708e8a087367..32e91c337f0862ff8f7be65f8995a82f24ca9e6a 100644 (file)
 
 #![allow(dead_code)] // FFI wrappers
 
-use lib;
-use lib::llvm::llvm;
-use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
-use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
-use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
+use llvm;
+use llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
+use llvm::{Opcode, IntPredicate, RealPredicate, False};
+use llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
 use middle::trans::base;
 use middle::trans::common::*;
 use middle::trans::machine::llalign_of_pref;
@@ -161,9 +160,9 @@ pub fn invoke(&self,
         self.count_insn("invoke");
 
         debug!("Invoke {} with args ({})",
-               self.ccx.tn.val_to_str(llfn),
+               self.ccx.tn.val_to_string(llfn),
                args.iter()
-                   .map(|&v| self.ccx.tn.val_to_str(v))
+                   .map(|&v| self.ccx.tn.val_to_string(v))
                    .collect::<Vec<String>>()
                    .connect(", "));
 
@@ -460,7 +459,7 @@ pub fn volatile_load(&self, ptr: ValueRef) -> ValueRef {
         self.count_insn("load.volatile");
         unsafe {
             let insn = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname());
-            llvm::LLVMSetVolatile(insn, lib::llvm::True);
+            llvm::LLVMSetVolatile(insn, llvm::True);
             insn
         }
     }
@@ -477,7 +476,7 @@ pub fn atomic_load(&self, ptr: ValueRef, order: AtomicOrdering) -> ValueRef {
 
 
     pub fn load_range_assert(&self, ptr: ValueRef, lo: c_ulonglong,
-                           hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
+                           hi: c_ulonglong, signed: llvm::Bool) -> ValueRef {
         let value = self.load(ptr);
 
         unsafe {
@@ -487,7 +486,7 @@ pub fn load_range_assert(&self, ptr: ValueRef, lo: c_ulonglong,
 
             let v = [min, max];
 
-            llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint,
+            llvm::LLVMSetMetadata(value, llvm::MD_range as c_uint,
                                   llvm::LLVMMDNodeInContext(self.ccx.llcx,
                                                             v.as_ptr(), v.len() as c_uint));
         }
@@ -497,8 +496,8 @@ pub fn load_range_assert(&self, ptr: ValueRef, lo: c_ulonglong,
 
     pub fn store(&self, val: ValueRef, ptr: ValueRef) {
         debug!("Store {} -> {}",
-               self.ccx.tn.val_to_str(val),
-               self.ccx.tn.val_to_str(ptr));
+               self.ccx.tn.val_to_string(val),
+               self.ccx.tn.val_to_string(ptr));
         assert!(self.llbuilder.is_not_null());
         self.count_insn("store");
         unsafe {
@@ -508,20 +507,20 @@ pub fn store(&self, val: ValueRef, ptr: ValueRef) {
 
     pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef) {
         debug!("Store {} -> {}",
-               self.ccx.tn.val_to_str(val),
-               self.ccx.tn.val_to_str(ptr));
+               self.ccx.tn.val_to_string(val),
+               self.ccx.tn.val_to_string(ptr));
         assert!(self.llbuilder.is_not_null());
         self.count_insn("store.volatile");
         unsafe {
             let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
-            llvm::LLVMSetVolatile(insn, lib::llvm::True);
+            llvm::LLVMSetVolatile(insn, llvm::True);
         }
     }
 
     pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering) {
         debug!("Store {} -> {}",
-               self.ccx.tn.val_to_str(val),
-               self.ccx.tn.val_to_str(ptr));
+               self.ccx.tn.val_to_string(val),
+               self.ccx.tn.val_to_string(ptr));
         self.count_insn("store.atomic");
         unsafe {
             let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
@@ -760,7 +759,7 @@ pub fn add_span_comment(&self, sp: Span, text: &str) {
         if self.ccx.sess().asm_comments() {
             let s = format!("{} ({})",
                             text,
-                            self.ccx.sess().codemap().span_to_str(sp));
+                            self.ccx.sess().codemap().span_to_string(sp));
             debug!("{}", s.as_slice());
             self.add_comment(s.as_slice());
         }
@@ -788,17 +787,17 @@ pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
                          dia: AsmDialect) -> ValueRef {
         self.count_insn("inlineasm");
 
-        let volatile = if volatile { lib::llvm::True }
-                       else        { lib::llvm::False };
-        let alignstack = if alignstack { lib::llvm::True }
-                         else          { lib::llvm::False };
+        let volatile = if volatile { llvm::True }
+                       else        { llvm::False };
+        let alignstack = if alignstack { llvm::True }
+                         else          { llvm::False };
 
         let argtys = inputs.iter().map(|v| {
-            debug!("Asm Input Type: {:?}", self.ccx.tn.val_to_str(*v));
+            debug!("Asm Input Type: {:?}", self.ccx.tn.val_to_string(*v));
             val_ty(*v)
         }).collect::<Vec<_>>();
 
-        debug!("Asm Output Type: {:?}", self.ccx.tn.type_to_str(output));
+        debug!("Asm Output Type: {:?}", self.ccx.tn.type_to_string(output));
         let fty = Type::func(argtys.as_slice(), &output);
         unsafe {
             let v = llvm::LLVMInlineAsm(
@@ -812,9 +811,9 @@ pub fn call(&self, llfn: ValueRef, args: &[ValueRef],
         self.count_insn("call");
 
         debug!("Call {} with args ({})",
-               self.ccx.tn.val_to_str(llfn),
+               self.ccx.tn.val_to_string(llfn),
                args.iter()
-                   .map(|&v| self.ccx.tn.val_to_str(v))
+                   .map(|&v| self.ccx.tn.val_to_string(v))
                    .collect::<Vec<String>>()
                    .connect(", "));
 
@@ -832,7 +831,7 @@ pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef],
                           conv: CallConv, attributes: &[(uint, u64)]) -> ValueRef {
         self.count_insn("callwithconv");
         let v = self.call(llfn, args, attributes);
-        lib::llvm::SetInstructionCallConv(v, conv);
+        llvm::SetInstructionCallConv(v, conv);
         v
     }
 
@@ -945,7 +944,7 @@ pub fn landing_pad(&self, ty: Type, pers_fn: ValueRef, num_clauses: uint) -> Val
     pub fn set_cleanup(&self, landing_pad: ValueRef) {
         self.count_insn("setcleanup");
         unsafe {
-            llvm::LLVMSetCleanup(landing_pad, lib::llvm::True);
+            llvm::LLVMSetCleanup(landing_pad, llvm::True);
         }
     }
 
index df1347f6d8f100a31caedf68d3d25ea91a6c8770..0a10fb8b1720830e9ac54b9efd52e151075fc236 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use lib::llvm::Attribute;
+use llvm::Attribute;
 use std::option;
 use middle::trans::context::CrateContext;
 use middle::trans::cabi_x86;
index 01bef64ebba642bf1fa0347de358191b179049eb..0e2bf2104fd55923bb61f002e59b03e855261489 100644 (file)
@@ -10,8 +10,9 @@
 
 #![allow(non_uppercase_pattern_statics)]
 
-use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
-use lib::llvm::{StructRetAttribute, ZExtAttribute};
+use llvm;
+use llvm::{Integer, Pointer, Float, Double, Struct, Array};
+use llvm::{StructRetAttribute, ZExtAttribute};
 use middle::trans::cabi::{FnType, ArgType};
 use middle::trans::context::CrateContext;
 use middle::trans::type_::Type;
@@ -85,7 +86,7 @@ fn ty_size(ty: Type) -> uint {
 
 fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         return ArgType::direct(ty, None, None, attr);
     }
     let size = ty_size(ty);
@@ -104,7 +105,7 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
 
 fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         return ArgType::direct(ty, None, None, attr);
     }
     let align = ty_align(ty);
index 60db609e59ed184cc9b7eac69e711be04643296f..d07090686874f9e8151d33d5fe2ac83f37b203e4 100644 (file)
@@ -12,8 +12,9 @@
 
 use libc::c_uint;
 use std::cmp;
-use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
-use lib::llvm::{StructRetAttribute, ZExtAttribute};
+use llvm;
+use llvm::{Integer, Pointer, Float, Double, Struct, Array};
+use llvm::{StructRetAttribute, ZExtAttribute};
 use middle::trans::context::CrateContext;
 use middle::trans::cabi::*;
 use middle::trans::type_::Type;
@@ -85,7 +86,7 @@ fn ty_size(ty: Type) -> uint {
 
 fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         ArgType::direct(ty, None, None, attr)
     } else {
         ArgType::indirect(ty, Some(StructRetAttribute))
@@ -102,7 +103,7 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut uint) -> ArgType {
     *offset += align_up_to(size, align * 8) / 8;
 
     if is_reg_ty(ty) {
-        let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         ArgType::direct(ty, None, None, attr)
     } else {
         ArgType::direct(
index 5fffdf08646b9824b9f8b1846fbe9041002bdcd2..6bb3d992f50c627a4745666c2072b4b729ff4694 100644 (file)
@@ -10,7 +10,7 @@
 
 
 use syntax::abi::{OsWin32, OsMacos, OsiOS};
-use lib::llvm::*;
+use llvm::*;
 use super::cabi::*;
 use super::common::*;
 use super::machine::*;
@@ -59,7 +59,7 @@ enum Strategy { RetValue(Type), RetPointer }
             }
         }
     } else {
-        let attr = if rty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if rty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
         ret_ty = ArgType::direct(rty, None, None, attr);
     }
 
@@ -74,7 +74,7 @@ enum Strategy { RetValue(Type), RetPointer }
                 }
             }
             _ => {
-                let attr = if t == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+                let attr = if t == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
                 ArgType::direct(t, None, None, attr)
             }
         };
index b2cd9d256dd43c4ea9845a3a74cf84d658433166..493aca0ddf0c415e9d8e45a4738bd859b513ed4c 100644 (file)
 
 #![allow(non_uppercase_pattern_statics)]
 
-use lib::llvm::{llvm, Integer, Pointer, Float, Double};
-use lib::llvm::{Struct, Array, Attribute};
-use lib::llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
+use llvm;
+use llvm::{Integer, Pointer, Float, Double};
+use llvm::{Struct, Array, Attribute};
+use llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
 use middle::trans::cabi::*;
 use middle::trans::context::CrateContext;
 use middle::trans::type_::Type;
@@ -350,7 +351,7 @@ fn x86_64_ty(ccx: &CrateContext,
                                 None)
             }
         } else {
-            let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+            let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
             ArgType::direct(ty, None, None, attr)
         }
     }
index 0cc4a9223d49963bd0909253711d2f3c3d8fb806..db2d17c85db5f64b834d0dde519ec48def0be54d 100644 (file)
@@ -19,9 +19,8 @@
 use arena::TypedArena;
 use back::abi;
 use back::link;
-use driver::session;
-use lib::llvm::ValueRef;
-use lib::llvm::llvm;
+use llvm;
+use llvm::ValueRef;
 use metadata::csearch;
 use middle::def;
 use middle::subst;
@@ -40,6 +39,7 @@
 use middle::trans::glue;
 use middle::trans::inline;
 use middle::trans::foreign;
+use middle::trans::intrinsic;
 use middle::trans::meth;
 use middle::trans::monomorphize;
 use middle::trans::type_::Type;
@@ -53,7 +53,6 @@
 use std::gc::Gc;
 use syntax::ast;
 use synabi = syntax::abi;
-use syntax::ast_map;
 
 pub struct MethodData {
     pub llfn: ValueRef,
@@ -68,6 +67,8 @@ pub enum CalleeData {
     // value (which is a pair).
     Fn(/* llfn */ ValueRef),
 
+    Intrinsic(ast::NodeId, subst::Substs),
+
     TraitMethod(MethodData)
 }
 
@@ -108,7 +109,7 @@ fn datum_callee<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
                     expr.span,
                     format!("type of callee is neither bare-fn nor closure: \
                              {}",
-                            bcx.ty_to_str(datum.ty)).as_slice());
+                            bcx.ty_to_string(datum.ty)).as_slice());
             }
         }
     }
@@ -119,7 +120,21 @@ fn fn_callee<'a>(bcx: &'a Block<'a>, llfn: ValueRef) -> Callee<'a> {
 
     fn trans_def<'a>(bcx: &'a Block<'a>, def: def::Def, ref_expr: &ast::Expr)
                  -> Callee<'a> {
+        debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
+        let expr_ty = node_id_type(bcx, ref_expr.id);
         match def {
+            def::DefFn(did, _) if match ty::get(expr_ty).sty {
+                ty::ty_bare_fn(ref f) => f.abi == synabi::RustIntrinsic,
+                _ => false
+            } => {
+                let substs = node_id_substs(bcx, ExprId(ref_expr.id));
+                let def_id = if did.krate != ast::LOCAL_CRATE {
+                    inline::maybe_instantiate_inline(bcx.ccx(), did)
+                } else {
+                    did
+                };
+                Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
+            }
             def::DefFn(did, _) |
             def::DefStaticMethod(did, def::FromImpl(_), _) => {
                 fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
@@ -216,10 +231,8 @@ fn resolve_default_method_vtables(bcx: &Block,
         bcx.tcx(), &param_substs, &impl_res);
 
     // Now we pull any vtables for parameters on the actual method.
-    param_vtables
-        .get_mut_vec(subst::FnSpace)
-        .push_all(
-            impl_vtables.get_vec(subst::FnSpace).as_slice());
+    param_vtables.push_all(subst::FnSpace,
+                           impl_vtables.get_slice(subst::FnSpace));
 
     param_vtables
 }
@@ -279,10 +292,9 @@ pub fn trans_unboxing_shim(bcx: &Block,
                           &empty_param_substs,
                           None,
                           &block_arena);
-    init_function(&fcx, false, return_type);
+    let mut bcx = init_function(&fcx, false, return_type);
 
     // Create the substituted versions of the self type.
-    let mut bcx = fcx.entry_bcx.borrow().clone().unwrap();
     let arg_scope = fcx.push_custom_cleanup_scope();
     let arg_scope_id = cleanup::CustomScope(arg_scope);
     let boxed_arg_types = ty::ty_fn_args(boxed_function_type);
@@ -348,7 +360,7 @@ pub fn trans_unboxing_shim(bcx: &Block,
                            }).bcx;
 
     bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, arg_scope);
-    finish_fn(&fcx, bcx);
+    finish_fn(&fcx, bcx, return_type);
 
     llfn
 }
@@ -463,27 +475,8 @@ pub fn trans_fn_ref_with_vtables(
         }
     };
 
-    // We must monomorphise if the fn has type parameters, is a rust
-    // intrinsic, or is a default method.  In particular, if we see an
-    // intrinsic that is inlined from a different crate, we want to reemit the
-    // intrinsic instead of trying to call it in the other crate.
-    let must_monomorphise = if !substs.types.is_empty() || is_default {
-        true
-    } else if def_id.krate == ast::LOCAL_CRATE {
-        let map_node = session::expect(
-            ccx.sess(),
-            tcx.map.find(def_id.node),
-            || "local item should be in ast map".to_string());
-
-        match map_node {
-            ast_map::NodeForeignItem(_) => {
-                tcx.map.get_foreign_abi(def_id.node) == synabi::RustIntrinsic
-            }
-            _ => false
-        }
-    } else {
-        false
-    };
+    // We must monomorphise if the fn has type parameters or is a default method.
+    let must_monomorphise = !substs.types.is_empty() || is_default;
 
     // Create a monomorphic version of generic functions
     if must_monomorphise {
@@ -665,6 +658,12 @@ pub fn trans_call_inner<'a>(
     let callee = get_callee(bcx, cleanup::CustomScope(arg_cleanup_scope));
     let mut bcx = callee.bcx;
 
+    let (abi, ret_ty) = match ty::get(callee_ty).sty {
+        ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
+        ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
+        _ => fail!("expected bare rust fn or closure in trans_call_inner")
+    };
+
     let (llfn, llenv, llself) = match callee.data {
         Fn(llfn) => {
             (llfn, None, None)
@@ -682,14 +681,19 @@ pub fn trans_call_inner<'a>(
             let llenv = Load(bcx, llenv);
             (llfn, Some(llenv), None)
         }
-    };
+        Intrinsic(node, substs) => {
+            assert!(abi == synabi::RustIntrinsic);
+            assert!(dest.is_some());
 
-    let (abi, ret_ty) = match ty::get(callee_ty).sty {
-        ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
-        ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
-        _ => fail!("expected bare rust fn or closure in trans_call_inner")
+            return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
+                                                   arg_cleanup_scope, args,
+                                                   dest.unwrap(), substs);
+        }
     };
-    let is_rust_fn = abi == synabi::Rust || abi == synabi::RustIntrinsic;
+
+    // Intrinsics should not become actual functions.
+    // We trans them in place in `trans_intrinsic_call`
+    assert!(abi != synabi::RustIntrinsic);
 
     // Generate a location to store the result. If the user does
     // not care about the result, just make a stack slot.
@@ -719,7 +723,7 @@ pub fn trans_call_inner<'a>(
     // and done, either the return value of the function will have been
     // written in opt_llretslot (if it is Some) or `llresult` will be
     // set appropriately (otherwise).
-    if is_rust_fn {
+    if abi == synabi::Rust {
         let mut llargs = Vec::new();
 
         // Push the out-pointer if we use an out-pointer for this
@@ -760,7 +764,7 @@ pub fn trans_call_inner<'a>(
                 if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
                     !type_is_zero_size(bcx.ccx(), ret_ty)
                 {
-                    Store(bcx, llret, llretslot);
+                    store_ty(bcx, llret, llretslot, ret_ty)
                 }
             }
             None => {}
@@ -819,13 +823,13 @@ pub enum CallArgs<'a> {
     ArgOverloadedOp(Datum<Expr>, Option<(Datum<Expr>, ast::NodeId)>),
 }
 
-fn trans_args<'a>(cx: &'a Block<'a>,
-                  args: CallArgs,
-                  fn_ty: ty::t,
-                  llargs: &mut Vec<ValueRef> ,
-                  arg_cleanup_scope: cleanup::ScopeId,
-                  ignore_self: bool)
-                  -> &'a Block<'a> {
+pub fn trans_args<'a>(cx: &'a Block<'a>,
+                      args: CallArgs,
+                      fn_ty: ty::t,
+                      llargs: &mut Vec<ValueRef> ,
+                      arg_cleanup_scope: cleanup::ScopeId,
+                      ignore_self: bool)
+                      -> &'a Block<'a> {
     let _icx = push_ctxt("trans_args");
     let arg_tys = ty::ty_fn_args(fn_ty);
     let variadic = ty::fn_is_variadic(fn_ty);
@@ -908,7 +912,7 @@ pub fn trans_arg_datum<'a>(
 
     let arg_datum_ty = arg_datum.ty;
 
-    debug!("   arg datum: {}", arg_datum.to_str(bcx.ccx()));
+    debug!("   arg datum: {}", arg_datum.to_string(bcx.ccx()));
 
     let mut val;
     if ty::type_is_bot(arg_datum_ty) {
@@ -952,11 +956,11 @@ pub fn trans_arg_datum<'a>(
             // this could happen due to e.g. subtyping
             let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, formal_arg_ty);
             debug!("casting actual type ({}) to match formal ({})",
-                   bcx.val_to_str(val), bcx.llty_str(llformal_arg_ty));
+                   bcx.val_to_string(val), bcx.llty_str(llformal_arg_ty));
             val = PointerCast(bcx, val, llformal_arg_ty);
         }
     }
 
-    debug!("--- trans_arg_datum passing {}", bcx.val_to_str(val));
+    debug!("--- trans_arg_datum passing {}", bcx.val_to_string(val));
     Result::new(bcx, val)
 }
index 24f30bae75a91fb762330adda0cea01b9bb50bc4..6e40445d8f9038b0a7096f685cb21f9d485a2620 100644 (file)
@@ -13,7 +13,7 @@
  * drop glue. See discussion in `doc.rs` for a high-level summary.
  */
 
-use lib::llvm::{BasicBlockRef, ValueRef};
+use llvm::{BasicBlockRef, ValueRef};
 use middle::trans::base;
 use middle::trans::build;
 use middle::trans::callee;
@@ -85,7 +85,7 @@ fn push_ast_cleanup_scope(&self, id: ast::NodeId) {
          */
 
         debug!("push_ast_cleanup_scope({})",
-               self.ccx.tcx.map.node_to_str(id));
+               self.ccx.tcx.map.node_to_string(id));
 
         // FIXME(#2202) -- currently closure bodies have a parent
         // region, which messes up the assertion below, since there
@@ -109,7 +109,7 @@ fn push_loop_cleanup_scope(&self,
                                id: ast::NodeId,
                                exits: [&'a Block<'a>, ..EXIT_MAX]) {
         debug!("push_loop_cleanup_scope({})",
-               self.ccx.tcx.map.node_to_str(id));
+               self.ccx.tcx.map.node_to_string(id));
         assert_eq!(Some(id), self.top_ast_scope());
 
         self.push_scope(CleanupScope::new(LoopScopeKind(id, exits)));
@@ -133,7 +133,7 @@ fn pop_and_trans_ast_cleanup_scope(&self,
          */
 
         debug!("pop_and_trans_ast_cleanup_scope({})",
-               self.ccx.tcx.map.node_to_str(cleanup_scope));
+               self.ccx.tcx.map.node_to_string(cleanup_scope));
 
         assert!(self.top_scope(|s| s.kind.is_ast_with_id(cleanup_scope)));
 
@@ -152,7 +152,7 @@ fn pop_loop_cleanup_scope(&self,
          */
 
         debug!("pop_loop_cleanup_scope({})",
-               self.ccx.tcx.map.node_to_str(cleanup_scope));
+               self.ccx.tcx.map.node_to_string(cleanup_scope));
 
         assert!(self.top_scope(|s| s.kind.is_loop_with_id(cleanup_scope)));
 
@@ -240,17 +240,45 @@ fn schedule_drop_mem(&self,
             is_immediate: false,
             on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
             val: val,
-            ty: ty
+            ty: ty,
+            zero: false
         };
 
         debug!("schedule_drop_mem({:?}, val={}, ty={})",
                cleanup_scope,
-               self.ccx.tn.val_to_str(val),
+               self.ccx.tn.val_to_string(val),
                ty.repr(self.ccx.tcx()));
 
         self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
     }
 
+    fn schedule_drop_and_zero_mem(&self,
+                                  cleanup_scope: ScopeId,
+                                  val: ValueRef,
+                                  ty: ty::t) {
+        /*!
+         * Schedules a (deep) drop and zero-ing of `val`, which is a pointer
+         * to an instance of `ty`
+         */
+
+        if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        let drop = box DropValue {
+            is_immediate: false,
+            on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
+            val: val,
+            ty: ty,
+            zero: true
+        };
+
+        debug!("schedule_drop_and_zero_mem({:?}, val={}, ty={}, zero={})",
+               cleanup_scope,
+               self.ccx.tn.val_to_string(val),
+               ty.repr(self.ccx.tcx()),
+               true);
+
+        self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
+    }
+
     fn schedule_drop_immediate(&self,
                                cleanup_scope: ScopeId,
                                val: ValueRef,
@@ -264,12 +292,13 @@ fn schedule_drop_immediate(&self,
             is_immediate: true,
             on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
             val: val,
-            ty: ty
+            ty: ty,
+            zero: false
         };
 
         debug!("schedule_drop_immediate({:?}, val={}, ty={})",
                cleanup_scope,
-               self.ccx.tn.val_to_str(val),
+               self.ccx.tn.val_to_string(val),
                ty.repr(self.ccx.tcx()));
 
         self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
@@ -289,7 +318,7 @@ fn schedule_free_value(&self,
 
         debug!("schedule_free_value({:?}, val={}, heap={:?})",
                cleanup_scope,
-               self.ccx.tn.val_to_str(val),
+               self.ccx.tn.val_to_string(val),
                heap);
 
         self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
@@ -329,7 +358,7 @@ fn schedule_clean_in_ast_scope(&self,
 
         self.ccx.sess().bug(
             format!("no cleanup scope {} found",
-                    self.ccx.tcx.map.node_to_str(cleanup_scope)).as_slice());
+                    self.ccx.tcx.map.node_to_string(cleanup_scope)).as_slice());
     }
 
     fn schedule_clean_in_custom_scope(&self,
@@ -824,6 +853,7 @@ pub struct DropValue {
     on_unwind: bool,
     val: ValueRef,
     ty: ty::t,
+    zero: bool
 }
 
 impl Cleanup for DropValue {
@@ -832,11 +862,15 @@ fn clean_on_unwind(&self) -> bool {
     }
 
     fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
-        if self.is_immediate {
+        let bcx = if self.is_immediate {
             glue::drop_ty_immediate(bcx, self.val, self.ty)
         } else {
             glue::drop_ty(bcx, self.val, self.ty)
+        };
+        if self.zero {
+            base::zero_mem(bcx, self.val, self.ty);
         }
+        bcx
     }
 }
 
@@ -927,6 +961,10 @@ fn schedule_drop_mem(&self,
                          cleanup_scope: ScopeId,
                          val: ValueRef,
                          ty: ty::t);
+    fn schedule_drop_and_zero_mem(&self,
+                                  cleanup_scope: ScopeId,
+                                  val: ValueRef,
+                                  ty: ty::t);
     fn schedule_drop_immediate(&self,
                                cleanup_scope: ScopeId,
                                val: ValueRef,
index f956b58031cde143c7812b1936d44ea997f07184..f2400f6bfefe35c6e7470151cb91d29e035a54fe 100644 (file)
@@ -12,7 +12,7 @@
 use back::abi;
 use back::link::mangle_internal_name_by_path_and_seq;
 use driver::config::FullDebugInfo;
-use lib::llvm::ValueRef;
+use llvm::ValueRef;
 use middle::def;
 use middle::freevars;
 use middle::lang_items::ClosureExchangeMallocFnLangItem;
@@ -27,7 +27,7 @@
 use middle::trans::type_::Type;
 use middle::ty;
 use util::ppaux::Repr;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 use arena::TypedArena;
 use syntax::ast;
@@ -104,8 +104,8 @@ pub struct EnvValue {
 }
 
 impl EnvValue {
-    pub fn to_str(&self, ccx: &CrateContext) -> String {
-        format!("{}({})", self.action, self.datum.to_str(ccx))
+    pub fn to_string(&self, ccx: &CrateContext) -> String {
+        format!("{}({})", self.action, self.datum.to_string(ccx))
     }
 }
 
@@ -124,7 +124,7 @@ pub fn mk_closure_tys(tcx: &ty::ctxt,
         }
     }).collect();
     let cdata_ty = ty::mk_tup(tcx, bound_tys);
-    debug!("cdata_ty={}", ty_to_str(tcx, cdata_ty));
+    debug!("cdata_ty={}", ty_to_string(tcx, cdata_ty));
     return cdata_ty;
 }
 
@@ -196,16 +196,16 @@ pub fn store_environment<'a>(
     let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, store, cdata_ty);
 
     let llbox = PointerCast(bcx, llbox, llboxptr_ty);
-    debug!("tuplify_box_ty = {}", ty_to_str(tcx, cbox_ty));
+    debug!("tuplify_box_ty = {}", ty_to_string(tcx, cbox_ty));
 
     // Copy expr values into boxed bindings.
     let mut bcx = bcx;
     for (i, bv) in bound_values.move_iter().enumerate() {
-        debug!("Copy {} into closure", bv.to_str(ccx));
+        debug!("Copy {} into closure", bv.to_string(ccx));
 
         if ccx.sess().asm_comments() {
             add_comment(bcx, format!("Copy {} into closure",
-                                     bv.to_str(ccx)).as_slice());
+                                     bv.to_string(ccx)).as_slice());
         }
 
         let bound_data = GEPi(bcx, llbox, [0u, abi::box_field_body, i]);
@@ -424,8 +424,7 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
     let empty_param_substs = param_substs::empty();
     let fcx = new_fn_ctxt(ccx, llfn, -1, true, f.sig.output,
                           &empty_param_substs, None, &arena);
-    init_function(&fcx, true, f.sig.output);
-    let bcx = fcx.entry_bcx.borrow().clone().unwrap();
+    let bcx = init_function(&fcx, true, f.sig.output);
 
     let args = create_datums_for_fn_args(&fcx,
                                          ty::ty_fn_args(closure_ty)
index b1577a6abfe1452f461a3a59c20ebb388424ad2a..945185f59534208593556a85b663f67dd119ab6d 100644 (file)
 //! Code that is useful in various trans modules.
 
 use driver::session::Session;
-use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef};
-use lib::llvm::{True, False, Bool};
-use lib::llvm::llvm;
-use lib;
+use llvm;
+use llvm::{ValueRef, BasicBlockRef, BuilderRef};
+use llvm::{True, False, Bool};
 use middle::def;
 use middle::lang_items::LangItem;
 use middle::subst;
@@ -196,13 +195,13 @@ pub fn validate(&self) {
     }
 }
 
-fn param_substs_to_str(this: &param_substs, tcx: &ty::ctxt) -> String {
+fn param_substs_to_string(this: &param_substs, tcx: &ty::ctxt) -> String {
     format!("param_substs({})", this.substs.repr(tcx))
 }
 
 impl Repr for param_substs {
     fn repr(&self, tcx: &ty::ctxt) -> String {
-        param_substs_to_str(self, tcx)
+        param_substs_to_string(self, tcx)
     }
 }
 
@@ -239,8 +238,6 @@ pub struct FunctionContext<'a> {
     // always be Some.
     pub llretptr: Cell<Option<ValueRef>>,
 
-    pub entry_bcx: RefCell<Option<&'a Block<'a>>>,
-
     // These pub elements: "hoisted basic blocks" containing
     // administrative activities that have to happen in only one place in
     // the function, due to LLVM's quirks.
@@ -322,8 +319,6 @@ pub fn cleanup(&self) {
                                                      .get()
                                                      .unwrap());
         }
-        // Remove the cycle between fcx and bcx, so memory can be freed
-        *self.entry_bcx.borrow_mut() = None;
     }
 
     pub fn get_llreturn(&self) -> BasicBlockRef {
@@ -440,11 +435,11 @@ pub fn ident(&self, ident: Ident) -> String {
         token::get_ident(ident).get().to_string()
     }
 
-    pub fn node_id_to_str(&self, id: ast::NodeId) -> String {
-        self.tcx().map.node_to_str(id).to_string()
+    pub fn node_id_to_string(&self, id: ast::NodeId) -> String {
+        self.tcx().map.node_to_string(id).to_string()
     }
 
-    pub fn expr_to_str(&self, e: &ast::Expr) -> String {
+    pub fn expr_to_string(&self, e: &ast::Expr) -> String {
         e.repr(self.tcx())
     }
 
@@ -458,15 +453,15 @@ pub fn def(&self, nid: ast::NodeId) -> def::Def {
         }
     }
 
-    pub fn val_to_str(&self, val: ValueRef) -> String {
-        self.ccx().tn.val_to_str(val)
+    pub fn val_to_string(&self, val: ValueRef) -> String {
+        self.ccx().tn.val_to_string(val)
     }
 
     pub fn llty_str(&self, ty: Type) -> String {
-        self.ccx().tn.type_to_str(ty)
+        self.ccx().tn.type_to_string(ty)
     }
 
-    pub fn ty_to_str(&self, t: ty::t) -> String {
+    pub fn ty_to_string(&self, t: ty::t) -> String {
         t.repr(self.tcx())
     }
 
@@ -526,10 +521,6 @@ pub fn C_nil(ccx: &CrateContext) -> ValueRef {
 }
 
 pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
-    C_integral(Type::bool(ccx), val as u64, false)
-}
-
-pub fn C_i1(ccx: &CrateContext, val: bool) -> ValueRef {
     C_integral(Type::i1(ccx), val as u64, false)
 }
 
@@ -578,7 +569,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
         });
         llvm::LLVMSetInitializer(g, sc);
         llvm::LLVMSetGlobalConstant(g, True);
-        lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
+        llvm::SetLinkage(g, llvm::InternalLinkage);
 
         cx.const_cstr_cache.borrow_mut().insert(s, g);
         g
@@ -607,7 +598,7 @@ pub fn C_binary_slice(cx: &CrateContext, data: &[u8]) -> ValueRef {
         });
         llvm::LLVMSetInitializer(g, lldata);
         llvm::LLVMSetGlobalConstant(g, True);
-        lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
+        llvm::SetLinkage(g, llvm::InternalLinkage);
 
         let cs = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref());
         C_struct(cx, [cs, C_uint(cx, len)], false)
@@ -653,7 +644,7 @@ pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
         let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
 
         debug!("const_get_elt(v={}, us={:?}, r={})",
-               cx.tn.val_to_str(v), us, cx.tn.val_to_str(r));
+               cx.tn.val_to_string(v), us, cx.tn.val_to_string(r));
 
         return r;
     }
index 527ce5dfaae4591d62285d229780ae8137279736..2fd468d8fda8fbe248c90b694fa146dc60fe4244 100644 (file)
 
 
 use back::abi;
-use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True,
+use llvm;
+use llvm::{ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True,
     False};
-use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
+use llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
     RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE};
 
 use metadata::csearch;
@@ -31,7 +32,7 @@
 use middle::trans::type_of;
 use middle::trans::debuginfo;
 use middle::ty;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
 
 use std::c_str::ToCStr;
 use std::gc::Gc;
@@ -42,6 +43,7 @@
 pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
     -> ValueRef {
     let _icx = push_ctxt("trans_lit");
+    debug!("const_lit: {}", lit);
     match lit.node {
         ast::LitByte(b) => C_integral(Type::uint_from_ty(cx, ast::TyU8), b as u64, false),
         ast::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
@@ -59,7 +61,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
                 _ => cx.sess().span_bug(lit.span,
                         format!("integer literal has type {} (expected int \
                                  or uint)",
-                                ty_to_str(cx.tcx(), lit_int_ty)).as_slice())
+                                ty_to_string(cx.tcx(), lit_int_ty)).as_slice())
             }
         }
         ast::LitFloat(ref fs, t) => {
@@ -155,14 +157,14 @@ fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool)
                 }
                 _ => {
                     cx.sess().bug(format!("unexpected dereferenceable type {}",
-                                          ty_to_str(cx.tcx(), t)).as_slice())
+                                          ty_to_string(cx.tcx(), t)).as_slice())
                 }
             };
             (dv, mt.ty)
         }
         None => {
             cx.sess().bug(format!("can't dereference const of type {}",
-                                  ty_to_str(cx.tcx(), t)).as_slice())
+                                  ty_to_string(cx.tcx(), t)).as_slice())
         }
     }
 }
@@ -285,7 +287,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
             llvm::LLVMDumpValue(C_undef(llty));
         }
         cx.sess().bug(format!("const {} of type {} has size {} instead of {}",
-                         e.repr(cx.tcx()), ty_to_str(cx.tcx(), ety),
+                         e.repr(cx.tcx()), ty_to_string(cx.tcx(), ety),
                          csize, tsize).as_slice());
     }
     (llconst, inlineable)
@@ -484,8 +486,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                 if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty.to_ref()) }
                 else { llvm::LLVMConstFPToUI(v, llty.to_ref()) }
               }
-              (expr::cast_enum, expr::cast_integral) |
-              (expr::cast_enum, expr::cast_float)  => {
+              (expr::cast_enum, expr::cast_integral) => {
                 let repr = adt::represent_type(cx, basety);
                 let discr = adt::const_get_discrim(cx, &*repr, v);
                 let iv = C_integral(cx.int_type, discr, false);
index 6387ec791bab93d6b5f4c5c9698c718ad2db55b3..8c55f33a0d46dd19b9c912c6f84010263704c6c1 100644 (file)
 
 use driver::config::NoDebugInfo;
 use driver::session::Session;
-use lib::llvm::{ContextRef, ModuleRef, ValueRef};
-use lib::llvm::{llvm, TargetData, TypeNames};
-use lib::llvm::mk_target_data;
+use llvm;
+use llvm::{ContextRef, ModuleRef, ValueRef};
+use llvm::{TargetData};
+use llvm::mk_target_data;
 use metadata::common::LinkMeta;
 use middle::resolve;
 use middle::trans::adt;
@@ -21,7 +22,7 @@
 use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res};
 use middle::trans::debuginfo;
 use middle::trans::monomorphize::MonoId;
-use middle::trans::type_::Type;
+use middle::trans::type_::{Type, TypeNames};
 use middle::ty;
 use util::sha2::Sha256;
 use util::nodemap::{NodeMap, NodeSet, DefIdMap};
index e9b1c56eb00320485f34ccc5767d3e328436ec6b..845684bb037a935f55f7d2abbf0bfe119621431f 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use lib::llvm::*;
+use llvm::*;
 use driver::config::FullDebugInfo;
 use middle::def;
 use middle::lang_items::{FailFnLangItem, FailBoundsCheckFnLangItem};
@@ -126,8 +126,8 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
                     dest: expr::Dest)
                     -> &'a Block<'a> {
     debug!("trans_if(bcx={}, if_id={}, cond={}, thn={:?}, dest={})",
-           bcx.to_str(), if_id, bcx.expr_to_str(cond), thn.id,
-           dest.to_str(bcx.ccx()));
+           bcx.to_str(), if_id, bcx.expr_to_string(cond), thn.id,
+           dest.to_string(bcx.ccx()));
     let _icx = push_ctxt("trans_if");
     let mut bcx = bcx;
 
index 440aa36b28cbd2e9e8cb864b0bc9aa044fa27150..d4b2b04745b58903689f66b2ae8a83000ff6e6fd 100644 (file)
  * Datums are and how they are intended to be used.
  */
 
-use lib;
-use lib::llvm::ValueRef;
+use llvm::ValueRef;
 use middle::trans::base::*;
-use middle::trans::build::*;
 use middle::trans::common::*;
 use middle::trans::cleanup;
 use middle::trans::cleanup::CleanupMethods;
@@ -25,7 +23,7 @@
 use middle::trans::tvec;
 use middle::trans::type_of;
 use middle::ty;
-use util::ppaux::{ty_to_str};
+use util::ppaux::{ty_to_string};
 
 use syntax::ast;
 
@@ -344,7 +342,7 @@ pub fn to_appropriate_datum<'a>(self,
                 match self.kind.mode {
                     ByValue => DatumBlock::new(bcx, self),
                     ByRef => {
-                        let llval = load(bcx, self.val, self.ty);
+                        let llval = load_ty(bcx, self.val, self.ty);
                         DatumBlock::new(bcx, Datum::new(llval, self.ty, Rvalue::new(ByValue)))
                     }
                 }
@@ -471,7 +469,7 @@ pub fn to_rvalue_datum<'a>(self,
                         DatumBlock::new(bcx, scratch)
                     }
                     ByValue => {
-                        let v = load(bcx, l.val, l.ty);
+                        let v = load_ty(bcx, l.val, l.ty);
                         bcx = l.kind.post_store(bcx, l.val, l.ty);
                         DatumBlock::new(bcx, Datum::new(v, l.ty, Rvalue::new(ByValue)))
                     }
@@ -516,24 +514,6 @@ pub fn get_vec_base_and_len<'a>(&self, bcx: &'a Block<'a>) -> (ValueRef, ValueRe
     }
 }
 
-fn load<'a>(bcx: &'a Block<'a>, llptr: ValueRef, ty: ty::t) -> ValueRef {
-    /*!
-     * Private helper for loading from a by-ref datum. Handles various
-     * special cases where the type gives us better information about
-     * what we are loading.
-     */
-
-    if type_is_zero_size(bcx.ccx(), ty) {
-        C_undef(type_of::type_of(bcx.ccx(), ty))
-    } else if ty::type_is_char(ty) {
-        // a char is a unicode codepoint, and so takes values from 0
-        // to 0x10FFFF inclusive only.
-        LoadRangeAssert(bcx, llptr, 0, 0x10FFFF + 1, lib::llvm::False)
-    } else {
-        Load(bcx, llptr)
-    }
-}
-
 /**
  * Generic methods applicable to any sort of datum.
  */
@@ -591,7 +571,7 @@ fn shallow_copy<'a>(&self,
         if self.kind.is_by_ref() {
             memcpy_ty(bcx, dst, self.val, self.ty);
         } else {
-            Store(bcx, self.val, dst);
+            store_ty(bcx, self.val, dst, self.ty);
         }
 
         return bcx;
@@ -616,10 +596,10 @@ pub fn shallow_copy_and_take<'a>(&self,
     }
 
     #[allow(dead_code)] // useful for debugging
-    pub fn to_str(&self, ccx: &CrateContext) -> String {
+    pub fn to_string(&self, ccx: &CrateContext) -> String {
         format!("Datum({}, {}, {:?})",
-                ccx.tn.val_to_str(self.val),
-                ty_to_str(ccx.tcx(), self.ty),
+                ccx.tn.val_to_string(self.val),
+                ty_to_string(ccx.tcx(), self.ty),
                 self.kind)
     }
 
@@ -642,7 +622,7 @@ pub fn to_llscalarish<'a>(self, bcx: &'a Block<'a>) -> ValueRef {
         assert!(!ty::type_needs_drop(bcx.tcx(), self.ty));
         assert!(self.appropriate_rvalue_mode(bcx.ccx()) == ByValue);
         if self.kind.is_by_ref() {
-            load(bcx, self.val, self.ty)
+            load_ty(bcx, self.val, self.ty)
         } else {
             self.val
         }
index b3c7c0d0fac46e19c278ed001880bf935842e695..6e81c10c4a0a91a80e5a871b742c36f1e7adcb25 100644 (file)
@@ -180,9 +180,9 @@ struct List {
 
 use driver::config;
 use driver::config::{FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
-use lib::llvm::llvm;
-use lib::llvm::{ModuleRef, ContextRef, ValueRef};
-use lib::llvm::debuginfo::*;
+use llvm;
+use llvm::{ModuleRef, ContextRef, ValueRef};
+use llvm::debuginfo::*;
 use metadata::csearch;
 use middle::subst;
 use middle::trans::adt;
@@ -270,7 +270,7 @@ fn register_type_with_metadata(&mut self,
                                    metadata: DIType) {
         if !self.type_to_metadata.insert(ty::type_id(type_), metadata) {
             cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!",
-                                   ppaux::ty_to_str(cx.tcx(), type_)).as_slice());
+                                   ppaux::ty_to_string(cx.tcx(), type_)).as_slice());
         }
     }
 
@@ -504,7 +504,7 @@ fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> Uni
             },
             _ => {
                 cx.sess().bug(format!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
-                                      ppaux::ty_to_str(cx.tcx(), type_).as_slice(),
+                                      ppaux::ty_to_string(cx.tcx(), type_).as_slice(),
                                       ty::get(type_).sty).as_slice())
             }
         };
@@ -554,7 +554,7 @@ fn from_def_id_and_substs(type_map: &mut TypeMap,
 
             // Maybe check that there is no self type here.
 
-            let tps = substs.types.get_vec(subst::TypeSpace);
+            let tps = substs.types.get_slice(subst::TypeSpace);
             if tps.len() > 0 {
                 output.push_char('<');
 
@@ -808,7 +808,7 @@ pub fn create_global_var_metadata(cx: &CrateContext,
     let type_metadata = type_metadata(cx, variable_type, span);
 
     let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
-    let var_name = token::get_ident(ident).get().to_str();
+    let var_name = token::get_ident(ident).get().to_string();
     let linkage_name =
         namespace_node.mangled_name_of_contained_item(var_name.as_slice());
     let var_scope = namespace_node.scope;
@@ -1056,7 +1056,7 @@ pub fn set_source_location(fcx: &FunctionContext,
         FunctionDebugContext(box ref function_debug_context) => {
             let cx = fcx.ccx;
 
-            debug!("set_source_location: {}", cx.sess().codemap().span_to_str(span));
+            debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
 
             if function_debug_context.source_locations_enabled.get() {
                 let loc = span_start(cx, span);
@@ -1138,10 +1138,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
             }
         }
         ast_map::NodeMethod(ref method) => {
-            (method.ident,
-             method.decl,
-             &method.generics,
-             method.body,
+            (ast_util::method_ident(&**method),
+             ast_util::method_fn_decl(&**method),
+             ast_util::method_generics(&**method),
+             ast_util::method_body(&**method),
              method.span,
              true)
         }
@@ -1167,10 +1167,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
         ast_map::NodeTraitMethod(ref trait_method) => {
             match **trait_method {
                 ast::Provided(ref method) => {
-                    (method.ident,
-                     method.decl,
-                     &method.generics,
-                     method.body,
+                    (ast_util::method_ident(&**method),
+                     ast_util::method_fn_decl(&**method),
+                     ast_util::method_generics(&**method),
+                     ast_util::method_body(&**method),
                      method.span,
                      true)
                 }
@@ -1377,9 +1377,9 @@ fn get_template_parameters(cx: &CrateContext,
         }
 
         // Handle other generic parameters
-        let actual_types = param_substs.substs.types.get_vec(subst::FnSpace);
+        let actual_types = param_substs.substs.types.get_slice(subst::FnSpace);
         for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() {
-            let actual_type = *actual_types.get(index);
+            let actual_type = actual_types[index];
             // Add actual type name to <...> clause of function name
             let actual_type_name = compute_debuginfo_type_name(cx,
                                                                actual_type,
@@ -1496,7 +1496,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
     });
 
     fn fallback_path(cx: &CrateContext) -> CString {
-        cx.link_meta.crateid.name.as_slice().to_c_str()
+        cx.link_meta.crate_name.as_slice().to_c_str()
     }
 }
 
@@ -1812,7 +1812,7 @@ fn finalize(&self, cx: &CrateContext) -> MetadataCreationResult {
                        type_map.find_metadata_for_type(unfinished_type).is_none() {
                         cx.sess().bug(format!("Forward declaration of potentially recursive type \
                                               '{}' was not found in TypeMap!",
-                                              ppaux::ty_to_str(cx.tcx(), unfinished_type))
+                                              ppaux::ty_to_string(cx.tcx(), unfinished_type))
                                       .as_slice());
                     }
                 }
@@ -2152,8 +2152,12 @@ fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription
                 let null_variant_index = (1 - nndiscr) as uint;
                 let null_variant_ident = self.variants.get(null_variant_index).name;
                 let null_variant_name = token::get_ident(null_variant_ident);
+                let discrfield = match ptrfield {
+                    adt::ThinPointer(field) => format!("{}", field),
+                    adt::FatPointer(field, pair) => format!("{}${}", field, pair)
+                };
                 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
-                                                ptrfield,
+                                                discrfield,
                                                 null_variant_name);
 
                 // Create the (singleton) list of descriptions of union members.
@@ -2196,7 +2200,7 @@ fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription
 
 enum EnumDiscriminantInfo {
     RegularDiscriminant(DIType),
-    OptimizedDiscriminant(uint),
+    OptimizedDiscriminant(adt::PointerField),
     NoDiscriminant
 }
 
@@ -2241,7 +2245,7 @@ fn describe_enum_variant(cx: &CrateContext,
         Some(ref names) => {
             names.iter()
                  .map(|ident| {
-                     token::get_ident(*ident).get().to_str().into_string()
+                     token::get_ident(*ident).get().to_string().into_string()
                  }).collect()
         }
         None => variant_info.args.iter().map(|_| "".to_string()).collect()
@@ -2868,7 +2872,7 @@ fn trait_pointer_metadata(cx: &CrateContext,
         ty::ty_uniq(pointee_type) => pointee_type,
         ty::ty_rptr(_, ty::mt { ty, .. }) => ty,
         _ => {
-            let pp_type_name = ppaux::ty_to_str(cx.tcx(), trait_pointer_type);
+            let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_pointer_type);
             cx.sess().bug(format!("debuginfo: Unexpected trait-pointer type in \
                                    trait_pointer_metadata(): {}",
                                    pp_type_name.as_slice()).as_slice());
@@ -2878,7 +2882,7 @@ fn trait_pointer_metadata(cx: &CrateContext,
     let def_id = match ty::get(trait_object_type).sty {
         ty::ty_trait(box ty::TyTrait { def_id, .. }) => def_id,
         _ => {
-            let pp_type_name = ppaux::ty_to_str(cx.tcx(), trait_object_type);
+            let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_object_type);
             cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \
                                    trait_pointer_metadata(): {}",
                                    pp_type_name.as_slice()).as_slice());
@@ -3060,7 +3064,7 @@ fn type_metadata(cx: &CrateContext,
                                                  the debuginfo::TypeMap but it \
                                                  was not. (ty::t = {})",
                                                 unique_type_id_str.as_slice(),
-                                                ppaux::ty_to_str(cx.tcx(), t));
+                                                ppaux::ty_to_string(cx.tcx(), t));
                     cx.sess().span_bug(usage_site_span, error_message.as_slice());
                 }
             };
@@ -3075,7 +3079,7 @@ fn type_metadata(cx: &CrateContext,
                                                      debuginfo::TypeMap. \
                                                      UniqueTypeId={}, ty::t={}",
                             unique_type_id_str.as_slice(),
-                            ppaux::ty_to_str(cx.tcx(), t));
+                            ppaux::ty_to_string(cx.tcx(), t));
                         cx.sess().span_bug(usage_site_span, error_message.as_slice());
                     }
                 }
@@ -3875,7 +3879,7 @@ fn push_debuginfo_type_name(cx: &CrateContext,
         ty::ty_infer(_) |
         ty::ty_param(_) => {
             cx.sess().bug(format!("debuginfo: Trying to create type name for \
-                unexpected type: {}", ppaux::ty_to_str(cx.tcx(), t)).as_slice());
+                unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t)).as_slice());
         }
     }
 
@@ -3972,7 +3976,7 @@ fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
 }
 
 fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str {
-    cx.link_meta.crateid.name.as_slice()
+    cx.link_meta.crate_name.as_slice()
 }
 
 fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
index b10190b23c721c87058a0f22bdee69ee53355e17..60bf80191cb1057386a73b7d84f7b87a189ee877 100644 (file)
@@ -34,8 +34,8 @@
 #![allow(non_camel_case_types)]
 
 use back::abi;
-use lib::llvm::{ValueRef, llvm};
-use lib;
+use llvm;
+use llvm::{ValueRef};
 use metadata::csearch;
 use middle::def;
 use middle::lang_items::MallocFnLangItem;
@@ -75,7 +75,7 @@
 
 use syntax::ast;
 use syntax::codemap;
-use syntax::print::pprust::{expr_to_str};
+use syntax::print::pprust::{expr_to_string};
 
 use std::gc::Gc;
 
@@ -91,9 +91,9 @@ pub enum Dest {
 }
 
 impl Dest {
-    pub fn to_str(&self, ccx: &CrateContext) -> String {
+    pub fn to_string(&self, ccx: &CrateContext) -> String {
         match *self {
-            SaveIn(v) => format!("SaveIn({})", ccx.tn.val_to_str(v)),
+            SaveIn(v) => format!("SaveIn({})", ccx.tn.val_to_string(v)),
             Ignore => "Ignore".to_string()
         }
     }
@@ -148,7 +148,7 @@ pub fn trans<'a>(bcx: &'a Block<'a>,
      * the stack.
      */
 
-    debug!("trans(expr={})", bcx.expr_to_str(expr));
+    debug!("trans(expr={})", bcx.expr_to_string(expr));
 
     let mut bcx = bcx;
     let fcx = bcx.fcx;
@@ -178,7 +178,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
         Some(adj) => { adj }
     };
     debug!("unadjusted datum for expr {}: {}",
-           expr.id, datum.to_str(bcx.ccx()));
+           expr.id, datum.to_string(bcx.ccx()));
     match adjustment {
         AutoAddEnv(..) => {
             datum = unpack_datum!(bcx, add_env(bcx, expr, datum));
@@ -216,7 +216,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
             datum = scratch.to_expr_datum();
         }
     }
-    debug!("after adjustments, datum={}", datum.to_str(bcx.ccx()));
+    debug!("after adjustments, datum={}", datum.to_string(bcx.ccx()));
     return DatumBlock {bcx: bcx, datum: datum};
 
     fn auto_slice<'a>(
@@ -325,7 +325,7 @@ fn trans_unadjusted<'a>(bcx: &'a Block<'a>,
 
     let mut bcx = bcx;
 
-    debug!("trans_unadjusted(expr={})", bcx.expr_to_str(expr));
+    debug!("trans_unadjusted(expr={})", bcx.expr_to_string(expr));
     let _indenter = indenter();
 
     debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
@@ -396,7 +396,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
             trans_rec_field(bcx, &**base, ident.node)
         }
         ast::ExprIndex(ref base, ref idx) => {
-            trans_index(bcx, expr, &**base, &**idx)
+            trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id))
         }
         ast::ExprVstore(ref contents, ast::ExprVstoreUniq) => {
             fcx.push_ast_cleanup_scope(contents.id);
@@ -467,7 +467,8 @@ fn trans_rec_field<'a>(bcx: &'a Block<'a>,
 fn trans_index<'a>(bcx: &'a Block<'a>,
                    index_expr: &ast::Expr,
                    base: &ast::Expr,
-                   idx: &ast::Expr)
+                   idx: &ast::Expr,
+                   method_call: MethodCall)
                    -> DatumBlock<'a, Expr> {
     //! Translates `base[idx]`.
 
@@ -475,43 +476,97 @@ fn trans_index<'a>(bcx: &'a Block<'a>,
     let ccx = bcx.ccx();
     let mut bcx = bcx;
 
-    let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base, "index"));
-
-    // Translate index expression and cast to a suitable LLVM integer.
-    // Rust is less strict than LLVM in this regard.
-    let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
-    let ix_val = ix_datum.to_llscalarish(bcx);
-    let ix_size = machine::llbitsize_of_real(bcx.ccx(), val_ty(ix_val));
-    let int_size = machine::llbitsize_of_real(bcx.ccx(), ccx.int_type);
-    let ix_val = {
-        if ix_size < int_size {
-            if ty::type_is_signed(expr_ty(bcx, idx)) {
-                SExt(bcx, ix_val, ccx.int_type)
-            } else { ZExt(bcx, ix_val, ccx.int_type) }
-        } else if ix_size > int_size {
-            Trunc(bcx, ix_val, ccx.int_type)
-        } else {
-            ix_val
-        }
-    };
+    // Check for overloaded index.
+    let method_ty = ccx.tcx
+                       .method_map
+                       .borrow()
+                       .find(&method_call)
+                       .map(|method| method.ty);
+    let elt_datum = match method_ty {
+        Some(method_ty) => {
+            let base_datum = unpack_datum!(bcx, trans(bcx, base));
 
-    let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), base_datum.ty));
-    base::maybe_name_value(bcx.ccx(), vt.llunit_size, "unit_sz");
+            // Translate index expression.
+            let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
 
-    let (base, len) = base_datum.get_vec_base_and_len(bcx);
+            // Overloaded. Evaluate `trans_overloaded_op`, which will
+            // invoke the user's index() method, which basically yields
+            // a `&T` pointer.  We can then proceed down the normal
+            // path (below) to dereference that `&T`.
+            let val =
+                unpack_result!(bcx,
+                               trans_overloaded_op(bcx,
+                                                   index_expr,
+                                                   method_call,
+                                                   base_datum,
+                                                   Some((ix_datum, idx.id)),
+                                                   None));
+            let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty));
+            let elt_ty = match ty::deref(ref_ty, true) {
+                None => {
+                    bcx.tcx().sess.span_bug(index_expr.span,
+                                            "index method didn't return a \
+                                             dereferenceable type?!")
+                }
+                Some(elt_tm) => elt_tm.ty,
+            };
+            Datum::new(val, elt_ty, LvalueExpr)
+        }
+        None => {
+            let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx,
+                                                                base,
+                                                                "index"));
+
+            // Translate index expression and cast to a suitable LLVM integer.
+            // Rust is less strict than LLVM in this regard.
+            let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
+            let ix_val = ix_datum.to_llscalarish(bcx);
+            let ix_size = machine::llbitsize_of_real(bcx.ccx(),
+                                                     val_ty(ix_val));
+            let int_size = machine::llbitsize_of_real(bcx.ccx(),
+                                                      ccx.int_type);
+            let ix_val = {
+                if ix_size < int_size {
+                    if ty::type_is_signed(expr_ty(bcx, idx)) {
+                        SExt(bcx, ix_val, ccx.int_type)
+                    } else { ZExt(bcx, ix_val, ccx.int_type) }
+                } else if ix_size > int_size {
+                    Trunc(bcx, ix_val, ccx.int_type)
+                } else {
+                    ix_val
+                }
+            };
 
-    debug!("trans_index: base {}", bcx.val_to_str(base));
-    debug!("trans_index: len {}", bcx.val_to_str(len));
+            let vt =
+                tvec::vec_types(bcx,
+                                ty::sequence_element_type(bcx.tcx(),
+                                                          base_datum.ty));
+            base::maybe_name_value(bcx.ccx(), vt.llunit_size, "unit_sz");
+
+            let (base, len) = base_datum.get_vec_base_and_len(bcx);
+
+            debug!("trans_index: base {}", bcx.val_to_string(base));
+            debug!("trans_index: len {}", bcx.val_to_string(len));
+
+            let bounds_check = ICmp(bcx, llvm::IntUGE, ix_val, len);
+            let expect = ccx.get_intrinsic(&("llvm.expect.i1"));
+            let expected = Call(bcx,
+                                expect,
+                                [bounds_check, C_bool(ccx, false)],
+                                []);
+            bcx = with_cond(bcx, expected, |bcx| {
+                controlflow::trans_fail_bounds_check(bcx,
+                                                     index_expr.span,
+                                                     ix_val,
+                                                     len)
+            });
+            let elt = InBoundsGEP(bcx, base, [ix_val]);
+            let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
+            Datum::new(elt, vt.unit_ty, LvalueExpr)
+        }
+    };
 
-    let bounds_check = ICmp(bcx, lib::llvm::IntUGE, ix_val, len);
-    let expect = ccx.get_intrinsic(&("llvm.expect.i1"));
-    let expected = Call(bcx, expect, [bounds_check, C_i1(ccx, false)], []);
-    let bcx = with_cond(bcx, expected, |bcx| {
-            controlflow::trans_fail_bounds_check(bcx, index_expr.span, ix_val, len)
-        });
-    let elt = InBoundsGEP(bcx, base, [ix_val]);
-    let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
-    DatumBlock::new(bcx, Datum::new(elt, vt.unit_ty, LvalueExpr))
+    DatumBlock::new(bcx, elt_datum)
 }
 
 fn trans_def<'a>(bcx: &'a Block<'a>,
@@ -725,7 +780,7 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
             let expr_ty = expr_ty(bcx, expr);
             let store = ty::ty_closure_store(expr_ty);
             debug!("translating block function {} with type {}",
-                   expr_to_str(expr), expr_ty.repr(tcx));
+                   expr_to_string(expr), expr_ty.repr(tcx));
             closure::trans_expr_fn(bcx, store, &**decl, &**body, expr.id, dest)
         }
         ast::ExprCall(ref f, ref args) => {
@@ -838,7 +893,7 @@ fn trans_def_dps_unadjusted<'a>(
         _ => {
             bcx.tcx().sess.span_bug(ref_expr.span, format!(
                 "Non-DPS def {:?} referened by {}",
-                def, bcx.node_id_to_str(ref_expr.id)).as_slice());
+                def, bcx.node_id_to_string(ref_expr.id)).as_slice());
         }
     }
 }
@@ -919,7 +974,7 @@ fn take_local<'a>(bcx: &'a Block<'a>,
             }
         };
         debug!("take_local(nid={:?}, v={}, ty={})",
-               nid, bcx.val_to_str(datum.val), bcx.ty_to_str(datum.ty));
+               nid, bcx.val_to_string(datum.val), bcx.ty_to_string(datum.ty));
         datum
     }
 }
@@ -1149,13 +1204,7 @@ fn trans_unary<'a>(bcx: &'a Block<'a>,
     match op {
         ast::UnNot => {
             let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
-            let llresult = if ty::type_is_bool(un_ty) {
-                let val = datum.to_llscalarish(bcx);
-                Xor(bcx, val, C_bool(ccx, true))
-            } else {
-                // Note: `Not` is bitwise, not suitable for logical not.
-                Not(bcx, datum.to_llscalarish(bcx))
-            };
+            let llresult = Not(bcx, datum.to_llscalarish(bcx));
             immediate_rvalue_bcx(bcx, llresult, un_ty).to_expr_datumblock()
         }
         ast::UnNeg => {
@@ -1380,7 +1429,7 @@ fn trans_lazy_binop<'a>(
     }
 
     Br(past_rhs, join.llbb);
-    let phi = Phi(join, Type::bool(bcx.ccx()), [lhs, rhs],
+    let phi = Phi(join, Type::i1(bcx.ccx()), [lhs, rhs],
                   [past_lhs.llbb, past_rhs.llbb]);
 
     return immediate_rvalue_bcx(join, phi, binop_ty).to_expr_datumblock();
@@ -1413,13 +1462,13 @@ fn trans_binary<'a>(bcx: &'a Block<'a>,
 
             debug!("trans_binary (expr {}): lhs_datum={}",
                    expr.id,
-                   lhs_datum.to_str(ccx));
+                   lhs_datum.to_string(ccx));
             let lhs_ty = lhs_datum.ty;
             let lhs = lhs_datum.to_llscalarish(bcx);
 
             debug!("trans_binary (expr {}): rhs_datum={}",
                    expr.id,
-                   rhs_datum.to_str(ccx));
+                   rhs_datum.to_string(ccx));
             let rhs_ty = rhs_datum.ty;
             let rhs = rhs_datum.to_llscalarish(bcx);
             trans_eager_binop(bcx, expr, binop_ty, op,
@@ -1597,8 +1646,8 @@ fn trans_imm_cast<'a>(bcx: &'a Block<'a>,
     let k_in = cast_type_kind(t_in);
     let k_out = cast_type_kind(t_out);
     let s_in = k_in == cast_integral && ty::type_is_signed(t_in);
-    let ll_t_in = type_of::type_of(ccx, t_in);
-    let ll_t_out = type_of::type_of(ccx, t_out);
+    let ll_t_in = type_of::arg_type_of(ccx, t_in);
+    let ll_t_out = type_of::arg_type_of(ccx, t_out);
 
     // Convert the value to be cast into a ValueRef, either by-ref or
     // by-value as appropriate given its type:
@@ -1680,7 +1729,7 @@ fn trans_assign_op<'a>(
     let _icx = push_ctxt("trans_assign_op");
     let mut bcx = bcx;
 
-    debug!("trans_assign_op(expr={})", bcx.expr_to_str(expr));
+    debug!("trans_assign_op(expr={})", bcx.expr_to_string(expr));
 
     // User-defined operator methods cannot be used with `+=` etc right now
     assert!(!bcx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id)));
@@ -1689,7 +1738,7 @@ fn trans_assign_op<'a>(
     let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op"));
     assert!(!ty::type_needs_drop(bcx.tcx(), dst_datum.ty));
     let dst_ty = dst_datum.ty;
-    let dst = Load(bcx, dst_datum.val);
+    let dst = load_ty(bcx, dst_datum.val, dst_datum.ty);
 
     // Evaluate RHS
     let rhs_datum = unpack_datum!(bcx, trans(bcx, &*src));
@@ -1750,7 +1799,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
 
     debug!("deref_once(expr={}, datum={}, method_call={})",
            expr.repr(bcx.tcx()),
-           datum.to_str(ccx),
+           datum.to_string(ccx),
            method_call);
 
     let mut bcx = bcx;
@@ -1762,7 +1811,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
         Some(method_ty) => {
             // Overloaded. Evaluate `trans_overloaded_op`, which will
             // invoke the user's deref() method, which basically
-            // converts from the `Shaht<T>` pointer that we have into
+            // converts from the `Smaht<T>` pointer that we have into
             // a `&T` pointer.  We can then proceed down the normal
             // path (below) to dereference that `&T`.
             let datum = match method_call.adjustment {
@@ -1828,7 +1877,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
     };
 
     debug!("deref_once(expr={}, method_call={}, result={})",
-           expr.id, method_call, r.datum.to_str(ccx));
+           expr.id, method_call, r.datum.to_string(ccx));
 
     return r;
 
index 488dc6d99e35c7a0d6063d816250a778ccaab540..56fbccefede5ea05f2c81ff4c73f69383193ab4c 100644 (file)
 
 
 use back::{link};
-use lib::llvm::llvm;
-use lib::llvm::{ValueRef, CallConv, Linkage};
-use lib;
+use llvm;
+use llvm::{ValueRef, CallConv, Linkage};
 use middle::weak_lang_items;
 use middle::trans::base::push_ctxt;
 use middle::trans::base;
 use middle::trans::build::*;
-use middle::trans::builder::noname;
 use middle::trans::cabi;
 use middle::trans::common::*;
 use middle::trans::machine;
@@ -77,7 +75,7 @@ pub fn llvm_calling_convention(ccx: &CrateContext,
     abi.for_target(os, arch).map(|abi| {
         match abi {
             RustIntrinsic => {
-                // Intrinsics are emitted by monomorphic fn
+                // Intrinsics are emitted at the call site
                 ccx.sess().bug("asked to register intrinsic fn");
             }
 
@@ -89,14 +87,14 @@ pub fn llvm_calling_convention(ccx: &CrateContext,
             // It's the ABI's job to select this, not us.
             System => ccx.sess().bug("system abi should be selected elsewhere"),
 
-            Stdcall => lib::llvm::X86StdcallCallConv,
-            Fastcall => lib::llvm::X86FastcallCallConv,
-            C => lib::llvm::CCallConv,
-            Win64 => lib::llvm::X86_64_Win64,
+            Stdcall => llvm::X86StdcallCallConv,
+            Fastcall => llvm::X86FastcallCallConv,
+            C => llvm::CCallConv,
+            Win64 => llvm::X86_64_Win64,
 
             // These API constants ought to be more specific...
-            Cdecl => lib::llvm::CCallConv,
-            Aapcs => lib::llvm::CCallConv,
+            Cdecl => llvm::CCallConv,
+            Aapcs => llvm::CCallConv,
         }
     })
 }
@@ -111,17 +109,17 @@ pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
     // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
     // and don't have to be, LLVM treats them as no-ops.
     match name {
-        "appending" => Some(lib::llvm::AppendingLinkage),
-        "available_externally" => Some(lib::llvm::AvailableExternallyLinkage),
-        "common" => Some(lib::llvm::CommonLinkage),
-        "extern_weak" => Some(lib::llvm::ExternalWeakLinkage),
-        "external" => Some(lib::llvm::ExternalLinkage),
-        "internal" => Some(lib::llvm::InternalLinkage),
-        "linkonce" => Some(lib::llvm::LinkOnceAnyLinkage),
-        "linkonce_odr" => Some(lib::llvm::LinkOnceODRLinkage),
-        "private" => Some(lib::llvm::PrivateLinkage),
-        "weak" => Some(lib::llvm::WeakAnyLinkage),
-        "weak_odr" => Some(lib::llvm::WeakODRLinkage),
+        "appending" => Some(llvm::AppendingLinkage),
+        "available_externally" => Some(llvm::AvailableExternallyLinkage),
+        "common" => Some(llvm::CommonLinkage),
+        "extern_weak" => Some(llvm::ExternalWeakLinkage),
+        "external" => Some(llvm::ExternalLinkage),
+        "internal" => Some(llvm::InternalLinkage),
+        "linkonce" => Some(llvm::LinkOnceAnyLinkage),
+        "linkonce_odr" => Some(llvm::LinkOnceODRLinkage),
+        "private" => Some(llvm::PrivateLinkage),
+        "weak" => Some(llvm::WeakAnyLinkage),
+        "weak_odr" => Some(llvm::WeakODRLinkage),
         _ => None,
     }
 }
@@ -158,14 +156,14 @@ pub fn register_static(ccx: &CrateContext,
                 let g1 = ident.get().with_c_str(|buf| {
                     llvm::LLVMAddGlobal(ccx.llmod, llty2.to_ref(), buf)
                 });
-                lib::llvm::SetLinkage(g1, linkage);
+                llvm::SetLinkage(g1, linkage);
 
                 let mut real_name = "_rust_extern_with_linkage_".to_string();
                 real_name.push_str(ident.get());
                 let g2 = real_name.with_c_str(|buf| {
                     llvm::LLVMAddGlobal(ccx.llmod, llty.to_ref(), buf)
                 });
-                lib::llvm::SetLinkage(g2, lib::llvm::InternalLinkage);
+                llvm::SetLinkage(g2, llvm::InternalLinkage);
                 llvm::LLVMSetInitializer(g2, g1);
                 g2
             }
@@ -218,7 +216,7 @@ pub fn register_foreign_item_fn(ccx: &CrateContext, abi: Abi, fty: ty::t,
     // Make sure the calling convention is right for variadic functions
     // (should've been caught if not in typeck)
     if tys.fn_sig.variadic {
-        assert!(cc == lib::llvm::CCallConv);
+        assert!(cc == llvm::CCallConv);
     }
 
     // Create the LLVM value for the C extern fn
@@ -267,8 +265,8 @@ pub fn trans_native_call<'a>(
             llfn={}, \
             llretptr={})",
            callee_ty.repr(tcx),
-           ccx.tn.val_to_str(llfn),
-           ccx.tn.val_to_str(llretptr));
+           ccx.tn.val_to_string(llfn),
+           ccx.tn.val_to_string(llretptr));
 
     let (fn_abi, fn_sig) = match ty::get(callee_ty).sty {
         ty::ty_bare_fn(ref fn_ty) => (fn_ty.abi, fn_ty.sig.clone()),
@@ -315,9 +313,9 @@ pub fn trans_native_call<'a>(
 
         debug!("argument {}, llarg_rust={}, rust_indirect={}, arg_ty={}",
                i,
-               ccx.tn.val_to_str(llarg_rust),
+               ccx.tn.val_to_string(llarg_rust),
                rust_indirect,
-               ccx.tn.type_to_str(arg_tys[i].ty));
+               ccx.tn.type_to_string(arg_tys[i].ty));
 
         // Ensure that we always have the Rust value indirectly,
         // because it makes bitcasting easier.
@@ -326,12 +324,12 @@ pub fn trans_native_call<'a>(
                 base::alloca(bcx,
                              type_of::type_of(ccx, *passed_arg_tys.get(i)),
                              "__arg");
-            Store(bcx, llarg_rust, scratch);
+            base::store_ty(bcx, llarg_rust, scratch, *passed_arg_tys.get(i));
             llarg_rust = scratch;
         }
 
         debug!("llarg_rust={} (after indirection)",
-               ccx.tn.val_to_str(llarg_rust));
+               ccx.tn.val_to_string(llarg_rust));
 
         // Check whether we need to do any casting
         match arg_tys[i].cast {
@@ -340,18 +338,23 @@ pub fn trans_native_call<'a>(
         }
 
         debug!("llarg_rust={} (after casting)",
-               ccx.tn.val_to_str(llarg_rust));
+               ccx.tn.val_to_string(llarg_rust));
 
         // Finally, load the value if needed for the foreign ABI
         let foreign_indirect = arg_tys[i].is_indirect();
         let llarg_foreign = if foreign_indirect {
             llarg_rust
         } else {
-            Load(bcx, llarg_rust)
+            if ty::type_is_bool(*passed_arg_tys.get(i)) {
+                let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, llvm::False);
+                Trunc(bcx, val, Type::i1(bcx.ccx()))
+            } else {
+                Load(bcx, llarg_rust)
+            }
         };
 
         debug!("argument {}, llarg_foreign={}",
-               i, ccx.tn.val_to_str(llarg_foreign));
+               i, ccx.tn.val_to_string(llarg_foreign));
 
         // fill padding with undef value
         match arg_tys[i].pad {
@@ -380,9 +383,9 @@ pub fn trans_native_call<'a>(
     if fn_type.ret_ty.is_indirect() {
         // The outptr can be noalias and nocapture because it's entirely
         // invisible to the program. We can also mark it as nonnull
-        attrs.push((1, lib::llvm::NoAliasAttribute as u64));
-        attrs.push((1, lib::llvm::NoCaptureAttribute as u64));
-        attrs.push((1, lib::llvm::NonNullAttribute as u64));
+        attrs.push((1, llvm::NoAliasAttribute as u64));
+        attrs.push((1, llvm::NoCaptureAttribute as u64));
+        attrs.push((1, llvm::NonNullAttribute as u64));
     };
 
     // Add attributes that depend on the concrete foreign ABI
@@ -426,13 +429,13 @@ pub fn trans_native_call<'a>(
             None => fn_type.ret_ty.ty
         };
 
-        debug!("llretptr={}", ccx.tn.val_to_str(llretptr));
-        debug!("llforeign_retval={}", ccx.tn.val_to_str(llforeign_retval));
-        debug!("llrust_ret_ty={}", ccx.tn.type_to_str(llrust_ret_ty));
-        debug!("llforeign_ret_ty={}", ccx.tn.type_to_str(llforeign_ret_ty));
+        debug!("llretptr={}", ccx.tn.val_to_string(llretptr));
+        debug!("llforeign_retval={}", ccx.tn.val_to_string(llforeign_retval));
+        debug!("llrust_ret_ty={}", ccx.tn.type_to_string(llrust_ret_ty));
+        debug!("llforeign_ret_ty={}", ccx.tn.type_to_string(llforeign_ret_ty));
 
         if llrust_ret_ty == llforeign_ret_ty {
-            Store(bcx, llforeign_retval, llretptr);
+            base::store_ty(bcx, llforeign_retval, llretptr, fn_sig.output)
         } else {
             // The actual return type is a struct, but the ABI
             // adaptation code has cast it into some scalar type.  The
@@ -527,14 +530,14 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
     let cconv = match ty::get(t).sty {
         ty::ty_bare_fn(ref fn_ty) => {
             let c = llvm_calling_convention(ccx, fn_ty.abi);
-            c.unwrap_or(lib::llvm::CCallConv)
+            c.unwrap_or(llvm::CCallConv)
         }
         _ => fail!("expected bare fn in register_rust_fn_with_foreign_abi")
     };
     let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty);
     add_argument_attributes(&tys, llfn);
     debug!("register_rust_fn_with_foreign_abi(node_id={:?}, llfn_ty={}, llfn={})",
-           node_id, ccx.tn.type_to_str(llfn_ty), ccx.tn.val_to_str(llfn));
+           node_id, ccx.tn.type_to_string(llfn_ty), ccx.tn.val_to_string(llfn));
     llfn
 }
 
@@ -567,7 +570,7 @@ fn build_rust_fn(ccx: &CrateContext,
 
         let ps = ccx.tcx.map.with_path(id, |path| {
             let abi = Some(ast_map::PathName(special_idents::clownshoe_abi.name));
-            link::mangle(path.chain(abi.move_iter()), None, None)
+            link::mangle(path.chain(abi.move_iter()), None)
         });
 
         // Compute the type that the function would have if it were just a
@@ -579,13 +582,13 @@ fn build_rust_fn(ccx: &CrateContext,
             _ => {
                 ccx.sess().bug(format!("build_rust_fn: extern fn {} has ty {}, \
                                         expected a bare fn ty",
-                                       ccx.tcx.map.path_to_str(id),
+                                       ccx.tcx.map.path_to_string(id),
                                        t.repr(tcx)).as_slice());
             }
         };
 
         debug!("build_rust_fn: path={} id={} t={}",
-               ccx.tcx.map.path_to_str(id),
+               ccx.tcx.map.path_to_string(id),
                id, t.repr(tcx));
 
         let llfn = base::decl_internal_rust_fn(ccx, t, ps.as_slice());
@@ -606,8 +609,8 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
         let t = ty::node_id_to_type(tcx, id);
 
         debug!("build_wrap_fn(llrustfn={}, llwrapfn={}, t={})",
-               ccx.tn.val_to_str(llrustfn),
-               ccx.tn.val_to_str(llwrapfn),
+               ccx.tn.val_to_string(llrustfn),
+               ccx.tn.val_to_string(llwrapfn),
                t.repr(ccx.tcx()));
 
         // Avoid all the Rust generation stuff and just generate raw
@@ -625,8 +628,8 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             "the block".with_c_str(
                 |s| llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llwrapfn, s));
 
-        let builder = ccx.builder.b;
-        llvm::LLVMPositionBuilderAtEnd(builder, the_block);
+        let builder = ccx.builder();
+        builder.position_at_end(the_block);
 
         // Array for the arguments we will pass to the rust function.
         let mut llrust_args = Vec::new();
@@ -664,31 +667,23 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             match foreign_outptr {
                 Some(llforeign_outptr) => {
                     debug!("out pointer, foreign={}",
-                           ccx.tn.val_to_str(llforeign_outptr));
+                           ccx.tn.val_to_string(llforeign_outptr));
                     let llrust_retptr =
-                        llvm::LLVMBuildBitCast(builder,
-                                               llforeign_outptr,
-                                               llrust_ret_ty.ptr_to().to_ref(),
-                                               noname());
+                        builder.bitcast(llforeign_outptr, llrust_ret_ty.ptr_to());
                     debug!("out pointer, foreign={} (casted)",
-                           ccx.tn.val_to_str(llrust_retptr));
+                           ccx.tn.val_to_string(llrust_retptr));
                     llrust_args.push(llrust_retptr);
                     return_alloca = None;
                 }
 
                 None => {
-                    let slot = {
-                        "return_alloca".with_c_str(
-                            |s| llvm::LLVMBuildAlloca(builder,
-                                                      llrust_ret_ty.to_ref(),
-                                                      s))
-                    };
+                    let slot = builder.alloca(llrust_ret_ty, "return_alloca");
                     debug!("out pointer, \
                             allocad={}, \
                             llrust_ret_ty={}, \
                             return_ty={}",
-                           ccx.tn.val_to_str(slot),
-                           ccx.tn.type_to_str(llrust_ret_ty),
+                           ccx.tn.val_to_string(slot),
+                           ccx.tn.type_to_string(llrust_ret_ty),
                            tys.fn_sig.output.repr(tcx));
                     llrust_args.push(slot);
                     return_alloca = Some(slot);
@@ -716,7 +711,7 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             let mut llforeign_arg = llvm::LLVMGetParam(llwrapfn, foreign_index);
 
             debug!("llforeign_arg {}{}: {}", "#",
-                   i, ccx.tn.val_to_str(llforeign_arg));
+                   i, ccx.tn.val_to_string(llforeign_arg));
             debug!("rust_indirect = {}, foreign_indirect = {}",
                    rust_indirect, foreign_indirect);
 
@@ -724,12 +719,15 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             // pointer).  It makes adapting types easier, since we can
             // always just bitcast pointers.
             if !foreign_indirect {
-                let lltemp =
-                    llvm::LLVMBuildAlloca(
-                        builder, val_ty(llforeign_arg).to_ref(), noname());
-                llvm::LLVMBuildStore(
-                    builder, llforeign_arg, lltemp);
-                llforeign_arg = lltemp;
+                llforeign_arg = if ty::type_is_bool(rust_ty) {
+                    let lltemp = builder.alloca(Type::bool(ccx), "");
+                    builder.store(builder.zext(llforeign_arg, Type::bool(ccx)), lltemp);
+                    lltemp
+                } else {
+                    let lltemp = builder.alloca(val_ty(llforeign_arg), "");
+                    builder.store(llforeign_arg, lltemp);
+                    lltemp
+                }
             }
 
             // If the types in the ABI and the Rust types don't match,
@@ -737,31 +735,29 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             // Rust expects.
             if llforeign_arg_ty.cast.is_some() {
                 assert!(!foreign_indirect);
-                llforeign_arg = llvm::LLVMBuildBitCast(
-                    builder, llforeign_arg,
-                    llrust_ty.ptr_to().to_ref(), noname());
+                llforeign_arg = builder.bitcast(llforeign_arg, llrust_ty.ptr_to());
             }
 
             let llrust_arg = if rust_indirect {
                 llforeign_arg
             } else {
-                llvm::LLVMBuildLoad(builder, llforeign_arg, noname())
+                if ty::type_is_bool(rust_ty) {
+                    let tmp = builder.load_range_assert(llforeign_arg, 0, 2, llvm::False);
+                    builder.trunc(tmp, Type::i1(ccx))
+                } else {
+                    builder.load(llforeign_arg)
+                }
             };
 
             debug!("llrust_arg {}{}: {}", "#",
-                   i, ccx.tn.val_to_str(llrust_arg));
+                   i, ccx.tn.val_to_string(llrust_arg));
             llrust_args.push(llrust_arg);
         }
 
         // Perform the call itself
-        debug!("calling llrustfn = {}, t = {}", ccx.tn.val_to_str(llrustfn), t.repr(ccx.tcx()));
-        let llrust_ret_val = llvm::LLVMBuildCall(builder, llrustfn, llrust_args.as_ptr(),
-                                                 llrust_args.len() as c_uint, noname());
-
+        debug!("calling llrustfn = {}, t = {}", ccx.tn.val_to_string(llrustfn), t.repr(ccx.tcx()));
         let attributes = base::get_fn_llvm_attributes(ccx, t);
-        for &(idx, attr) in attributes.iter() {
-            llvm::LLVMAddCallSiteAttribute(llrust_ret_val, idx as c_uint, attr);
-        }
+        let llrust_ret_val = builder.call(llrustfn, llrust_args.as_slice(), attributes.as_slice());
 
         // Get the return value where the foreign fn expects it.
         let llforeign_ret_ty = match tys.fn_ty.ret_ty.cast {
@@ -772,20 +768,16 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             None if !tys.ret_def => {
                 // Function returns `()` or `bot`, which in Rust is the LLVM
                 // type "{}" but in foreign ABIs is "Void".
-                llvm::LLVMBuildRetVoid(builder);
+                builder.ret_void();
             }
 
             None if rust_uses_outptr => {
                 // Rust uses an outpointer, but the foreign ABI does not. Load.
                 let llrust_outptr = return_alloca.unwrap();
                 let llforeign_outptr_casted =
-                    llvm::LLVMBuildBitCast(builder,
-                                           llrust_outptr,
-                                           llforeign_ret_ty.ptr_to().to_ref(),
-                                           noname());
-                let llforeign_retval =
-                    llvm::LLVMBuildLoad(builder, llforeign_outptr_casted, noname());
-                llvm::LLVMBuildRet(builder, llforeign_retval);
+                    builder.bitcast(llrust_outptr, llforeign_ret_ty.ptr_to());
+                let llforeign_retval = builder.load(llforeign_outptr_casted);
+                builder.ret(llforeign_retval);
             }
 
             None if llforeign_ret_ty != llrust_ret_ty => {
@@ -795,43 +787,31 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
                 // right now we just use a temp memory location and
                 // bitcast the pointer, which is the same thing the
                 // old wrappers used to do.
-                let lltemp =
-                    llvm::LLVMBuildAlloca(
-                        builder, llforeign_ret_ty.to_ref(), noname());
-                let lltemp_casted =
-                    llvm::LLVMBuildBitCast(builder,
-                                           lltemp,
-                                           llrust_ret_ty.ptr_to().to_ref(),
-                                           noname());
-                llvm::LLVMBuildStore(
-                    builder, llrust_ret_val, lltemp_casted);
-                let llforeign_retval =
-                    llvm::LLVMBuildLoad(builder, lltemp, noname());
-                llvm::LLVMBuildRet(builder, llforeign_retval);
+                let lltemp = builder.alloca(llforeign_ret_ty, "");
+                let lltemp_casted = builder.bitcast(lltemp, llrust_ret_ty.ptr_to());
+                builder.store(llrust_ret_val, lltemp_casted);
+                let llforeign_retval = builder.load(lltemp);
+                builder.ret(llforeign_retval);
             }
 
             None => {
                 // Neither ABI uses an outpointer, and the types
                 // match. Easy peasy.
-                llvm::LLVMBuildRet(builder, llrust_ret_val);
+                builder.ret(llrust_ret_val);
             }
 
             Some(llforeign_outptr) if !rust_uses_outptr => {
                 // Foreign ABI requires an out pointer, but Rust doesn't.
                 // Store Rust return value.
                 let llforeign_outptr_casted =
-                    llvm::LLVMBuildBitCast(builder,
-                                           llforeign_outptr,
-                                           llrust_retptr_ty.to_ref(),
-                                           noname());
-                llvm::LLVMBuildStore(
-                    builder, llrust_ret_val, llforeign_outptr_casted);
-                llvm::LLVMBuildRetVoid(builder);
+                    builder.bitcast(llforeign_outptr, llrust_retptr_ty);
+                builder.store(llrust_ret_val, llforeign_outptr_casted);
+                builder.ret_void();
             }
 
             Some(_) => {
                 // Both ABIs use outpointers. Easy peasy.
-                llvm::LLVMBuildRetVoid(builder);
+                builder.ret_void();
             }
         }
     }
@@ -863,8 +843,8 @@ fn foreign_signature(ccx: &CrateContext, fn_sig: &ty::FnSig, arg_tys: &[ty::t])
      * values by pointer like we do.
      */
 
-    let llarg_tys = arg_tys.iter().map(|&arg| type_of(ccx, arg)).collect();
-    let llret_ty = type_of::type_of(ccx, fn_sig.output);
+    let llarg_tys = arg_tys.iter().map(|&arg| arg_type_of(ccx, arg)).collect();
+    let llret_ty = type_of::arg_type_of(ccx, fn_sig.output);
     LlvmSignature {
         llarg_tys: llarg_tys,
         llret_ty: llret_ty
@@ -895,9 +875,9 @@ fn foreign_types_for_fn_ty(ccx: &CrateContext,
            ret_def={}",
            ty.repr(ccx.tcx()),
            ccx.tn.types_to_str(llsig.llarg_tys.as_slice()),
-           ccx.tn.type_to_str(llsig.llret_ty),
+           ccx.tn.type_to_string(llsig.llret_ty),
            ccx.tn.types_to_str(fn_ty.arg_tys.iter().map(|t| t.ty).collect::<Vec<_>>().as_slice()),
-           ccx.tn.type_to_str(fn_ty.ret_ty.ty),
+           ccx.tn.type_to_string(fn_ty.ret_ty.ty),
            ret_def);
 
     ForeignTypes {
index 7024ea4b3756907b0af8a544311a928e9ad7540a..40065d0bc5053f327562956d7f3bbb003d1804ae 100644 (file)
@@ -15,8 +15,8 @@
 
 use back::abi;
 use back::link::*;
-use lib::llvm::{llvm, ValueRef, True};
-use lib;
+use llvm;
+use llvm::{ValueRef, True};
 use middle::lang_items::{FreeFnLangItem, ExchangeFreeFnLangItem};
 use middle::subst;
 use middle::trans::adt;
@@ -167,11 +167,11 @@ pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: &tydesc_info) -> ValueRef
     match ti.visit_glue.get() {
         Some(visit_glue) => visit_glue,
         None => {
-            debug!("+++ lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty));
+            debug!("+++ lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_string(ccx.tcx(), ti.ty));
             let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "visit");
             ti.visit_glue.set(Some(glue_fn));
             make_generic_glue(ccx, ti.ty, glue_fn, make_visit_glue, "visit");
-            debug!("--- lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty));
+            debug!("--- lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_string(ccx.tcx(), ti.ty));
             glue_fn
         }
     }
@@ -234,7 +234,7 @@ fn trans_struct_drop_flag<'a>(bcx: &'a Block<'a>,
                               -> &'a Block<'a> {
     let repr = adt::represent_type(bcx.ccx(), t);
     let drop_flag = adt::trans_drop_flag_ptr(bcx, &*repr, v0);
-    with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag)), |cx| {
+    with_cond(bcx, load_ty(bcx, drop_flag, ty::mk_bool()), |cx| {
         trans_struct_drop(cx, t, v0, dtor_did, class_did, substs)
     })
 }
@@ -432,13 +432,13 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> tydesc_info {
 
     if ccx.sess().count_type_sizes() {
         println!("{}\t{}", llsize_of_real(ccx, llty),
-                 ppaux::ty_to_str(ccx.tcx(), t));
+                 ppaux::ty_to_string(ccx.tcx(), t));
     }
 
     let llsize = llsize_of(ccx, llty);
     let llalign = llalign_of(ccx, llty);
     let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc");
-    debug!("+++ declare_tydesc {} {}", ppaux::ty_to_str(ccx.tcx(), t), name);
+    debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name);
     let gvar = name.as_slice().with_c_str(|buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type().to_ref(), buf)
@@ -447,10 +447,10 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> tydesc_info {
     note_unique_llvm_symbol(ccx, name);
 
     let ty_name = token::intern_and_get_ident(
-        ppaux::ty_to_str(ccx.tcx(), t).as_slice());
+        ppaux::ty_to_string(ccx.tcx(), t).as_slice());
     let ty_name = C_str_slice(ccx, ty_name);
 
-    debug!("--- declare_tydesc {}", ppaux::ty_to_str(ccx.tcx(), t));
+    debug!("--- declare_tydesc {}", ppaux::ty_to_string(ccx.tcx(), t));
     tydesc_info {
         ty: t,
         tydesc: gvar,
@@ -468,7 +468,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
         ccx,
         t,
         format!("glue_{}", name).as_slice());
-    debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx(), t));
+    debug!("{} is for type {}", fn_nm, ppaux::ty_to_string(ccx.tcx(), t));
     let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil());
     note_unique_llvm_symbol(ccx, fn_nm);
     return llfn;
@@ -490,9 +490,9 @@ fn make_generic_glue(ccx: &CrateContext,
     let fcx = new_fn_ctxt(ccx, llfn, -1, false, ty::mk_nil(),
                           &empty_param_substs, None, &arena);
 
-    init_function(&fcx, false, ty::mk_nil());
+    let bcx = init_function(&fcx, false, ty::mk_nil());
 
-    lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
+    llvm::SetLinkage(llfn, llvm::InternalLinkage);
     ccx.stats.n_glues_created.set(ccx.stats.n_glues_created.get() + 1u);
     // All glue functions take values passed *by alias*; this is a
     // requirement since in many contexts glue is invoked indirectly and
@@ -502,10 +502,9 @@ fn make_generic_glue(ccx: &CrateContext,
     // llfn is expected be declared to take a parameter of the appropriate
     // type, so we don't need to explicitly cast the function parameter.
 
-    let bcx = fcx.entry_bcx.borrow().clone().unwrap();
     let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, fcx.arg_pos(0) as c_uint) };
     let bcx = helper(bcx, llrawptr0, t);
-    finish_fn(&fcx, bcx);
+    finish_fn(&fcx, bcx, ty::mk_nil());
 
     llfn
 }
@@ -551,7 +550,7 @@ pub fn emit_tydescs(ccx: &CrateContext) {
             let gvar = ti.tydesc;
             llvm::LLVMSetInitializer(gvar, tydesc);
             llvm::LLVMSetGlobalConstant(gvar, True);
-            lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage);
+            llvm::SetLinkage(gvar, llvm::InternalLinkage);
         }
     };
 }
index 2ebbc2f5340b79a1cbcc602fce831da84cb9e9b8..d64eeb727e733bdc6820a4c77c8336911a47d9eb 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use lib::llvm::{AvailableExternallyLinkage, SetLinkage};
+use llvm::{AvailableExternallyLinkage, SetLinkage};
 use metadata::csearch;
 use middle::astencode;
 use middle::trans::base::{push_ctxt, trans_item, get_item_val, trans_fn};
@@ -128,11 +128,12 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
             let unparameterized =
                 impl_tpt.generics.types.is_empty() &&
-                mth.generics.ty_params.is_empty();
+                ast_util::method_generics(&*mth).ty_params.is_empty();
 
           if unparameterized {
               let llfn = get_item_val(ccx, mth.id);
-              trans_fn(ccx, &*mth.decl, &*mth.body, llfn,
+              trans_fn(ccx, ast_util::method_fn_decl(&*mth),
+                       ast_util::method_body(&*mth), llfn,
                        &param_substs::empty(), mth.id, []);
           }
           local_def(mth.id)
index bc0c88ceee95fc5866159c067f70773851ad51f5..bb33a5e4f8d2fa5a1b392a47d6212ae85d617f11 100644 (file)
 
 #![allow(non_uppercase_pattern_statics)]
 
-use arena::TypedArena;
-use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
-use lib::llvm::{ValueRef, Pointer, Array, Struct};
-use lib;
+use llvm;
+use llvm::{SequentiallyConsistent, Acquire, Release, Xchg, ValueRef};
+use middle::subst;
 use middle::subst::FnSpace;
 use middle::trans::base::*;
 use middle::trans::build::*;
+use middle::trans::callee;
+use middle::trans::cleanup;
+use middle::trans::cleanup::CleanupMethods;
 use middle::trans::common::*;
 use middle::trans::datum::*;
+use middle::trans::expr;
 use middle::trans::glue;
 use middle::trans::type_of::*;
 use middle::trans::type_of;
@@ -27,9 +30,8 @@
 use middle::trans::type_::Type;
 use middle::ty;
 use syntax::ast;
-use syntax::ast_map;
 use syntax::parse::token;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
     let name = match token::get_ident(item.ident).get() {
@@ -83,247 +85,168 @@ pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Opti
     Some(ccx.get_intrinsic(&name))
 }
 
-pub fn trans_intrinsic(ccx: &CrateContext,
-                       decl: ValueRef,
-                       item: &ast::ForeignItem,
-                       substs: &param_substs,
-                       ref_id: Option<ast::NodeId>) {
-    debug!("trans_intrinsic(item.ident={})", token::get_ident(item.ident));
-
-    fn with_overflow_instrinsic(bcx: &Block, name: &'static str, t: ty::t) {
-        let first_real_arg = bcx.fcx.arg_pos(0u);
-        let a = get_param(bcx.fcx.llfn, first_real_arg);
-        let b = get_param(bcx.fcx.llfn, first_real_arg + 1);
-        let llfn = bcx.ccx().get_intrinsic(&name);
-
-        let val = Call(bcx, llfn, [a, b], []);
-
-        if type_is_immediate(bcx.ccx(), t) {
-            Ret(bcx, val);
-        } else {
-            let retptr = get_param(bcx.fcx.llfn, bcx.fcx.out_arg_pos());
-            Store(bcx, val, retptr);
-            RetVoid(bcx);
+/// Performs late verification that intrinsics are used correctly. At present,
+/// the only intrinsic that needs such verification is `transmute`.
+pub fn check_intrinsics(ccx: &CrateContext) {
+    for transmute_restriction in ccx.tcx
+                                    .transmute_restrictions
+                                    .borrow()
+                                    .iter() {
+        let llfromtype = type_of::sizing_type_of(ccx,
+                                                 transmute_restriction.from);
+        let lltotype = type_of::sizing_type_of(ccx,
+                                               transmute_restriction.to);
+        let from_type_size = machine::llbitsize_of_real(ccx, llfromtype);
+        let to_type_size = machine::llbitsize_of_real(ccx, lltotype);
+        if from_type_size != to_type_size {
+            ccx.sess()
+               .span_err(transmute_restriction.span,
+                format!("transmute called on types with different sizes: \
+                         {} ({} bit{}) to {} ({} bit{})",
+                        ty_to_string(ccx.tcx(), transmute_restriction.from),
+                        from_type_size as uint,
+                        if from_type_size == 1 {
+                            ""
+                        } else {
+                            "s"
+                        },
+                        ty_to_string(ccx.tcx(), transmute_restriction.to),
+                        to_type_size as uint,
+                        if to_type_size == 1 {
+                            ""
+                        } else {
+                            "s"
+                        }).as_slice());
         }
     }
+    ccx.sess().abort_if_errors();
+}
 
-    fn volatile_load_intrinsic(bcx: &Block) {
-        let first_real_arg = bcx.fcx.arg_pos(0u);
-        let src = get_param(bcx.fcx.llfn, first_real_arg);
+pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,
+                                callee_ty: ty::t, cleanup_scope: cleanup::CustomScopeIndex,
+                                args: callee::CallArgs, dest: expr::Dest,
+                                substs: subst::Substs) -> Result<'a> {
 
-        let val = VolatileLoad(bcx, src);
-        Ret(bcx, val);
-    }
+    let fcx = bcx.fcx;
+    let ccx = fcx.ccx;
+    let tcx = bcx.tcx();
 
-    fn volatile_store_intrinsic(bcx: &Block) {
-        let first_real_arg = bcx.fcx.arg_pos(0u);
-        let dst = get_param(bcx.fcx.llfn, first_real_arg);
-        let val = get_param(bcx.fcx.llfn, first_real_arg + 1);
+    let ret_ty = match ty::get(callee_ty).sty {
+        ty::ty_bare_fn(ref f) => f.sig.output,
+        _ => fail!("expected bare_fn in trans_intrinsic_call")
+    };
+    let llret_ty = type_of::type_of(ccx, ret_ty);
+    let foreign_item = tcx.map.expect_foreign_item(node);
+    let name = token::get_ident(foreign_item.ident);
+
+    // For `transmute` we can just trans the input expr directly into dest
+    if name.get() == "transmute" {
+        match args {
+            callee::ArgExprs(arg_exprs) => {
+                assert_eq!(arg_exprs.len(), 1);
+
+                let (in_type, out_type) = (*substs.types.get(FnSpace, 0),
+                                           *substs.types.get(FnSpace, 1));
+                let llintype = type_of::type_of(ccx, in_type);
+                let llouttype = type_of::type_of(ccx, out_type);
+
+                let in_type_size = machine::llbitsize_of_real(ccx, llintype);
+                let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
+
+                // This should be caught by the intrinsicck pass
+                assert_eq!(in_type_size, out_type_size);
+
+                // We need to cast the dest so the types work out
+                let dest = match dest {
+                    expr::SaveIn(d) => expr::SaveIn(PointerCast(bcx, d, llintype.ptr_to())),
+                    expr::Ignore => expr::Ignore
+                };
+                bcx = expr::trans_into(bcx, &*arg_exprs[0], dest);
 
-        VolatileStore(bcx, val, dst);
-        RetVoid(bcx);
-    }
+                fcx.pop_custom_cleanup_scope(cleanup_scope);
 
-    fn copy_intrinsic(bcx: &Block, allow_overlap: bool, volatile: bool, tp_ty: ty::t) {
-        let ccx = bcx.ccx();
-        let lltp_ty = type_of::type_of(ccx, tp_ty);
-        let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
-        let size = machine::llsize_of(ccx, lltp_ty);
-        let int_size = machine::llbitsize_of_real(ccx, ccx.int_type);
-        let name = if allow_overlap {
-            if int_size == 32 {
-                "llvm.memmove.p0i8.p0i8.i32"
-            } else {
-                "llvm.memmove.p0i8.p0i8.i64"
-            }
-        } else {
-            if int_size == 32 {
-                "llvm.memcpy.p0i8.p0i8.i32"
-            } else {
-                "llvm.memcpy.p0i8.p0i8.i64"
-            }
-        };
-
-        let decl = bcx.fcx.llfn;
-        let first_real_arg = bcx.fcx.arg_pos(0u);
-        let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p(ccx));
-        let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p(ccx));
-        let count = get_param(decl, first_real_arg + 2);
-        let llfn = ccx.get_intrinsic(&name);
-        Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []);
-        RetVoid(bcx);
-    }
+                return match dest {
+                    expr::SaveIn(d) => Result::new(bcx, d),
+                    expr::Ignore => Result::new(bcx, C_undef(llret_ty.ptr_to()))
+                };
 
-    fn memset_intrinsic(bcx: &Block, volatile: bool, tp_ty: ty::t) {
-        let ccx = bcx.ccx();
-        let lltp_ty = type_of::type_of(ccx, tp_ty);
-        let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
-        let size = machine::llsize_of(ccx, lltp_ty);
-        let name = if machine::llbitsize_of_real(ccx, ccx.int_type) == 32 {
-            "llvm.memset.p0i8.i32"
-        } else {
-            "llvm.memset.p0i8.i64"
-        };
-
-        let decl = bcx.fcx.llfn;
-        let first_real_arg = bcx.fcx.arg_pos(0u);
-        let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p(ccx));
-        let val = get_param(decl, first_real_arg + 1);
-        let count = get_param(decl, first_real_arg + 2);
-        let llfn = ccx.get_intrinsic(&name);
-        Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []);
-        RetVoid(bcx);
-    }
+            }
 
-    fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
-        let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u));
-        let y = C_i1(bcx.ccx(), false);
-        let llfn = bcx.ccx().get_intrinsic(&name);
-        let llcall = Call(bcx, llfn, [x, y], []);
-        Ret(bcx, llcall);
+            _ => {
+                ccx.sess().bug("expected expr as argument for transmute");
+            }
+        }
     }
 
-    let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx(), item.id));
-
-    let arena = TypedArena::new();
-    let fcx = new_fn_ctxt(ccx, decl, item.id, false, output_type,
-                          substs, Some(item.span), &arena);
-    init_function(&fcx, true, output_type);
-
-    set_always_inline(fcx.llfn);
+    // Get location to store the result. If the user does
+    // not care about the result, just make a stack slot
+    let llresult = match dest {
+        expr::SaveIn(d) => d,
+        expr::Ignore => {
+            if !type_is_zero_size(ccx, ret_ty) {
+                alloc_ty(bcx, ret_ty, "intrinsic_result")
+            } else {
+                C_undef(llret_ty.ptr_to())
+            }
+        }
+    };
 
-    let mut bcx = fcx.entry_bcx.borrow().clone().unwrap();
-    let first_real_arg = fcx.arg_pos(0u);
+    // Push the arguments.
+    let mut llargs = Vec::new();
+    bcx = callee::trans_args(bcx, args, callee_ty, &mut llargs,
+                             cleanup::CustomScope(cleanup_scope), false);
 
-    let name = token::get_ident(item.ident);
+    fcx.pop_custom_cleanup_scope(cleanup_scope);
 
-    // This requires that atomic intrinsics follow a specific naming pattern:
-    // "atomic_<operation>[_<ordering>], and no ordering means SeqCst
-    if name.get().starts_with("atomic_") {
-        let split: Vec<&str> = name.get().split('_').collect();
-        assert!(split.len() >= 2, "Atomic intrinsic not correct format");
-        let order = if split.len() == 2 {
-            lib::llvm::SequentiallyConsistent
-        } else {
-            match *split.get(2) {
-                "relaxed" => lib::llvm::Monotonic,
-                "acq"     => lib::llvm::Acquire,
-                "rel"     => lib::llvm::Release,
-                "acqrel"  => lib::llvm::AcquireRelease,
-                _ => ccx.sess().fatal("unknown ordering in atomic intrinsic")
-            }
-        };
-
-        match *split.get(1) {
-            "cxchg" => {
-                // See include/llvm/IR/Instructions.h for their implementation
-                // of this, I assume that it's good enough for us to use for
-                // now.
-                let strongest_failure_ordering = match order {
-                    lib::llvm::NotAtomic | lib::llvm::Unordered =>
-                        ccx.sess().fatal("cmpxchg must be atomic"),
-                    lib::llvm::Monotonic | lib::llvm::Release =>
-                        lib::llvm::Monotonic,
-                    lib::llvm::Acquire | lib::llvm::AcquireRelease =>
-                        lib::llvm::Acquire,
-                    lib::llvm::SequentiallyConsistent =>
-                        lib::llvm::SequentiallyConsistent,
-                };
-                let res = AtomicCmpXchg(bcx, get_param(decl, first_real_arg),
-                                        get_param(decl, first_real_arg + 1u),
-                                        get_param(decl, first_real_arg + 2u),
-                                        order, strongest_failure_ordering);
-                if unsafe { lib::llvm::llvm::LLVMVersionMinor() >= 5 } {
-                    Ret(bcx, ExtractValue(bcx, res, 0));
-                } else {
-                    Ret(bcx, res);
-                }
-            }
-            "load" => {
-                let old = AtomicLoad(bcx, get_param(decl, first_real_arg),
-                                     order);
-                Ret(bcx, old);
-            }
-            "store" => {
-                AtomicStore(bcx, get_param(decl, first_real_arg + 1u),
-                            get_param(decl, first_real_arg),
-                            order);
-                RetVoid(bcx);
-            }
-            "fence" => {
-                AtomicFence(bcx, order);
-                RetVoid(bcx);
-            }
-            op => {
-                // These are all AtomicRMW ops
-                let atom_op = match op {
-                    "xchg"  => lib::llvm::Xchg,
-                    "xadd"  => lib::llvm::Add,
-                    "xsub"  => lib::llvm::Sub,
-                    "and"   => lib::llvm::And,
-                    "nand"  => lib::llvm::Nand,
-                    "or"    => lib::llvm::Or,
-                    "xor"   => lib::llvm::Xor,
-                    "max"   => lib::llvm::Max,
-                    "min"   => lib::llvm::Min,
-                    "umax"  => lib::llvm::UMax,
-                    "umin"  => lib::llvm::UMin,
-                    _ => ccx.sess().fatal("unknown atomic operation")
-                };
+    let simple = get_simple_intrinsic(ccx, &*foreign_item);
 
-                let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg),
-                                    get_param(decl, first_real_arg + 1u),
-                                    order);
-                Ret(bcx, old);
-            }
+    let llval = match (simple, name.get()) {
+        (Some(llfn), _) => {
+            Call(bcx, llfn, llargs.as_slice(), [])
         }
-
-        fcx.cleanup();
-        return;
-    }
-
-    match name.get() {
-        "abort" => {
-            let llfn = bcx.ccx().get_intrinsic(&("llvm.trap"));
-            Call(bcx, llfn, [], []);
+        (_, "abort") => {
+            let llfn = ccx.get_intrinsic(&("llvm.trap"));
+            let v = Call(bcx, llfn, [], []);
             Unreachable(bcx);
+            v
+        }
+        (_, "breakpoint") => {
+            let llfn = ccx.get_intrinsic(&("llvm.debugtrap"));
+            Call(bcx, llfn, [], [])
         }
-        "breakpoint" => {
-            let llfn = bcx.ccx().get_intrinsic(&("llvm.debugtrap"));
-            Call(bcx, llfn, [], []);
-            RetVoid(bcx);
+        (_, "size_of") => {
+            let tp_ty = *substs.types.get(FnSpace, 0);
+            let lltp_ty = type_of::type_of(ccx, tp_ty);
+            C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty) as uint)
+        }
+        (_, "min_align_of") => {
+            let tp_ty = *substs.types.get(FnSpace, 0);
+            let lltp_ty = type_of::type_of(ccx, tp_ty);
+            C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty) as uint)
         }
-        "size_of" => {
-            let tp_ty = *substs.substs.types.get(FnSpace, 0);
+        (_, "pref_align_of") => {
+            let tp_ty = *substs.types.get(FnSpace, 0);
             let lltp_ty = type_of::type_of(ccx, tp_ty);
-            Ret(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty) as uint));
+            C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty) as uint)
         }
-        "move_val_init" => {
+        (_, "move_val_init") => {
             // Create a datum reflecting the value being moved.
             // Use `appropriate_mode` so that the datum is by ref
             // if the value is non-immediate. Note that, with
             // intrinsics, there are no argument cleanups to
             // concern ourselves with, so we can use an rvalue datum.
-            let tp_ty = *substs.substs.types.get(FnSpace, 0);
+            let tp_ty = *substs.types.get(FnSpace, 0);
             let mode = appropriate_rvalue_mode(ccx, tp_ty);
-            let src = Datum {val: get_param(decl, first_real_arg + 1u),
-                             ty: tp_ty,
-                             kind: Rvalue::new(mode)};
-            bcx = src.store_to(bcx, get_param(decl, first_real_arg));
-            RetVoid(bcx);
+            let src = Datum {
+                val: *llargs.get(1),
+                ty: tp_ty,
+                kind: Rvalue::new(mode)
+            };
+            bcx = src.store_to(bcx, *llargs.get(0));
+            C_nil(ccx)
         }
-        "min_align_of" => {
-            let tp_ty = *substs.substs.types.get(FnSpace, 0);
-            let lltp_ty = type_of::type_of(ccx, tp_ty);
-            Ret(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty) as uint));
-        }
-        "pref_align_of"=> {
-            let tp_ty = *substs.substs.types.get(FnSpace, 0);
-            let lltp_ty = type_of::type_of(ccx, tp_ty);
-            Ret(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty) as uint));
-        }
-        "get_tydesc" => {
-            let tp_ty = *substs.substs.types.get(FnSpace, 0);
+        (_, "get_tydesc") => {
+            let tp_ty = *substs.types.get(FnSpace, 0);
             let static_ti = get_tydesc(ccx, tp_ty);
             glue::lazily_emit_visit_glue(ccx, &*static_ti);
 
@@ -331,272 +254,338 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
             // but there's a circularity between translating rust types to llvm
             // types and having a tydesc type available. So I can't directly access
             // the llvm type of intrinsic::TyDesc struct.
-            let userland_tydesc_ty = type_of::type_of(ccx, output_type);
-            let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty);
-            Ret(bcx, td);
+            PointerCast(bcx, static_ti.tydesc, llret_ty)
         }
-        "type_id" => {
+        (_, "type_id") => {
             let hash = ty::hash_crate_independent(
                 ccx.tcx(),
-                *substs.substs.types.get(FnSpace, 0),
+                *substs.types.get(FnSpace, 0),
                 &ccx.link_meta.crate_hash);
             // NB: This needs to be kept in lockstep with the TypeId struct in
-            //     libstd/unstable/intrinsics.rs
-            let val = C_named_struct(type_of::type_of(ccx, output_type),
-                                     [C_u64(ccx, hash)]);
-            match bcx.fcx.llretptr.get() {
-                Some(ptr) => {
-                    Store(bcx, val, ptr);
-                    RetVoid(bcx);
-                },
-                None => Ret(bcx, val)
-            }
+            //     the intrinsic module
+            C_named_struct(llret_ty, [C_u64(ccx, hash)])
         }
-        "init" => {
-            let tp_ty = *substs.substs.types.get(FnSpace, 0);
+        (_, "init") => {
+            let tp_ty = *substs.types.get(FnSpace, 0);
             let lltp_ty = type_of::type_of(ccx, tp_ty);
-            match bcx.fcx.llretptr.get() {
-                Some(ptr) => { Store(bcx, C_null(lltp_ty), ptr); RetVoid(bcx); }
-                None if ty::type_is_nil(tp_ty) => RetVoid(bcx),
-                None => Ret(bcx, C_null(lltp_ty)),
-            }
-        }
-        "uninit" => {
-            // Do nothing, this is effectively a no-op
-            let retty = *substs.substs.types.get(FnSpace, 0);
-            if type_is_immediate(ccx, retty) && !return_type_is_void(ccx, retty) {
-                unsafe {
-                    Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
-                }
+            if return_type_is_void(ccx, tp_ty) {
+                C_nil(ccx)
             } else {
-                RetVoid(bcx)
+                C_null(lltp_ty)
             }
         }
-        "forget" => {
-            RetVoid(bcx);
-        }
-        "transmute" => {
-            let (in_type, out_type) = (*substs.substs.types.get(FnSpace, 0),
-                                       *substs.substs.types.get(FnSpace, 1));
-            let llintype = type_of::type_of(ccx, in_type);
-            let llouttype = type_of::type_of(ccx, out_type);
-
-            let in_type_size = machine::llbitsize_of_real(ccx, llintype);
-            let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
-            if in_type_size != out_type_size {
-                let sp = match ccx.tcx.map.get(ref_id.unwrap()) {
-                    ast_map::NodeExpr(e) => e.span,
-                    _ => fail!("transmute has non-expr arg"),
-                };
-                ccx.sess().span_bug(sp,
-                    format!("transmute called on types with different sizes: \
-                             {} ({} bit{}) to \
-                             {} ({} bit{})",
-                            ty_to_str(ccx.tcx(), in_type),
-                            in_type_size,
-                            if in_type_size == 1 {""} else {"s"},
-                            ty_to_str(ccx.tcx(), out_type),
-                            out_type_size,
-                            if out_type_size == 1 {""} else {"s"}).as_slice());
-            }
-
-            if !return_type_is_void(ccx, out_type) {
-                let llsrcval = get_param(decl, first_real_arg);
-                if type_is_immediate(ccx, in_type) {
-                    match fcx.llretptr.get() {
-                        Some(llretptr) => {
-                            Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to()));
-                            RetVoid(bcx);
-                        }
-                        None => match (llintype.kind(), llouttype.kind()) {
-                            (Pointer, other) | (other, Pointer) if other != Pointer => {
-                                let tmp = Alloca(bcx, llouttype, "");
-                                Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
-                                Ret(bcx, Load(bcx, tmp));
-                            }
-                            (Array, _) | (_, Array) | (Struct, _) | (_, Struct) => {
-                                let tmp = Alloca(bcx, llouttype, "");
-                                Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
-                                Ret(bcx, Load(bcx, tmp));
-                            }
-                            _ => {
-                                let llbitcast = BitCast(bcx, llsrcval, llouttype);
-                                Ret(bcx, llbitcast)
-                            }
-                        }
-                    }
-                } else if type_is_immediate(ccx, out_type) {
-                    let llsrcptr = PointerCast(bcx, llsrcval, llouttype.ptr_to());
-                    let ll_load = Load(bcx, llsrcptr);
-                    Ret(bcx, ll_load);
-                } else {
-                    // NB: Do not use a Load and Store here. This causes massive
-                    // code bloat when `transmute` is used on large structural
-                    // types.
-                    let lldestptr = fcx.llretptr.get().unwrap();
-                    let lldestptr = PointerCast(bcx, lldestptr, Type::i8p(ccx));
-                    let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p(ccx));
-
-                    let llsize = llsize_of(ccx, llintype);
-                    call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1);
-                    RetVoid(bcx);
-                };
-            } else {
-                RetVoid(bcx);
-            }
+        // Effectively no-ops
+        (_, "uninit") | (_, "forget") => {
+            C_nil(ccx)
         }
-        "needs_drop" => {
-            let tp_ty = *substs.substs.types.get(FnSpace, 0);
-            Ret(bcx, C_bool(ccx, ty::type_needs_drop(ccx.tcx(), tp_ty)));
+        (_, "needs_drop") => {
+            let tp_ty = *substs.types.get(FnSpace, 0);
+            C_bool(ccx, ty::type_needs_drop(ccx.tcx(), tp_ty))
         }
-        "owns_managed" => {
-            let tp_ty = *substs.substs.types.get(FnSpace, 0);
-            Ret(bcx, C_bool(ccx, ty::type_contents(ccx.tcx(), tp_ty).owns_managed()));
+        (_, "owns_managed") => {
+            let tp_ty = *substs.types.get(FnSpace, 0);
+            C_bool(ccx, ty::type_contents(ccx.tcx(), tp_ty).owns_managed())
         }
-        "visit_tydesc" => {
-            let td = get_param(decl, first_real_arg);
-            let visitor = get_param(decl, first_real_arg + 1u);
+        (_, "visit_tydesc") => {
+            let td = *llargs.get(0);
+            let visitor = *llargs.get(1);
             let td = PointerCast(bcx, td, ccx.tydesc_type().ptr_to());
             glue::call_visit_glue(bcx, visitor, td, None);
-            RetVoid(bcx);
+            C_nil(ccx)
         }
-        "offset" => {
-            let ptr = get_param(decl, first_real_arg);
-            let offset = get_param(decl, first_real_arg + 1);
-            let lladdr = InBoundsGEP(bcx, ptr, [offset]);
-            Ret(bcx, lladdr);
+        (_, "offset") => {
+            let ptr = *llargs.get(0);
+            let offset = *llargs.get(1);
+            InBoundsGEP(bcx, ptr, [offset])
         }
-        "copy_nonoverlapping_memory" => {
-            copy_intrinsic(bcx, false, false, *substs.substs.types.get(FnSpace, 0))
+
+        (_, "copy_nonoverlapping_memory") => {
+            copy_intrinsic(bcx, false, false, *substs.types.get(FnSpace, 0),
+                           *llargs.get(0), *llargs.get(1), *llargs.get(2))
         }
-        "copy_memory" => {
-            copy_intrinsic(bcx, true, false, *substs.substs.types.get(FnSpace, 0))
+        (_, "copy_memory") => {
+            copy_intrinsic(bcx, true, false, *substs.types.get(FnSpace, 0),
+                           *llargs.get(0), *llargs.get(1), *llargs.get(2))
         }
-        "set_memory" => {
-            memset_intrinsic(bcx, false, *substs.substs.types.get(FnSpace, 0))
+        (_, "set_memory") => {
+            memset_intrinsic(bcx, false, *substs.types.get(FnSpace, 0),
+                             *llargs.get(0), *llargs.get(1), *llargs.get(2))
         }
 
-        "volatile_copy_nonoverlapping_memory" => {
-            copy_intrinsic(bcx, false, true, *substs.substs.types.get(FnSpace, 0))
+        (_, "volatile_copy_nonoverlapping_memory") => {
+            copy_intrinsic(bcx, false, true, *substs.types.get(FnSpace, 0),
+                           *llargs.get(0), *llargs.get(1), *llargs.get(2))
         }
-
-        "volatile_copy_memory" => {
-            copy_intrinsic(bcx, true, true, *substs.substs.types.get(FnSpace, 0))
+        (_, "volatile_copy_memory") => {
+            copy_intrinsic(bcx, true, true, *substs.types.get(FnSpace, 0),
+                           *llargs.get(0), *llargs.get(1), *llargs.get(2))
         }
+        (_, "volatile_set_memory") => {
+            memset_intrinsic(bcx, true, *substs.types.get(FnSpace, 0),
+                             *llargs.get(0), *llargs.get(1), *llargs.get(2))
+        }
+        (_, "volatile_load") => {
+            VolatileLoad(bcx, *llargs.get(0))
+        },
+        (_, "volatile_store") => {
+            VolatileStore(bcx, *llargs.get(1), *llargs.get(0));
+            C_nil(ccx)
+        },
+
+        (_, "ctlz8") => count_zeros_intrinsic(bcx, "llvm.ctlz.i8", *llargs.get(0)),
+        (_, "ctlz16") => count_zeros_intrinsic(bcx, "llvm.ctlz.i16", *llargs.get(0)),
+        (_, "ctlz32") => count_zeros_intrinsic(bcx, "llvm.ctlz.i32", *llargs.get(0)),
+        (_, "ctlz64") => count_zeros_intrinsic(bcx, "llvm.ctlz.i64", *llargs.get(0)),
+        (_, "cttz8") => count_zeros_intrinsic(bcx, "llvm.cttz.i8", *llargs.get(0)),
+        (_, "cttz16") => count_zeros_intrinsic(bcx, "llvm.cttz.i16", *llargs.get(0)),
+        (_, "cttz32") => count_zeros_intrinsic(bcx, "llvm.cttz.i32", *llargs.get(0)),
+        (_, "cttz64") => count_zeros_intrinsic(bcx, "llvm.cttz.i64", *llargs.get(0)),
+
+        (_, "i8_add_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i8", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "i16_add_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i16", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "i32_add_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i32", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "i64_add_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i64", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+
+        (_, "u8_add_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i8", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "u16_add_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i16", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "u32_add_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i32", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "u64_add_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i64", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+
+        (_, "i8_sub_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i8", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "i16_sub_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i16", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "i32_sub_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i32", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "i64_sub_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i64", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+
+        (_, "u8_sub_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i8", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "u16_sub_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i16", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "u32_sub_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i32", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "u64_sub_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i64", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+
+        (_, "i8_mul_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i8", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "i16_mul_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i16", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "i32_mul_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i32", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+        (_, "i64_mul_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i64", ret_ty,
+                                   *llargs.get(0), *llargs.get(1)),
+
+        (_, "u8_mul_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i8", ret_ty,
+                                    *llargs.get(0), *llargs.get(1)),
+        (_, "u16_mul_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i16", ret_ty,
+                                    *llargs.get(0), *llargs.get(1)),
+        (_, "u32_mul_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i32", ret_ty,
+                                    *llargs.get(0), *llargs.get(1)),
+        (_, "u64_mul_with_overflow") =>
+            with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i64", ret_ty,
+                                    *llargs.get(0), *llargs.get(1)),
+
+        // This requires that atomic intrinsics follow a specific naming pattern:
+        // "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
+        (_, name) if name.starts_with("atomic_") => {
+            let split: Vec<&str> = name.split('_').collect();
+            assert!(split.len() >= 2, "Atomic intrinsic not correct format");
+
+            let order = if split.len() == 2 {
+                llvm::SequentiallyConsistent
+            } else {
+                match *split.get(2) {
+                    "relaxed" => llvm::Monotonic,
+                    "acq"     => llvm::Acquire,
+                    "rel"     => llvm::Release,
+                    "acqrel"  => llvm::AcquireRelease,
+                    _ => ccx.sess().fatal("unknown ordering in atomic intrinsic")
+                }
+            };
+
+            match *split.get(1) {
+                "cxchg" => {
+                    // See include/llvm/IR/Instructions.h for their implementation
+                    // of this, I assume that it's good enough for us to use for
+                    // now.
+                    let strongest_failure_ordering = match order {
+                        llvm::NotAtomic | llvm::Unordered =>
+                            ccx.sess().fatal("cmpxchg must be atomic"),
+
+                        llvm::Monotonic | llvm::Release =>
+                            llvm::Monotonic,
+
+                        llvm::Acquire | llvm::AcquireRelease =>
+                            llvm::Acquire,
+
+                        llvm::SequentiallyConsistent =>
+                            llvm::SequentiallyConsistent
+                    };
+
+                    let res = AtomicCmpXchg(bcx, *llargs.get(0), *llargs.get(1),
+                                            *llargs.get(2), order,
+                                            strongest_failure_ordering);
+                    if unsafe { llvm::LLVMVersionMinor() >= 5 } {
+                        ExtractValue(bcx, res, 0)
+                    } else {
+                        res
+                    }
+                }
+
+                "load" => {
+                    AtomicLoad(bcx, *llargs.get(0), order)
+                }
+                "store" => {
+                    AtomicStore(bcx, *llargs.get(1), *llargs.get(0), order);
+                    C_nil(ccx)
+                }
+
+                "fence" => {
+                    AtomicFence(bcx, order);
+                    C_nil(ccx)
+                }
+
+                // These are all AtomicRMW ops
+                op => {
+                    let atom_op = match op {
+                        "xchg"  => llvm::Xchg,
+                        "xadd"  => llvm::Add,
+                        "xsub"  => llvm::Sub,
+                        "and"   => llvm::And,
+                        "nand"  => llvm::Nand,
+                        "or"    => llvm::Or,
+                        "xor"   => llvm::Xor,
+                        "max"   => llvm::Max,
+                        "min"   => llvm::Min,
+                        "umax"  => llvm::UMax,
+                        "umin"  => llvm::UMin,
+                        _ => ccx.sess().fatal("unknown atomic operation")
+                    };
+
+                    AtomicRMW(bcx, atom_op, *llargs.get(0), *llargs.get(1), order)
+                }
+            }
 
-        "volatile_set_memory" => {
-            memset_intrinsic(bcx, true, *substs.substs.types.get(FnSpace, 0))
         }
 
-        "ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"),
-        "ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"),
-        "ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"),
-        "ctlz64" => count_zeros_intrinsic(bcx, "llvm.ctlz.i64"),
-        "cttz8" => count_zeros_intrinsic(bcx, "llvm.cttz.i8"),
-        "cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"),
-        "cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"),
-        "cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"),
-
-        "volatile_load" => volatile_load_intrinsic(bcx),
-        "volatile_store" => volatile_store_intrinsic(bcx),
-
-        "i8_add_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i8", output_type),
-        "i16_add_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i16", output_type),
-        "i32_add_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i32", output_type),
-        "i64_add_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i64", output_type),
-
-        "u8_add_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i8", output_type),
-        "u16_add_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i16", output_type),
-        "u32_add_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i32", output_type),
-        "u64_add_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i64", output_type),
-
-        "i8_sub_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i8", output_type),
-        "i16_sub_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i16", output_type),
-        "i32_sub_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i32", output_type),
-        "i64_sub_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i64", output_type),
-
-        "u8_sub_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i8", output_type),
-        "u16_sub_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i16", output_type),
-        "u32_sub_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i32", output_type),
-        "u64_sub_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i64", output_type),
-
-        "i8_mul_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i8", output_type),
-        "i16_mul_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i16", output_type),
-        "i32_mul_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i32", output_type),
-        "i64_mul_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i64", output_type),
-
-        "u8_mul_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i8", output_type),
-        "u16_mul_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i16", output_type),
-        "u32_mul_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i32", output_type),
-        "u64_mul_with_overflow" =>
-            with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i64", output_type),
-
-        _ => {
-            // Could we make this an enum rather than a string? does it get
-            // checked earlier?
-            ccx.sess().span_bug(item.span, "unknown intrinsic");
+        (_, _) => ccx.sess().span_bug(foreign_item.span, "unknown intrinsic")
+    };
+
+    if val_ty(llval) != Type::void(ccx) &&
+       machine::llsize_of_alloc(ccx, val_ty(llval)) != 0 {
+        store_ty(bcx, llval, llresult, ret_ty);
+    }
+
+    // If we made a temporary stack slot, let's clean it up
+    match dest {
+        expr::Ignore => {
+            bcx = glue::drop_ty(bcx, llresult, ret_ty);
         }
+        expr::SaveIn(_) => {}
     }
-    fcx.cleanup();
+
+    Result::new(bcx, llresult)
 }
 
-/// Performs late verification that intrinsics are used correctly. At present,
-/// the only intrinsic that needs such verification is `transmute`.
-pub fn check_intrinsics(ccx: &CrateContext) {
-    for transmute_restriction in ccx.tcx
-                                    .transmute_restrictions
-                                    .borrow()
-                                    .iter() {
-        let llfromtype = type_of::sizing_type_of(ccx,
-                                                 transmute_restriction.from);
-        let lltotype = type_of::sizing_type_of(ccx,
-                                               transmute_restriction.to);
-        let from_type_size = machine::llbitsize_of_real(ccx, llfromtype);
-        let to_type_size = machine::llbitsize_of_real(ccx, lltotype);
-        if from_type_size != to_type_size {
-            ccx.sess()
-               .span_err(transmute_restriction.span,
-                format!("transmute called on types with different sizes: \
-                         {} ({} bit{}) to {} ({} bit{})",
-                        ty_to_str(ccx.tcx(), transmute_restriction.from),
-                        from_type_size as uint,
-                        if from_type_size == 1 {
-                            ""
-                        } else {
-                            "s"
-                        },
-                        ty_to_str(ccx.tcx(), transmute_restriction.to),
-                        to_type_size as uint,
-                        if to_type_size == 1 {
-                            ""
-                        } else {
-                            "s"
-                        }).as_slice());
+fn copy_intrinsic(bcx: &Block, allow_overlap: bool, volatile: bool,
+                  tp_ty: ty::t, dst: ValueRef, src: ValueRef, count: ValueRef) -> ValueRef {
+    let ccx = bcx.ccx();
+    let lltp_ty = type_of::type_of(ccx, tp_ty);
+    let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
+    let size = machine::llsize_of(ccx, lltp_ty);
+    let int_size = machine::llbitsize_of_real(ccx, ccx.int_type);
+    let name = if allow_overlap {
+        if int_size == 32 {
+            "llvm.memmove.p0i8.p0i8.i32"
+        } else {
+            "llvm.memmove.p0i8.p0i8.i64"
         }
-    }
-    ccx.sess().abort_if_errors();
+    } else {
+        if int_size == 32 {
+            "llvm.memcpy.p0i8.p0i8.i32"
+        } else {
+            "llvm.memcpy.p0i8.p0i8.i64"
+        }
+    };
+
+    let dst_ptr = PointerCast(bcx, dst, Type::i8p(ccx));
+    let src_ptr = PointerCast(bcx, src, Type::i8p(ccx));
+    let llfn = ccx.get_intrinsic(&name);
+
+    Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align,
+                     C_bool(ccx, volatile)], [])
 }
 
+fn memset_intrinsic(bcx: &Block, volatile: bool, tp_ty: ty::t,
+                    dst: ValueRef, val: ValueRef, count: ValueRef) -> ValueRef {
+    let ccx = bcx.ccx();
+    let lltp_ty = type_of::type_of(ccx, tp_ty);
+    let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
+    let size = machine::llsize_of(ccx, lltp_ty);
+    let name = if machine::llbitsize_of_real(ccx, ccx.int_type) == 32 {
+        "llvm.memset.p0i8.i32"
+    } else {
+        "llvm.memset.p0i8.i64"
+    };
+
+    let dst_ptr = PointerCast(bcx, dst, Type::i8p(ccx));
+    let llfn = ccx.get_intrinsic(&name);
+
+    Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align,
+                     C_bool(ccx, volatile)], [])
+}
+
+fn count_zeros_intrinsic(bcx: &Block, name: &'static str, val: ValueRef) -> ValueRef {
+    let y = C_bool(bcx.ccx(), false);
+    let llfn = bcx.ccx().get_intrinsic(&name);
+    Call(bcx, llfn, [val, y], [])
+}
+
+fn with_overflow_intrinsic(bcx: &Block, name: &'static str, t: ty::t,
+                           a: ValueRef, b: ValueRef) -> ValueRef {
+    let llfn = bcx.ccx().get_intrinsic(&name);
+
+    // Convert `i1` to a `bool`, and write it to the out parameter
+    let val = Call(bcx, llfn, [a, b], []);
+    let result = ExtractValue(bcx, val, 0);
+    let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool(bcx.ccx()));
+    let ret = C_undef(type_of::type_of(bcx.ccx(), t));
+    let ret = InsertValue(bcx, ret, result, 0);
+    let ret = InsertValue(bcx, ret, overflow, 1);
+
+    ret
+}
index 3cd1a59abef38c1a56b5b06f34f9cf71afc23151..2740e5695be107b76b92a4c2f99671e6a7d1db7a 100644 (file)
@@ -10,7 +10,7 @@
 
 use middle::trans::context::CrateContext;
 use middle::trans::type_::Type;
-use lib::llvm::ValueRef;
+use llvm::ValueRef;
 
 pub trait LlvmRepr {
     fn llrepr(&self, ccx: &CrateContext) -> String;
@@ -25,13 +25,13 @@ fn llrepr(&self, ccx: &CrateContext) -> String {
 
 impl LlvmRepr for Type {
     fn llrepr(&self, ccx: &CrateContext) -> String {
-        ccx.tn.type_to_str(*self)
+        ccx.tn.type_to_string(*self)
     }
 }
 
 impl LlvmRepr for ValueRef {
     fn llrepr(&self, ccx: &CrateContext) -> String {
-        ccx.tn.val_to_str(*self)
+        ccx.tn.val_to_string(*self)
     }
 }
 
index 7a7e3a9b759132fa18c0097c2e45fd5fa41dda96..15bbc5ae845898390644965b38ea10c53076e574 100644 (file)
@@ -10,9 +10,9 @@
 
 // Information concerning the machine representation of various types.
 
-use lib::llvm::{ValueRef};
-use lib::llvm::False;
-use lib::llvm::llvm;
+use llvm;
+use llvm::{ValueRef};
+use llvm::False;
 use middle::trans::common::*;
 
 use middle::trans::type_::Type;
index e1d43c5240059ee03fd51e40f451269ec123f17d..092a524e48a1898476d7c283cbfa92cb20735415 100644 (file)
@@ -10,9 +10,8 @@
 
 
 use back::abi;
-use lib::llvm::llvm;
-use lib::llvm::ValueRef;
-use lib;
+use llvm;
+use llvm::ValueRef;
 use metadata::csearch;
 use middle::subst;
 use middle::trans::base::*;
@@ -38,7 +37,7 @@
 use std::gc::Gc;
 use syntax::abi::Rust;
 use syntax::parse::token;
-use syntax::{ast, ast_map, visit};
+use syntax::{ast, ast_map, visit, ast_util};
 
 /**
 The main "translation" pass for methods.  Generates code
@@ -66,9 +65,10 @@ pub fn trans_impl(ccx: &CrateContext,
         return;
     }
     for method in methods.iter() {
-        if method.generics.ty_params.len() == 0u {
+        if ast_util::method_generics(&**method).ty_params.len() == 0u {
             let llfn = get_item_val(ccx, method.id);
-            trans_fn(ccx, &*method.decl, &*method.body,
+            trans_fn(ccx, ast_util::method_fn_decl(&**method),
+                     ast_util::method_body(&**method),
                      llfn, &param_substs::empty(), method.id, []);
         } else {
             let mut v = TransItemVisitor{ ccx: ccx };
@@ -160,7 +160,7 @@ pub fn trans_static_method_callee(bcx: &Block,
             ast_map::NodeTraitMethod(method) => {
                 let ident = match *method {
                     ast::Required(ref m) => m.ident,
-                    ast::Provided(ref m) => m.ident
+                    ast::Provided(ref m) => ast_util::method_ident(&**m)
                 };
                 ident.name
             }
@@ -459,8 +459,8 @@ pub fn make_vtable<I: Iterator<ValueRef>>(ccx: &CrateContext,
             llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
         });
         llvm::LLVMSetInitializer(vt_gvar, tbl);
-        llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True);
-        lib::llvm::SetLinkage(vt_gvar, lib::llvm::InternalLinkage);
+        llvm::LLVMSetGlobalConstant(vt_gvar, llvm::True);
+        llvm::SetLinkage(vt_gvar, llvm::InternalLinkage);
         vt_gvar
     }
 }
@@ -502,12 +502,15 @@ fn emit_vtable_methods(bcx: &Block,
                                                        ExprId(0),
                                                        substs.clone(),
                                                        vtables.clone());
-            if m.explicit_self == ast::SelfValue {
-                fn_ref = trans_unboxing_shim(bcx,
-                                             fn_ref,
-                                             &*m,
-                                             m_id,
-                                             substs.clone());
+            match m.explicit_self {
+                ast::SelfValue(_) => {
+                    fn_ref = trans_unboxing_shim(bcx,
+                                                 fn_ref,
+                                                 &*m,
+                                                 m_id,
+                                                 substs.clone());
+                },
+                _ => {}
             }
             fn_ref
         }
index 125fa6828c5562c82fb719ea7b455d0d8eafacdf..7687e82654a9201e3e891927116951e53d08745e 100644 (file)
@@ -10,7 +10,7 @@
 
 use back::link::exported_name;
 use driver::session;
-use lib::llvm::ValueRef;
+use llvm::ValueRef;
 use middle::subst;
 use middle::subst::Subst;
 use middle::trans::base::{set_llvm_fn_attrs, set_inline_hint};
@@ -18,7 +18,6 @@
 use middle::trans::base::{trans_fn, decl_internal_rust_fn};
 use middle::trans::base;
 use middle::trans::common::*;
-use middle::trans::intrinsic;
 use middle::ty;
 use middle::typeck;
 use util::ppaux::Repr;
@@ -26,6 +25,7 @@
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_map;
+use syntax::ast_util;
 use syntax::ast_util::local_def;
 use std::hash::{sip, Hash};
 
@@ -129,9 +129,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
         hash_id.hash(&mut state);
         mono_ty.hash(&mut state);
 
-        exported_name(path,
-                      format!("h{}", state.result()).as_slice(),
-                      ccx.link_meta.crateid.version_or_default())
+        exported_name(path, format!("h{}", state.result()).as_slice())
     });
     debug!("monomorphize_fn mangled to {}", s);
 
@@ -160,17 +158,6 @@ pub fn monomorphic_fn(ccx: &CrateContext,
               }
             }
         }
-        ast_map::NodeForeignItem(i) => {
-            let simple = intrinsic::get_simple_intrinsic(ccx, &*i);
-            match simple {
-                Some(decl) => decl,
-                None => {
-                    let d = mk_lldecl();
-                    intrinsic::trans_intrinsic(ccx, d, &*i, &psubsts, ref_id);
-                    d
-                }
-            }
-        }
         ast_map::NodeVariant(v) => {
             let parent = ccx.tcx.map.get_parent(fn_id.node);
             let tvs = ty::enum_variants(ccx.tcx(), local_def(parent));
@@ -195,7 +182,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
         ast_map::NodeMethod(mth) => {
             let d = mk_lldecl();
             set_llvm_fn_attrs(mth.attrs.as_slice(), d);
-            trans_fn(ccx, &*mth.decl, &*mth.body, d, &psubsts, mth.id, []);
+            trans_fn(ccx, ast_util::method_fn_decl(&*mth),
+                     ast_util::method_body(&*mth), d, &psubsts, mth.id, []);
             d
         }
         ast_map::NodeTraitMethod(method) => {
@@ -203,7 +191,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
                 ast::Provided(mth) => {
                     let d = mk_lldecl();
                     set_llvm_fn_attrs(mth.attrs.as_slice(), d);
-                    trans_fn(ccx, &*mth.decl, &*mth.body, d, &psubsts, mth.id, []);
+                    trans_fn(ccx, ast_util::method_fn_decl(&*mth),
+                             ast_util::method_body(&*mth), d, &psubsts, mth.id, []);
                     d
                 }
                 _ => {
@@ -225,6 +214,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
         }
 
         // Ugh -- but this ensures any new variants won't be forgotten
+        ast_map::NodeForeignItem(..) |
         ast_map::NodeLifetime(..) |
         ast_map::NodeExpr(..) |
         ast_map::NodeStmt(..) |
index 91148d31423fb59a9e0ee6e560ef4a2ce5123aa3..bc156fc37917cc8ec1c9601b3f0cad308f70d044 100644 (file)
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 use back::link::mangle_internal_name_by_path_and_seq;
-use lib::llvm::{ValueRef, llvm};
+use llvm;
+use llvm::{ValueRef};
 use middle::trans::adt;
 use middle::trans::base::*;
 use middle::trans::build::*;
@@ -23,7 +24,7 @@
 use middle::trans::type_::Type;
 use middle::trans::type_of::*;
 use middle::ty;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 use std::rc::Rc;
 use arena::TypedArena;
@@ -98,7 +99,7 @@ pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) {
         debug!("passing {} args:", args.len());
         let mut bcx = self.bcx;
         for (i, a) in args.iter().enumerate() {
-            debug!("arg {}: {}", i, bcx.val_to_str(*a));
+            debug!("arg {}: {}", i, bcx.val_to_string(*a));
         }
         let result = unpack_result!(bcx, callee::trans_call_inner(
             self.bcx, None, mth_ty,
@@ -129,7 +130,7 @@ pub fn leaf(&mut self, name: &str) {
     pub fn visit_ty(&mut self, t: ty::t) {
         let bcx = self.bcx;
         let tcx = bcx.tcx();
-        debug!("reflect::visit_ty {}", ty_to_str(bcx.tcx(), t));
+        debug!("reflect::visit_ty {}", ty_to_string(bcx.tcx(), t));
 
         match ty::get(t).sty {
           ty::ty_bot => self.leaf("bot"),
@@ -175,7 +176,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                   ty::ty_trait(..) => {
                       let extra = [
                           self.c_slice(token::intern_and_get_ident(
-                                  ty_to_str(tcx, t).as_slice()))
+                                  ty_to_string(tcx, t).as_slice()))
                       ];
                       self.visit("trait", extra);
                   }
@@ -204,7 +205,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                   ty::ty_trait(..) => {
                       let extra = [
                           self.c_slice(token::intern_and_get_ident(
-                                  ty_to_str(tcx, t).as_slice()))
+                                  ty_to_string(tcx, t).as_slice()))
                       ];
                       self.visit("trait", extra);
                   }
@@ -269,7 +270,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
 
               let extra = (vec!(
                   self.c_slice(
-                      token::intern_and_get_ident(ty_to_str(tcx,
+                      token::intern_and_get_ident(ty_to_string(tcx,
                                                             t).as_slice())),
                   self.c_bool(named_fields),
                   self.c_uint(fields.len())
@@ -313,7 +314,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                 let fcx = new_fn_ctxt(ccx, llfdecl, -1, false,
                                       ty::mk_u64(), &empty_param_substs,
                                       None, &arena);
-                init_function(&fcx, false, ty::mk_u64());
+                let bcx = init_function(&fcx, false, ty::mk_u64());
 
                 let arg = unsafe {
                     //
@@ -323,7 +324,6 @@ pub fn visit_ty(&mut self, t: ty::t) {
                     //
                     llvm::LLVMGetParam(llfdecl, fcx.arg_pos(0u) as c_uint)
                 };
-                let bcx = fcx.entry_bcx.borrow().clone().unwrap();
                 let arg = BitCast(bcx, arg, llptrty);
                 let ret = adt::trans_get_discr(bcx, &*repr, arg, Some(Type::i64(ccx)));
                 Store(bcx, ret, fcx.llretptr.get().unwrap());
@@ -331,7 +331,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                     Some(llreturn) => Br(bcx, llreturn),
                     None => {}
                 };
-                finish_fn(&fcx, bcx);
+                finish_fn(&fcx, bcx, ty::mk_u64());
                 llfdecl
             };
 
index 65bf0b8500821d820a9e87ade08fab792fd5d4f1..07571b2f4c4a509d036263308e2787ed2c4085eb 100644 (file)
@@ -11,8 +11,8 @@
 #![allow(non_camel_case_types)]
 
 use back::abi;
-use lib;
-use lib::llvm::{llvm, ValueRef};
+use llvm;
+use llvm::{ValueRef};
 use middle::lang_items::StrDupUniqFnLangItem;
 use middle::trans::base::*;
 use middle::trans::base;
@@ -29,7 +29,7 @@
 use middle::trans::type_::Type;
 use middle::trans::type_of;
 use middle::ty;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
 
 use syntax::ast;
 use syntax::parse::token::InternedString;
@@ -73,12 +73,12 @@ pub struct VecTypes {
 }
 
 impl VecTypes {
-    pub fn to_str(&self, ccx: &CrateContext) -> String {
+    pub fn to_string(&self, ccx: &CrateContext) -> String {
         format!("VecTypes {{unit_ty={}, llunit_ty={}, \
                  llunit_size={}, llunit_alloc_size={}}}",
-                ty_to_str(ccx.tcx(), self.unit_ty),
-                ccx.tn.type_to_str(self.llunit_ty),
-                ccx.tn.val_to_str(self.llunit_size),
+                ty_to_string(ccx.tcx(), self.unit_ty),
+                ccx.tn.type_to_string(self.llunit_ty),
+                ccx.tn.val_to_string(self.llunit_size),
                 self.llunit_alloc_size)
     }
 }
@@ -97,7 +97,7 @@ pub fn trans_fixed_vstore<'a>(
     // generate the content.
 
     debug!("trans_fixed_vstore(vstore_expr={}, dest={:?})",
-           bcx.expr_to_str(vstore_expr), dest.to_str(bcx.ccx()));
+           bcx.expr_to_string(vstore_expr), dest.to_string(bcx.ccx()));
 
     let vt = vec_types_from_expr(bcx, vstore_expr);
 
@@ -129,7 +129,7 @@ pub fn trans_slice_vstore<'a>(
     let mut bcx = bcx;
 
     debug!("trans_slice_vstore(vstore_expr={}, dest={})",
-           bcx.expr_to_str(vstore_expr), dest.to_str(ccx));
+           bcx.expr_to_string(vstore_expr), dest.to_string(ccx));
 
     // Handle the &"..." case:
     match content_expr.node {
@@ -150,13 +150,14 @@ pub fn trans_slice_vstore<'a>(
     // Handle the &[...] case:
     let vt = vec_types_from_expr(bcx, vstore_expr);
     let count = elements_required(bcx, content_expr);
-    debug!("vt={}, count={:?}", vt.to_str(ccx), count);
+    debug!("vt={}, count={:?}", vt.to_string(ccx), count);
 
     let llcount = C_uint(ccx, count);
     let llfixed;
     if count == 0 {
-        // Zero-length array: just use NULL as the data pointer
-        llfixed = C_null(vt.llunit_ty.ptr_to());
+        // Just create a zero-sized alloca to preserve
+        // the non-null invariant of the inner slice ptr
+        llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
     } else {
         // Make a fixed-length backing array and allocate it on the stack.
         llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
@@ -201,8 +202,8 @@ pub fn trans_lit_str<'a>(
      */
 
     debug!("trans_lit_str(lit_expr={}, dest={})",
-           bcx.expr_to_str(lit_expr),
-           dest.to_str(bcx.ccx()));
+           bcx.expr_to_string(lit_expr),
+           dest.to_string(bcx.ccx()));
 
     match dest {
         Ignore => bcx,
@@ -232,7 +233,7 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>,
      * the array elements into them.
      */
 
-    debug!("trans_uniq_vstore(vstore_expr={})", bcx.expr_to_str(vstore_expr));
+    debug!("trans_uniq_vstore(vstore_expr={})", bcx.expr_to_string(vstore_expr));
     let fcx = bcx.fcx;
     let ccx = fcx.ccx;
 
@@ -296,7 +297,7 @@ pub fn trans_uniq_vstore<'a>(bcx: &'a Block<'a>,
     let dataptr = get_dataptr(bcx, val);
 
     debug!("alloc_uniq_vec() returned val={}, dataptr={}",
-           bcx.val_to_str(val), bcx.val_to_str(dataptr));
+           bcx.val_to_string(val), bcx.val_to_string(dataptr));
 
     let bcx = write_content(bcx, &vt, vstore_expr,
                             content_expr, SaveIn(dataptr));
@@ -318,9 +319,9 @@ pub fn write_content<'a>(
     let mut bcx = bcx;
 
     debug!("write_content(vt={}, dest={}, vstore_expr={:?})",
-           vt.to_str(bcx.ccx()),
-           dest.to_str(bcx.ccx()),
-           bcx.expr_to_str(vstore_expr));
+           vt.to_string(bcx.ccx()),
+           dest.to_string(bcx.ccx()),
+           bcx.expr_to_string(vstore_expr));
 
     match content_expr.node {
         ast::ExprLit(lit) => {
@@ -360,7 +361,7 @@ pub fn write_content<'a>(
                     for (i, element) in elements.iter().enumerate() {
                         let lleltptr = GEPi(bcx, lldest, [i]);
                         debug!("writing index {:?} with lleltptr={:?}",
-                               i, bcx.val_to_str(lleltptr));
+                               i, bcx.val_to_string(lleltptr));
                         bcx = expr::trans_into(bcx, &**element,
                                                SaveIn(lleltptr));
                         fcx.schedule_drop_mem(
@@ -542,7 +543,7 @@ pub fn iter_vec_loop<'r,
     { // i < count
         let lhs = Load(cond_bcx, loop_counter);
         let rhs = count;
-        let cond_val = ICmp(cond_bcx, lib::llvm::IntULT, lhs, rhs);
+        let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs);
 
         CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb);
     }
@@ -598,7 +599,7 @@ pub fn iter_vec_raw<'r,
         let data_ptr =
             Phi(header_bcx, val_ty(data_ptr), [data_ptr], [bcx.llbb]);
         let not_yet_at_end =
-            ICmp(header_bcx, lib::llvm::IntULT, data_ptr, data_end_ptr);
+            ICmp(header_bcx, llvm::IntULT, data_ptr, data_end_ptr);
         let body_bcx = fcx.new_temp_block("iter_vec_loop_body");
         let next_bcx = fcx.new_temp_block("iter_vec_next");
         CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb);
index 1ec792182bd1e5171379ca28bbd333ec3637ef04..573965108ad9468671343b120ebb9b513209b7a9 100644 (file)
@@ -10,8 +10,9 @@
 
 #![allow(non_uppercase_pattern_statics)]
 
-use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind};
-use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
+use llvm;
+use llvm::{TypeRef, Bool, False, True, TypeKind, ValueRef};
+use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
 
 use middle::trans::context::CrateContext;
 
 
 use std::c_str::ToCStr;
 use std::mem;
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::str::raw::from_c_str;
 
-use libc::{c_uint};
+use libc::{c_uint, c_void, free};
 
 #[deriving(Clone, PartialEq, Show)]
 pub struct Type {
@@ -89,7 +93,7 @@ pub fn f64(ccx: &CrateContext) -> Type {
     }
 
     pub fn bool(ccx: &CrateContext) -> Type {
-        Type::i1(ccx)
+        Type::i8(ccx)
     }
 
     pub fn char(ccx: &CrateContext) -> Type {
@@ -303,3 +307,50 @@ pub fn float_width(&self) -> uint {
         }
     }
 }
+
+
+/* Memory-managed object interface to type handles. */
+
+pub struct TypeNames {
+    named_types: RefCell<HashMap<String, TypeRef>>,
+}
+
+impl TypeNames {
+    pub fn new() -> TypeNames {
+        TypeNames {
+            named_types: RefCell::new(HashMap::new())
+        }
+    }
+
+    pub fn associate_type(&self, s: &str, t: &Type) {
+        assert!(self.named_types.borrow_mut().insert(s.to_string(),
+                                                     t.to_ref()));
+    }
+
+    pub fn find_type(&self, s: &str) -> Option<Type> {
+        self.named_types.borrow().find_equiv(&s).map(|x| Type::from_ref(*x))
+    }
+
+    pub fn type_to_string(&self, ty: Type) -> String {
+        unsafe {
+            let s = llvm::LLVMTypeToString(ty.to_ref());
+            let ret = from_c_str(s);
+            free(s as *mut c_void);
+            ret.to_string()
+        }
+    }
+
+    pub fn types_to_str(&self, tys: &[Type]) -> String {
+        let strs: Vec<String> = tys.iter().map(|t| self.type_to_string(*t)).collect();
+        format!("[{}]", strs.connect(","))
+    }
+
+    pub fn val_to_string(&self, val: ValueRef) -> String {
+        unsafe {
+            let s = llvm::LLVMValueToString(val);
+            let ret = from_c_str(s);
+            free(s as *mut c_void);
+            ret.to_string()
+        }
+    }
+}
index 31bf6cb0110a489699e189359b86db04a765ded9..f54ab190d5ef8d976f7b2e06d06b4470cfe82cce 100644 (file)
@@ -31,7 +31,7 @@ pub fn return_uses_outptr(ccx: &CrateContext, ty: ty::t) -> bool {
 }
 
 pub fn type_of_explicit_arg(ccx: &CrateContext, arg_ty: ty::t) -> Type {
-    let llty = type_of(ccx, arg_ty);
+    let llty = arg_type_of(ccx, arg_ty);
     if arg_is_indirect(ccx, arg_ty) {
         llty.ptr_to()
     } else {
@@ -46,7 +46,7 @@ pub fn type_of_rust_fn(cx: &CrateContext, has_env: bool,
     // Arg 0: Output pointer.
     // (if the output type is non-immediate)
     let use_out_pointer = return_uses_outptr(cx, output);
-    let lloutputtype = type_of(cx, output);
+    let lloutputtype = arg_type_of(cx, output);
     if use_out_pointer {
         atys.push(lloutputtype.ptr_to());
     }
@@ -75,11 +75,13 @@ pub fn type_of_fn_from_ty(cx: &CrateContext, fty: ty::t) -> Type {
             type_of_rust_fn(cx, true, f.sig.inputs.as_slice(), f.sig.output)
         }
         ty::ty_bare_fn(ref f) => {
-            if f.abi == abi::Rust || f.abi == abi::RustIntrinsic {
+            if f.abi == abi::Rust {
                 type_of_rust_fn(cx,
                                 false,
                                 f.sig.inputs.as_slice(),
                                 f.sig.output)
+            } else if f.abi == abi::RustIntrinsic {
+                cx.sess().bug("type_of_fn_from_ty given intrinsic")
             } else {
                 foreign::lltype_for_foreign_fn(cx, fty)
             }
@@ -167,6 +169,14 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
     llsizingty
 }
 
+pub fn arg_type_of(cx: &CrateContext, t: ty::t) -> Type {
+    if ty::type_is_bool(t) {
+        Type::i1(cx)
+    } else {
+        type_of(cx, t)
+    }
+}
+
 // NB: If you update this, be sure to update `sizing_type_of()` as well.
 pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
     // Check the cache.
@@ -191,7 +201,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
                 t,
                 t_norm.repr(cx.tcx()),
                 t_norm,
-                cx.tn.type_to_str(llty));
+                cx.tn.type_to_string(llty));
         cx.lltypes.borrow_mut().insert(t, llty);
         return llty;
     }
@@ -209,7 +219,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
         // avoids creating more than one copy of the enum when one
         // of the enum's variants refers to the enum itself.
         let repr = adt::represent_type(cx, t);
-        let tps = substs.types.get_vec(subst::TypeSpace);
+        let tps = substs.types.get_slice(subst::TypeSpace);
         let name = llvm_type_name(cx, an_enum, did, tps);
         adt::incomplete_type_of(cx, &*repr, name.as_slice())
       }
@@ -266,7 +276,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
               // in *after* placing it into the type cache. This prevents
               // infinite recursion with recursive struct types.
               let repr = adt::represent_type(cx, t);
-              let tps = substs.types.get_vec(subst::TypeSpace);
+              let tps = substs.types.get_slice(subst::TypeSpace);
               let name = llvm_type_name(cx, a_struct, did, tps);
               adt::incomplete_type_of(cx, &*repr, name.as_slice())
           }
@@ -283,7 +293,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
     debug!("--> mapped t={} {:?} to llty={}",
             t.repr(cx.tcx()),
             t,
-            cx.tn.type_to_str(llty));
+            cx.tn.type_to_string(llty));
 
     cx.lltypes.borrow_mut().insert(t, llty);
 
@@ -305,7 +315,7 @@ pub enum named_ty { a_struct, an_enum }
 pub fn llvm_type_name(cx: &CrateContext,
                       what: named_ty,
                       did: ast::DefId,
-                      tps: &Vec<ty::t>)
+                      tps: &[ty::t])
                       -> String
 {
     let name = match what {
index e627b859f4295d91a8c093480a4a4fc2467e9c2c..2db6a87a9dc53a99b8fcb216421fe9489ddda57e 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use lib::llvm::{llvm, UseRef, ValueRef};
+use llvm;
+use llvm::{UseRef, ValueRef};
 use middle::trans::basic_block::BasicBlock;
 use middle::trans::common::Block;
 use libc::c_uint;
index 9629fb38af80fb62cf58726d520725b139aba143..eee53b79763be9b023825311b25d24963bf5bdfe 100644 (file)
@@ -32,8 +32,8 @@
 use middle::ty_fold;
 use middle::ty_fold::{TypeFoldable,TypeFolder};
 use middle;
-use util::ppaux::{note_and_explain_region, bound_region_ptr_to_str};
-use util::ppaux::{trait_store_to_str, ty_to_str};
+use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
+use util::ppaux::{trait_store_to_string, ty_to_string};
 use util::ppaux::{Repr, UserString};
 use util::common::{indenter};
 use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet, FnvHashMap};
@@ -981,7 +981,7 @@ pub fn empty() -> Generics {
     }
 
     pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
-        !self.types.get_vec(space).is_empty()
+        !self.types.is_empty_in(space)
     }
 }
 
@@ -2243,8 +2243,8 @@ pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool {
     fn type_requires(cx: &ctxt, seen: &mut Vec<DefId>,
                      r_ty: t, ty: t) -> bool {
         debug!("type_requires({}, {})?",
-               ::util::ppaux::ty_to_str(cx, r_ty),
-               ::util::ppaux::ty_to_str(cx, ty));
+               ::util::ppaux::ty_to_string(cx, r_ty),
+               ::util::ppaux::ty_to_string(cx, ty));
 
         let r = {
             get(r_ty).sty == get(ty).sty ||
@@ -2252,8 +2252,8 @@ fn type_requires(cx: &ctxt, seen: &mut Vec<DefId>,
         };
 
         debug!("type_requires({}, {})? {}",
-               ::util::ppaux::ty_to_str(cx, r_ty),
-               ::util::ppaux::ty_to_str(cx, ty),
+               ::util::ppaux::ty_to_string(cx, r_ty),
+               ::util::ppaux::ty_to_string(cx, ty),
                r);
         return r;
     }
@@ -2261,8 +2261,8 @@ fn type_requires(cx: &ctxt, seen: &mut Vec<DefId>,
     fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
                         r_ty: t, ty: t) -> bool {
         debug!("subtypes_require({}, {})?",
-               ::util::ppaux::ty_to_str(cx, r_ty),
-               ::util::ppaux::ty_to_str(cx, ty));
+               ::util::ppaux::ty_to_string(cx, r_ty),
+               ::util::ppaux::ty_to_string(cx, ty));
 
         let r = match get(ty).sty {
             // fixed length vectors need special treatment compared to
@@ -2337,8 +2337,8 @@ fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
         };
 
         debug!("subtypes_require({}, {})? {}",
-               ::util::ppaux::ty_to_str(cx, r_ty),
-               ::util::ppaux::ty_to_str(cx, ty),
+               ::util::ppaux::ty_to_string(cx, r_ty),
+               ::util::ppaux::ty_to_string(cx, ty),
                r);
 
         return r;
@@ -2381,7 +2381,7 @@ fn find_nonrepresentable<It: Iterator<t>>(cx: &ctxt, sp: Span, seen: &mut Vec<De
     fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
                                    ty: t) -> Representability {
         debug!("type_structurally_recursive: {}",
-               ::util::ppaux::ty_to_str(cx, ty));
+               ::util::ppaux::ty_to_string(cx, ty));
 
         // Compare current type to previously seen types
         match get(ty).sty {
@@ -2441,7 +2441,7 @@ fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
     }
 
     debug!("is_type_representable: {}",
-           ::util::ppaux::ty_to_str(cx, ty));
+           ::util::ppaux::ty_to_string(cx, ty));
 
     // To avoid a stack overflow when checking an enum variant or struct that
     // contains a different, structurally recursive type, maintain a stack
@@ -2595,7 +2595,7 @@ pub fn node_id_to_trait_ref(cx: &ctxt, id: ast::NodeId) -> Rc<ty::TraitRef> {
         Some(t) => t.clone(),
         None => cx.sess.bug(
             format!("node_id_to_trait_ref: no trait ref for node `{}`",
-                    cx.map.node_to_str(id)).as_slice())
+                    cx.map.node_to_string(id)).as_slice())
     }
 }
 
@@ -2608,7 +2608,7 @@ pub fn node_id_to_type(cx: &ctxt, id: ast::NodeId) -> t {
        Some(t) => t,
        None => cx.sess.bug(
            format!("node_id_to_type: no type for node `{}`",
-                   cx.map.node_to_str(id)).as_slice())
+                   cx.map.node_to_string(id)).as_slice())
     }
 }
 
@@ -2842,7 +2842,7 @@ pub fn adjust_ty(cx: &ctxt,
                                         format!("the {}th autoderef failed: \
                                                 {}",
                                                 i,
-                                                ty_to_str(cx, adjusted_ty))
+                                                ty_to_string(cx, adjusted_ty))
                                                           .as_slice());
                                 }
                             }
@@ -3030,6 +3030,9 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
             // the deref method invoked for `*a` always yields an `&T`
             ast::ExprUnary(ast::UnDeref, _) => LvalueExpr,
 
+            // the index method invoked for `a[i]` always yields an `&T`
+            ast::ExprIndex(..) => LvalueExpr,
+
             // in the general case, result could be any type, use DPS
             _ => RvalueDpsExpr
         };
@@ -3217,11 +3220,11 @@ pub fn param_tys_in_type(ty: t) -> Vec<ParamTy> {
     rslt
 }
 
-pub fn ty_sort_str(cx: &ctxt, t: t) -> String {
+pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
     match get(t).sty {
         ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
         ty_uint(_) | ty_float(_) | ty_str => {
-            ::util::ppaux::ty_to_str(cx, t)
+            ::util::ppaux::ty_to_string(cx, t)
         }
 
         ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
@@ -3274,18 +3277,18 @@ fn tstore_to_closure(s: &TraitStore) -> String {
         terr_mismatch => "types differ".to_string(),
         terr_fn_style_mismatch(values) => {
             format!("expected {} fn but found {} fn",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_abi_mismatch(values) => {
             format!("expected {} fn but found {} fn",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_onceness_mismatch(values) => {
             format!("expected {} fn but found {} fn",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_sigil_mismatch(values) => {
             format!("expected {}, found {}",
@@ -3341,22 +3344,22 @@ fn tstore_to_closure(s: &TraitStore) -> String {
         terr_regions_insufficiently_polymorphic(br, _) => {
             format!("expected bound lifetime parameter {}, \
                      but found concrete lifetime",
-                    bound_region_ptr_to_str(cx, br))
+                    bound_region_ptr_to_string(cx, br))
         }
         terr_regions_overly_polymorphic(br, _) => {
             format!("expected concrete lifetime, \
                      but found bound lifetime parameter {}",
-                    bound_region_ptr_to_str(cx, br))
+                    bound_region_ptr_to_string(cx, br))
         }
         terr_trait_stores_differ(_, ref values) => {
             format!("trait storage differs: expected `{}` but found `{}`",
-                    trait_store_to_str(cx, (*values).expected),
-                    trait_store_to_str(cx, (*values).found))
+                    trait_store_to_string(cx, (*values).expected),
+                    trait_store_to_string(cx, (*values).found))
         }
         terr_sorts(values) => {
             format!("expected {} but found {}",
-                    ty_sort_str(cx, values.expected),
-                    ty_sort_str(cx, values.found))
+                    ty_sort_string(cx, values.expected),
+                    ty_sort_string(cx, values.found))
         }
         terr_traits(values) => {
             format!("expected trait `{}` but found trait `{}`",
@@ -3381,13 +3384,13 @@ fn tstore_to_closure(s: &TraitStore) -> String {
         }
         terr_int_mismatch(ref values) => {
             format!("expected `{}` but found `{}`",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_float_mismatch(ref values) => {
             format!("expected `{}` but found `{}`",
-                    values.expected.to_str(),
-                    values.found.to_str())
+                    values.expected.to_string(),
+                    values.found.to_string())
         }
         terr_variadic_mismatch(ref values) => {
             format!("expected {} fn but found {} function",
@@ -3698,7 +3701,7 @@ pub fn substd_enum_variants(cx: &ctxt,
 }
 
 pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String {
-    with_path(cx, id, |path| ast_map::path_to_str(path)).to_string()
+    with_path(cx, id, |path| ast_map::path_to_string(path)).to_string()
 }
 
 pub enum DtorKind {
@@ -3884,13 +3887,13 @@ pub fn lookup_trait_def(cx: &ctxt, did: ast::DefId) -> Rc<ty::TraitDef> {
 pub fn each_attr(tcx: &ctxt, did: DefId, f: |&ast::Attribute| -> bool) -> bool {
     if is_local(did) {
         let item = tcx.map.expect_item(did.node);
-        item.attrs.iter().advance(|attr| f(attr))
+        item.attrs.iter().all(|attr| f(attr))
     } else {
         info!("getting foreign attrs");
         let mut cont = true;
         csearch::get_item_attrs(&tcx.sess.cstore, did, |attrs| {
             if cont {
-                cont = attrs.iter().advance(|attr| f(attr));
+                cont = attrs.iter().all(|attr| f(attr));
             }
         });
         info!("done");
@@ -3970,7 +3973,7 @@ fn each_super_struct(cx: &ctxt, mut did: ast::DefId, f: |ast::DefId|) {
             None => {
                 cx.sess.bug(
                     format!("ID not mapped to super-struct: {}",
-                            cx.map.node_to_str(did.node)).as_slice());
+                            cx.map.node_to_string(did.node)).as_slice());
             }
         }
     }
@@ -3992,7 +3995,7 @@ pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
                 _ => {
                     cx.sess.bug(
                         format!("ID not mapped to struct fields: {}",
-                                cx.map.node_to_str(did.node)).as_slice());
+                                cx.map.node_to_string(did.node)).as_slice());
                 }
             }
         });
@@ -4618,7 +4621,7 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
 }
 
 impl Variance {
-    pub fn to_str(self) -> &'static str {
+    pub fn to_string(self) -> &'static str {
         match self {
             Covariant => "+",
             Contravariant => "-",
@@ -4644,14 +4647,14 @@ pub fn construct_parameter_environment(
     let mut types = VecPerParamSpace::empty();
     for &space in subst::ParamSpace::all().iter() {
         push_types_from_defs(tcx, &mut types, space,
-                             generics.types.get_vec(space));
+                             generics.types.get_slice(space));
     }
 
     // map bound 'a => free 'a
     let mut regions = VecPerParamSpace::empty();
     for &space in subst::ParamSpace::all().iter() {
         push_region_params(&mut regions, space, free_id,
-                           generics.regions.get_vec(space));
+                           generics.regions.get_slice(space));
     }
 
     let free_substs = Substs {
@@ -4666,7 +4669,7 @@ pub fn construct_parameter_environment(
     let mut bounds = VecPerParamSpace::empty();
     for &space in subst::ParamSpace::all().iter() {
         push_bounds_from_defs(tcx, &mut bounds, space, &free_substs,
-                              generics.types.get_vec(space));
+                              generics.types.get_slice(space));
     }
 
     debug!("construct_parameter_environment: free_id={} \
@@ -4684,7 +4687,7 @@ pub fn construct_parameter_environment(
     fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
                           space: subst::ParamSpace,
                           free_id: ast::NodeId,
-                          region_params: &Vec<RegionParameterDef>)
+                          region_params: &[RegionParameterDef])
     {
         for r in region_params.iter() {
             regions.push(space, ty::free_region_from_def(free_id, r));
@@ -4694,7 +4697,7 @@ fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
     fn push_types_from_defs(tcx: &ty::ctxt,
                             types: &mut subst::VecPerParamSpace<ty::t>,
                             space: subst::ParamSpace,
-                            defs: &Vec<TypeParameterDef>) {
+                            defs: &[TypeParameterDef]) {
         for (i, def) in defs.iter().enumerate() {
             let ty = ty::mk_param(tcx, space, i, def.def_id);
             types.push(space, ty);
@@ -4705,7 +4708,7 @@ fn push_bounds_from_defs(tcx: &ty::ctxt,
                              bounds: &mut subst::VecPerParamSpace<ParamBounds>,
                              space: subst::ParamSpace,
                              free_substs: &subst::Substs,
-                             defs: &Vec<TypeParameterDef>) {
+                             defs: &[TypeParameterDef]) {
         for def in defs.iter() {
             let b = (*def.bounds).subst(tcx, free_substs);
             bounds.push(space, b);
index 1ad15e536ecc474f5f8cc71ec10a351729f371bf..90331d8f43430c2e3531b870e4724508c6df06d7 100644 (file)
@@ -66,7 +66,7 @@
 use syntax::{ast, ast_util};
 use syntax::codemap::Span;
 use syntax::owned_slice::OwnedSlice;
-use syntax::print::pprust::{lifetime_to_str, path_to_str};
+use syntax::print::pprust::{lifetime_to_string, path_to_string};
 
 pub trait AstConv {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt;
@@ -108,7 +108,7 @@ pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime)
     };
 
     debug!("ast_region_to_region(lifetime={} id={}) yields {}",
-            lifetime_to_str(lifetime),
+            lifetime_to_string(lifetime),
             lifetime.id, r.repr(tcx));
 
     r
@@ -142,7 +142,7 @@ pub fn opt_ast_region_to_region<AC:AstConv,RS:RegionScope>(
     };
 
     debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {}",
-            opt_lifetime.as_ref().map(|e| lifetime_to_str(e)),
+            opt_lifetime.as_ref().map(|e| lifetime_to_string(e)),
             r.repr(this.tcx()));
 
     r
@@ -203,7 +203,7 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
     };
 
     // Convert the type parameters supplied by the user.
-    let ty_param_defs = decl_generics.types.get_vec(TypeSpace);
+    let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
     let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).count();
     let formal_ty_param_count = ty_param_defs.len();
     let required_ty_param_count = ty_param_defs.iter()
@@ -331,7 +331,7 @@ pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option<ty::t> {
                 None => {
                     tcx.sess.span_bug(ast_ty.span,
                                       format!("unbound path {}",
-                                              path_to_str(path)).as_slice())
+                                              path_to_string(path)).as_slice())
                 }
                 Some(&d) => d
             };
@@ -394,7 +394,7 @@ pub fn ast_ty_to_builtin_ty<AC:AstConv,
                         .sess
                         .span_bug(ast_ty.span,
                                   format!("unbound path {}",
-                                          path_to_str(path)).as_slice())
+                                          path_to_string(path)).as_slice())
                 }
                 Some(&d) => d
             };
@@ -793,7 +793,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                         tcx.sess
                            .span_bug(ast_ty.span,
                                      format!("unbound path {}",
-                                             path_to_str(path)).as_slice())
+                                             path_to_string(path)).as_slice())
                     }
                     Some(&d) => d
                 };
@@ -808,7 +808,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                 }
                 match a_def {
                     def::DefTrait(_) => {
-                        let path_str = path_to_str(path);
+                        let path_str = path_to_string(path);
                         tcx.sess.span_err(
                             ast_ty.span,
                             format!("reference to trait `{name}` where a \
@@ -835,7 +835,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                     def::DefMod(id) => {
                         tcx.sess.span_fatal(ast_ty.span,
                             format!("found module name used as a type: {}",
-                                    tcx.map.node_to_str(id.node)).as_slice());
+                                    tcx.map.node_to_string(id.node)).as_slice());
                     }
                     def::DefPrimTy(_) => {
                         fail!("DefPrimTy arm missed in previous ast_ty_to_prim_ty call");
@@ -938,10 +938,10 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
     let self_ty = opt_self_info.and_then(|self_info| {
         match self_info.explicit_self.node {
             ast::SelfStatic => None,
-            ast::SelfValue => {
+            ast::SelfValue(_) => {
                 Some(self_info.untransformed_self_ty)
             }
-            ast::SelfRegion(ref lifetime, mutability) => {
+            ast::SelfRegion(ref lifetime, mutability, _) => {
                 let region =
                     opt_ast_region_to_region(this, &rb,
                                              self_info.explicit_self.span,
@@ -950,7 +950,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
                                  ty::mt {ty: self_info.untransformed_self_ty,
                                          mutbl: mutability}))
             }
-            ast::SelfUniq => {
+            ast::SelfUniq(_) => {
                 Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty))
             }
         }
index 697c5d367ee5a51ab3a65cd2a6945de0d3ae5db6..2232cc4965785fcab7d6aa3b4f787a27c6665c48 100644 (file)
@@ -362,36 +362,16 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
     }
 }
 
-pub fn check_struct_pat(pcx: &pat_ctxt, pat_id: ast::NodeId, span: Span,
-                        expected: ty::t, path: &ast::Path,
+pub fn check_struct_pat(pcx: &pat_ctxt, _pat_id: ast::NodeId, span: Span,
+                        _expected: ty::t, _path: &ast::Path,
                         fields: &[ast::FieldPat], etc: bool,
                         struct_id: ast::DefId,
                         substitutions: &subst::Substs) {
-    let fcx = pcx.fcx;
+    let _fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
     let class_fields = ty::lookup_struct_fields(tcx, struct_id);
 
-    // Check to ensure that the struct is the one specified.
-    match tcx.def_map.borrow().find(&pat_id) {
-        Some(&def::DefStruct(supplied_def_id))
-                if supplied_def_id == struct_id => {
-            // OK.
-        }
-        Some(&def::DefStruct(..)) | Some(&def::DefVariant(..)) => {
-            let name = pprust::path_to_str(path);
-            tcx.sess
-               .span_err(span,
-                         format!("mismatched types: expected `{}` but found \
-                                  `{}`",
-                                 fcx.infcx().ty_to_str(expected),
-                                 name).as_slice());
-        }
-        _ => {
-            tcx.sess.span_bug(span, "resolve didn't write in struct ID");
-        }
-    }
-
     check_struct_pat_fields(pcx, span, fields, class_fields, struct_id,
                             substitutions, etc);
 }
@@ -419,11 +399,11 @@ pub fn check_struct_like_enum_variant_pat(pcx: &pat_ctxt,
                                     variant_id, substitutions, etc);
         }
         Some(&def::DefStruct(..)) | Some(&def::DefVariant(..)) => {
-            let name = pprust::path_to_str(path);
+            let name = pprust::path_to_string(path);
             tcx.sess.span_err(span,
                               format!("mismatched types: expected `{}` but \
                                        found `{}`",
-                                      fcx.infcx().ty_to_str(expected),
+                                      fcx.infcx().ty_to_string(expected),
                                       name).as_slice());
         }
         _ => {
@@ -535,6 +515,21 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
         let mut error_happened = false;
         match *structure {
             ty::ty_struct(cid, ref substs) => {
+                // Verify that the pattern named the right structure.
+                let item_did = tcx.def_map.borrow().get(&pat.id).def_id();
+                let struct_did =
+                    ty::ty_to_def_id(
+                        ty::lookup_item_type(tcx, item_did).ty).unwrap();
+                if struct_did != cid {
+                    tcx.sess
+                       .span_err(path.span,
+                                 format!("`{}` does not name the \
+                                          structure `{}`",
+                                         pprust::path_to_string(path),
+                                         fcx.infcx()
+                                            .ty_to_string(expected)).as_slice())
+                }
+
                 check_struct_pat(pcx, pat.id, pat.span, expected, path,
                                  fields.as_slice(), etc, cid, substs);
             }
@@ -562,7 +557,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
                             "a structure pattern".to_string(),
                             None);
                 match tcx.def_map.borrow().find(&pat.id) {
-                    Some(&def::DefStruct(supplied_def_id)) => {
+                    Some(def) => {
                          check_struct_pat(pcx,
                                           pat.id,
                                           pat.span,
@@ -570,10 +565,14 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
                                           path,
                                           fields.as_slice(),
                                           etc,
-                                          supplied_def_id,
+                                          def.def_id(),
                                           &subst::Substs::empty());
                     }
-                    _ => () // Error, but we're already in an error case
+                    None => {
+                        tcx.sess.span_bug(pat.span,
+                                          "whoops, looks like resolve didn't \
+                                           write a def in here")
+                    }
                 }
                 error_happened = true;
             }
@@ -748,7 +747,7 @@ fn check_pointer_pat(pcx: &pat_ctxt,
                 tcx.sess.span_err(
                     span,
                     format!("type `{}` cannot be dereferenced",
-                            fcx.infcx().ty_to_str(expected)).as_slice());
+                            fcx.infcx().ty_to_string(expected)).as_slice());
                 fcx.write_error(pat_id);
             }
             _ => {
index c3b2756bdbff2f7f165af2718ec6a1fe293a7452..a184ecac9dea669196a66ce619dc40341f6a9586 100644 (file)
@@ -30,14 +30,14 @@ impl like `impl Foo` are inherent methods.  Nothing needs to be
 module as the type itself).
 
 Inherent candidates are not always derived from impls.  If you have a
-trait instance, such as a value of type `Box<ToStr>`, then the trait
-methods (`to_str()`, in this case) are inherently associated with it.
+trait instance, such as a value of type `Box<ToString>`, then the trait
+methods (`to_string()`, in this case) are inherently associated with it.
 Another case is type parameters, in which case the methods of their
 bounds are inherent.
 
 Extension candidates are derived from imported traits.  If I have the
-trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
-then we will go off to find out whether there is an impl of `ToStr`
+trait `ToString` imported, and I call `to_string()` on a value of type `T`,
+then we will go off to find out whether there is an impl of `ToString`
 for `T`.  These kinds of method calls are called "extension methods".
 They can be defined in any module, not only the one that defined `T`.
 Furthermore, you must import the trait to call such a method.
@@ -264,18 +264,18 @@ fn construct_transformed_self_ty_for_object(
     // The subst we get in has Err as the "Self" type. For an object
     // type, we don't put any type into the Self paramspace, so let's
     // make a copy of rcvr_substs that has the Self paramspace empty.
-    obj_substs.types.get_mut_vec(subst::SelfSpace).pop().unwrap();
+    obj_substs.types.pop(subst::SelfSpace).unwrap();
 
     match method_ty.explicit_self {
         ast::SelfStatic => {
             tcx.sess.span_bug(span, "static method for object type receiver");
         }
-        ast::SelfValue => {
+        ast::SelfValue(_) => {
             let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
                                   ty::empty_builtin_bounds());
             ty::mk_uniq(tcx, tr)
         }
-        ast::SelfRegion(..) | ast::SelfUniq => {
+        ast::SelfRegion(..) | ast::SelfUniq(..) => {
             let transformed_self_ty = *method_ty.fty.sig.inputs.get(0);
             match ty::get(transformed_self_ty).sty {
                 ty::ty_rptr(r, mt) => { // must be SelfRegion
@@ -376,7 +376,7 @@ fn search_step(&self,
                    autoderefs: uint)
                    -> Option<Option<MethodCallee>> {
         debug!("search_step: self_ty={} autoderefs={}",
-               self.ty_to_str(self_ty), autoderefs);
+               self.ty_to_string(self_ty), autoderefs);
 
         match self.deref_args {
             check::DontDerefArgs => {
@@ -508,7 +508,7 @@ fn push_inherent_candidates_from_object(&mut self,
                                             did: DefId,
                                             substs: &subst::Substs) {
         debug!("push_inherent_candidates_from_object(did={}, substs={})",
-               self.did_to_str(did),
+               self.did_to_string(did),
                substs.repr(self.tcx()));
         let _indenter = indenter();
         let tcx = self.tcx();
@@ -733,7 +733,7 @@ fn search_for_autoderefd_method(&self,
             None => None,
             Some(method) => {
                 debug!("(searching for autoderef'd method) writing \
-                       adjustment {:?} for {}", adjustment, self.ty_to_str( self_ty));
+                       adjustment {:?} for {}", adjustment, self.ty_to_string( self_ty));
                 match adjustment {
                     Some((self_expr_id, adj)) => {
                         self.fcx.write_adjustment(self_expr_id, adj);
@@ -809,7 +809,7 @@ fn default_method_hack(self_mt: ty::mt) -> bool {
 
     fn auto_slice_vec(&self, mt: ty::mt, autoderefs: uint) -> Option<MethodCallee> {
         let tcx = self.tcx();
-        debug!("auto_slice_vec {}", ppaux::ty_to_str(tcx, mt.ty));
+        debug!("auto_slice_vec {}", ppaux::ty_to_string(tcx, mt.ty));
 
         // First try to borrow to a slice
         let entry = self.search_for_some_kind_of_autorefd_method(
@@ -886,7 +886,7 @@ fn search_for_autosliced_method(&self,
          * `~[]` to `&[]`.
          */
 
-        debug!("search_for_autosliced_method {}", ppaux::ty_to_str(self.tcx(), self_ty));
+        debug!("search_for_autosliced_method {}", ppaux::ty_to_string(self.tcx(), self_ty));
 
         let sty = ty::get(self_ty).sty.clone();
         match sty {
@@ -939,7 +939,7 @@ fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
 
             ty_infer(TyVar(_)) => {
                 self.bug(format!("unexpected type: {}",
-                                 self.ty_to_str(self_ty)).as_slice());
+                                 self.ty_to_string(self_ty)).as_slice());
             }
         }
     }
@@ -993,7 +993,7 @@ fn search_for_some_kind_of_autorefd_method(
     }
 
     fn search_for_method(&self, rcvr_ty: ty::t) -> Option<MethodCallee> {
-        debug!("search_for_method(rcvr_ty={})", self.ty_to_str(rcvr_ty));
+        debug!("search_for_method(rcvr_ty={})", self.ty_to_string(rcvr_ty));
         let _indenter = indenter();
 
         // I am not sure that inherent methods should have higher
@@ -1094,7 +1094,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         let tcx = self.tcx();
 
         debug!("confirm_candidate(rcvr_ty={}, candidate={})",
-               self.ty_to_str(rcvr_ty),
+               self.ty_to_string(rcvr_ty),
                candidate.repr(self.tcx()));
 
         self.enforce_object_limitations(candidate);
@@ -1133,7 +1133,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         let m_regions =
             self.fcx.infcx().region_vars_for_defs(
                 self.span,
-                candidate.method_ty.generics.regions.get_vec(subst::FnSpace));
+                candidate.method_ty.generics.regions.get_slice(subst::FnSpace));
 
         let all_substs = candidate.rcvr_substs.clone().with_method(m_types, m_regions);
 
@@ -1177,7 +1177,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
             fn_style: bare_fn_ty.fn_style,
             abi: bare_fn_ty.abi.clone(),
         });
-        debug!("after replacing bound regions, fty={}", self.ty_to_str(fty));
+        debug!("after replacing bound regions, fty={}", self.ty_to_string(fty));
 
         // Before, we only checked whether self_ty could be a subtype
         // of rcvr_ty; now we actually make it so (this may cause
@@ -1191,8 +1191,8 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
             Err(_) => {
                 self.bug(format!(
                         "{} was a subtype of {} but now is not?",
-                        self.ty_to_str(rcvr_ty),
-                        self.ty_to_str(transformed_self_ty)).as_slice());
+                        self.ty_to_string(rcvr_ty),
+                        self.ty_to_string(transformed_self_ty)).as_slice());
             }
         }
 
@@ -1227,7 +1227,7 @@ fn enforce_object_limitations(&self, candidate: &Candidate) {
                      through an object");
             }
 
-            ast::SelfValue | ast::SelfRegion(..) | ast::SelfUniq => {}
+            ast::SelfValue(_) | ast::SelfRegion(..) | ast::SelfUniq(_) => {}
         }
 
         // reason (a) above
@@ -1288,7 +1288,7 @@ fn enforce_drop_trait_limitations(&self, candidate: &Candidate) {
     // candidate method's `self_ty`.
     fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
         debug!("is_relevant(rcvr_ty={}, candidate={})",
-               self.ty_to_str(rcvr_ty), candidate.repr(self.tcx()));
+               self.ty_to_string(rcvr_ty), candidate.repr(self.tcx()));
 
         return match candidate.method_ty.explicit_self {
             SelfStatic => {
@@ -1296,7 +1296,7 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 self.report_statics == ReportStaticMethods
             }
 
-            SelfValue => {
+            SelfValue(_) => {
                 debug!("(is relevant?) explicit self is by-value");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_uniq(typ) => {
@@ -1319,7 +1319,7 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 }
             }
 
-            SelfRegion(_, m) => {
+            SelfRegion(_, m, _) => {
                 debug!("(is relevant?) explicit self is a region");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_rptr(_, mt) => {
@@ -1339,7 +1339,7 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 }
             }
 
-            SelfUniq => {
+            SelfUniq(_) => {
                 debug!("(is relevant?) explicit self is a unique pointer");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_uniq(typ) => {
@@ -1457,11 +1457,11 @@ fn tcx(&self) -> &'a ty::ctxt {
         self.fcx.tcx()
     }
 
-    fn ty_to_str(&self, t: ty::t) -> String {
-        self.fcx.infcx().ty_to_str(t)
+    fn ty_to_string(&self, t: ty::t) -> String {
+        self.fcx.infcx().ty_to_string(t)
     }
 
-    fn did_to_str(&self, did: DefId) -> String {
+    fn did_to_string(&self, did: DefId) -> String {
         ty::item_path_str(self.tcx(), did)
     }
 
index b68991aed70963c53c341788689c4f11e1652a7a..fb29baeea73f2c592d5ad99303d1e3865863b82d 100644 (file)
@@ -397,8 +397,8 @@ fn visit_local(&mut self, local: &ast::Local, _: ()) {
         };
         self.assign(local.id, o_ty);
         debug!("Local variable {} is assigned type {}",
-               self.fcx.pat_to_str(&*local.pat),
-               self.fcx.infcx().ty_to_str(
+               self.fcx.pat_to_string(&*local.pat),
+               self.fcx.infcx().ty_to_string(
                    self.fcx.inh.locals.borrow().get_copy(&local.id)));
         visit::walk_local(self, local, ());
     }
@@ -411,7 +411,7 @@ fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
                 self.assign(p.id, None);
                 debug!("Pattern binding {} is assigned to {}",
                        token::get_ident(path1.node),
-                       self.fcx.infcx().ty_to_str(
+                       self.fcx.infcx().ty_to_string(
                            self.fcx.inh.locals.borrow().get_copy(&p.id)));
               }
               _ => {}
@@ -534,7 +534,7 @@ fn span_for_field(tcx: &ty::ctxt, field: &ty::field_ty, struct_id: ast::DefId) -
     let item = match tcx.map.find(struct_id.node) {
         Some(ast_map::NodeItem(item)) => item,
         None => fail!("node not in ast map: {}", struct_id.node),
-        _ => fail!("expected item, found {}", tcx.map.node_to_str(struct_id.node))
+        _ => fail!("expected item, found {}", tcx.map.node_to_string(struct_id.node))
     };
 
     match item.node {
@@ -757,14 +757,16 @@ fn check_method_body(ccx: &CrateCtxt,
     let method_def_id = local_def(method.id);
     let method_ty = ty::method(ccx.tcx, method_def_id);
     let method_generics = &method_ty.generics;
+    let m_body = ast_util::method_body(&*method);
 
     let param_env = ty::construct_parameter_environment(ccx.tcx,
                                                         method_generics,
-                                                        method.body.id);
+                                                        m_body.id);
 
     let fty = ty::node_id_to_type(ccx.tcx, method.id);
 
-    check_bare_fn(ccx, &*method.decl, &*method.body, method.id, fty, param_env);
+    check_bare_fn(ccx, ast_util::method_fn_decl(&*method),
+                  m_body, method.id, fty, param_env);
 }
 
 fn check_impl_methods_against_trait(ccx: &CrateCtxt,
@@ -792,7 +794,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
                 compare_impl_method(ccx.tcx,
                                     &*impl_method_ty,
                                     impl_method.span,
-                                    impl_method.body.id,
+                                    ast_util::method_body(&**impl_method).id,
                                     &**trait_method_ty,
                                     &impl_trait_ref.substs);
             }
@@ -803,7 +805,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
                     format!(
                         "method `{}` is not a member of trait `{}`",
                         token::get_ident(impl_method_ty.ident),
-                        pprust::path_to_str(&ast_trait_ref.path)).as_slice());
+                        pprust::path_to_string(&ast_trait_ref.path)).as_slice());
             }
         }
     }
@@ -815,7 +817,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
     for trait_method in trait_methods.iter() {
         let is_implemented =
             impl_methods.iter().any(
-                |m| m.ident.name == trait_method.ident.name);
+                |m| ast_util::method_ident(&**m).name == trait_method.ident.name);
         let is_provided =
             provided_methods.iter().any(
                 |m| m.ident.name == trait_method.ident.name);
@@ -870,7 +872,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                 format!("method `{}` has a `{}` declaration in the impl, \
                         but not in the trait",
                         token::get_ident(trait_m.ident),
-                        pprust::explicit_self_to_str(
+                        pprust::explicit_self_to_string(
                             impl_m.explicit_self)).as_slice());
             return;
         }
@@ -880,7 +882,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                 format!("method `{}` has a `{}` declaration in the trait, \
                         but not in the impl",
                         token::get_ident(trait_m.ident),
-                        pprust::explicit_self_to_str(
+                        pprust::explicit_self_to_string(
                             trait_m.explicit_self)).as_slice());
             return;
         }
@@ -917,8 +919,8 @@ fn compare_impl_method(tcx: &ty::ctxt,
         return;
     }
 
-    let it = trait_m.generics.types.get_vec(subst::FnSpace).iter()
-        .zip(impl_m.generics.types.get_vec(subst::FnSpace).iter());
+    let it = trait_m.generics.types.get_slice(subst::FnSpace).iter()
+        .zip(impl_m.generics.types.get_slice(subst::FnSpace).iter());
 
     // This code is best explained by example. Consider a trait:
     //
@@ -989,8 +991,8 @@ fn compare_impl_method(tcx: &ty::ctxt,
     let trait_to_skol_substs =
         trait_to_impl_substs
         .subst(tcx, &impl_to_skol_substs)
-        .with_method(skol_tps.get_vec(subst::FnSpace).clone(),
-                     skol_regions.get_vec(subst::FnSpace).clone());
+        .with_method(Vec::from_slice(skol_tps.get_slice(subst::FnSpace)),
+                     Vec::from_slice(skol_regions.get_slice(subst::FnSpace)));
     let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone());
     let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs);
 
@@ -1051,7 +1053,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                                            declaration",
                                           token::get_ident(trait_m.ident),
                                           i,
-                                          ppaux::trait_ref_to_str(
+                                          ppaux::trait_ref_to_string(
                                               tcx,
                                               &*impl_trait_bound)).as_slice())
             }
@@ -1101,8 +1103,8 @@ fn check_cast(fcx: &FnCtxt,
 
     let t_e = fcx.expr_ty(e);
 
-    debug!("t_1={}", fcx.infcx().ty_to_str(t_1));
-    debug!("t_e={}", fcx.infcx().ty_to_str(t_e));
+    debug!("t_1={}", fcx.infcx().ty_to_string(t_1));
+    debug!("t_e={}", fcx.infcx().ty_to_string(t_e));
 
     if ty::type_is_error(t_e) {
         fcx.write_error(id);
@@ -1126,13 +1128,13 @@ fn check_cast(fcx: &FnCtxt,
         fcx.type_error_message(span, |actual| {
             format!("cast from nil: `{}` as `{}`",
                     actual,
-                    fcx.infcx().ty_to_str(t_1))
+                    fcx.infcx().ty_to_string(t_1))
         }, t_e, None);
     } else if ty::type_is_nil(t_1) {
         fcx.type_error_message(span, |actual| {
             format!("cast to nil: `{}` as `{}`",
                     actual,
-                    fcx.infcx().ty_to_str(t_1))
+                    fcx.infcx().ty_to_string(t_1))
         }, t_e, None);
     }
 
@@ -1149,7 +1151,7 @@ fn check_cast(fcx: &FnCtxt,
                 format!("illegal cast; cast through an \
                          integer first: `{}` as `{}`",
                         actual,
-                        fcx.infcx().ty_to_str(t_1))
+                        fcx.infcx().ty_to_string(t_1))
             }, t_e, None);
         }
         // casts from C-like enums are allowed
@@ -1217,7 +1219,14 @@ fn types_compatible(fcx: &FnCtxt, sp: Span,
         fcx.type_error_message(span, |actual| {
             format!("non-scalar cast: `{}` as `{}`",
                     actual,
-                    fcx.infcx().ty_to_str(t_1))
+                    fcx.infcx().ty_to_string(t_1))
+        }, t_e, None);
+    } else if ty::type_is_unsafe_ptr(t_e) && t_1_is_float {
+        fcx.type_error_message(span, |actual| {
+            format!("cannot cast from pointer to float directly: `{}` as `{}`; cast through an \
+                     integer first",
+                    actual,
+                    fcx.infcx().ty_to_string(t_1))
         }, t_e, None);
     }
 
@@ -1286,7 +1295,7 @@ pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> ty::t {
     #[inline]
     pub fn write_ty(&self, node_id: ast::NodeId, ty: ty::t) {
         debug!("write_ty({}, {}) in fcx {}",
-               node_id, ppaux::ty_to_str(self.tcx(), ty), self.tag());
+               node_id, ppaux::ty_to_string(self.tcx(), ty), self.tag());
         self.inh.node_types.borrow_mut().insert(node_id, ty);
     }
 
@@ -1343,7 +1352,7 @@ pub fn to_ty(&self, ast_t: &ast::Ty) -> ty::t {
         ast_ty_to_ty(self, self.infcx(), ast_t)
     }
 
-    pub fn pat_to_str(&self, pat: &ast::Pat) -> String {
+    pub fn pat_to_string(&self, pat: &ast::Pat) -> String {
         pat.repr(self.tcx())
     }
 
@@ -1363,7 +1372,7 @@ pub fn node_ty(&self, id: ast::NodeId) -> ty::t {
             None => {
                 self.tcx().sess.bug(
                     format!("no type for node {}: {} in fcx {}",
-                            id, self.tcx().map.node_to_str(id),
+                            id, self.tcx().map.node_to_string(id),
                             self.tag()).as_slice());
             }
         }
@@ -1375,7 +1384,7 @@ pub fn method_ty_substs(&self, id: ast::NodeId) -> subst::Substs {
             None => {
                 self.tcx().sess.bug(
                     format!("no method entry for node {}: {} in fcx {}",
-                            id, self.tcx().map.node_to_str(id),
+                            id, self.tcx().map.node_to_string(id),
                             self.tag()).as_slice());
             }
         }
@@ -1629,6 +1638,76 @@ fn try_overloaded_deref(fcx: &FnCtxt,
     }
 }
 
+fn try_overloaded_index(fcx: &FnCtxt,
+                        method_call: Option<MethodCall>,
+                        expr: &ast::Expr,
+                        base_expr: Gc<ast::Expr>,
+                        base_ty: ty::t,
+                        index_expr: Gc<ast::Expr>,
+                        lvalue_pref: LvaluePreference)
+                        -> Option<ty::mt> {
+    // Try `IndexMut` first, if preferred.
+    let method = match (lvalue_pref, fcx.tcx().lang_items.index_mut_trait()) {
+        (PreferMutLvalue, Some(trait_did)) => {
+            method::lookup_in_trait(fcx,
+                                    expr.span,
+                                    Some(&*base_expr),
+                                    token::intern("index_mut"),
+                                    trait_did,
+                                    base_ty,
+                                    [],
+                                    DontAutoderefReceiver,
+                                    IgnoreStaticMethods)
+        }
+        _ => None,
+    };
+
+    // Otherwise, fall back to `Index`.
+    let method = match (method, fcx.tcx().lang_items.index_trait()) {
+        (None, Some(trait_did)) => {
+            method::lookup_in_trait(fcx,
+                                    expr.span,
+                                    Some(&*base_expr),
+                                    token::intern("index"),
+                                    trait_did,
+                                    base_ty,
+                                    [],
+                                    DontAutoderefReceiver,
+                                    IgnoreStaticMethods)
+        }
+        (method, _) => method,
+    };
+
+    // Regardless of whether the lookup succeeds, check the method arguments
+    // so that we have *some* type for each argument.
+    let method_type = match method {
+        Some(ref method) => method.ty,
+        None => ty::mk_err()
+    };
+    check_method_argument_types(fcx,
+                                expr.span,
+                                method_type,
+                                expr,
+                                [base_expr, index_expr],
+                                DoDerefArgs,
+                                DontTupleArguments);
+
+    match method {
+        Some(method) => {
+            let ref_ty = ty::ty_fn_ret(method.ty);
+            match method_call {
+                Some(method_call) => {
+                    fcx.inh.method_map.borrow_mut().insert(method_call,
+                                                           method);
+                }
+                None => {}
+            }
+            ty::deref(ref_ty, true)
+        }
+        None => None,
+    }
+}
+
 fn check_method_argument_types(fcx: &FnCtxt,
                                sp: Span,
                                method_fn_ty: ty::t,
@@ -1772,7 +1851,7 @@ fn check_argument_types(fcx: &FnCtxt,
     };
 
     debug!("check_argument_types: formal_tys={:?}",
-           formal_tys.iter().map(|t| fcx.infcx().ty_to_str(*t)).collect::<Vec<String>>());
+           formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
 
     // Check the arguments.
     // We do this in a pretty awful way: first we typecheck any arguments
@@ -2002,7 +2081,7 @@ pub fn impl_self_ty(vcx: &VtableContext,
     let ity = ty::lookup_item_type(tcx, did);
     let (n_tps, rps, raw_ty) =
         (ity.generics.types.len(subst::TypeSpace),
-         ity.generics.regions.get_vec(subst::TypeSpace),
+         ity.generics.regions.get_slice(subst::TypeSpace),
          ity.ty);
 
     let rps = vcx.infcx.region_vars_for_defs(span, rps);
@@ -2340,7 +2419,7 @@ fn check_binop(fcx: &FnCtxt,
                                              operation `{}` not \
                                              supported for floating \
                                              point SIMD vector `{}`",
-                                            ast_util::binop_to_str(op),
+                                            ast_util::binop_to_string(op),
                                             actual)
                                 },
                                 lhs_t,
@@ -2370,7 +2449,7 @@ fn check_binop(fcx: &FnCtxt,
                                    |actual| {
                     format!("binary operation `{}` cannot be applied \
                              to type `{}`",
-                            ast_util::binop_to_str(op),
+                            ast_util::binop_to_string(op),
                             actual)
                 },
                 lhs_t,
@@ -2387,7 +2466,7 @@ fn check_binop(fcx: &FnCtxt,
                                                  operation `{}=` \
                                                  cannot be applied to \
                                                  type `{}`",
-                                                ast_util::binop_to_str(op),
+                                                ast_util::binop_to_string(op),
                                                 actual)
                                    },
                                    lhs_t,
@@ -2436,7 +2515,7 @@ fn check_user_binop(fcx: &FnCtxt,
                          trait_did, [lhs_expr, rhs], DontAutoderefReceiver, || {
             fcx.type_error_message(ex.span, |actual| {
                 format!("binary operation `{}` cannot be applied to type `{}`",
-                        ast_util::binop_to_str(op),
+                        ast_util::binop_to_string(op),
                         actual)
             }, lhs_resolved_t, None)
         })
@@ -2524,7 +2603,7 @@ fn check_expr_fn(fcx: &FnCtxt,
                                            expected_sig);
         let fty_sig = fn_ty.sig.clone();
         let fty = ty::mk_closure(tcx, fn_ty);
-        debug!("check_expr_fn fty={}", fcx.infcx().ty_to_str(fty));
+        debug!("check_expr_fn fty={}", fcx.infcx().ty_to_string(fty));
 
         fcx.write_ty(expr.id, fty);
 
@@ -2558,7 +2637,7 @@ fn check_field(fcx: &FnCtxt,
             autoderef(fcx, expr.span, expr_t, Some(base.id), lvalue_pref, |base_t, _| {
                 match ty::get(base_t).sty {
                     ty::ty_struct(base_id, ref substs) => {
-                        debug!("struct named {}", ppaux::ty_to_str(tcx, base_t));
+                        debug!("struct named {}", ppaux::ty_to_string(tcx, base_t));
                         let fields = ty::lookup_struct_fields(tcx, base_id);
                         lookup_field_ty(tcx, base_id, fields.as_slice(),
                                         field.node.name, &(*substs))
@@ -3296,17 +3375,34 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
         // Resolve the path.
         let def = tcx.def_map.borrow().find(&id).map(|i| *i);
         match def {
-            Some(def::DefStruct(type_def_id)) => {
-                check_struct_constructor(fcx, id, expr.span, type_def_id,
-                                         fields.as_slice(), base_expr);
-            }
             Some(def::DefVariant(enum_id, variant_id, _)) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
                                           variant_id, fields.as_slice());
             }
+            Some(def) => {
+                // Verify that this was actually a struct.
+                let typ = ty::lookup_item_type(fcx.ccx.tcx, def.def_id());
+                match ty::get(typ.ty).sty {
+                    ty::ty_struct(struct_did, _) => {
+                        check_struct_constructor(fcx,
+                                                 id,
+                                                 expr.span,
+                                                 struct_did,
+                                                 fields.as_slice(),
+                                                 base_expr);
+                    }
+                    _ => {
+                        tcx.sess
+                           .span_err(path.span,
+                                     format!("`{}` does not name a structure",
+                                             pprust::path_to_string(
+                                                 path)).as_slice())
+                    }
+                }
+            }
             _ => {
                 tcx.sess.span_bug(path.span,
-                                  "structure constructor does not name a structure type");
+                                  "structure constructor wasn't resolved")
             }
         }
       }
@@ -3323,7 +3419,7 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
           } else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) {
               fcx.write_ty(id, idx_t);
           } else {
-              let (base_t, autoderefs, field_ty) =
+              let (_, autoderefs, field_ty) =
                 autoderef(fcx, expr.span, raw_base_t, Some(base.id),
                           lvalue_pref, |base_t, _| ty::index(base_t));
               match field_ty {
@@ -3333,27 +3429,33 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
                       fcx.write_autoderef_adjustment(base.id, autoderefs);
                   }
                   None => {
-                      let resolved = structurally_resolved_type(fcx,
-                                                                expr.span,
-                                                                raw_base_t);
-                      let ret_ty = lookup_op_method(fcx,
-                                                    expr,
-                                                    resolved,
-                                                    token::intern("index"),
-                                                    tcx.lang_items.index_trait(),
-                                                    [base.clone(), idx.clone()],
-                                                    AutoderefReceiver,
-                                                    || {
-                        fcx.type_error_message(expr.span,
-                                               |actual| {
-                                                    format!("cannot index a \
-                                                             value of type \
-                                                             `{}`", actual)
-                                               },
-                                               base_t,
-                                               None);
-                      });
-                      fcx.write_ty(id, ret_ty);
+                      // This is an overloaded method.
+                      let base_t = structurally_resolved_type(fcx,
+                                                              expr.span,
+                                                              raw_base_t);
+                      let method_call = MethodCall::expr(expr.id);
+                      match try_overloaded_index(fcx,
+                                                 Some(method_call),
+                                                 expr,
+                                                 *base,
+                                                 base_t,
+                                                 *idx,
+                                                 lvalue_pref) {
+                          Some(mt) => fcx.write_ty(id, mt.ty),
+                          None => {
+                                fcx.type_error_message(expr.span,
+                                                       |actual| {
+                                                        format!("cannot \
+                                                                 index a \
+                                                                 value of \
+                                                                 type `{}`",
+                                                                actual)
+                                                       },
+                                                       base_t,
+                                                       None);
+                                fcx.write_ty(id, ty::mk_err())
+                          }
+                      }
                   }
               }
           }
@@ -3361,10 +3463,10 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
     }
 
     debug!("type of expr({}) {} is...", expr.id,
-           syntax::print::pprust::expr_to_str(expr));
+           syntax::print::pprust::expr_to_string(expr));
     debug!("... {}, expected is {}",
-           ppaux::ty_to_str(tcx, fcx.expr_ty(expr)),
-           expected.repr(tcx))
+           ppaux::ty_to_string(tcx, fcx.expr_ty(expr)),
+           expected.repr(tcx));
 
     unifier();
 }
@@ -3699,7 +3801,7 @@ pub fn check_instantiable(tcx: &ty::ctxt,
                      format!("this type cannot be instantiated without an \
                               instance of itself; consider using \
                               `Option<{}>`",
-                             ppaux::ty_to_str(tcx, item_ty)).as_slice());
+                             ppaux::ty_to_string(tcx, item_ty)).as_slice());
         false
     } else {
         true
@@ -3760,7 +3862,7 @@ pub fn check_enum_variants_sized(ccx: &CrateCtxt,
                                         dynamically sized types may only \
                                         appear as the final type in a \
                                         variant",
-                                       ppaux::ty_to_str(ccx.tcx,
+                                       ppaux::ty_to_string(ccx.tcx,
                                                         *t)).as_slice());
                     }
                 }
@@ -3825,7 +3927,7 @@ fn do_check(ccx: &CrateCtxt,
 
             match v.node.disr_expr {
                 Some(e) => {
-                    debug!("disr expr, checking {}", pprust::expr_to_str(&*e));
+                    debug!("disr expr, checking {}", pprust::expr_to_string(&*e));
 
                     let inh = blank_inherited_fields(ccx);
                     let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id);
@@ -4126,12 +4228,10 @@ pub fn instantiate_path(fcx: &FnCtxt,
     // a problem.
     for &space in ParamSpace::all().iter() {
         adjust_type_parameters(fcx, span, space, type_defs, &mut substs);
-        assert_eq!(substs.types.get_vec(space).len(),
-                   type_defs.get_vec(space).len());
+        assert_eq!(substs.types.len(space), type_defs.len(space));
 
         adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
-        assert_eq!(substs.regions().get_vec(space).len(),
-                   region_defs.get_vec(space).len());
+        assert_eq!(substs.regions().len(space), region_defs.len(space));
     }
 
     fcx.write_ty_substs(node_id, polytype.ty, ty::ItemSubsts {
@@ -4183,8 +4283,8 @@ fn push_explicit_parameters_from_segment_to_substs(
          */
 
         {
-            let type_count = type_defs.get_vec(space).len();
-            assert_eq!(substs.types.get_vec(space).len(), 0);
+            let type_count = type_defs.len(space);
+            assert_eq!(substs.types.len(space), 0);
             for (i, &typ) in segment.types.iter().enumerate() {
                 let t = fcx.to_ty(&*typ);
                 if i < type_count {
@@ -4198,14 +4298,14 @@ fn push_explicit_parameters_from_segment_to_substs(
                              but found {} parameter(s)",
                             type_count,
                             segment.types.len()).as_slice());
-                    substs.types.get_mut_vec(space).truncate(0);
+                    substs.types.truncate(space, 0);
                 }
             }
         }
 
         {
-            let region_count = region_defs.get_vec(space).len();
-            assert_eq!(substs.regions().get_vec(space).len(), 0);
+            let region_count = region_defs.len(space);
+            assert_eq!(substs.regions().len(space), 0);
             for (i, lifetime) in segment.lifetimes.iter().enumerate() {
                 let r = ast_region_to_region(fcx.tcx(), lifetime);
                 if i < region_count {
@@ -4218,7 +4318,7 @@ fn push_explicit_parameters_from_segment_to_substs(
                              expected {} parameter(s) but found {} parameter(s)",
                             region_count,
                             segment.lifetimes.len()).as_slice());
-                    substs.mut_regions().get_mut_vec(space).truncate(0);
+                    substs.mut_regions().truncate(space, 0);
                 }
             }
         }
@@ -4231,8 +4331,8 @@ fn adjust_type_parameters(
         defs: &VecPerParamSpace<ty::TypeParameterDef>,
         substs: &mut Substs)
     {
-        let provided_len = substs.types.get_vec(space).len();
-        let desired = defs.get_vec(space).as_slice();
+        let provided_len = substs.types.len(space);
+        let desired = defs.get_slice(space);
         let required_len = desired.iter()
                               .take_while(|d| d.default.is_none())
                               .count();
@@ -4252,8 +4352,8 @@ fn adjust_type_parameters(
         // Nothing specified at all: supply inference variables for
         // everything.
         if provided_len == 0 {
-            let provided = substs.types.get_mut_vec(space);
-            *provided = fcx.infcx().next_ty_vars(desired.len());
+            substs.types.replace(space,
+                                 fcx.infcx().next_ty_vars(desired.len()));
             return;
         }
 
@@ -4270,8 +4370,8 @@ fn adjust_type_parameters(
                             qualifier,
                             required_len,
                             provided_len).as_slice());
-            let provided = substs.types.get_mut_vec(space);
-            *provided = Vec::from_elem(desired.len(), ty::mk_err());
+            substs.types.replace(space,
+                                 Vec::from_elem(desired.len(), ty::mk_err()));
             return;
         }
 
@@ -4287,7 +4387,7 @@ fn adjust_type_parameters(
             let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
             substs.types.push(space, default);
         }
-        assert_eq!(substs.types.get_vec(space).len(), desired.len());
+        assert_eq!(substs.types.len(space), desired.len());
 
         debug!("Final substs: {}", substs.repr(fcx.tcx()));
     }
@@ -4299,20 +4399,22 @@ fn adjust_region_parameters(
         defs: &VecPerParamSpace<ty::RegionParameterDef>,
         substs: &mut Substs)
     {
-        let provided = substs.mut_regions().get_mut_vec(space);
-        let desired = defs.get_vec(space);
+        let provided_len = substs.mut_regions().len(space);
+        let desired = defs.get_slice(space);
 
         // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
-        assert!(provided.len() <= desired.len());
+        assert!(provided_len <= desired.len());
 
         // If nothing was provided, just use inference variables.
-        if provided.len() == 0 {
-            *provided = fcx.infcx().region_vars_for_defs(span, desired);
+        if provided_len == 0 {
+            substs.mut_regions().replace(
+                space,
+                fcx.infcx().region_vars_for_defs(span, desired));
             return;
         }
 
         // If just the right number were provided, everybody is happy.
-        if provided.len() == desired.len() {
+        if provided_len == desired.len() {
             return;
         }
 
@@ -4325,9 +4427,11 @@ fn adjust_region_parameters(
                          expected {} parameter(s) \
                          but found {} parameter(s)",
                 desired.len(),
-                provided.len()).as_slice());
+                provided_len).as_slice());
 
-        *provided = fcx.infcx().region_vars_for_defs(span, desired);
+        substs.mut_regions().replace(
+            space,
+            fcx.infcx().region_vars_for_defs(span, desired));
     }
 }
 
@@ -4427,7 +4531,7 @@ pub fn check_bounds_are_used(ccx: &CrateCtxt,
                              tps: &OwnedSlice<ast::TyParam>,
                              ty: ty::t) {
     debug!("check_bounds_are_used(n_tps={}, ty={})",
-           tps.len(), ppaux::ty_to_str(ccx.tcx, ty));
+           tps.len(), ppaux::ty_to_string(ccx.tcx, ty));
 
     // make a vector of booleans initially false, set to true when used
     if tps.len() == 0u { return; }
@@ -4745,7 +4849,7 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
                            fty,
                            || {
                 format!("intrinsic has wrong type: expected `{}`",
-                        ppaux::ty_to_str(ccx.tcx, fty))
+                        ppaux::ty_to_string(ccx.tcx, fty))
             });
     }
 }
index 07fb43d0d34dfdb824b55b89e123f6ee9b4769c3..924934e4bcdc5e34eac00cc6af2f3b450e597988 100644 (file)
@@ -133,7 +133,7 @@ fn get_i(x: &'a Bar) -> &'a int {
 use middle::typeck::MethodCall;
 use middle::pat_util;
 use util::nodemap::NodeMap;
-use util::ppaux::{ty_to_str, region_to_str, Repr};
+use util::ppaux::{ty_to_string, region_to_string, Repr};
 
 use syntax::ast;
 use syntax::codemap::Span;
@@ -876,7 +876,7 @@ fn constrain_autoderefs(rcx: &mut Rcx,
     let r_deref_expr = ty::ReScope(deref_expr.id);
     for i in range(0u, derefs) {
         debug!("constrain_autoderefs(deref_expr=?, derefd_ty={}, derefs={:?}/{:?}",
-               rcx.fcx.infcx().ty_to_str(derefd_ty),
+               rcx.fcx.infcx().ty_to_string(derefd_ty),
                i, derefs);
 
         let method_call = MethodCall::autoderef(deref_expr.id, i);
@@ -948,7 +948,7 @@ fn constrain_index(rcx: &mut Rcx,
      */
 
     debug!("constrain_index(index_expr=?, indexed_ty={}",
-           rcx.fcx.infcx().ty_to_str(indexed_ty));
+           rcx.fcx.infcx().ty_to_string(indexed_ty));
 
     let r_index_expr = ty::ReScope(index_expr.id);
     match ty::get(indexed_ty).sty {
@@ -984,7 +984,7 @@ fn constrain_regions_in_type_of_node(
                            |method_call| rcx.resolve_method_type(method_call));
     debug!("constrain_regions_in_type_of_node(\
             ty={}, ty0={}, id={}, minimum_lifetime={:?})",
-           ty_to_str(tcx, ty), ty_to_str(tcx, ty0),
+           ty_to_string(tcx, ty), ty_to_string(tcx, ty0),
            id, minimum_lifetime);
     constrain_regions_in_type(rcx, minimum_lifetime, origin, ty);
 }
@@ -1011,8 +1011,8 @@ fn constrain_regions_in_type(
     let tcx = rcx.fcx.ccx.tcx;
 
     debug!("constrain_regions_in_type(minimum_lifetime={}, ty={})",
-           region_to_str(tcx, "", false, minimum_lifetime),
-           ty_to_str(tcx, ty));
+           region_to_string(tcx, "", false, minimum_lifetime),
+           ty_to_string(tcx, ty));
 
     relate_nested_regions(tcx, Some(minimum_lifetime), ty, |r_sub, r_sup| {
         debug!("relate_nested_regions(r_sub={}, r_sup={})",
@@ -1190,7 +1190,7 @@ fn link_region_from_node_type(rcx: &Rcx,
     let rptr_ty = rcx.resolve_node_type(id);
     if !ty::type_is_bot(rptr_ty) && !ty::type_is_error(rptr_ty) {
         let tcx = rcx.fcx.ccx.tcx;
-        debug!("rptr_ty={}", ty_to_str(tcx, rptr_ty));
+        debug!("rptr_ty={}", ty_to_string(tcx, rptr_ty));
         let r = ty::ty_region(tcx, span, rptr_ty);
         link_region(rcx, span, r, ty::BorrowKind::from_mutbl(mutbl),
                     cmt_borrowed);
index 146b42a00ffafe191df5e4aa002c8c694f9481ba..53e26f8696f61fe9e2f964bef5d03e41fccb2e25 100644 (file)
@@ -30,7 +30,7 @@ pub fn replace_late_bound_regions_in_fn_sig(
     let mut map = HashMap::new();
     let fn_sig = {
         let mut f = ty_fold::RegionFolder::regions(tcx, |r| {
-            debug!("region r={}", r.to_str());
+            debug!("region r={}", r.to_string());
             match r {
                 ty::ReLateBound(s, br) if s == fn_sig.binder_id => {
                     *map.find_or_insert_with(br, |_| mapf(br))
@@ -153,7 +153,7 @@ pub fn relate_free_regions(tcx: &ty::ctxt, fn_sig: &ty::FnSig) {
     }
 
     for &t in all_tys.iter() {
-        debug!("relate_free_regions(t={})", ppaux::ty_to_str(tcx, t));
+        debug!("relate_free_regions(t={})", ppaux::ty_to_string(tcx, t));
         relate_nested_regions(tcx, None, t, |a, b| {
             match (&a, &b) {
                 (&ty::ReFree(free_a), &ty::ReFree(free_b)) => {
index bda47d99ed7146d0ec7b12ab9dd292a8d19df9ae..d2a1ef786bd29f209ed1bba40cfa5dd3e5539cab 100644 (file)
@@ -16,7 +16,7 @@
 use middle::typeck::check::{FnCtxt, impl_self_ty};
 use middle::typeck::check::{structurally_resolved_type};
 use middle::typeck::check::writeback;
-use middle::typeck::infer::fixup_err_to_str;
+use middle::typeck::infer::fixup_err_to_string;
 use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type};
 use middle::typeck::infer;
 use middle::typeck::{vtable_origin, vtable_res, vtable_param_res};
@@ -35,7 +35,7 @@
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::Span;
-use syntax::print::pprust::expr_to_str;
+use syntax::print::pprust::expr_to_string;
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -154,8 +154,8 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
                 vcx.tcx().sess.span_fatal(span,
                     format!("failed to find an implementation of \
                           trait {} for {}",
-                         vcx.infcx.trait_ref_to_str(&*trait_ref),
-                         vcx.infcx.ty_to_str(ty)).as_slice());
+                         vcx.infcx.trait_ref_to_string(&*trait_ref),
+                         vcx.infcx.ty_to_string(ty)).as_slice());
             }
         }
         true
@@ -205,8 +205,8 @@ fn relate_trait_refs(vcx: &VtableContext,
                 let tcx = vcx.tcx();
                 tcx.sess.span_err(span,
                     format!("expected {}, but found {} ({})",
-                            ppaux::trait_ref_to_str(tcx, &r_exp_trait_ref),
-                            ppaux::trait_ref_to_str(tcx, &r_act_trait_ref),
+                            ppaux::trait_ref_to_string(tcx, &r_exp_trait_ref),
+                            ppaux::trait_ref_to_string(tcx, &r_act_trait_ref),
                             ty::type_err_to_str(tcx, err)).as_slice());
             }
         }
@@ -385,8 +385,8 @@ fn search_for_vtable(vcx: &VtableContext,
 
         debug!("(checking vtable) num 2 relating trait \
                 ty {} to of_trait_ref {}",
-               vcx.infcx.trait_ref_to_str(&*trait_ref),
-               vcx.infcx.trait_ref_to_str(&*of_trait_ref));
+               vcx.infcx.trait_ref_to_string(&*trait_ref),
+               vcx.infcx.trait_ref_to_string(&*of_trait_ref));
 
         relate_trait_refs(vcx, span, of_trait_ref, trait_ref.clone());
 
@@ -488,7 +488,7 @@ fn fixup_ty(vcx: &VtableContext,
             tcx.sess.span_fatal(span,
                 format!("cannot determine a type for this bounded type \
                          parameter: {}",
-                        fixup_err_to_str(e)).as_slice())
+                        fixup_err_to_string(e)).as_slice())
         }
         Err(_) => {
             None
@@ -527,7 +527,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
     }
 
     debug!("vtable: early_resolve_expr() ex with id {:?} (early: {}): {}",
-           ex.id, is_early, expr_to_str(ex));
+           ex.id, is_early, expr_to_string(ex));
     let _indent = indenter();
 
     let cx = fcx.ccx;
@@ -626,7 +626,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
                           ex.span,
                           format!("can only cast an boxed pointer \
                                    to a boxed object, not a {}",
-                               ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
+                               ty::ty_sort_string(fcx.tcx(), src_ty)).as_slice());
                   }
                   _ => {}
               }
@@ -639,7 +639,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
                           ex.span,
                           format!("can only cast an &-pointer \
                                    to an &-object, not a {}",
-                                  ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
+                                  ty::ty_sort_string(fcx.tcx(), src_ty)).as_slice());
                   }
                   _ => {}
               }
@@ -657,7 +657,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
             let did = def.def_id();
             let item_ty = ty::lookup_item_type(cx.tcx, did);
             debug!("early resolve expr: def {:?} {:?}, {:?}, {}", ex.id, did, def,
-                   fcx.infcx().ty_to_str(item_ty.ty));
+                   fcx.infcx().ty_to_string(item_ty.ty));
             debug!("early_resolve_expr: looking up vtables for type params {}",
                    item_ty.generics.types.repr(fcx.tcx()));
             let vcx = fcx.vtable_context();
index eb43144571e2abc9173e58c0aa05507250fd4f4e..59b65fdbec790231b0b999bf282a642c21834278 100644 (file)
@@ -31,7 +31,7 @@
 
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::print::pprust::pat_to_str;
+use syntax::print::pprust::pat_to_string;
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -159,7 +159,7 @@ fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
         self.visit_node_id(ResolvingPattern(p.span), p.id);
 
         debug!("Type for pattern binding {} (id {}) resolved to {}",
-               pat_to_str(p),
+               pat_to_string(p),
                p.id,
                ty::node_id_to_type(self.tcx(), p.id).repr(self.tcx()));
 
@@ -403,7 +403,7 @@ fn report_error(&self, e: infer::fixup_err) {
                         span,
                         format!("cannot determine a type for \
                                  this expression: {}",
-                                infer::fixup_err_to_str(e)).as_slice())
+                                infer::fixup_err_to_string(e)).as_slice())
                 }
 
                 ResolvingLocal(span) => {
@@ -411,7 +411,7 @@ fn report_error(&self, e: infer::fixup_err) {
                         span,
                         format!("cannot determine a type for \
                                  this local variable: {}",
-                                infer::fixup_err_to_str(e)).as_slice())
+                                infer::fixup_err_to_string(e)).as_slice())
                 }
 
                 ResolvingPattern(span) => {
@@ -419,7 +419,7 @@ fn report_error(&self, e: infer::fixup_err) {
                         span,
                         format!("cannot determine a type for \
                                  this pattern binding: {}",
-                                infer::fixup_err_to_str(e)).as_slice())
+                                infer::fixup_err_to_string(e)).as_slice())
                 }
 
                 ResolvingUpvar(upvar_id) => {
@@ -430,8 +430,8 @@ fn report_error(&self, e: infer::fixup_err) {
                                  captured variable `{}`: {}",
                                 ty::local_var_name_str(
                                     self.tcx,
-                                    upvar_id.var_id).get().to_str(),
-                                infer::fixup_err_to_str(e)).as_slice());
+                                    upvar_id.var_id).get().to_string(),
+                                infer::fixup_err_to_string(e)).as_slice());
                 }
 
                 ResolvingImplRes(span) => {
index 32e34d1320eb55b809b017c5fc3b5eeb06d653bc..b9bf8e37dead8c926faaa328412dd77a5e90edbc 100644 (file)
@@ -735,12 +735,12 @@ pub fn make_substs_for_receiver_types(tcx: &ty::ctxt,
      */
 
     let meth_tps: Vec<ty::t> =
-        method.generics.types.get_vec(subst::FnSpace)
+        method.generics.types.get_slice(subst::FnSpace)
               .iter()
               .map(|def| ty::mk_param_from_def(tcx, def))
               .collect();
     let meth_regions: Vec<ty::Region> =
-        method.generics.regions.get_vec(subst::FnSpace)
+        method.generics.regions.get_slice(subst::FnSpace)
               .iter()
               .map(|def| ty::ReEarlyBound(def.def_id.node, def.space,
                                           def.index, def.name))
@@ -767,10 +767,12 @@ fn subst_receiver_types_in_method_ty(tcx: &ty::ctxt,
     // replace the type parameters declared on the trait with those
     // from the impl
     for &space in [subst::TypeSpace, subst::SelfSpace].iter() {
-        *method_generics.types.get_mut_vec(space) =
-            impl_poly_type.generics.types.get_vec(space).clone();
-        *method_generics.regions.get_mut_vec(space) =
-            impl_poly_type.generics.regions.get_vec(space).clone();
+        method_generics.types.replace(
+            space,
+            Vec::from_slice(impl_poly_type.generics.types.get_slice(space)));
+        method_generics.regions.replace(
+            space,
+            Vec::from_slice(impl_poly_type.generics.regions.get_slice(space)));
     }
 
     debug!("subst_receiver_types_in_method_ty: method_generics={}",
index bf88ec5c438f28a62e3d52f61327a2b1dbb2b6af..9f08dc2c924839df6f62db371a154ca097300d08 100644 (file)
 use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound};
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{local_def, split_trait_methods};
+use syntax::ast_util;
+use syntax::ast_util::{local_def, method_ident, split_trait_methods};
 use syntax::codemap::Span;
 use syntax::codemap;
 use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
-use syntax::print::pprust::{path_to_str};
+use syntax::print::pprust::{path_to_string};
 use syntax::visit;
 
 struct CollectItemTypesVisitor<'a> {
@@ -213,8 +214,11 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
                             &ast::Provided(ref m) => {
                                 ty_method_of_trait_method(
                                     ccx, trait_id, &trait_def.generics,
-                                    &m.id, &m.ident, &m.explicit_self,
-                                    &m.generics, &m.fn_style, &*m.decl)
+                                    &m.id, &ast_util::method_ident(&**m),
+                                    ast_util::method_explicit_self(&**m),
+                                    ast_util::method_generics(&**m),
+                                    &ast_util::method_fn_style(&**m),
+                                    ast_util::method_fn_decl(&**m))
                             }
                         });
 
@@ -330,7 +334,7 @@ fn convert_methods(ccx: &CrateCtxt,
     let tcx = ccx.tcx;
     let mut seen_methods = HashSet::new();
     for m in ms.iter() {
-        if !seen_methods.insert(m.ident.repr(ccx.tcx)) {
+        if !seen_methods.insert(ast_util::method_ident(&**m).repr(tcx)) {
             tcx.sess.span_err(m.span, "duplicate method in trait impl");
         }
 
@@ -342,9 +346,9 @@ fn convert_methods(ccx: &CrateCtxt,
                                        rcvr_visibility));
         let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
         debug!("method {} (id {}) has type {}",
-                m.ident.repr(ccx.tcx),
+                method_ident(&**m).repr(tcx),
                 m.id,
-                fty.repr(ccx.tcx));
+                fty.repr(tcx));
         tcx.tcache.borrow_mut().insert(
             local_def(m.id),
             Polytype {
@@ -365,23 +369,24 @@ fn ty_of_method(ccx: &CrateCtxt,
                     rcvr_visibility: ast::Visibility)
                     -> ty::Method
     {
-        let fty = astconv::ty_of_method(ccx, m.id, m.fn_style,
+        let fty = astconv::ty_of_method(ccx, m.id, ast_util::method_fn_style(&*m),
                                         untransformed_rcvr_ty,
-                                        m.explicit_self, &*m.decl);
+                                        *ast_util::method_explicit_self(&*m),
+                                        ast_util::method_fn_decl(&*m));
 
         // if the method specifies a visibility, use that, otherwise
         // inherit the visibility from the impl (so `foo` in `pub impl
         // { fn foo(); }` is public, but private in `priv impl { fn
         // foo(); }`).
-        let method_vis = m.vis.inherit_from(rcvr_visibility);
+        let method_vis = ast_util::method_vis(&*m).inherit_from(rcvr_visibility);
 
         let m_ty_generics =
-            ty_generics_for_fn_or_method(ccx, &m.generics,
+            ty_generics_for_fn_or_method(ccx, ast_util::method_generics(&*m),
                                          (*rcvr_ty_generics).clone());
-        ty::Method::new(m.ident,
+        ty::Method::new(ast_util::method_ident(&*m),
                         m_ty_generics,
                         fty,
-                        m.explicit_self.node,
+                        ast_util::method_explicit_self(&*m).node,
                         method_vis,
                         local_def(m.id),
                         container,
@@ -665,7 +670,7 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt,
             ccx.tcx.sess.span_fatal(
                 ast_trait_ref.path.span,
                 format!("`{}` is not a trait",
-                        path_to_str(&ast_trait_ref.path)).as_slice());
+                        path_to_string(&ast_trait_ref.path)).as_slice());
         }
     }
 }
@@ -692,9 +697,9 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
         _ => {}
     }
 
-    let (generics, sized, supertraits) = match it.node {
-        ast::ItemTrait(ref generics, sized, ref supertraits, _) => {
-            (generics, sized, supertraits)
+    let (generics, unbound, supertraits) = match it.node {
+        ast::ItemTrait(ref generics, ref unbound, ref supertraits, _) => {
+            (generics, unbound, supertraits)
         }
         ref s => {
             tcx.sess.span_bug(
@@ -711,7 +716,7 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
                                             generics);
 
     let builtin_bounds =
-        ensure_supertraits(ccx, it.id, it.span, supertraits, sized);
+        ensure_supertraits(ccx, it.id, it.span, supertraits, unbound);
 
     let substs = mk_item_substs(ccx, &ty_generics);
     let trait_def = Rc::new(ty::TraitDef {
@@ -759,7 +764,7 @@ fn ensure_supertraits(ccx: &CrateCtxt,
                           id: ast::NodeId,
                           sp: codemap::Span,
                           ast_trait_refs: &Vec<ast::TraitRef>,
-                          sized: ast::Sized)
+                          unbound: &Option<ast::TyParamBound>)
                           -> ty::BuiltinBounds
     {
         let tcx = ccx.tcx;
@@ -798,15 +803,7 @@ fn ensure_supertraits(ccx: &CrateCtxt,
             }
         }
 
-        if sized == ast::StaticSize {
-            match tcx.lang_items.require(SizedTraitLangItem) {
-                Ok(def_id) => {
-                    ty::try_add_builtin_trait(tcx, def_id, &mut bounds);
-                }
-                Err(s) => tcx.sess.err(s.as_slice()),
-            };
-        }
-
+        add_unsized_bound(ccx, unbound, &mut bounds, "trait", sp);
         tcx.supertraits.borrow_mut().insert(local_def(id),
                                             Rc::new(ty_trait_refs));
         bounds
@@ -844,7 +841,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
             debug!("type of {} (id {}) is {}",
                     token::get_ident(it.ident),
                     it.id,
-                    ppaux::ty_to_str(tcx, pty.ty));
+                    ppaux::ty_to_string(tcx, pty.ty));
 
             ccx.tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
             return pty;
@@ -974,6 +971,43 @@ fn ty_generics_for_fn_or_method(ccx: &CrateCtxt,
                 &generics.ty_params, base_generics)
 }
 
+// Add the Sized bound, unless the type parameter is marked as `Sized?`.
+fn add_unsized_bound(ccx: &CrateCtxt,
+                     unbound: &Option<ast::TyParamBound>,
+                     bounds: &mut ty::BuiltinBounds,
+                     desc: &str,
+                     span: Span) {
+    let kind_id = ccx.tcx.lang_items.require(SizedTraitLangItem);
+    match unbound {
+        &Some(TraitTyParamBound(ref tpb)) => {
+            // #FIXME(8559) currently requires the unbound to be built-in.
+            let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, tpb);
+            match kind_id {
+                Ok(kind_id) if trait_def_id != kind_id => {
+                    ccx.tcx.sess.span_warn(span,
+                                           format!("default bound relaxed \
+                                                    for a {}, but this does \
+                                                    nothing because the given \
+                                                    bound is not a default. \
+                                                    Only `Sized?` is supported.",
+                                                   desc).as_slice());
+                    ty::try_add_builtin_trait(ccx.tcx,
+                                              kind_id,
+                                              bounds);
+                }
+                _ => {}
+            }
+        }
+        _ if kind_id.is_ok() => {
+            ty::try_add_builtin_trait(ccx.tcx,
+                                      kind_id.unwrap(),
+                                      bounds);
+        }
+        // No lang item for Sized, so we can't add it as a bound.
+        _ => {}
+    }
+}
+
 fn ty_generics(ccx: &CrateCtxt,
                space: subst::ParamSpace,
                lifetimes: &Vec<ast::Lifetime>,
@@ -1016,7 +1050,7 @@ fn get_or_create_type_parameter_def(ccx: &CrateCtxt,
         let bounds = Rc::new(compute_bounds(ccx,
                                             param_ty,
                                             &param.bounds,
-                                            param.sized,
+                                            &param.unbound,
                                             param.ident,
                                             param.span));
         let default = param.default.map(|path| {
@@ -1056,7 +1090,7 @@ fn compute_bounds(
         ccx: &CrateCtxt,
         param_ty: ty::ParamTy,
         ast_bounds: &OwnedSlice<ast::TyParamBound>,
-        sized: ast::Sized,
+        unbound: &Option<ast::TyParamBound>,
         ident: ast::Ident,
         span: Span) -> ty::ParamBounds
     {
@@ -1113,15 +1147,11 @@ fn compute_bounds(
             }
         }
 
-        if sized == ast::StaticSize {
-            match ccx.tcx.lang_items.require(SizedTraitLangItem) {
-                Ok(def_id) => { ty::try_add_builtin_trait(ccx.tcx,
-                                                          def_id,
-                                                          &mut param_bounds.builtin_bounds); },
-                // Fixme(13367) after `type` makes it into the snapshot, we can check this properly
-                Err(_s) => {}, //ccx.tcx.sess.err(s),
-            }
-        }
+        add_unsized_bound(ccx,
+                          unbound,
+                          &mut param_bounds.builtin_bounds,
+                          "type parameter",
+                          span);
 
         check_bounds_compatible(ccx.tcx, &param_bounds, ident, span);
 
@@ -1144,7 +1174,7 @@ fn check_bounds_compatible(tcx: &ty::ctxt,
                         format!("incompatible bounds on type parameter {}, \
                                  bound {} does not allow unsized type",
                         token::get_ident(ident),
-                        ppaux::trait_ref_to_str(tcx,
+                        ppaux::trait_ref_to_string(tcx,
                                                 &*trait_ref)).as_slice());
                 }
                 true
index 2984ea086efc59064d00919ddf70c15ccf5ffa64..1e33b1d5d0ebd5368044a1a6c51a5c273a95ed64 100644 (file)
@@ -115,32 +115,30 @@ fn substs(&self,
         let mut substs = subst::Substs::empty();
 
         for &space in subst::ParamSpace::all().iter() {
-            let a_tps = a_subst.types.get_vec(space);
-            let b_tps = b_subst.types.get_vec(space);
-            let tps = if_ok!(self.tps(space,
-                                      a_tps.as_slice(),
-                                      b_tps.as_slice()));
-
-            let a_regions = a_subst.regions().get_vec(space);
-            let b_regions = b_subst.regions().get_vec(space);
-            let r_variances = variances.regions.get_vec(space);
+            let a_tps = a_subst.types.get_slice(space);
+            let b_tps = b_subst.types.get_slice(space);
+            let tps = if_ok!(self.tps(space, a_tps, b_tps));
+
+            let a_regions = a_subst.regions().get_slice(space);
+            let b_regions = b_subst.regions().get_slice(space);
+            let r_variances = variances.regions.get_slice(space);
             let regions = if_ok!(relate_region_params(self,
                                                       item_def_id,
                                                       r_variances,
                                                       a_regions,
                                                       b_regions));
 
-            *substs.types.get_mut_vec(space) = tps;
-            *substs.mut_regions().get_mut_vec(space) = regions;
+            substs.types.replace(space, tps);
+            substs.mut_regions().replace(space, regions);
         }
 
         return Ok(substs);
 
         fn relate_region_params<C:Combine>(this: &C,
                                            item_def_id: ast::DefId,
-                                           variances: &Vec<ty::Variance>,
-                                           a_rs: &Vec<ty::Region>,
-                                           b_rs: &Vec<ty::Region>)
+                                           variances: &[ty::Variance],
+                                           a_rs: &[ty::Region],
+                                           b_rs: &[ty::Region])
                                            -> cres<Vec<ty::Region>>
         {
             let tcx = this.infcx().tcx;
@@ -160,9 +158,9 @@ fn relate_region_params<C:Combine>(this: &C,
             assert_eq!(num_region_params, b_rs.len());
             let mut rs = vec!();
             for i in range(0, num_region_params) {
-                let a_r = *a_rs.get(i);
-                let b_r = *b_rs.get(i);
-                let variance = *variances.get(i);
+                let a_r = a_rs[i];
+                let b_r = b_rs[i];
+                let variance = variances[i];
                 let r = match variance {
                     ty::Invariant => {
                         eq_regions(this, a_r, b_r)
index a5bdea72da2302f1e9906fde9326260b32413c88..bdd6d96f394a29131e357e47eeb9adf6aff022c7 100644 (file)
@@ -90,7 +90,7 @@
 use syntax::parse::token;
 use syntax::print::pprust;
 use util::ppaux::UserString;
-use util::ppaux::bound_region_to_str;
+use util::ppaux::bound_region_to_string;
 use util::ppaux::note_and_explain_region;
 
 pub trait ErrorReporting {
@@ -442,7 +442,7 @@ fn report_concrete_failure(&self,
                             ty::local_var_name_str(self.tcx,
                                                    upvar_id.var_id)
                                 .get()
-                                .to_str()).as_slice());
+                                .to_string()).as_slice());
                 note_and_explain_region(
                     self.tcx,
                     "...the borrowed pointer is valid for ",
@@ -454,7 +454,7 @@ fn report_concrete_failure(&self,
                             ty::local_var_name_str(self.tcx,
                                                    upvar_id.var_id)
                                 .get()
-                                .to_str()).as_slice(),
+                                .to_string()).as_slice(),
                     sup,
                     "");
             }
@@ -500,7 +500,7 @@ fn report_concrete_failure(&self,
                             outlive the enclosing closure",
                             ty::local_var_name_str(self.tcx,
                                                    id).get()
-                                                      .to_str()).as_slice());
+                                                      .to_string()).as_slice());
                 note_and_explain_region(
                     self.tcx,
                     "captured variable is valid for ",
@@ -676,10 +676,10 @@ fn report_processed_errors(&self,
                                var_origins: &[RegionVariableOrigin],
                                trace_origins: &[(TypeTrace, ty::type_err)],
                                same_regions: &[SameRegions]) {
-        self.give_suggestion(same_regions);
         for vo in var_origins.iter() {
             self.report_inference_failure(vo.clone());
         }
+        self.give_suggestion(same_regions);
         for &(ref trace, terr) in trace_origins.iter() {
             self.report_type_error(trace.clone(), &terr);
         }
@@ -693,15 +693,18 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
             Some(ref node) => match *node {
                 ast_map::NodeItem(ref item) => {
                     match item.node {
-                        ast::ItemFn(ref fn_decl, ref pur, _, ref gen, _) => {
+                        ast::ItemFn(fn_decl, ref pur, _, ref gen, _) => {
                             Some((fn_decl, gen, *pur, item.ident, None, item.span))
                         },
                         _ => None
                     }
                 }
                 ast_map::NodeMethod(ref m) => {
-                    Some((&m.decl, &m.generics, m.fn_style,
-                          m.ident, Some(m.explicit_self.node), m.span))
+                    Some((ast_util::method_fn_decl(&**m),
+                          ast_util::method_generics(&**m),
+                          ast_util::method_fn_style(&**m),
+                          ast_util::method_ident(&**m),
+                          Some(ast_util::method_explicit_self(&**m).node), m.span))
                 },
                 _ => None
             },
@@ -711,7 +714,7 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
                                     = node_inner.expect("expect item fn");
         let taken = lifetimes_in_scope(self.tcx, scope_id);
         let life_giver = LifeGiver::with_taken(taken.as_slice());
-        let rebuilder = Rebuilder::new(self.tcx, *fn_decl, expl_self,
+        let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
                                        generics, same_regions, &life_giver);
         let (fn_decl, expl_self, generics) = rebuilder.rebuild();
         self.give_expl_lifetime_param(&fn_decl, fn_style, ident,
@@ -895,9 +898,9 @@ fn rebuild_ty_params(&self,
                 ident: ty_param.ident,
                 id: ty_param.id,
                 bounds: bounds,
+                unbound: ty_param.unbound.clone(),
                 default: ty_param.default,
                 span: ty_param.span,
-                sized: ty_param.sized,
             }
         })
     }
@@ -947,16 +950,16 @@ fn rebuild_expl_self(&self,
                          -> Option<ast::ExplicitSelf_> {
         match expl_self_opt {
             Some(expl_self) => match expl_self {
-                ast::SelfRegion(lt_opt, muta) => match lt_opt {
+                ast::SelfRegion(lt_opt, muta, id) => match lt_opt {
                     Some(lt) => if region_names.contains(&lt.name) {
-                        return Some(ast::SelfRegion(Some(lifetime), muta));
+                        return Some(ast::SelfRegion(Some(lifetime), muta, id));
                     },
                     None => {
                         let anon = self.cur_anon.get();
                         self.inc_and_offset_cur_anon(1);
                         if anon_nums.contains(&anon) {
                             self.track_anon(anon);
-                            return Some(ast::SelfRegion(Some(lifetime), muta));
+                            return Some(ast::SelfRegion(Some(lifetime), muta, id));
                         }
                     }
                 },
@@ -1046,7 +1049,7 @@ fn rebuild_arg_ty_or_output(&self,
                                 .sess
                                 .fatal(format!(
                                         "unbound path {}",
-                                        pprust::path_to_str(path)).as_slice())
+                                        pprust::path_to_string(path)).as_slice())
                         }
                         Some(&d) => d
                     };
@@ -1231,7 +1234,7 @@ fn give_expl_lifetime_param(&self,
                                 opt_explicit_self: Option<ast::ExplicitSelf_>,
                                 generics: &ast::Generics,
                                 span: codemap::Span) {
-        let suggested_fn = pprust::fun_to_str(decl, fn_style, ident,
+        let suggested_fn = pprust::fun_to_string(decl, fn_style, ident,
                                               opt_explicit_self, generics);
         let msg = format!("consider using an explicit lifetime \
                            parameter as shown: {}", suggested_fn);
@@ -1249,11 +1252,11 @@ fn report_inference_failure(&self,
             infer::Coercion(_) => " for automatic coercion".to_string(),
             infer::LateBoundRegion(_, br) => {
                 format!(" for {}in function call",
-                        bound_region_to_str(self.tcx, "lifetime parameter ", true, br))
+                        bound_region_to_string(self.tcx, "lifetime parameter ", true, br))
             }
             infer::BoundRegionInFnType(_, br) => {
                 format!(" for {}in function type",
-                        bound_region_to_str(self.tcx, "lifetime parameter ", true, br))
+                        bound_region_to_string(self.tcx, "lifetime parameter ", true, br))
             }
             infer::EarlyBoundRegion(_, name) => {
                 format!(" for lifetime parameter `{}",
@@ -1265,7 +1268,7 @@ fn report_inference_failure(&self,
             }
             infer::UpvarRegion(ref upvar_id, _) => {
                 format!(" for capture of `{}` by closure",
-                        ty::local_var_name_str(self.tcx, upvar_id.var_id).get().to_str())
+                        ty::local_var_name_str(self.tcx, upvar_id.var_id).get().to_string())
             }
         };
 
@@ -1334,7 +1337,7 @@ fn note_region_origin(&self, origin: SubregionOrigin) {
                         "...so that closure can access `{}`",
                         ty::local_var_name_str(self.tcx, upvar_id.var_id)
                             .get()
-                            .to_str()).as_slice())
+                            .to_string()).as_slice())
             }
             infer::InfStackClosure(span) => {
                 self.tcx.sess.span_note(
@@ -1359,7 +1362,7 @@ fn note_region_origin(&self, origin: SubregionOrigin) {
                             does not outlive the enclosing closure",
                             ty::local_var_name_str(
                                 self.tcx,
-                                id).get().to_str()).as_slice());
+                                id).get().to_string()).as_slice());
             }
             infer::IndexSlice(span) => {
                 self.tcx.sess.span_note(
@@ -1452,7 +1455,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
                 _ => None
             },
             ast_map::NodeMethod(m) => {
-                taken.push_all(m.generics.lifetimes.as_slice());
+                taken.push_all(ast_util::method_generics(&*m).lifetimes.as_slice());
                 Some(m.id)
             },
             _ => None
@@ -1508,7 +1511,7 @@ fn give_lifetime(&self) -> ast::Lifetime {
         let mut lifetime;
         loop {
             let mut s = String::from_str("'");
-            s.push_str(num_to_str(self.counter.get()).as_slice());
+            s.push_str(num_to_string(self.counter.get()).as_slice());
             if !self.taken.contains(&s) {
                 lifetime = name_to_dummy_lifetime(
                                     token::str_to_ident(s.as_slice()).name);
@@ -1521,7 +1524,7 @@ fn give_lifetime(&self) -> ast::Lifetime {
         return lifetime;
 
         // 0 .. 25 generates a .. z, 26 .. 51 generates aa .. zz, and so on
-        fn num_to_str(counter: uint) -> String {
+        fn num_to_string(counter: uint) -> String {
             let mut s = String::new();
             let (n, r) = (counter/26 + 1, counter % 26);
             let letter: char = from_u32((r+97) as u32).unwrap();
index d2c27330a94ade27e266e64a360615ac46b8d28a..b6628c22ae60ae2961b34a5c911e34a21f773d3e 100644 (file)
@@ -26,7 +26,7 @@
 use syntax::ast::{Onceness, FnStyle};
 use std::collections::HashMap;
 use util::common::{indenter};
-use util::ppaux::mt_to_str;
+use util::ppaux::mt_to_string;
 use util::ppaux::Repr;
 
 pub struct Glb<'f>(pub CombineFields<'f>);  // "greatest lower bound" (common subtype)
@@ -50,8 +50,8 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
 
         debug!("{}.mts({}, {})",
                self.tag(),
-               mt_to_str(tcx, a),
-               mt_to_str(tcx, b));
+               mt_to_string(tcx, a),
+               mt_to_string(tcx, b));
 
         match (a.mutbl, b.mutbl) {
           // If one side or both is mut, then the GLB must use
index 1b3d96e474e4b5f051aae01b892f3eb4c9a959fd..708eb498f8421ea5fb059a08ccf5b109b9a2459d 100644 (file)
@@ -39,7 +39,7 @@
 use middle::typeck::infer::combine::*;
 use middle::typeck::infer::glb::Glb;
 use middle::typeck::infer::lub::Lub;
-use middle::typeck::infer::unify::{Root, UnifyKey};
+use middle::typeck::infer::unify::*;
 use middle::typeck::infer::sub::Sub;
 use util::ppaux::Repr;
 
@@ -436,8 +436,7 @@ pub enum LatticeVarResult<K,T> {
  * - If the variables do not both have an upper bound, we will unify
  *   the variables and return the unified variable, in which case the
  *   result is a variable.  This is indicated with a `VarResult`
- *   return.
- */
+ *   return. */
 pub fn lattice_vars<L:LatticeDir+Combine,
                     T:LatticeValue,
                     K:UnifyKey<Bounds<T>>>(
index 7ccffdfeb062fc1ffa4ba2d735784ba41798c354..6a50038afe77fc20ea89f51d6648952e9ea1972c 100644 (file)
@@ -25,7 +25,7 @@
 use syntax::ast::{NormalFn, UnsafeFn};
 use syntax::ast::{Onceness, FnStyle};
 use syntax::ast::{MutMutable, MutImmutable};
-use util::ppaux::mt_to_str;
+use util::ppaux::mt_to_string;
 use util::ppaux::Repr;
 
 pub struct Lub<'f>(pub CombineFields<'f>);  // least-upper-bound: common supertype
@@ -49,8 +49,8 @@ fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
 
         debug!("{}.mts({}, {})",
                self.tag(),
-               mt_to_str(tcx, a),
-               mt_to_str(tcx, b));
+               mt_to_string(tcx, a),
+               mt_to_string(tcx, b));
 
         if a.mutbl != b.mutbl {
             return Err(ty::terr_mutability)
index bc02297b5b1f3cd27d89a55b4fb4890ab96cf9c7..16e758df9dbbd2ad7c3354f7d716bace80d93f5b 100644 (file)
@@ -44,7 +44,7 @@
 use syntax::codemap;
 use syntax::codemap::Span;
 use util::common::indent;
-use util::ppaux::{bound_region_to_str, ty_to_str, trait_ref_to_str, Repr};
+use util::ppaux::{bound_region_to_string, ty_to_string, trait_ref_to_string, Repr};
 
 pub mod doc;
 pub mod macros;
@@ -245,7 +245,7 @@ pub enum fixup_err {
     region_var_bound_by_region_var(RegionVid, RegionVid)
 }
 
-pub fn fixup_err_to_str(f: fixup_err) -> String {
+pub fn fixup_err_to_string(f: fixup_err) -> String {
     match f {
       unresolved_int_ty(_) => {
           "cannot determine the type of this integer; add a suffix to \
@@ -624,7 +624,7 @@ pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
 
     pub fn region_vars_for_defs(&self,
                                 span: Span,
-                                defs: &Vec<ty::RegionParameterDef>)
+                                defs: &[ty::RegionParameterDef])
                                 -> Vec<ty::Region> {
         defs.iter()
             .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
@@ -647,7 +647,7 @@ pub fn fresh_substs_for_type(&self,
         assert!(generics.regions.len(subst::FnSpace) == 0);
 
         let type_parameter_count = generics.types.len(subst::TypeSpace);
-        let region_param_defs = generics.regions.get_vec(subst::TypeSpace);
+        let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
         let regions = self.region_vars_for_defs(span, region_param_defs);
         let type_parameters = self.next_ty_vars(type_parameter_count);
         subst::Substs::new_type(type_parameters, regions)
@@ -662,19 +662,19 @@ pub fn resolve_regions_and_report_errors(&self) {
         self.report_region_errors(&errors); // see error_reporting.rs
     }
 
-    pub fn ty_to_str(&self, t: ty::t) -> String {
-        ty_to_str(self.tcx,
+    pub fn ty_to_string(&self, t: ty::t) -> String {
+        ty_to_string(self.tcx,
                   self.resolve_type_vars_if_possible(t))
     }
 
-    pub fn tys_to_str(&self, ts: &[ty::t]) -> String {
-        let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_str(*t)).collect();
+    pub fn tys_to_string(&self, ts: &[ty::t]) -> String {
+        let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
         format!("({})", tstrs.connect(", "))
     }
 
-    pub fn trait_ref_to_str(&self, t: &ty::TraitRef) -> String {
+    pub fn trait_ref_to_string(&self, t: &ty::TraitRef) -> String {
         let t = self.resolve_type_vars_in_trait_ref_if_possible(t);
-        trait_ref_to_str(self.tcx, &t)
+        trait_ref_to_string(self.tcx, &t)
     }
 
     pub fn resolve_type_vars_if_possible(&self, typ: ty::t) -> ty::t {
@@ -707,8 +707,8 @@ pub fn resolve_type_vars_in_trait_ref_if_possible(&self,
                 self.tcx.sess.bug(
                     format!("resolve_type_vars_if_possible() yielded {} \
                              when supplied with {}",
-                            self.ty_to_str(dummy0),
-                            self.ty_to_str(dummy1)).as_slice());
+                            self.ty_to_string(dummy0),
+                            self.ty_to_string(dummy1)).as_slice());
             }
         }
     }
@@ -761,7 +761,7 @@ pub fn type_error_message_str_with_expected(&self,
                 Some(e) => {
                     self.tcx.sess.span_err(sp,
                         format!("{}{}",
-                                mk_msg(Some(self.ty_to_str(e)), actual_ty),
+                                mk_msg(Some(self.ty_to_string(e)), actual_ty),
                                 error_str).as_slice());
                 }
             }
@@ -783,7 +783,7 @@ pub fn type_error_message(&self,
             return;
         }
 
-        self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_str(actual_ty), err);
+        self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err);
     }
 
     pub fn report_mismatched_types(&self,
@@ -800,7 +800,7 @@ pub fn report_mismatched_types(&self,
                 // if I leave out : String, it infers &str and complains
                 |actual: String| {
                     format!("mismatched types: expected `{}` but found `{}`",
-                            self.ty_to_str(resolved_expected),
+                            self.ty_to_string(resolved_expected),
                             actual)
                 }
             }
@@ -819,7 +819,7 @@ pub fn replace_late_bound_regions_with_fresh_regions(&self,
                 let rvar = self.next_region_var(
                     BoundRegionInFnType(trace.origin.span(), br));
                 debug!("Bound region {} maps to {:?}",
-                       bound_region_to_str(self.tcx, "", false, br),
+                       bound_region_to_string(self.tcx, "", false, br),
                        rvar);
                 rvar
             });
index adfbe9de2d5bf8b72769c6784a879a16dd64b702..2ae95309d41d98a76e6c00b8f254ddffd415a08c 100644 (file)
@@ -56,7 +56,7 @@
 use middle::typeck::infer::{unresolved_ty};
 use syntax::codemap::Span;
 use util::common::indent;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
 
 pub static resolve_nested_tvar: uint = 0b0000000001;
 pub static resolve_rvar: uint        = 0b0000000010;
@@ -121,7 +121,7 @@ pub fn resolve_type_chk(&mut self,
         self.err = None;
 
         debug!("Resolving {} (modes={:x})",
-               ty_to_str(self.infcx.tcx, typ),
+               ty_to_string(self.infcx.tcx, typ),
                self.modes);
 
         // n.b. This is a hokey mess because the current fold doesn't
@@ -133,8 +133,8 @@ pub fn resolve_type_chk(&mut self,
         match self.err {
           None => {
             debug!("Resolved to {} + {} (modes={:x})",
-                   ty_to_str(self.infcx.tcx, rty),
-                   ty_to_str(self.infcx.tcx, rty),
+                   ty_to_string(self.infcx.tcx, rty),
+                   ty_to_string(self.infcx.tcx, rty),
                    self.modes);
             return Ok(rty);
           }
index 856237c4bcaa4c3634468e23839267db6a4d74f3..44c147bfe7f62f962b75c813b4e608b4136d5deb 100644 (file)
@@ -22,7 +22,7 @@
 use middle::typeck::infer::then;
 use middle::typeck::infer::{TypeTrace, Subtype};
 use util::common::{indenter};
-use util::ppaux::{bound_region_to_str, Repr};
+use util::ppaux::{bound_region_to_string, Repr};
 
 use syntax::ast::{Onceness, FnStyle, MutImmutable, MutMutable};
 
@@ -176,7 +176,7 @@ fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
             replace_late_bound_regions_in_fn_sig(self.get_ref().infcx.tcx, b, |br| {
                 let skol = self.get_ref().infcx.region_vars.new_skolemized(br);
                 debug!("Bound region {} skolemized to {:?}",
-                       bound_region_to_str(self.get_ref().infcx.tcx, "", false, br),
+                       bound_region_to_string(self.get_ref().infcx.tcx, "", false, br),
                        skol);
                 skol
             })
index 5ae469c41f2dfa39ed0f37b06b50454db956cf3c..c06e40fce14f915e410208e5393bb57eccbf885f 100644 (file)
@@ -37,8 +37,7 @@
 use syntax::codemap::{Span, CodeMap, DUMMY_SP};
 use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
 use syntax::ast;
-use syntax::crateid::CrateId;
-use util::ppaux::{ty_to_str, UserString};
+use util::ppaux::{ty_to_string, UserString};
 
 struct Env<'a> {
     krate: ast::Crate,
@@ -79,6 +78,7 @@ impl Emitter for ExpectErrorEmitter {
     fn emit(&mut self,
             _cmsp: Option<(&codemap::CodeMap, Span)>,
             msg: &str,
+            _: Option<&str>,
             lvl: Level)
     {
         remove_message(self, msg, lvl);
@@ -116,11 +116,8 @@ fn test_env(_test_name: &str,
     let krate_config = Vec::new();
     let input = driver::StrInput(source_string.to_owned());
     let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
-    let krate_id = CrateId { path: "test".to_owned(),
-                             name: "test".to_owned(),
-                             version: None };
     let (krate, ast_map) =
-        driver::phase_2_configure_and_expand(&sess, krate, &krate_id)
+        driver::phase_2_configure_and_expand(&sess, krate, "test")
             .expect("phase 2 aborted");
 
     // run just enough stuff to build a tcx:
@@ -229,16 +226,16 @@ pub fn is_subtype(&self, a: ty::t, b: ty::t) -> bool {
     pub fn assert_subtype(&self, a: ty::t, b: ty::t) {
         if !self.is_subtype(a, b) {
             fail!("{} is not a subtype of {}, but it should be",
-                  self.ty_to_str(a),
-                  self.ty_to_str(b));
+                  self.ty_to_string(a),
+                  self.ty_to_string(b));
         }
     }
 
     pub fn assert_not_subtype(&self, a: ty::t, b: ty::t) {
         if self.is_subtype(a, b) {
             fail!("{} is a subtype of {}, but it shouldn't be",
-                  self.ty_to_str(a),
-                  self.ty_to_str(b));
+                  self.ty_to_string(a),
+                  self.ty_to_string(b));
         }
     }
 
@@ -247,8 +244,8 @@ pub fn assert_eq(&self, a: ty::t, b: ty::t) {
         self.assert_subtype(b, a);
     }
 
-    pub fn ty_to_str(&self, a: ty::t) -> String {
-        ty_to_str(self.tcx, a)
+    pub fn ty_to_string(&self, a: ty::t) -> String {
+        ty_to_string(self.tcx, a)
     }
 
     pub fn t_fn(&self,
@@ -332,9 +329,9 @@ pub fn check_lub(&self, t1: ty::t, t2: ty::t, t_lub: ty::t) {
     /// Checks that `GLB(t1,t2) == t_glb`
     pub fn check_glb(&self, t1: ty::t, t2: ty::t, t_glb: ty::t) {
         debug!("check_glb(t1={}, t2={}, t_glb={})",
-               self.ty_to_str(t1),
-               self.ty_to_str(t2),
-               self.ty_to_str(t_glb));
+               self.ty_to_string(t1),
+               self.ty_to_string(t2),
+               self.ty_to_string(t_glb));
         match self.glb().tys(t1, t2) {
             Err(e) => {
                 fail!("unexpected error computing LUB: {:?}", e)
@@ -354,7 +351,7 @@ pub fn check_no_lub(&self, t1: ty::t, t2: ty::t) {
         match self.lub().tys(t1, t2) {
             Err(_) => {}
             Ok(t) => {
-                fail!("unexpected success computing LUB: {}", self.ty_to_str(t))
+                fail!("unexpected success computing LUB: {}", self.ty_to_string(t))
             }
         }
     }
@@ -364,7 +361,7 @@ pub fn check_no_glb(&self, t1: ty::t, t2: ty::t) {
         match self.glb().tys(t1, t2) {
             Err(_) => {}
             Ok(t) => {
-                fail!("unexpected success computing GLB: {}", self.ty_to_str(t))
+                fail!("unexpected success computing GLB: {}", self.ty_to_string(t))
             }
         }
     }
index 7b6935df42079a561fd0e8a12006937679511f71..ad6864ba487921680001aa59e6b180a3032207ac 100644 (file)
@@ -276,7 +276,7 @@ pub struct CrateCtxt<'a> {
 
 // Functions that write types into the node type table
 pub fn write_ty_to_tcx(tcx: &ty::ctxt, node_id: ast::NodeId, ty: ty::t) {
-    debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_str(tcx, ty));
+    debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_string(tcx, ty));
     assert!(!ty::type_needs_infer(ty));
     tcx.node_types.borrow_mut().insert(node_id as uint, ty);
 }
@@ -383,14 +383,14 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
             require_same_types(tcx, None, false, main_span, main_t, se_ty,
                 || {
                     format!("main function expects type: `{}`",
-                            ppaux::ty_to_str(ccx.tcx, se_ty))
+                            ppaux::ty_to_string(ccx.tcx, se_ty))
                 });
         }
         _ => {
             tcx.sess.span_bug(main_span,
                               format!("main has a non-function type: found \
                                        `{}`",
-                                      ppaux::ty_to_str(tcx,
+                                      ppaux::ty_to_string(tcx,
                                                        main_t)).as_slice());
         }
     }
@@ -436,7 +436,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
             require_same_types(tcx, None, false, start_span, start_t, se_ty,
                 || {
                     format!("start function expects type: `{}`",
-                            ppaux::ty_to_str(ccx.tcx, se_ty))
+                            ppaux::ty_to_string(ccx.tcx, se_ty))
                 });
 
         }
@@ -444,7 +444,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
             tcx.sess.span_bug(start_span,
                               format!("start has a non-function type: found \
                                        `{}`",
-                                      ppaux::ty_to_str(tcx,
+                                      ppaux::ty_to_string(tcx,
                                                        start_t)).as_slice());
         }
     }
index 0a60a5ce0e9fa3900a5d8b7d031f189f45e17aa8..8b5d16620b0f5898d02a5f0b89bdea289b6a34c2 100644 (file)
@@ -547,7 +547,7 @@ fn inferred_index(&self, param_id: ast::NodeId) -> InferredIndex {
             None => {
                 self.tcx().sess.bug(format!(
                         "no inferred index entry for {}",
-                        self.tcx().map.node_to_str(param_id)).as_slice());
+                        self.tcx().map.node_to_string(param_id)).as_slice());
             }
         }
     }
@@ -588,8 +588,8 @@ fn is_to_be_inferred(&self, param_id: ast::NodeId) -> bool {
             let is_inferred;
             macro_rules! cannot_happen { () => { {
                 fail!("invalid parent: {:s} for {:s}",
-                      tcx.map.node_to_str(parent_id),
-                      tcx.map.node_to_str(param_id));
+                      tcx.map.node_to_string(parent_id),
+                      tcx.map.node_to_string(param_id));
             } } }
 
             match parent {
@@ -658,7 +658,7 @@ fn add_constraint(&mut self,
                       InferredIndex(index): InferredIndex,
                       variance: VarianceTermPtr<'a>) {
         debug!("add_constraint(index={}, variance={})",
-                index, variance.to_str());
+                index, variance.to_string());
         self.constraints.push(Constraint { inferred: InferredIndex(index),
                                            variance: variance });
     }
@@ -749,15 +749,15 @@ fn add_constraints_from_ty(&mut self,
 
                 // All type parameters on enums and structs should be
                 // in the TypeSpace.
-                assert!(generics.types.get_vec(subst::SelfSpace).is_empty());
-                assert!(generics.types.get_vec(subst::FnSpace).is_empty());
-                assert!(generics.regions.get_vec(subst::SelfSpace).is_empty());
-                assert!(generics.regions.get_vec(subst::FnSpace).is_empty());
+                assert!(generics.types.is_empty_in(subst::SelfSpace));
+                assert!(generics.types.is_empty_in(subst::FnSpace));
+                assert!(generics.regions.is_empty_in(subst::SelfSpace));
+                assert!(generics.regions.is_empty_in(subst::FnSpace));
 
                 self.add_constraints_from_substs(
                     def_id,
-                    generics.types.get_vec(subst::TypeSpace),
-                    generics.regions.get_vec(subst::TypeSpace),
+                    generics.types.get_slice(subst::TypeSpace),
+                    generics.regions.get_slice(subst::TypeSpace),
                     substs,
                     variance);
             }
@@ -768,22 +768,22 @@ fn add_constraints_from_ty(&mut self,
 
                 // Traits DO have a Self type parameter, but it is
                 // erased from object types.
-                assert!(!generics.types.get_vec(subst::SelfSpace).is_empty() &&
-                        substs.types.get_vec(subst::SelfSpace).is_empty());
+                assert!(!generics.types.is_empty_in(subst::SelfSpace) &&
+                        substs.types.is_empty_in(subst::SelfSpace));
 
                 // Traits never declare region parameters in the self
                 // space.
-                assert!(generics.regions.get_vec(subst::SelfSpace).is_empty());
+                assert!(generics.regions.is_empty_in(subst::SelfSpace));
 
                 // Traits never declare type/region parameters in the
                 // fn space.
-                assert!(generics.types.get_vec(subst::FnSpace).is_empty());
-                assert!(generics.regions.get_vec(subst::FnSpace).is_empty());
+                assert!(generics.types.is_empty_in(subst::FnSpace));
+                assert!(generics.regions.is_empty_in(subst::FnSpace));
 
                 self.add_constraints_from_substs(
                     def_id,
-                    generics.types.get_vec(subst::TypeSpace),
-                    generics.regions.get_vec(subst::TypeSpace),
+                    generics.types.get_slice(subst::TypeSpace),
+                    generics.regions.get_slice(subst::TypeSpace),
                     substs,
                     variance);
             }
@@ -832,8 +832,8 @@ fn add_constraints_from_ty(&mut self,
     /// object, etc) appearing in a context with ambient variance `variance`
     fn add_constraints_from_substs(&mut self,
                                    def_id: ast::DefId,
-                                   type_param_defs: &Vec<ty::TypeParameterDef>,
-                                   region_param_defs: &Vec<ty::RegionParameterDef>,
+                                   type_param_defs: &[ty::TypeParameterDef],
+                                   region_param_defs: &[ty::RegionParameterDef],
                                    substs: &subst::Substs,
                                    variance: VarianceTermPtr<'a>) {
         debug!("add_constraints_from_substs(def_id={:?})", def_id);
@@ -975,7 +975,7 @@ fn solve(&mut self) {
                                 .param_id,
                             old_value,
                             new_value,
-                            term.to_str());
+                            term.to_string());
 
                     *self.solutions.get_mut(inferred) = new_value;
                     changed = true;
index 79d0690653faf9d3a6a99d501bea05f3fb947b72..499cffa42aac9f124913adb549a0c81175765ffc 100644 (file)
@@ -72,6 +72,7 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate) -> Plugins {
     loader.plugins
 }
 
+// note that macros aren't expanded yet, and therefore macros can't add plugins.
 impl<'a> Visitor<()> for PluginLoader<'a> {
     fn visit_view_item(&mut self, vi: &ast::ViewItem, _: ()) {
         match vi.node {
@@ -109,6 +110,10 @@ fn visit_view_item(&mut self, vi: &ast::ViewItem, _: ()) {
             _ => (),
         }
     }
+    fn visit_mac(&mut self, _: &ast::Mac, _:()) {
+        // bummer... can't see plugins inside macros.
+        // do nothing.
+    }
 }
 
 impl<'a> PluginLoader<'a> {
index fa70ffc7392f3c2b4405393e1cbed15fc9a5ec85..71423ee56bc5a9c36f620cab45b3f26336dd821d 100644 (file)
@@ -22,7 +22,7 @@
  * `#[plugin_registrar]` function:
  *
  * ```rust,ignore
- * #![crate_id = "myplugin"]
+ * #![crate_name = "myplugin"]
  * #![crate_type = "dylib"]
  * #![feature(plugin_registrar)]
  *
index 587bedd502e15015d7920fc7110126c152f02512..2581ba51c2e107b1830a6a5fda3b82b971eda11c 100644 (file)
@@ -13,7 +13,7 @@
 use lint::LintPassObject;
 
 use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
-use syntax::ext::base::{IdentTT, ItemDecorator, ItemModifier, BasicMacroExpander};
+use syntax::ext::base::{IdentTT, LetSyntaxTT, ItemDecorator, ItemModifier, BasicMacroExpander};
 use syntax::ext::base::{MacroExpanderFn};
 use syntax::codemap::Span;
 use syntax::parse::token;
@@ -57,6 +57,8 @@ pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxEx
             IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)),
             ItemDecorator(ext) => ItemDecorator(ext),
             ItemModifier(ext) => ItemModifier(ext),
+            // there's probably a nicer way to signal this:
+            LetSyntaxTT(_, _) => fail!("can't register a new LetSyntax!"),
         }));
     }
 
diff --git a/src/librustc/util/fs.rs b/src/librustc/util/fs.rs
deleted file mode 100644 (file)
index c051b8e..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::io;
-use std::io::fs;
-use std::os;
-
-/// Returns an absolute path in the filesystem that `path` points to. The
-/// returned path does not contain any symlinks in its hierarchy.
-pub fn realpath(original: &Path) -> io::IoResult<Path> {
-    static MAX_LINKS_FOLLOWED: uint = 256;
-    let original = os::make_absolute(original);
-
-    // Right now lstat on windows doesn't work quite well
-    if cfg!(windows) {
-        return Ok(original)
-    }
-
-    let result = original.root_path();
-    let mut result = result.expect("make_absolute has no root_path");
-    let mut followed = 0;
-
-    for part in original.components() {
-        result.push(part);
-
-        loop {
-            if followed == MAX_LINKS_FOLLOWED {
-                return Err(io::standard_error(io::InvalidInput))
-            }
-
-            match fs::lstat(&result) {
-                Err(..) => break,
-                Ok(ref stat) if stat.kind != io::TypeSymlink => break,
-                Ok(..) => {
-                    followed += 1;
-                    let path = try!(fs::readlink(&result));
-                    result.pop();
-                    result.push(path);
-                }
-            }
-        }
-    }
-
-    return Ok(result);
-}
-
-#[cfg(not(windows), test)]
-mod test {
-    use std::io;
-    use std::io::fs::{File, symlink, mkdir, mkdir_recursive};
-    use super::realpath;
-    use std::io::TempDir;
-
-    #[test]
-    fn realpath_works() {
-        let tmpdir = TempDir::new("rustc-fs").unwrap();
-        let tmpdir = realpath(tmpdir.path()).unwrap();
-        let file = tmpdir.join("test");
-        let dir = tmpdir.join("test2");
-        let link = dir.join("link");
-        let linkdir = tmpdir.join("test3");
-
-        File::create(&file).unwrap();
-        mkdir(&dir, io::UserRWX).unwrap();
-        symlink(&file, &link).unwrap();
-        symlink(&dir, &linkdir).unwrap();
-
-        assert!(realpath(&tmpdir).unwrap() == tmpdir);
-        assert!(realpath(&file).unwrap() == file);
-        assert!(realpath(&link).unwrap() == file);
-        assert!(realpath(&linkdir).unwrap() == dir);
-        assert!(realpath(&linkdir.join("link")).unwrap() == file);
-    }
-
-    #[test]
-    fn realpath_works_tricky() {
-        let tmpdir = TempDir::new("rustc-fs").unwrap();
-        let tmpdir = realpath(tmpdir.path()).unwrap();
-
-        let a = tmpdir.join("a");
-        let b = a.join("b");
-        let c = b.join("c");
-        let d = a.join("d");
-        let e = d.join("e");
-        let f = a.join("f");
-
-        mkdir_recursive(&b, io::UserRWX).unwrap();
-        mkdir_recursive(&d, io::UserRWX).unwrap();
-        File::create(&f).unwrap();
-        symlink(&Path::new("../d/e"), &c).unwrap();
-        symlink(&Path::new("../f"), &e).unwrap();
-
-        assert!(realpath(&c).unwrap() == f);
-        assert!(realpath(&e).unwrap() == f);
-    }
-}
index fa353652fe1ec21ae311ae6ea866a417df431ade..6526943955c92860c3c9500ed1719666fab0a937 100644 (file)
@@ -16,8 +16,7 @@
 use middle::ty::{BoundRegion, BrAnon, BrNamed};
 use middle::ty::{BrFresh, ctxt};
 use middle::ty::{mt, t, ParamTy};
-use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region,
-                 ReEmpty};
+use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
 use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
 use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_tup};
@@ -106,7 +105,7 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
           BrFresh(_) => "an anonymous lifetime defined on".to_string(),
           _ => {
               format!("the lifetime {} as defined on",
-                      bound_region_ptr_to_str(cx, fr.bound_region))
+                      bound_region_ptr_to_string(cx, fr.bound_region))
           }
         };
 
@@ -146,11 +145,11 @@ fn explain_span(cx: &ctxt, heading: &str, span: Span)
     }
 }
 
-pub fn bound_region_ptr_to_str(cx: &ctxt, br: BoundRegion) -> String {
-    bound_region_to_str(cx, "", false, br)
+pub fn bound_region_ptr_to_string(cx: &ctxt, br: BoundRegion) -> String {
+    bound_region_to_string(cx, "", false, br)
 }
 
-pub fn bound_region_to_str(cx: &ctxt,
+pub fn bound_region_to_string(cx: &ctxt,
                            prefix: &str, space: bool,
                            br: BoundRegion) -> String {
     let space_str = if space { " " } else { "" };
@@ -171,11 +170,11 @@ pub fn bound_region_to_str(cx: &ctxt,
 // In general, if you are giving a region error message,
 // you should use `explain_region()` or, better yet,
 // `note_and_explain_region()`
-pub fn region_ptr_to_str(cx: &ctxt, region: Region) -> String {
-    region_to_str(cx, "&", true, region)
+pub fn region_ptr_to_string(cx: &ctxt, region: Region) -> String {
+    region_to_string(cx, "&", true, region)
 }
 
-pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, region: Region) -> String {
+pub fn region_to_string(cx: &ctxt, prefix: &str, space: bool, region: Region) -> String {
     let space_str = if space { " " } else { "" };
 
     if cx.sess.verbose() {
@@ -191,10 +190,10 @@ pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, region: Region) -> St
         ty::ReEarlyBound(_, _, _, name) => {
             token::get_name(name).get().to_string()
         }
-        ty::ReLateBound(_, br) => bound_region_to_str(cx, prefix, space, br),
-        ty::ReFree(ref fr) => bound_region_to_str(cx, prefix, space, fr.bound_region),
+        ty::ReLateBound(_, br) => bound_region_to_string(cx, prefix, space, br),
+        ty::ReFree(ref fr) => bound_region_to_string(cx, prefix, space, fr.bound_region),
         ty::ReInfer(ReSkolemized(_, br)) => {
-            bound_region_to_str(cx, prefix, space, br)
+            bound_region_to_string(cx, prefix, space, br)
         }
         ty::ReInfer(ReVar(_)) => prefix.to_string(),
         ty::ReStatic => format!("{}'static{}", prefix, space_str),
@@ -202,45 +201,45 @@ pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, region: Region) -> St
     }
 }
 
-pub fn mutability_to_str(m: ast::Mutability) -> String {
+pub fn mutability_to_string(m: ast::Mutability) -> String {
     match m {
         ast::MutMutable => "mut ".to_string(),
         ast::MutImmutable => "".to_string(),
     }
 }
 
-pub fn mt_to_str(cx: &ctxt, m: &mt) -> String {
-    format!("{}{}", mutability_to_str(m.mutbl), ty_to_str(cx, m.ty))
+pub fn mt_to_string(cx: &ctxt, m: &mt) -> String {
+    format!("{}{}", mutability_to_string(m.mutbl), ty_to_string(cx, m.ty))
 }
 
-pub fn trait_store_to_str(cx: &ctxt, s: ty::TraitStore) -> String {
+pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String {
     match s {
         ty::UniqTraitStore => "Box ".to_string(),
         ty::RegionTraitStore(r, m) => {
-            format!("{}{}", region_ptr_to_str(cx, r), mutability_to_str(m))
+            format!("{}{}", region_ptr_to_string(cx, r), mutability_to_string(m))
         }
     }
 }
 
-pub fn vec_map_to_str<T>(ts: &[T], f: |t: &T| -> String) -> String {
+pub fn vec_map_to_string<T>(ts: &[T], f: |t: &T| -> String) -> String {
     let tstrs = ts.iter().map(f).collect::<Vec<String>>();
     format!("[{}]", tstrs.connect(", "))
 }
 
-pub fn fn_sig_to_str(cx: &ctxt, typ: &ty::FnSig) -> String {
+pub fn fn_sig_to_string(cx: &ctxt, typ: &ty::FnSig) -> String {
     format!("fn{}{} -> {}", typ.binder_id, typ.inputs.repr(cx),
             typ.output.repr(cx))
 }
 
-pub fn trait_ref_to_str(cx: &ctxt, trait_ref: &ty::TraitRef) -> String {
+pub fn trait_ref_to_string(cx: &ctxt, trait_ref: &ty::TraitRef) -> String {
     trait_ref.user_string(cx).to_string()
 }
 
-pub fn ty_to_str(cx: &ctxt, typ: t) -> String {
-    fn fn_input_to_str(cx: &ctxt, input: ty::t) -> String {
-        ty_to_str(cx, input).to_string()
+pub fn ty_to_string(cx: &ctxt, typ: t) -> String {
+    fn fn_input_to_string(cx: &ctxt, input: ty::t) -> String {
+        ty_to_string(cx, input).to_string()
     }
-    fn bare_fn_to_str(cx: &ctxt,
+    fn bare_fn_to_string(cx: &ctxt,
                       fn_style: ast::FnStyle,
                       abi: abi::Abi,
                       ident: Option<ast::Ident>,
@@ -250,13 +249,13 @@ fn bare_fn_to_str(cx: &ctxt,
         match fn_style {
             ast::NormalFn => {}
             _ => {
-                s.push_str(fn_style.to_str().as_slice());
+                s.push_str(fn_style.to_string().as_slice());
                 s.push_char(' ');
             }
         };
 
         if abi != abi::Rust {
-            s.push_str(format!("extern {} ", abi.to_str()).as_slice());
+            s.push_str(format!("extern {} ", abi.to_string()).as_slice());
         };
 
         s.push_str("fn");
@@ -269,25 +268,25 @@ fn bare_fn_to_str(cx: &ctxt,
             _ => { }
         }
 
-        push_sig_to_str(cx, &mut s, '(', ')', sig);
+        push_sig_to_string(cx, &mut s, '(', ')', sig);
 
         s
     }
 
-    fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> String {
+    fn closure_to_string(cx: &ctxt, cty: &ty::ClosureTy) -> String {
         let mut s = String::new();
 
         match cty.store {
             ty::UniqTraitStore => {}
             ty::RegionTraitStore(region, _) => {
-                s.push_str(region_to_str(cx, "", true, region).as_slice());
+                s.push_str(region_to_string(cx, "", true, region).as_slice());
             }
         }
 
         match cty.fn_style {
             ast::NormalFn => {}
             _ => {
-                s.push_str(cty.fn_style.to_str().as_slice());
+                s.push_str(cty.fn_style.to_string().as_slice());
                 s.push_char(' ');
             }
         };
@@ -296,14 +295,14 @@ fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> String {
             ty::UniqTraitStore => {
                 assert_eq!(cty.onceness, ast::Once);
                 s.push_str("proc");
-                push_sig_to_str(cx, &mut s, '(', ')', &cty.sig);
+                push_sig_to_string(cx, &mut s, '(', ')', &cty.sig);
             }
             ty::RegionTraitStore(..) => {
                 match cty.onceness {
                     ast::Many => {}
                     ast::Once => s.push_str("once ")
                 }
-                push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
+                push_sig_to_string(cx, &mut s, '|', '|', &cty.sig);
             }
         }
 
@@ -315,13 +314,13 @@ fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> String {
         s
     }
 
-    fn push_sig_to_str(cx: &ctxt,
+    fn push_sig_to_string(cx: &ctxt,
                        s: &mut String,
                        bra: char,
                        ket: char,
                        sig: &ty::FnSig) {
         s.push_char(bra);
-        let strs: Vec<String> = sig.inputs.iter().map(|a| fn_input_to_str(cx, *a)).collect();
+        let strs: Vec<String> = sig.inputs.iter().map(|a| fn_input_to_string(cx, *a)).collect();
         s.push_str(strs.connect(", ").as_slice());
         if sig.variadic {
             s.push_str(", ...");
@@ -333,7 +332,7 @@ fn push_sig_to_str(cx: &ctxt,
             if ty::type_is_bot(sig.output) {
                 s.push_char('!');
             } else {
-                s.push_str(ty_to_str(cx, sig.output).as_slice());
+                s.push_str(ty_to_string(cx, sig.output).as_slice());
             }
         }
     }
@@ -350,33 +349,33 @@ fn push_sig_to_str(cx: &ctxt,
       ty_bot => "!".to_string(),
       ty_bool => "bool".to_string(),
       ty_char => "char".to_string(),
-      ty_int(t) => ast_util::int_ty_to_str(t, None).to_string(),
-      ty_uint(t) => ast_util::uint_ty_to_str(t, None).to_string(),
-      ty_float(t) => ast_util::float_ty_to_str(t).to_string(),
-      ty_box(typ) => format!("Gc<{}>", ty_to_str(cx, typ)),
-      ty_uniq(typ) => format!("Box<{}>", ty_to_str(cx, typ)),
+      ty_int(t) => ast_util::int_ty_to_string(t, None).to_string(),
+      ty_uint(t) => ast_util::uint_ty_to_string(t, None).to_string(),
+      ty_float(t) => ast_util::float_ty_to_string(t).to_string(),
+      ty_box(typ) => format!("Gc<{}>", ty_to_string(cx, typ)),
+      ty_uniq(typ) => format!("Box<{}>", ty_to_string(cx, typ)),
       ty_ptr(ref tm) => {
           format!("*{} {}", match tm.mutbl {
               ast::MutMutable => "mut",
               ast::MutImmutable => "const",
-          }, ty_to_str(cx, tm.ty))
+          }, ty_to_string(cx, tm.ty))
       }
       ty_rptr(r, ref tm) => {
-          let mut buf = region_ptr_to_str(cx, r);
-          buf.push_str(mt_to_str(cx, tm).as_slice());
+          let mut buf = region_ptr_to_string(cx, r);
+          buf.push_str(mt_to_string(cx, tm).as_slice());
           buf
       }
       ty_tup(ref elems) => {
-        let strs: Vec<String> = elems.iter().map(|elem| ty_to_str(cx, *elem)).collect();
+        let strs: Vec<String> = elems.iter().map(|elem| ty_to_string(cx, *elem)).collect();
         format!("({})", strs.connect(","))
       }
       ty_closure(ref f) => {
-          closure_to_str(cx, *f)
+          closure_to_string(cx, *f)
       }
       ty_bare_fn(ref f) => {
-          bare_fn_to_str(cx, f.fn_style, f.abi, None, &f.sig)
+          bare_fn_to_string(cx, f.fn_style, f.abi, None, &f.sig)
       }
-      ty_infer(infer_ty) => infer_ty.to_str(),
+      ty_infer(infer_ty) => infer_ty.to_string(),
       ty_err => "[type error]".to_string(),
       ty_param(ParamTy {idx: id, def_id: did, ..}) => {
           let ident = match cx.ty_param_defs.borrow().find(&did.node) {
@@ -414,9 +413,9 @@ fn push_sig_to_str(cx: &ctxt,
       ty_vec(ref mt, sz) => {
           match sz {
               Some(n) => {
-                  format!("[{}, .. {}]", mt_to_str(cx, mt), n)
+                  format!("[{}, .. {}]", mt_to_string(cx, mt), n)
               }
-              None => format!("[{}]", ty_to_str(cx, mt.ty)),
+              None => format!("[{}]", ty_to_string(cx, mt.ty)),
           }
       }
     }
@@ -434,7 +433,7 @@ pub fn parameterized(cx: &ctxt,
         subst::ErasedRegions => { }
         subst::NonerasedRegions(ref regions) => {
             for &r in regions.iter() {
-                let s = region_to_str(cx, "", false, r);
+                let s = region_to_string(cx, "", false, r);
                 if !s.is_empty() {
                     strs.push(s)
                 } else {
@@ -449,8 +448,8 @@ pub fn parameterized(cx: &ctxt,
         }
     }
 
-    let tps = substs.types.get_vec(subst::TypeSpace);
-    let ty_params = generics.types.get_vec(subst::TypeSpace);
+    let tps = substs.types.get_slice(subst::TypeSpace);
+    let ty_params = generics.types.get_slice(subst::TypeSpace);
     let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some());
     let num_defaults = if has_defaults && !cx.sess.verbose() {
         ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| {
@@ -464,11 +463,11 @@ pub fn parameterized(cx: &ctxt,
     };
 
     for t in tps.slice_to(tps.len() - num_defaults).iter() {
-        strs.push(ty_to_str(cx, *t))
+        strs.push(ty_to_string(cx, *t))
     }
 
     if cx.sess.verbose() {
-        for t in substs.types.get_vec(subst::SelfSpace).iter() {
+        for t in substs.types.get_slice(subst::SelfSpace).iter() {
             strs.push(format!("for {}", t.repr(cx)));
         }
     }
@@ -531,7 +530,7 @@ fn repr(&self, tcx: &ctxt) -> String {
 }
 
 fn repr_vec<T:Repr>(tcx: &ctxt, v: &[T]) -> String {
-    vec_map_to_str(v, |t| t.repr(tcx))
+    vec_map_to_string(v, |t| t.repr(tcx))
 }
 
 impl<'a, T:Repr> Repr for &'a [T] {
@@ -577,13 +576,13 @@ fn repr(&self, _tcx: &ctxt) -> String {
 
 impl Repr for ty::t {
     fn repr(&self, tcx: &ctxt) -> String {
-        ty_to_str(tcx, *self)
+        ty_to_string(tcx, *self)
     }
 }
 
 impl Repr for ty::mt {
     fn repr(&self, tcx: &ctxt) -> String {
-        mt_to_str(tcx, self)
+        mt_to_string(tcx, self)
     }
 }
 
@@ -598,9 +597,9 @@ fn repr(&self, tcx: &ctxt) -> String {
 impl<T:Repr> Repr for subst::VecPerParamSpace<T> {
     fn repr(&self, tcx: &ctxt) -> String {
         format!("[{};{};{}]",
-                       self.get_vec(subst::TypeSpace).repr(tcx),
-                       self.get_vec(subst::SelfSpace).repr(tcx),
-                       self.get_vec(subst::FnSpace).repr(tcx))
+                       self.get_slice(subst::TypeSpace).repr(tcx),
+                       self.get_slice(subst::SelfSpace).repr(tcx),
+                       self.get_slice(subst::FnSpace).repr(tcx))
     }
 }
 
@@ -640,25 +639,25 @@ fn repr(&self, tcx: &ctxt) -> String {
 
 impl Repr for ty::TraitRef {
     fn repr(&self, tcx: &ctxt) -> String {
-        trait_ref_to_str(tcx, self)
+        trait_ref_to_string(tcx, self)
     }
 }
 
 impl Repr for ast::Expr {
     fn repr(&self, _tcx: &ctxt) -> String {
-        format!("expr({}: {})", self.id, pprust::expr_to_str(self))
+        format!("expr({}: {})", self.id, pprust::expr_to_string(self))
     }
 }
 
 impl Repr for ast::Path {
     fn repr(&self, _tcx: &ctxt) -> String {
-        format!("path({})", pprust::path_to_str(self))
+        format!("path({})", pprust::path_to_string(self))
     }
 }
 
 impl Repr for ast::Item {
     fn repr(&self, tcx: &ctxt) -> String {
-        format!("item({})", tcx.map.node_to_str(self.id))
+        format!("item({})", tcx.map.node_to_string(self.id))
     }
 }
 
@@ -666,13 +665,13 @@ impl Repr for ast::Stmt {
     fn repr(&self, _tcx: &ctxt) -> String {
         format!("stmt({}: {})",
                 ast_util::stmt_id(self),
-                pprust::stmt_to_str(self))
+                pprust::stmt_to_string(self))
     }
 }
 
 impl Repr for ast::Pat {
     fn repr(&self, _tcx: &ctxt) -> String {
-        format!("pat({}: {})", self.id, pprust::pat_to_str(self))
+        format!("pat({}: {})", self.id, pprust::pat_to_string(self))
     }
 }
 
@@ -788,10 +787,10 @@ fn repr(&self, tcx: &ctxt) -> String {
 
 impl Repr for ty::Variance {
     fn repr(&self, _: &ctxt) -> String {
-        // The first `.to_str()` returns a &'static str (it is not an implementation
-        // of the ToStr trait). Because of that, we need to call `.to_str()` again
+        // The first `.to_string()` returns a &'static str (it is not an implementation
+        // of the ToString trait). Because of that, we need to call `.to_string()` again
         // if we want to have a `String`.
-        self.to_str().to_str()
+        self.to_string().to_string()
     }
 }
 
@@ -836,14 +835,14 @@ impl Repr for ty::BareFnTy {
     fn repr(&self, tcx: &ctxt) -> String {
         format!("BareFnTy {{fn_style: {:?}, abi: {}, sig: {}}}",
                 self.fn_style,
-                self.abi.to_str(),
+                self.abi.to_string(),
                 self.sig.repr(tcx))
     }
 }
 
 impl Repr for ty::FnSig {
     fn repr(&self, tcx: &ctxt) -> String {
-        fn_sig_to_str(tcx, self)
+        fn_sig_to_string(tcx, self)
     }
 }
 
@@ -893,7 +892,7 @@ fn repr(&self, tcx: &ctxt) -> String {
 
 impl Repr for ty::TraitStore {
     fn repr(&self, tcx: &ctxt) -> String {
-        trait_store_to_str(tcx, *self)
+        trait_store_to_string(tcx, *self)
     }
 }
 
@@ -923,7 +922,7 @@ fn repr(&self, tcx: &ctxt) -> String {
 
 impl Repr for Span {
     fn repr(&self, tcx: &ctxt) -> String {
-        tcx.sess.codemap().span_to_str(*self).to_string()
+        tcx.sess.codemap().span_to_string(*self).to_string()
     }
 }
 
@@ -954,7 +953,7 @@ fn user_string(&self, tcx: &ctxt) -> String {
 
 impl UserString for ty::t {
     fn user_string(&self, tcx: &ctxt) -> String {
-        ty_to_str(tcx, *self)
+        ty_to_string(tcx, *self)
     }
 }
 
@@ -966,13 +965,13 @@ fn user_string(&self, _tcx: &ctxt) -> String {
 
 impl Repr for abi::Abi {
     fn repr(&self, _tcx: &ctxt) -> String {
-        self.to_str()
+        self.to_string()
     }
 }
 
 impl UserString for abi::Abi {
     fn user_string(&self, _tcx: &ctxt) -> String {
-        self.to_str()
+        self.to_string()
     }
 }
 
diff --git a/src/librustc/util/sha2.rs b/src/librustc/util/sha2.rs
deleted file mode 100644 (file)
index bfd3deb..0000000
+++ /dev/null
@@ -1,680 +0,0 @@
-// Copyright 2012-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.
-
-//! This module implements only the Sha256 function since that is all that is needed for internal
-//! use. This implementation is not intended for external use or for any use where security is
-//! important.
-
-use std::iter::range_step;
-use std::num::Zero;
-use std::slice::bytes::{MutableByteVector, copy_memory};
-use serialize::hex::ToHex;
-
-/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
-/// format.
-fn write_u32_be(dst: &mut[u8], input: u32) {
-    use std::mem::to_be32;
-    assert!(dst.len() == 4);
-    unsafe {
-        let x = dst.unsafe_mut_ref(0) as *mut _ as *mut u32;
-        *x = to_be32(input);
-    }
-}
-
-/// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
-fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
-    use std::mem::to_be32;
-    assert!(dst.len() * 4 == input.len());
-    unsafe {
-        let mut x = dst.unsafe_mut_ref(0) as *mut _ as *mut u32;
-        let mut y = input.unsafe_ref(0) as *const _ as *const u32;
-        for _ in range(0, dst.len()) {
-            *x = to_be32(*y);
-            x = x.offset(1);
-            y = y.offset(1);
-        }
-    }
-}
-
-trait ToBits {
-    /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
-    /// high-order value and the 2nd item is the low order value.
-    fn to_bits(self) -> (Self, Self);
-}
-
-impl ToBits for u64 {
-    fn to_bits(self) -> (u64, u64) {
-        return (self >> 61, self << 3);
-    }
-}
-
-/// Adds the specified number of bytes to the bit count. fail!() if this would cause numeric
-/// overflow.
-fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T {
-    let (new_high_bits, new_low_bits) = bytes.to_bits();
-
-    if new_high_bits > Zero::zero() {
-        fail!("numeric overflow occurred.")
-    }
-
-    match bits.checked_add(&new_low_bits) {
-        Some(x) => return x,
-        None => fail!("numeric overflow occurred.")
-    }
-}
-
-/// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it
-/// must be processed. The input() method takes care of processing and then clearing the buffer
-/// automatically. However, other methods do not and require the caller to process the buffer. Any
-/// method that modifies the buffer directory or provides the caller with bytes that can be modified
-/// results in those bytes being marked as used by the buffer.
-trait FixedBuffer {
-    /// Input a vector of bytes. If the buffer becomes full, process it with the provided
-    /// function and then clear the buffer.
-    fn input(&mut self, input: &[u8], func: |&[u8]|);
-
-    /// Reset the buffer.
-    fn reset(&mut self);
-
-    /// Zero the buffer up until the specified index. The buffer position currently must not be
-    /// greater than that index.
-    fn zero_until(&mut self, idx: uint);
-
-    /// Get a slice of the buffer of the specified size. There must be at least that many bytes
-    /// remaining in the buffer.
-    fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8];
-
-    /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
-    fn full_buffer<'s>(&'s mut self) -> &'s [u8];
-
-    /// Get the current position of the buffer.
-    fn position(&self) -> uint;
-
-    /// Get the number of bytes remaining in the buffer until it is full.
-    fn remaining(&self) -> uint;
-
-    /// Get the size of the buffer
-    fn size(&self) -> uint;
-}
-
-/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
-struct FixedBuffer64 {
-    buffer: [u8, ..64],
-    buffer_idx: uint,
-}
-
-impl FixedBuffer64 {
-    /// Create a new FixedBuffer64
-    fn new() -> FixedBuffer64 {
-        return FixedBuffer64 {
-            buffer: [0u8, ..64],
-            buffer_idx: 0
-        };
-    }
-}
-
-impl FixedBuffer for FixedBuffer64 {
-    fn input(&mut self, input: &[u8], func: |&[u8]|) {
-        let mut i = 0;
-
-        let size = self.size();
-
-        // If there is already data in the buffer, copy as much as we can into it and process
-        // the data if the buffer becomes full.
-        if self.buffer_idx != 0 {
-            let buffer_remaining = size - self.buffer_idx;
-            if input.len() >= buffer_remaining {
-                    copy_memory(
-                        self.buffer.mut_slice(self.buffer_idx, size),
-                        input.slice_to(buffer_remaining));
-                self.buffer_idx = 0;
-                func(self.buffer);
-                i += buffer_remaining;
-            } else {
-                copy_memory(
-                    self.buffer.mut_slice(self.buffer_idx, self.buffer_idx + input.len()),
-                    input);
-                self.buffer_idx += input.len();
-                return;
-            }
-        }
-
-        // While we have at least a full buffer size chunk's worth of data, process that data
-        // without copying it into the buffer
-        while input.len() - i >= size {
-            func(input.slice(i, i + size));
-            i += size;
-        }
-
-        // Copy any input data into the buffer. At this point in the method, the amount of
-        // data left in the input vector will be less than the buffer size and the buffer will
-        // be empty.
-        let input_remaining = input.len() - i;
-        copy_memory(
-            self.buffer.mut_slice(0, input_remaining),
-            input.slice_from(i));
-        self.buffer_idx += input_remaining;
-    }
-
-    fn reset(&mut self) {
-        self.buffer_idx = 0;
-    }
-
-    fn zero_until(&mut self, idx: uint) {
-        assert!(idx >= self.buffer_idx);
-        self.buffer.mut_slice(self.buffer_idx, idx).set_memory(0);
-        self.buffer_idx = idx;
-    }
-
-    fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] {
-        self.buffer_idx += len;
-        return self.buffer.mut_slice(self.buffer_idx - len, self.buffer_idx);
-    }
-
-    fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
-        assert!(self.buffer_idx == 64);
-        self.buffer_idx = 0;
-        return self.buffer.slice_to(64);
-    }
-
-    fn position(&self) -> uint { self.buffer_idx }
-
-    fn remaining(&self) -> uint { 64 - self.buffer_idx }
-
-    fn size(&self) -> uint { 64 }
-}
-
-/// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct.
-trait StandardPadding {
-    /// Add padding to the buffer. The buffer must not be full when this method is called and is
-    /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
-    /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
-    /// with zeros again until only rem bytes are remaining.
-    fn standard_padding(&mut self, rem: uint, func: |&[u8]|);
-}
-
-impl <T: FixedBuffer> StandardPadding for T {
-    fn standard_padding(&mut self, rem: uint, func: |&[u8]|) {
-        let size = self.size();
-
-        self.next(1)[0] = 128;
-
-        if self.remaining() < rem {
-            self.zero_until(size);
-            func(self.full_buffer());
-        }
-
-        self.zero_until(size - rem);
-    }
-}
-
-/// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
-/// family of digest functions.
-pub trait Digest {
-    /// Provide message data.
-    ///
-    /// # Arguments
-    ///
-    /// * input - A vector of message data
-    fn input(&mut self, input: &[u8]);
-
-    /// Retrieve the digest result. This method may be called multiple times.
-    ///
-    /// # Arguments
-    ///
-    /// * out - the vector to hold the result. Must be large enough to contain output_bits().
-    fn result(&mut self, out: &mut [u8]);
-
-    /// Reset the digest. This method must be called after result() and before supplying more
-    /// data.
-    fn reset(&mut self);
-
-    /// Get the output size in bits.
-    fn output_bits(&self) -> uint;
-
-    /// Convenience function that feeds a string into a digest.
-    ///
-    /// # Arguments
-    ///
-    /// * `input` The string to feed into the digest
-    fn input_str(&mut self, input: &str) {
-        self.input(input.as_bytes());
-    }
-
-    /// Convenience function that retrieves the result of a digest as a
-    /// newly allocated vec of bytes.
-    fn result_bytes(&mut self) -> Vec<u8> {
-        let mut buf = Vec::from_elem((self.output_bits()+7)/8, 0u8);
-        self.result(buf.as_mut_slice());
-        buf
-    }
-
-    /// Convenience function that retrieves the result of a digest as a
-    /// String in hexadecimal format.
-    fn result_str(&mut self) -> String {
-        self.result_bytes().as_slice().to_hex().to_string()
-    }
-}
-
-// A structure that represents that state of a digest computation for the SHA-2 512 family of digest
-// functions
-struct Engine256State {
-    h0: u32,
-    h1: u32,
-    h2: u32,
-    h3: u32,
-    h4: u32,
-    h5: u32,
-    h6: u32,
-    h7: u32,
-}
-
-impl Engine256State {
-    fn new(h: &[u32, ..8]) -> Engine256State {
-        return Engine256State {
-            h0: h[0],
-            h1: h[1],
-            h2: h[2],
-            h3: h[3],
-            h4: h[4],
-            h5: h[5],
-            h6: h[6],
-            h7: h[7]
-        };
-    }
-
-    fn reset(&mut self, h: &[u32, ..8]) {
-        self.h0 = h[0];
-        self.h1 = h[1];
-        self.h2 = h[2];
-        self.h3 = h[3];
-        self.h4 = h[4];
-        self.h5 = h[5];
-        self.h6 = h[6];
-        self.h7 = h[7];
-    }
-
-    fn process_block(&mut self, data: &[u8]) {
-        fn ch(x: u32, y: u32, z: u32) -> u32 {
-            ((x & y) ^ ((!x) & z))
-        }
-
-        fn maj(x: u32, y: u32, z: u32) -> u32 {
-            ((x & y) ^ (x & z) ^ (y & z))
-        }
-
-        fn sum0(x: u32) -> u32 {
-            ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))
-        }
-
-        fn sum1(x: u32) -> u32 {
-            ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))
-        }
-
-        fn sigma0(x: u32) -> u32 {
-            ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3)
-        }
-
-        fn sigma1(x: u32) -> u32 {
-            ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10)
-        }
-
-        let mut a = self.h0;
-        let mut b = self.h1;
-        let mut c = self.h2;
-        let mut d = self.h3;
-        let mut e = self.h4;
-        let mut f = self.h5;
-        let mut g = self.h6;
-        let mut h = self.h7;
-
-        let mut w = [0u32, ..64];
-
-        // Sha-512 and Sha-256 use basically the same calculations which are implemented
-        // by these macros. Inlining the calculations seems to result in better generated code.
-        macro_rules! schedule_round( ($t:expr) => (
-                w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
-                )
-        )
-
-        macro_rules! sha2_round(
-            ($A:ident, $B:ident, $C:ident, $D:ident,
-             $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
-                {
-                    $H += sum1($E) + ch($E, $F, $G) + $K[$t] + w[$t];
-                    $D += $H;
-                    $H += sum0($A) + maj($A, $B, $C);
-                }
-             )
-        )
-
-        read_u32v_be(w.mut_slice(0, 16), data);
-
-        // Putting the message schedule inside the same loop as the round calculations allows for
-        // the compiler to generate better code.
-        for t in range_step(0u, 48, 8) {
-            schedule_round!(t + 16);
-            schedule_round!(t + 17);
-            schedule_round!(t + 18);
-            schedule_round!(t + 19);
-            schedule_round!(t + 20);
-            schedule_round!(t + 21);
-            schedule_round!(t + 22);
-            schedule_round!(t + 23);
-
-            sha2_round!(a, b, c, d, e, f, g, h, K32, t);
-            sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
-            sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
-            sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
-            sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
-            sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
-            sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
-            sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
-        }
-
-        for t in range_step(48u, 64, 8) {
-            sha2_round!(a, b, c, d, e, f, g, h, K32, t);
-            sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
-            sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
-            sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
-            sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
-            sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
-            sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
-            sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
-        }
-
-        self.h0 += a;
-        self.h1 += b;
-        self.h2 += c;
-        self.h3 += d;
-        self.h4 += e;
-        self.h5 += f;
-        self.h6 += g;
-        self.h7 += h;
-    }
-}
-
-static K32: [u32, ..64] = [
-    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
-    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
-    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
-    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
-    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
-    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
-    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-];
-
-// A structure that keeps track of the state of the Sha-256 operation and contains the logic
-// necessary to perform the final calculations.
-struct Engine256 {
-    length_bits: u64,
-    buffer: FixedBuffer64,
-    state: Engine256State,
-    finished: bool,
-}
-
-impl Engine256 {
-    fn new(h: &[u32, ..8]) -> Engine256 {
-        return Engine256 {
-            length_bits: 0,
-            buffer: FixedBuffer64::new(),
-            state: Engine256State::new(h),
-            finished: false
-        }
-    }
-
-    fn reset(&mut self, h: &[u32, ..8]) {
-        self.length_bits = 0;
-        self.buffer.reset();
-        self.state.reset(h);
-        self.finished = false;
-    }
-
-    fn input(&mut self, input: &[u8]) {
-        assert!(!self.finished)
-        // Assumes that input.len() can be converted to u64 without overflow
-        self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);
-        let self_state = &mut self.state;
-        self.buffer.input(input, |input: &[u8]| { self_state.process_block(input) });
-    }
-
-    fn finish(&mut self) {
-        if self.finished {
-            return;
-        }
-
-        let self_state = &mut self.state;
-        self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) });
-        write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 );
-        write_u32_be(self.buffer.next(4), self.length_bits as u32);
-        self_state.process_block(self.buffer.full_buffer());
-
-        self.finished = true;
-    }
-}
-
-/// The SHA-256 hash algorithm
-pub struct Sha256 {
-    engine: Engine256
-}
-
-impl Sha256 {
-    /// Construct a new instance of a SHA-256 digest.
-    pub fn new() -> Sha256 {
-        Sha256 {
-            engine: Engine256::new(&H256)
-        }
-    }
-}
-
-impl Digest for Sha256 {
-    fn input(&mut self, d: &[u8]) {
-        self.engine.input(d);
-    }
-
-    fn result(&mut self, out: &mut [u8]) {
-        self.engine.finish();
-
-        write_u32_be(out.mut_slice(0, 4), self.engine.state.h0);
-        write_u32_be(out.mut_slice(4, 8), self.engine.state.h1);
-        write_u32_be(out.mut_slice(8, 12), self.engine.state.h2);
-        write_u32_be(out.mut_slice(12, 16), self.engine.state.h3);
-        write_u32_be(out.mut_slice(16, 20), self.engine.state.h4);
-        write_u32_be(out.mut_slice(20, 24), self.engine.state.h5);
-        write_u32_be(out.mut_slice(24, 28), self.engine.state.h6);
-        write_u32_be(out.mut_slice(28, 32), self.engine.state.h7);
-    }
-
-    fn reset(&mut self) {
-        self.engine.reset(&H256);
-    }
-
-    fn output_bits(&self) -> uint { 256 }
-}
-
-static H256: [u32, ..8] = [
-    0x6a09e667,
-    0xbb67ae85,
-    0x3c6ef372,
-    0xa54ff53a,
-    0x510e527f,
-    0x9b05688c,
-    0x1f83d9ab,
-    0x5be0cd19
-];
-
-#[cfg(test)]
-mod tests {
-    extern crate rand;
-
-    use super::{Digest, Sha256, FixedBuffer};
-    use std::num::Bounded;
-    use self::rand::isaac::IsaacRng;
-    use self::rand::Rng;
-    use serialize::hex::FromHex;
-
-    // A normal addition - no overflow occurs
-    #[test]
-    fn test_add_bytes_to_bits_ok() {
-        assert!(super::add_bytes_to_bits::<u64>(100, 10) == 180);
-    }
-
-    // A simple failure case - adding 1 to the max value
-    #[test]
-    #[should_fail]
-    fn test_add_bytes_to_bits_overflow() {
-        super::add_bytes_to_bits::<u64>(Bounded::max_value(), 1);
-    }
-
-    struct Test {
-        input: String,
-        output_str: String,
-    }
-
-    fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
-        // Test that it works when accepting the message all at once
-        for t in tests.iter() {
-            sh.reset();
-            sh.input_str(t.input.as_slice());
-            let out_str = sh.result_str();
-            assert!(out_str == t.output_str);
-        }
-
-        // Test that it works when accepting the message in pieces
-        for t in tests.iter() {
-            sh.reset();
-            let len = t.input.len();
-            let mut left = len;
-            while left > 0u {
-                let take = (left + 1u) / 2u;
-                sh.input_str(t.input
-                              .as_slice()
-                              .slice(len - left, take + len - left));
-                left = left - take;
-            }
-            let out_str = sh.result_str();
-            assert!(out_str == t.output_str);
-        }
-    }
-
-    #[test]
-    fn test_sha256() {
-        // Examples from wikipedia
-        let wikipedia_tests = vec!(
-            Test {
-                input: "".to_string(),
-                output_str: "e3b0c44298fc1c149afb\
-            f4c8996fb92427ae41e4649b934ca495991b7852b855".to_string()
-            },
-            Test {
-                input: "The quick brown fox jumps over the lazy \
-                        dog".to_string(),
-                output_str: "d7a8fbb307d7809469ca\
-            9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592".to_string()
-            },
-            Test {
-                input: "The quick brown fox jumps over the lazy \
-                        dog.".to_string(),
-                output_str: "ef537f25c895bfa78252\
-            6529a9b63d97aa631564d5d789c2b765448c8635fb6c".to_string()
-            });
-
-        let tests = wikipedia_tests;
-
-        let mut sh = box Sha256::new();
-
-        test_hash(&mut *sh, tests.as_slice());
-    }
-
-    /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
-    /// correct.
-    fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, expected: &str) {
-        let total_size = 1000000;
-        let buffer = Vec::from_elem(blocksize * 2, 'a' as u8);
-        let mut rng = IsaacRng::new_unseeded();
-        let mut count = 0;
-
-        digest.reset();
-
-        while count < total_size {
-            let next: uint = rng.gen_range(0, 2 * blocksize + 1);
-            let remaining = total_size - count;
-            let size = if next > remaining { remaining } else { next };
-            digest.input(buffer.slice_to(size));
-            count += size;
-        }
-
-        let result_str = digest.result_str();
-        let result_bytes = digest.result_bytes();
-
-        assert_eq!(expected, result_str.as_slice());
-
-        let expected_vec: Vec<u8> = expected.from_hex()
-                                            .unwrap()
-                                            .move_iter()
-                                            .collect();
-        assert_eq!(expected_vec, result_bytes);
-    }
-
-    #[test]
-    fn test_1million_random_sha256() {
-        let mut sh = Sha256::new();
-        test_digest_1million_random(
-            &mut sh,
-            64,
-            "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::Bencher;
-    use super::{Sha256, FixedBuffer, Digest};
-
-    #[bench]
-    pub fn sha256_10(b: &mut Bencher) {
-        let mut sh = Sha256::new();
-        let bytes = [1u8, ..10];
-        b.iter(|| {
-            sh.input(bytes);
-        });
-        b.bytes = bytes.len() as u64;
-    }
-
-    #[bench]
-    pub fn sha256_1k(b: &mut Bencher) {
-        let mut sh = Sha256::new();
-        let bytes = [1u8, ..1024];
-        b.iter(|| {
-            sh.input(bytes);
-        });
-        b.bytes = bytes.len() as u64;
-    }
-
-    #[bench]
-    pub fn sha256_64k(b: &mut Bencher) {
-        let mut sh = Sha256::new();
-        let bytes = [1u8, ..65536];
-        b.iter(|| {
-            sh.input(bytes);
-        });
-        b.bytes = bytes.len() as u64;
-    }
-}
diff --git a/src/librustc_back/abi.rs b/src/librustc_back/abi.rs
new file mode 100644 (file)
index 0000000..c722beb
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub static box_field_refcnt: uint = 0u;
+pub static box_field_tydesc: uint = 1u;
+pub static box_field_body: uint = 4u;
+
+pub static tydesc_field_visit_glue: uint = 3u;
+
+// The two halves of a closure: code and environment.
+pub static fn_field_code: uint = 0u;
+pub static fn_field_box: uint = 1u;
+
+// The two fields of a trait object/trait instance: vtable and box.
+// The vtable contains the type descriptor as first element.
+pub static trt_field_vtable: uint = 0u;
+pub static trt_field_box: uint = 1u;
+
+pub static vec_elt_fill: uint = 0u;
+
+pub static vec_elt_alloc: uint = 1u;
+
+pub static vec_elt_elems: uint = 2u;
+
+pub static slice_elt_base: uint = 0u;
+pub static slice_elt_len: uint = 1u;
diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs
new file mode 100644 (file)
index 0000000..c4a9d9c
--- /dev/null
@@ -0,0 +1,231 @@
+// Copyright 2013-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.
+
+//! A helper class for dealing with static archives
+
+use std::io::process::{Command, ProcessOutput};
+use std::io::{fs, TempDir};
+use std::io;
+use std::os;
+use std::str;
+use syntax::abi;
+use ErrorHandler = syntax::diagnostic::Handler;
+
+pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";
+
+pub struct ArchiveConfig<'a> {
+    pub handler: &'a ErrorHandler,
+    pub dst: Path,
+    pub lib_search_paths: Vec<Path>,
+    pub os: abi::Os,
+    pub maybe_ar_prog: Option<String>
+}
+
+pub struct Archive<'a> {
+    handler: &'a ErrorHandler,
+    dst: Path,
+    lib_search_paths: Vec<Path>,
+    os: abi::Os,
+    maybe_ar_prog: Option<String>
+}
+
+fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
+          args: &str, cwd: Option<&Path>,
+          paths: &[&Path]) -> ProcessOutput {
+    let ar = match *maybe_ar_prog {
+        Some(ref ar) => ar.as_slice(),
+        None => "ar"
+    };
+    let mut cmd = Command::new(ar);
+
+    cmd.arg(args).args(paths);
+    debug!("{}", cmd);
+
+    match cwd {
+        Some(p) => {
+            cmd.cwd(p);
+            debug!("inside {}", p.display());
+        }
+        None => {}
+    }
+
+    match cmd.spawn() {
+        Ok(prog) => {
+            let o = prog.wait_with_output().unwrap();
+            if !o.status.success() {
+                handler.err(format!("{} failed with: {}",
+                                 cmd,
+                                 o.status).as_slice());
+                handler.note(format!("stdout ---\n{}",
+                                  str::from_utf8(o.output
+                                                  .as_slice()).unwrap())
+                          .as_slice());
+                handler.note(format!("stderr ---\n{}",
+                                  str::from_utf8(o.error
+                                                  .as_slice()).unwrap())
+                          .as_slice());
+                handler.abort_if_errors();
+            }
+            o
+        },
+        Err(e) => {
+            handler.err(format!("could not exec `{}`: {}", ar.as_slice(),
+                             e).as_slice());
+            handler.abort_if_errors();
+            fail!("rustc::back::archive::run_ar() should not reach this point");
+        }
+    }
+}
+
+impl<'a> Archive<'a> {
+    /// Initializes a new static archive with the given object file
+    pub fn create<'b>(config: ArchiveConfig<'a>, initial_object: &'b Path) -> Archive<'a> {
+        let ArchiveConfig { handler, dst, lib_search_paths, os, maybe_ar_prog } = config;
+        run_ar(handler, &maybe_ar_prog, "crus", None, [&dst, initial_object]);
+        Archive {
+            handler: handler,
+            dst: dst,
+            lib_search_paths: lib_search_paths,
+            os: os,
+            maybe_ar_prog: maybe_ar_prog
+        }
+    }
+
+    /// Opens an existing static archive
+    pub fn open(config: ArchiveConfig<'a>) -> Archive<'a> {
+        let ArchiveConfig { handler, dst, lib_search_paths, os, maybe_ar_prog } = config;
+        assert!(dst.exists());
+        Archive {
+            handler: handler,
+            dst: dst,
+            lib_search_paths: lib_search_paths,
+            os: os,
+            maybe_ar_prog: maybe_ar_prog
+        }
+    }
+
+    /// Adds all of the contents of a native library to this archive. This will
+    /// search in the relevant locations for a library named `name`.
+    pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
+        let location = self.find_library(name);
+        self.add_archive(&location, name, [])
+    }
+
+    /// Adds all of the contents of the rlib at the specified path to this
+    /// archive.
+    ///
+    /// This ignores adding the bytecode from the rlib, and if LTO is enabled
+    /// then the object file also isn't added.
+    pub fn add_rlib(&mut self, rlib: &Path, name: &str,
+                    lto: bool) -> io::IoResult<()> {
+        let object = format!("{}.o", name);
+        let bytecode = format!("{}.bytecode.deflate", name);
+        let mut ignore = vec!(bytecode.as_slice(), METADATA_FILENAME);
+        if lto {
+            ignore.push(object.as_slice());
+        }
+        self.add_archive(rlib, name, ignore.as_slice())
+    }
+
+    /// Adds an arbitrary file to this archive
+    pub fn add_file(&mut self, file: &Path, has_symbols: bool) {
+        let cmd = if has_symbols {"r"} else {"rS"};
+        run_ar(self.handler, &self.maybe_ar_prog, cmd, None, [&self.dst, file]);
+    }
+
+    /// Removes a file from this archive
+    pub fn remove_file(&mut self, file: &str) {
+        run_ar(self.handler, &self.maybe_ar_prog, "d", None, [&self.dst, &Path::new(file)]);
+    }
+
+    /// Updates all symbols in the archive (runs 'ar s' over it)
+    pub fn update_symbols(&mut self) {
+        run_ar(self.handler, &self.maybe_ar_prog, "s", None, [&self.dst]);
+    }
+
+    /// Lists all files in an archive
+    pub fn files(&self) -> Vec<String> {
+        let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, [&self.dst]);
+        let output = str::from_utf8(output.output.as_slice()).unwrap();
+        // use lines_any because windows delimits output with `\r\n` instead of
+        // just `\n`
+        output.lines_any().map(|s| s.to_string()).collect()
+    }
+
+    fn add_archive(&mut self, archive: &Path, name: &str,
+                   skip: &[&str]) -> io::IoResult<()> {
+        let loc = TempDir::new("rsar").unwrap();
+
+        // First, extract the contents of the archive to a temporary directory
+        let archive = os::make_absolute(archive);
+        run_ar(self.handler, &self.maybe_ar_prog, "x", Some(loc.path()), [&archive]);
+
+        // Next, we must rename all of the inputs to "guaranteed unique names".
+        // The reason for this is that archives are keyed off the name of the
+        // files, so if two files have the same name they will override one
+        // another in the archive (bad).
+        //
+        // We skip any files explicitly desired for skipping, and we also skip
+        // all SYMDEF files as these are just magical placeholders which get
+        // re-created when we make a new archive anyway.
+        let files = try!(fs::readdir(loc.path()));
+        let mut inputs = Vec::new();
+        for file in files.iter() {
+            let filename = file.filename_str().unwrap();
+            if skip.iter().any(|s| *s == filename) { continue }
+            if filename.contains(".SYMDEF") { continue }
+
+            let filename = format!("r-{}-{}", name, filename);
+            // LLDB (as mentioned in back::link) crashes on filenames of exactly
+            // 16 bytes in length. If we're including an object file with
+            // exactly 16-bytes of characters, give it some prefix so that it's
+            // not 16 bytes.
+            let filename = if filename.len() == 16 {
+                format!("lldb-fix-{}", filename)
+            } else {
+                filename
+            };
+            let new_filename = file.with_filename(filename);
+            try!(fs::rename(file, &new_filename));
+            inputs.push(new_filename);
+        }
+        if inputs.len() == 0 { return Ok(()) }
+
+        // Finally, add all the renamed files to this archive
+        let mut args = vec!(&self.dst);
+        args.extend(inputs.iter());
+        run_ar(self.handler, &self.maybe_ar_prog, "r", None, args.as_slice());
+        Ok(())
+    }
+
+    fn find_library(&self, name: &str) -> Path {
+        let (osprefix, osext) = match self.os {
+            abi::OsWin32 => ("", "lib"), _ => ("lib", "a"),
+        };
+        // On Windows, static libraries sometimes show up as libfoo.a and other
+        // times show up as foo.lib
+        let oslibname = format!("{}{}.{}", osprefix, name, osext);
+        let unixlibname = format!("lib{}.a", name);
+
+        for path in self.lib_search_paths.iter() {
+            debug!("looking for {} inside {}", name, path.display());
+            let test = path.join(oslibname.as_slice());
+            if test.exists() { return test }
+            if oslibname != unixlibname {
+                let test = path.join(unixlibname.as_slice());
+                if test.exists() { return test }
+            }
+        }
+        self.handler.fatal(format!("could not find native static library `{}`, \
+                                 perhaps an -L flag is missing?",
+                                name).as_slice());
+    }
+}
+
diff --git a/src/librustc_back/arm.rs b/src/librustc_back/arm.rs
new file mode 100644 (file)
index 0000000..a073036
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
+    let cc_args = if target_triple.as_slice().contains("thumb") {
+        vec!("-mthumb".to_string())
+    } else {
+        vec!("-marm".to_string())
+    };
+    return target_strs::t {
+        module_asm: "".to_string(),
+
+        data_layout: match target_os {
+          abi::OsMacos => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsiOS => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsWin32 => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsLinux => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsAndroid => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsFreebsd => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+        },
+
+        target_triple: target_triple,
+
+        cc_args: cc_args,
+    };
+}
diff --git a/src/librustc_back/fs.rs b/src/librustc_back/fs.rs
new file mode 100644 (file)
index 0000000..c051b8e
--- /dev/null
@@ -0,0 +1,103 @@
+// 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 std::io;
+use std::io::fs;
+use std::os;
+
+/// Returns an absolute path in the filesystem that `path` points to. The
+/// returned path does not contain any symlinks in its hierarchy.
+pub fn realpath(original: &Path) -> io::IoResult<Path> {
+    static MAX_LINKS_FOLLOWED: uint = 256;
+    let original = os::make_absolute(original);
+
+    // Right now lstat on windows doesn't work quite well
+    if cfg!(windows) {
+        return Ok(original)
+    }
+
+    let result = original.root_path();
+    let mut result = result.expect("make_absolute has no root_path");
+    let mut followed = 0;
+
+    for part in original.components() {
+        result.push(part);
+
+        loop {
+            if followed == MAX_LINKS_FOLLOWED {
+                return Err(io::standard_error(io::InvalidInput))
+            }
+
+            match fs::lstat(&result) {
+                Err(..) => break,
+                Ok(ref stat) if stat.kind != io::TypeSymlink => break,
+                Ok(..) => {
+                    followed += 1;
+                    let path = try!(fs::readlink(&result));
+                    result.pop();
+                    result.push(path);
+                }
+            }
+        }
+    }
+
+    return Ok(result);
+}
+
+#[cfg(not(windows), test)]
+mod test {
+    use std::io;
+    use std::io::fs::{File, symlink, mkdir, mkdir_recursive};
+    use super::realpath;
+    use std::io::TempDir;
+
+    #[test]
+    fn realpath_works() {
+        let tmpdir = TempDir::new("rustc-fs").unwrap();
+        let tmpdir = realpath(tmpdir.path()).unwrap();
+        let file = tmpdir.join("test");
+        let dir = tmpdir.join("test2");
+        let link = dir.join("link");
+        let linkdir = tmpdir.join("test3");
+
+        File::create(&file).unwrap();
+        mkdir(&dir, io::UserRWX).unwrap();
+        symlink(&file, &link).unwrap();
+        symlink(&dir, &linkdir).unwrap();
+
+        assert!(realpath(&tmpdir).unwrap() == tmpdir);
+        assert!(realpath(&file).unwrap() == file);
+        assert!(realpath(&link).unwrap() == file);
+        assert!(realpath(&linkdir).unwrap() == dir);
+        assert!(realpath(&linkdir.join("link")).unwrap() == file);
+    }
+
+    #[test]
+    fn realpath_works_tricky() {
+        let tmpdir = TempDir::new("rustc-fs").unwrap();
+        let tmpdir = realpath(tmpdir.path()).unwrap();
+
+        let a = tmpdir.join("a");
+        let b = a.join("b");
+        let c = b.join("c");
+        let d = a.join("d");
+        let e = d.join("e");
+        let f = a.join("f");
+
+        mkdir_recursive(&b, io::UserRWX).unwrap();
+        mkdir_recursive(&d, io::UserRWX).unwrap();
+        File::create(&f).unwrap();
+        symlink(&Path::new("../d/e"), &c).unwrap();
+        symlink(&Path::new("../f"), &e).unwrap();
+
+        assert!(realpath(&c).unwrap() == f);
+        assert!(realpath(&e).unwrap() == f);
+    }
+}
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
new file mode 100644 (file)
index 0000000..8ec74f4
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Some stuff used by rustc that doesn't have many dependencies
+//!
+//! Originally extracted from rustc::back, which was nominally the
+//! compiler 'backend', though LLVM is rustc's backend, so rustc_back
+//! is really just odds-and-ends relating to code gen and linking.
+//! This crate mostly exists to make rustc smaller, so we might put
+//! more 'stuff' here in the future.  It does not have a dependency on
+//! rustc_llvm.
+//!
+//! FIXME: Split this into two crates: one that has deps on syntax, and
+//! one that doesn't; the one that doesn't might get decent parallel
+//! build speedups.
+
+#![crate_id = "rustc_back#0.11.0-pre"]
+#![crate_name = "rustc_back"]
+#![experimental]
+#![comment = "The Rust compiler minimal-dependency dumping-ground"]
+#![license = "MIT/ASL2"]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+      html_root_url = "http://doc.rust-lang.org/")]
+
+#![feature(globs, phase, macro_rules)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
+
+#[phase(plugin, link)]
+extern crate log;
+extern crate syntax;
+extern crate libc;
+extern crate flate;
+extern crate serialize;
+
+pub mod abi;
+pub mod archive;
+pub mod arm;
+pub mod fs;
+pub mod mips;
+pub mod mipsel;
+pub mod rpath;
+pub mod sha2;
+pub mod svh;
+pub mod target_strs;
+pub mod x86;
+pub mod x86_64;
diff --git a/src/librustc_back/mips.rs b/src/librustc_back/mips.rs
new file mode 100644 (file)
index 0000000..4176d0e
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
+    return target_strs::t {
+        module_asm: "".to_string(),
+
+        data_layout: match target_os {
+          abi::OsMacos => {
+            "E-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsiOS => {
+            "E-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsWin32 => {
+            "E-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsLinux => {
+            "E-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsAndroid => {
+            "E-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsFreebsd => {
+            "E-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+        },
+
+        target_triple: target_triple,
+
+        cc_args: Vec::new(),
+    };
+}
diff --git a/src/librustc_back/mipsel.rs b/src/librustc_back/mipsel.rs
new file mode 100644 (file)
index 0000000..d3ea9d3
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
+    return target_strs::t {
+        module_asm: "".to_string(),
+
+        data_layout: match target_os {
+          abi::OsMacos => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsiOS => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsWin32 => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsLinux => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsAndroid => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+
+          abi::OsFreebsd => {
+            "e-p:32:32:32\
+                -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+                -f32:32:32-f64:64:64\
+                -v64:64:64-v128:64:128\
+                -a0:0:64-n32".to_string()
+          }
+        },
+
+        target_triple: target_triple,
+
+        cc_args: Vec::new(),
+    };
+}
diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs
new file mode 100644 (file)
index 0000000..e298e1d
--- /dev/null
@@ -0,0 +1,238 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use std::collections::HashSet;
+use std::os;
+use std::io::IoError;
+use syntax::abi;
+use syntax::ast;
+
+pub struct RPathConfig<'a> {
+    pub os: abi::Os,
+    pub used_crates: Vec<(ast::CrateNum, Option<Path>)>,
+    pub out_filename: Path,
+    pub get_install_prefix_lib_path: ||:'a -> Path,
+    pub realpath: |&Path|:'a -> Result<Path, IoError>
+}
+
+pub fn get_rpath_flags(config: RPathConfig) -> Vec<String> {
+
+    // No rpath on windows
+    if config.os == abi::OsWin32 {
+        return Vec::new();
+    }
+
+    let mut flags = Vec::new();
+
+    if config.os == abi::OsFreebsd {
+        flags.push_all(["-Wl,-rpath,/usr/local/lib/gcc46".to_string(),
+                        "-Wl,-rpath,/usr/local/lib/gcc44".to_string(),
+                        "-Wl,-z,origin".to_string()]);
+    }
+
+    debug!("preparing the RPATH!");
+
+    let libs = config.used_crates.clone();
+    let libs = libs.move_iter().filter_map(|(_, l)| {
+        l.map(|p| p.clone())
+    }).collect::<Vec<_>>();
+
+    let rpaths = get_rpaths(config, libs.as_slice());
+    flags.push_all(rpaths_to_flags(rpaths.as_slice()).as_slice());
+    flags
+}
+
+fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
+    let mut ret = Vec::new();
+    for rpath in rpaths.iter() {
+        ret.push(format!("-Wl,-rpath,{}", (*rpath).as_slice()));
+    }
+    return ret;
+}
+
+fn get_rpaths(mut config: RPathConfig,
+              libs: &[Path]) -> Vec<String> {
+    debug!("output: {}", config.out_filename.display());
+    debug!("libs:");
+    for libpath in libs.iter() {
+        debug!("    {}", libpath.display());
+    }
+
+    // Use relative paths to the libraries. Binaries can be moved
+    // as long as they maintain the relative relationship to the
+    // crates they depend on.
+    let rel_rpaths = get_rpaths_relative_to_output(&mut config, libs);
+
+    // And a final backup rpath to the global library location.
+    let fallback_rpaths = vec!(get_install_prefix_rpath(config));
+
+    fn log_rpaths(desc: &str, rpaths: &[String]) {
+        debug!("{} rpaths:", desc);
+        for rpath in rpaths.iter() {
+            debug!("    {}", *rpath);
+        }
+    }
+
+    log_rpaths("relative", rel_rpaths.as_slice());
+    log_rpaths("fallback", fallback_rpaths.as_slice());
+
+    let mut rpaths = rel_rpaths;
+    rpaths.push_all(fallback_rpaths.as_slice());
+
+    // Remove duplicates
+    let rpaths = minimize_rpaths(rpaths.as_slice());
+    return rpaths;
+}
+
+fn get_rpaths_relative_to_output(config: &mut RPathConfig,
+                                 libs: &[Path]) -> Vec<String> {
+    libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
+}
+
+fn get_rpath_relative_to_output(config: &mut RPathConfig,
+                                lib: &Path) -> String {
+    use std::os;
+
+    assert!(config.os != abi::OsWin32);
+
+    // Mac doesn't appear to support $ORIGIN
+    let prefix = match config.os {
+        abi::OsAndroid | abi::OsLinux | abi::OsFreebsd
+                          => "$ORIGIN",
+        abi::OsMacos => "@loader_path",
+        abi::OsWin32 | abi::OsiOS => unreachable!()
+    };
+
+    let mut lib = (config.realpath)(&os::make_absolute(lib)).unwrap();
+    lib.pop();
+    let mut output = (config.realpath)(&os::make_absolute(&config.out_filename)).unwrap();
+    output.pop();
+    let relative = lib.path_relative_from(&output);
+    let relative = relative.expect("could not create rpath relative to output");
+    // FIXME (#9639): This needs to handle non-utf8 paths
+    format!("{}/{}",
+            prefix,
+            relative.as_str().expect("non-utf8 component in path"))
+}
+
+fn get_install_prefix_rpath(config: RPathConfig) -> String {
+    let path = (config.get_install_prefix_lib_path)();
+    let path = os::make_absolute(&path);
+    // FIXME (#9639): This needs to handle non-utf8 paths
+    path.as_str().expect("non-utf8 component in rpath").to_string()
+}
+
+fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
+    let mut set = HashSet::new();
+    let mut minimized = Vec::new();
+    for rpath in rpaths.iter() {
+        if set.insert(rpath.as_slice()) {
+            minimized.push(rpath.clone());
+        }
+    }
+    minimized
+}
+
+#[cfg(unix, test)]
+mod test {
+    use super::{RPathConfig};
+    use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
+    use syntax::abi;
+
+    #[test]
+    fn test_rpaths_to_flags() {
+        let flags = rpaths_to_flags([
+            "path1".to_string(),
+            "path2".to_string()
+        ]);
+        assert_eq!(flags,
+                   vec!("-Wl,-rpath,path1".to_string(),
+                        "-Wl,-rpath,path2".to_string()));
+    }
+
+    #[test]
+    fn test_minimize1() {
+        let res = minimize_rpaths([
+            "rpath1".to_string(),
+            "rpath2".to_string(),
+            "rpath1".to_string()
+        ]);
+        assert!(res.as_slice() == [
+            "rpath1".to_string(),
+            "rpath2".to_string()
+        ]);
+    }
+
+    #[test]
+    fn test_minimize2() {
+        let res = minimize_rpaths([
+            "1a".to_string(),
+            "2".to_string(),
+            "2".to_string(),
+            "1a".to_string(),
+            "4a".to_string(),
+            "1a".to_string(),
+            "2".to_string(),
+            "3".to_string(),
+            "4a".to_string(),
+            "3".to_string()
+        ]);
+        assert!(res.as_slice() == [
+            "1a".to_string(),
+            "2".to_string(),
+            "4a".to_string(),
+            "3".to_string()
+        ]);
+    }
+
+    #[test]
+    #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
+    fn test_rpath_relative() {
+        let config = &mut RPathConfig {
+            os: abi::OsLinux,
+            used_crates: Vec::new(),
+            out_filename: Path::new("bin/rustc"),
+            get_install_prefix_lib_path: || fail!(),
+            realpath: |p| Ok(p.clone())
+        };
+        let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
+        assert_eq!(res.as_slice(), "$ORIGIN/../lib");
+    }
+
+    #[test]
+    #[cfg(target_os = "freebsd")]
+    fn test_rpath_relative() {
+        let config = &mut RPathConfig {
+            os: abi::OsFreebsd,
+            used_crates: Vec::new(),
+            out_filename: Path::new("bin/rustc"),
+            get_install_prefix_lib_path: || fail!(),
+            realpath: |p| Ok(p.clone())
+        };
+        let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
+        assert_eq!(res.as_slice(), "$ORIGIN/../lib");
+    }
+
+    #[test]
+    #[cfg(target_os = "macos")]
+    fn test_rpath_relative() {
+        let config = &mut RPathConfig {
+            os: abi::OsMacos,
+            used_crates: Vec::new(),
+            out_filename: Path::new("bin/rustc"),
+            get_install_prefix_lib_path: || fail!(),
+            realpath: |p| Ok(p.clone())
+        };
+        let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
+        assert_eq!(res.as_slice(), "@loader_path/../lib");
+    }
+}
diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs
new file mode 100644 (file)
index 0000000..681de6a
--- /dev/null
@@ -0,0 +1,682 @@
+// Copyright 2012-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.
+
+//! This module implements only the Sha256 function since that is all that is needed for internal
+//! use. This implementation is not intended for external use or for any use where security is
+//! important.
+
+#![allow(deprecated)] // to_be32
+
+use std::iter::range_step;
+use std::num::Zero;
+use std::slice::bytes::{MutableByteVector, copy_memory};
+use serialize::hex::ToHex;
+
+/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
+/// format.
+fn write_u32_be(dst: &mut[u8], input: u32) {
+    use std::mem::to_be32;
+    assert!(dst.len() == 4);
+    unsafe {
+        let x = dst.unsafe_mut_ref(0) as *mut _ as *mut u32;
+        *x = to_be32(input);
+    }
+}
+
+/// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
+fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
+    use std::mem::to_be32;
+    assert!(dst.len() * 4 == input.len());
+    unsafe {
+        let mut x = dst.unsafe_mut_ref(0) as *mut _ as *mut u32;
+        let mut y = input.unsafe_ref(0) as *const _ as *const u32;
+        for _ in range(0, dst.len()) {
+            *x = to_be32(*y);
+            x = x.offset(1);
+            y = y.offset(1);
+        }
+    }
+}
+
+trait ToBits {
+    /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
+    /// high-order value and the 2nd item is the low order value.
+    fn to_bits(self) -> (Self, Self);
+}
+
+impl ToBits for u64 {
+    fn to_bits(self) -> (u64, u64) {
+        return (self >> 61, self << 3);
+    }
+}
+
+/// Adds the specified number of bytes to the bit count. fail!() if this would cause numeric
+/// overflow.
+fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T {
+    let (new_high_bits, new_low_bits) = bytes.to_bits();
+
+    if new_high_bits > Zero::zero() {
+        fail!("numeric overflow occurred.")
+    }
+
+    match bits.checked_add(&new_low_bits) {
+        Some(x) => return x,
+        None => fail!("numeric overflow occurred.")
+    }
+}
+
+/// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it
+/// must be processed. The input() method takes care of processing and then clearing the buffer
+/// automatically. However, other methods do not and require the caller to process the buffer. Any
+/// method that modifies the buffer directory or provides the caller with bytes that can be modified
+/// results in those bytes being marked as used by the buffer.
+trait FixedBuffer {
+    /// Input a vector of bytes. If the buffer becomes full, process it with the provided
+    /// function and then clear the buffer.
+    fn input(&mut self, input: &[u8], func: |&[u8]|);
+
+    /// Reset the buffer.
+    fn reset(&mut self);
+
+    /// Zero the buffer up until the specified index. The buffer position currently must not be
+    /// greater than that index.
+    fn zero_until(&mut self, idx: uint);
+
+    /// Get a slice of the buffer of the specified size. There must be at least that many bytes
+    /// remaining in the buffer.
+    fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8];
+
+    /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
+    fn full_buffer<'s>(&'s mut self) -> &'s [u8];
+
+    /// Get the current position of the buffer.
+    fn position(&self) -> uint;
+
+    /// Get the number of bytes remaining in the buffer until it is full.
+    fn remaining(&self) -> uint;
+
+    /// Get the size of the buffer
+    fn size(&self) -> uint;
+}
+
+/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
+struct FixedBuffer64 {
+    buffer: [u8, ..64],
+    buffer_idx: uint,
+}
+
+impl FixedBuffer64 {
+    /// Create a new FixedBuffer64
+    fn new() -> FixedBuffer64 {
+        return FixedBuffer64 {
+            buffer: [0u8, ..64],
+            buffer_idx: 0
+        };
+    }
+}
+
+impl FixedBuffer for FixedBuffer64 {
+    fn input(&mut self, input: &[u8], func: |&[u8]|) {
+        let mut i = 0;
+
+        let size = self.size();
+
+        // If there is already data in the buffer, copy as much as we can into it and process
+        // the data if the buffer becomes full.
+        if self.buffer_idx != 0 {
+            let buffer_remaining = size - self.buffer_idx;
+            if input.len() >= buffer_remaining {
+                    copy_memory(
+                        self.buffer.mut_slice(self.buffer_idx, size),
+                        input.slice_to(buffer_remaining));
+                self.buffer_idx = 0;
+                func(self.buffer);
+                i += buffer_remaining;
+            } else {
+                copy_memory(
+                    self.buffer.mut_slice(self.buffer_idx, self.buffer_idx + input.len()),
+                    input);
+                self.buffer_idx += input.len();
+                return;
+            }
+        }
+
+        // While we have at least a full buffer size chunk's worth of data, process that data
+        // without copying it into the buffer
+        while input.len() - i >= size {
+            func(input.slice(i, i + size));
+            i += size;
+        }
+
+        // Copy any input data into the buffer. At this point in the method, the amount of
+        // data left in the input vector will be less than the buffer size and the buffer will
+        // be empty.
+        let input_remaining = input.len() - i;
+        copy_memory(
+            self.buffer.mut_slice(0, input_remaining),
+            input.slice_from(i));
+        self.buffer_idx += input_remaining;
+    }
+
+    fn reset(&mut self) {
+        self.buffer_idx = 0;
+    }
+
+    fn zero_until(&mut self, idx: uint) {
+        assert!(idx >= self.buffer_idx);
+        self.buffer.mut_slice(self.buffer_idx, idx).set_memory(0);
+        self.buffer_idx = idx;
+    }
+
+    fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] {
+        self.buffer_idx += len;
+        return self.buffer.mut_slice(self.buffer_idx - len, self.buffer_idx);
+    }
+
+    fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
+        assert!(self.buffer_idx == 64);
+        self.buffer_idx = 0;
+        return self.buffer.slice_to(64);
+    }
+
+    fn position(&self) -> uint { self.buffer_idx }
+
+    fn remaining(&self) -> uint { 64 - self.buffer_idx }
+
+    fn size(&self) -> uint { 64 }
+}
+
+/// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct.
+trait StandardPadding {
+    /// Add padding to the buffer. The buffer must not be full when this method is called and is
+    /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
+    /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
+    /// with zeros again until only rem bytes are remaining.
+    fn standard_padding(&mut self, rem: uint, func: |&[u8]|);
+}
+
+impl <T: FixedBuffer> StandardPadding for T {
+    fn standard_padding(&mut self, rem: uint, func: |&[u8]|) {
+        let size = self.size();
+
+        self.next(1)[0] = 128;
+
+        if self.remaining() < rem {
+            self.zero_until(size);
+            func(self.full_buffer());
+        }
+
+        self.zero_until(size - rem);
+    }
+}
+
+/// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
+/// family of digest functions.
+pub trait Digest {
+    /// Provide message data.
+    ///
+    /// # Arguments
+    ///
+    /// * input - A vector of message data
+    fn input(&mut self, input: &[u8]);
+
+    /// Retrieve the digest result. This method may be called multiple times.
+    ///
+    /// # Arguments
+    ///
+    /// * out - the vector to hold the result. Must be large enough to contain output_bits().
+    fn result(&mut self, out: &mut [u8]);
+
+    /// Reset the digest. This method must be called after result() and before supplying more
+    /// data.
+    fn reset(&mut self);
+
+    /// Get the output size in bits.
+    fn output_bits(&self) -> uint;
+
+    /// Convenience function that feeds a string into a digest.
+    ///
+    /// # Arguments
+    ///
+    /// * `input` The string to feed into the digest
+    fn input_str(&mut self, input: &str) {
+        self.input(input.as_bytes());
+    }
+
+    /// Convenience function that retrieves the result of a digest as a
+    /// newly allocated vec of bytes.
+    fn result_bytes(&mut self) -> Vec<u8> {
+        let mut buf = Vec::from_elem((self.output_bits()+7)/8, 0u8);
+        self.result(buf.as_mut_slice());
+        buf
+    }
+
+    /// Convenience function that retrieves the result of a digest as a
+    /// String in hexadecimal format.
+    fn result_str(&mut self) -> String {
+        self.result_bytes().as_slice().to_hex().to_string()
+    }
+}
+
+// A structure that represents that state of a digest computation for the SHA-2 512 family of digest
+// functions
+struct Engine256State {
+    h0: u32,
+    h1: u32,
+    h2: u32,
+    h3: u32,
+    h4: u32,
+    h5: u32,
+    h6: u32,
+    h7: u32,
+}
+
+impl Engine256State {
+    fn new(h: &[u32, ..8]) -> Engine256State {
+        return Engine256State {
+            h0: h[0],
+            h1: h[1],
+            h2: h[2],
+            h3: h[3],
+            h4: h[4],
+            h5: h[5],
+            h6: h[6],
+            h7: h[7]
+        };
+    }
+
+    fn reset(&mut self, h: &[u32, ..8]) {
+        self.h0 = h[0];
+        self.h1 = h[1];
+        self.h2 = h[2];
+        self.h3 = h[3];
+        self.h4 = h[4];
+        self.h5 = h[5];
+        self.h6 = h[6];
+        self.h7 = h[7];
+    }
+
+    fn process_block(&mut self, data: &[u8]) {
+        fn ch(x: u32, y: u32, z: u32) -> u32 {
+            ((x & y) ^ ((!x) & z))
+        }
+
+        fn maj(x: u32, y: u32, z: u32) -> u32 {
+            ((x & y) ^ (x & z) ^ (y & z))
+        }
+
+        fn sum0(x: u32) -> u32 {
+            ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))
+        }
+
+        fn sum1(x: u32) -> u32 {
+            ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))
+        }
+
+        fn sigma0(x: u32) -> u32 {
+            ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3)
+        }
+
+        fn sigma1(x: u32) -> u32 {
+            ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10)
+        }
+
+        let mut a = self.h0;
+        let mut b = self.h1;
+        let mut c = self.h2;
+        let mut d = self.h3;
+        let mut e = self.h4;
+        let mut f = self.h5;
+        let mut g = self.h6;
+        let mut h = self.h7;
+
+        let mut w = [0u32, ..64];
+
+        // Sha-512 and Sha-256 use basically the same calculations which are implemented
+        // by these macros. Inlining the calculations seems to result in better generated code.
+        macro_rules! schedule_round( ($t:expr) => (
+                w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
+                )
+        )
+
+        macro_rules! sha2_round(
+            ($A:ident, $B:ident, $C:ident, $D:ident,
+             $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
+                {
+                    $H += sum1($E) + ch($E, $F, $G) + $K[$t] + w[$t];
+                    $D += $H;
+                    $H += sum0($A) + maj($A, $B, $C);
+                }
+             )
+        )
+
+        read_u32v_be(w.mut_slice(0, 16), data);
+
+        // Putting the message schedule inside the same loop as the round calculations allows for
+        // the compiler to generate better code.
+        for t in range_step(0u, 48, 8) {
+            schedule_round!(t + 16);
+            schedule_round!(t + 17);
+            schedule_round!(t + 18);
+            schedule_round!(t + 19);
+            schedule_round!(t + 20);
+            schedule_round!(t + 21);
+            schedule_round!(t + 22);
+            schedule_round!(t + 23);
+
+            sha2_round!(a, b, c, d, e, f, g, h, K32, t);
+            sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
+            sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
+            sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
+            sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
+            sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
+            sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
+            sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
+        }
+
+        for t in range_step(48u, 64, 8) {
+            sha2_round!(a, b, c, d, e, f, g, h, K32, t);
+            sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
+            sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
+            sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
+            sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
+            sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
+            sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
+            sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
+        }
+
+        self.h0 += a;
+        self.h1 += b;
+        self.h2 += c;
+        self.h3 += d;
+        self.h4 += e;
+        self.h5 += f;
+        self.h6 += g;
+        self.h7 += h;
+    }
+}
+
+static K32: [u32, ..64] = [
+    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+];
+
+// A structure that keeps track of the state of the Sha-256 operation and contains the logic
+// necessary to perform the final calculations.
+struct Engine256 {
+    length_bits: u64,
+    buffer: FixedBuffer64,
+    state: Engine256State,
+    finished: bool,
+}
+
+impl Engine256 {
+    fn new(h: &[u32, ..8]) -> Engine256 {
+        return Engine256 {
+            length_bits: 0,
+            buffer: FixedBuffer64::new(),
+            state: Engine256State::new(h),
+            finished: false
+        }
+    }
+
+    fn reset(&mut self, h: &[u32, ..8]) {
+        self.length_bits = 0;
+        self.buffer.reset();
+        self.state.reset(h);
+        self.finished = false;
+    }
+
+    fn input(&mut self, input: &[u8]) {
+        assert!(!self.finished)
+        // Assumes that input.len() can be converted to u64 without overflow
+        self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);
+        let self_state = &mut self.state;
+        self.buffer.input(input, |input: &[u8]| { self_state.process_block(input) });
+    }
+
+    fn finish(&mut self) {
+        if self.finished {
+            return;
+        }
+
+        let self_state = &mut self.state;
+        self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) });
+        write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 );
+        write_u32_be(self.buffer.next(4), self.length_bits as u32);
+        self_state.process_block(self.buffer.full_buffer());
+
+        self.finished = true;
+    }
+}
+
+/// The SHA-256 hash algorithm
+pub struct Sha256 {
+    engine: Engine256
+}
+
+impl Sha256 {
+    /// Construct a new instance of a SHA-256 digest.
+    pub fn new() -> Sha256 {
+        Sha256 {
+            engine: Engine256::new(&H256)
+        }
+    }
+}
+
+impl Digest for Sha256 {
+    fn input(&mut self, d: &[u8]) {
+        self.engine.input(d);
+    }
+
+    fn result(&mut self, out: &mut [u8]) {
+        self.engine.finish();
+
+        write_u32_be(out.mut_slice(0, 4), self.engine.state.h0);
+        write_u32_be(out.mut_slice(4, 8), self.engine.state.h1);
+        write_u32_be(out.mut_slice(8, 12), self.engine.state.h2);
+        write_u32_be(out.mut_slice(12, 16), self.engine.state.h3);
+        write_u32_be(out.mut_slice(16, 20), self.engine.state.h4);
+        write_u32_be(out.mut_slice(20, 24), self.engine.state.h5);
+        write_u32_be(out.mut_slice(24, 28), self.engine.state.h6);
+        write_u32_be(out.mut_slice(28, 32), self.engine.state.h7);
+    }
+
+    fn reset(&mut self) {
+        self.engine.reset(&H256);
+    }
+
+    fn output_bits(&self) -> uint { 256 }
+}
+
+static H256: [u32, ..8] = [
+    0x6a09e667,
+    0xbb67ae85,
+    0x3c6ef372,
+    0xa54ff53a,
+    0x510e527f,
+    0x9b05688c,
+    0x1f83d9ab,
+    0x5be0cd19
+];
+
+#[cfg(test)]
+mod tests {
+    extern crate rand;
+
+    use super::{Digest, Sha256, FixedBuffer};
+    use std::num::Bounded;
+    use self::rand::isaac::IsaacRng;
+    use self::rand::Rng;
+    use serialize::hex::FromHex;
+
+    // A normal addition - no overflow occurs
+    #[test]
+    fn test_add_bytes_to_bits_ok() {
+        assert!(super::add_bytes_to_bits::<u64>(100, 10) == 180);
+    }
+
+    // A simple failure case - adding 1 to the max value
+    #[test]
+    #[should_fail]
+    fn test_add_bytes_to_bits_overflow() {
+        super::add_bytes_to_bits::<u64>(Bounded::max_value(), 1);
+    }
+
+    struct Test {
+        input: String,
+        output_str: String,
+    }
+
+    fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
+        // Test that it works when accepting the message all at once
+        for t in tests.iter() {
+            sh.reset();
+            sh.input_str(t.input.as_slice());
+            let out_str = sh.result_str();
+            assert!(out_str == t.output_str);
+        }
+
+        // Test that it works when accepting the message in pieces
+        for t in tests.iter() {
+            sh.reset();
+            let len = t.input.len();
+            let mut left = len;
+            while left > 0u {
+                let take = (left + 1u) / 2u;
+                sh.input_str(t.input
+                              .as_slice()
+                              .slice(len - left, take + len - left));
+                left = left - take;
+            }
+            let out_str = sh.result_str();
+            assert!(out_str == t.output_str);
+        }
+    }
+
+    #[test]
+    fn test_sha256() {
+        // Examples from wikipedia
+        let wikipedia_tests = vec!(
+            Test {
+                input: "".to_string(),
+                output_str: "e3b0c44298fc1c149afb\
+            f4c8996fb92427ae41e4649b934ca495991b7852b855".to_string()
+            },
+            Test {
+                input: "The quick brown fox jumps over the lazy \
+                        dog".to_string(),
+                output_str: "d7a8fbb307d7809469ca\
+            9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592".to_string()
+            },
+            Test {
+                input: "The quick brown fox jumps over the lazy \
+                        dog.".to_string(),
+                output_str: "ef537f25c895bfa78252\
+            6529a9b63d97aa631564d5d789c2b765448c8635fb6c".to_string()
+            });
+
+        let tests = wikipedia_tests;
+
+        let mut sh = box Sha256::new();
+
+        test_hash(&mut *sh, tests.as_slice());
+    }
+
+    /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
+    /// correct.
+    fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, expected: &str) {
+        let total_size = 1000000;
+        let buffer = Vec::from_elem(blocksize * 2, 'a' as u8);
+        let mut rng = IsaacRng::new_unseeded();
+        let mut count = 0;
+
+        digest.reset();
+
+        while count < total_size {
+            let next: uint = rng.gen_range(0, 2 * blocksize + 1);
+            let remaining = total_size - count;
+            let size = if next > remaining { remaining } else { next };
+            digest.input(buffer.slice_to(size));
+            count += size;
+        }
+
+        let result_str = digest.result_str();
+        let result_bytes = digest.result_bytes();
+
+        assert_eq!(expected, result_str.as_slice());
+
+        let expected_vec: Vec<u8> = expected.from_hex()
+                                            .unwrap()
+                                            .move_iter()
+                                            .collect();
+        assert_eq!(expected_vec, result_bytes);
+    }
+
+    #[test]
+    fn test_1million_random_sha256() {
+        let mut sh = Sha256::new();
+        test_digest_1million_random(
+            &mut sh,
+            64,
+            "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::Bencher;
+    use super::{Sha256, FixedBuffer, Digest};
+
+    #[bench]
+    pub fn sha256_10(b: &mut Bencher) {
+        let mut sh = Sha256::new();
+        let bytes = [1u8, ..10];
+        b.iter(|| {
+            sh.input(bytes);
+        });
+        b.bytes = bytes.len() as u64;
+    }
+
+    #[bench]
+    pub fn sha256_1k(b: &mut Bencher) {
+        let mut sh = Sha256::new();
+        let bytes = [1u8, ..1024];
+        b.iter(|| {
+            sh.input(bytes);
+        });
+        b.bytes = bytes.len() as u64;
+    }
+
+    #[bench]
+    pub fn sha256_64k(b: &mut Bencher) {
+        let mut sh = Sha256::new();
+        let bytes = [1u8, ..65536];
+        b.iter(|| {
+            sh.input(bytes);
+        });
+        b.bytes = bytes.len() as u64;
+    }
+}
diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs
new file mode 100644 (file)
index 0000000..66bc8c7
--- /dev/null
@@ -0,0 +1,512 @@
+// Copyright 2012-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.
+
+//! Calculation and management of a Strict Version Hash for crates
+//!
+//! # Today's ABI problem
+//!
+//! In today's implementation of rustc, it is incredibly difficult to achieve
+//! forward binary compatibility without resorting to C-like interfaces. Within
+//! rust code itself, abi details such as symbol names suffer from a variety of
+//! unrelated factors to code changing such as the "def id drift" problem. This
+//! ends up yielding confusing error messages about metadata mismatches and
+//! such.
+//!
+//! The core of this problem is when an upstream dependency changes and
+//! downstream dependents are not recompiled. This causes compile errors because
+//! the upstream crate's metadata has changed but the downstream crates are
+//! still referencing the older crate's metadata.
+//!
+//! This problem exists for many reasons, the primary of which is that rust does
+//! not currently support forwards ABI compatibility (in place upgrades of a
+//! crate).
+//!
+//! # SVH and how it alleviates the problem
+//!
+//! With all of this knowledge on hand, this module contains the implementation
+//! of a notion of a "Strict Version Hash" for a crate. This is essentially a
+//! hash of all contents of a crate which can somehow be exposed to downstream
+//! crates.
+//!
+//! This hash is currently calculated by just hashing the AST, but this is
+//! obviously wrong (doc changes should not result in an incompatible ABI).
+//! Implementation-wise, this is required at this moment in time.
+//!
+//! By encoding this strict version hash into all crate's metadata, stale crates
+//! can be detected immediately and error'd about by rustc itself.
+//!
+//! # Relevant links
+//!
+//! Original issue: https://github.com/rust-lang/rust/issues/10207
+
+use std::fmt;
+use std::hash::Hash;
+use std::hash::sip::SipState;
+use std::iter::range_step;
+use syntax::ast;
+use syntax::visit;
+
+#[deriving(Clone, PartialEq)]
+pub struct Svh {
+    hash: String,
+}
+
+impl Svh {
+    pub fn new(hash: &str) -> Svh {
+        assert!(hash.len() == 16);
+        Svh { hash: hash.to_string() }
+    }
+
+    pub fn as_str<'a>(&'a self) -> &'a str {
+        self.hash.as_slice()
+    }
+
+    pub fn calculate(metadata: &Vec<String>, krate: &ast::Crate) -> Svh {
+        // FIXME (#14132): This is better than it used to be, but it still not
+        // ideal. We now attempt to hash only the relevant portions of the
+        // Crate AST as well as the top-level crate attributes. (However,
+        // the hashing of the crate attributes should be double-checked
+        // to ensure it is not incorporating implementation artifacts into
+        // the hash that are not otherwise visible.)
+
+        // FIXME: this should use SHA1, not SipHash. SipHash is not built to
+        //        avoid collisions.
+        let mut state = SipState::new();
+
+        for data in metadata.iter() {
+            data.hash(&mut state);
+        }
+
+        {
+            let mut visit = svh_visitor::make(&mut state);
+            visit::walk_crate(&mut visit, krate, ());
+        }
+
+        // FIXME (#14132): This hash is still sensitive to e.g. the
+        // spans of the crate Attributes and their underlying
+        // MetaItems; we should make ContentHashable impl for those
+        // types and then use hash_content.  But, since all crate
+        // attributes should appear near beginning of the file, it is
+        // not such a big deal to be sensitive to their spans for now.
+        //
+        // We hash only the MetaItems instead of the entire Attribute
+        // to avoid hashing the AttrId
+        for attr in krate.attrs.iter() {
+            attr.node.value.hash(&mut state);
+        }
+
+        let hash = state.result();
+        return Svh {
+            hash: range_step(0u, 64u, 4u).map(|i| hex(hash >> i)).collect()
+        };
+
+        fn hex(b: u64) -> char {
+            let b = (b & 0xf) as u8;
+            let b = match b {
+                0 .. 9 => '0' as u8 + b,
+                _ => 'a' as u8 + b - 10,
+            };
+            b as char
+        }
+    }
+}
+
+impl fmt::Show for Svh {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad(self.as_str())
+    }
+}
+
+// FIXME (#14132): Even this SVH computation still has implementation
+// artifacts: namely, the order of item declaration will affect the
+// hash computation, but for many kinds of items the order of
+// declaration should be irrelevant to the ABI.
+
+mod svh_visitor {
+    use syntax::ast;
+    use syntax::ast::*;
+    use syntax::codemap::Span;
+    use syntax::parse::token;
+    use syntax::print::pprust;
+    use syntax::visit;
+    use syntax::visit::{Visitor, FnKind};
+
+    use std::hash::Hash;
+    use std::hash::sip::SipState;
+
+    pub struct StrictVersionHashVisitor<'a> {
+        pub st: &'a mut SipState,
+    }
+
+    pub fn make<'a>(st: &'a mut SipState) -> StrictVersionHashVisitor<'a> {
+        StrictVersionHashVisitor { st: st }
+    }
+
+    // To off-load the bulk of the hash-computation on deriving(Hash),
+    // we define a set of enums corresponding to the content that our
+    // crate visitor will encounter as it traverses the ast.
+    //
+    // The important invariant is that all of the Saw*Component enums
+    // do not carry any Spans, Names, or Idents.
+    //
+    // Not carrying any Names/Idents is the important fix for problem
+    // noted on PR #13948: using the ident.name as the basis for a
+    // hash leads to unstable SVH, because ident.name is just an index
+    // into intern table (i.e. essentially a random address), not
+    // computed from the name content.
+    //
+    // With the below enums, the SVH computation is not sensitive to
+    // artifacts of how rustc was invoked nor of how the source code
+    // was laid out.  (Or at least it is *less* sensitive.)
+
+    // This enum represents the different potential bits of code the
+    // visitor could encounter that could affect the ABI for the crate,
+    // and assigns each a distinct tag to feed into the hash computation.
+    #[deriving(Hash)]
+    enum SawAbiComponent<'a> {
+
+        // FIXME (#14132): should we include (some function of)
+        // ident.ctxt as well?
+        SawIdent(token::InternedString),
+        SawStructDef(token::InternedString),
+
+        SawLifetimeRef(token::InternedString),
+        SawLifetimeDecl(token::InternedString),
+
+        SawMod,
+        SawViewItem,
+        SawForeignItem,
+        SawItem,
+        SawDecl,
+        SawTy,
+        SawGenerics,
+        SawFn,
+        SawTyMethod,
+        SawTraitMethod,
+        SawStructField,
+        SawVariant,
+        SawExplicitSelf,
+        SawPath,
+        SawOptLifetimeRef,
+        SawBlock,
+        SawPat,
+        SawLocal,
+        SawArm,
+        SawExpr(SawExprComponent<'a>),
+        SawStmt(SawStmtComponent),
+    }
+
+    /// SawExprComponent carries all of the information that we want
+    /// to include in the hash that *won't* be covered by the
+    /// subsequent recursive traversal of the expression's
+    /// substructure by the visitor.
+    ///
+    /// We know every Expr_ variant is covered by a variant because
+    /// `fn saw_expr` maps each to some case below.  Ensuring that
+    /// each variant carries an appropriate payload has to be verified
+    /// by hand.
+    ///
+    /// (However, getting that *exactly* right is not so important
+    /// because the SVH is just a developer convenience; there is no
+    /// guarantee of collision-freedom, hash collisions are just
+    /// (hopefully) unlikely.)
+    #[deriving(Hash)]
+    pub enum SawExprComponent<'a> {
+
+        SawExprLoop(Option<token::InternedString>),
+        SawExprField(token::InternedString),
+        SawExprBreak(Option<token::InternedString>),
+        SawExprAgain(Option<token::InternedString>),
+
+        SawExprVstore,
+        SawExprBox,
+        SawExprVec,
+        SawExprCall,
+        SawExprMethodCall,
+        SawExprTup,
+        SawExprBinary(ast::BinOp),
+        SawExprUnary(ast::UnOp),
+        SawExprLit(ast::Lit_),
+        SawExprCast,
+        SawExprIf,
+        SawExprWhile,
+        SawExprMatch,
+        SawExprFnBlock,
+        SawExprProc,
+        SawExprBlock,
+        SawExprAssign,
+        SawExprAssignOp(ast::BinOp),
+        SawExprIndex,
+        SawExprPath,
+        SawExprAddrOf(ast::Mutability),
+        SawExprRet,
+        SawExprInlineAsm(&'a ast::InlineAsm),
+        SawExprStruct,
+        SawExprRepeat,
+        SawExprParen,
+    }
+
+    fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> {
+        match *node {
+            ExprVstore(..)           => SawExprVstore,
+            ExprBox(..)              => SawExprBox,
+            ExprVec(..)              => SawExprVec,
+            ExprCall(..)             => SawExprCall,
+            ExprMethodCall(..)       => SawExprMethodCall,
+            ExprTup(..)              => SawExprTup,
+            ExprBinary(op, _, _)     => SawExprBinary(op),
+            ExprUnary(op, _)         => SawExprUnary(op),
+            ExprLit(lit)             => SawExprLit(lit.node.clone()),
+            ExprCast(..)             => SawExprCast,
+            ExprIf(..)               => SawExprIf,
+            ExprWhile(..)            => SawExprWhile,
+            ExprLoop(_, id)          => SawExprLoop(id.map(content)),
+            ExprMatch(..)            => SawExprMatch,
+            ExprFnBlock(..)          => SawExprFnBlock,
+            ExprProc(..)             => SawExprProc,
+            ExprBlock(..)            => SawExprBlock,
+            ExprAssign(..)           => SawExprAssign,
+            ExprAssignOp(op, _, _)   => SawExprAssignOp(op),
+            ExprField(_, id, _)      => SawExprField(content(id.node)),
+            ExprIndex(..)            => SawExprIndex,
+            ExprPath(..)             => SawExprPath,
+            ExprAddrOf(m, _)         => SawExprAddrOf(m),
+            ExprBreak(id)            => SawExprBreak(id.map(content)),
+            ExprAgain(id)            => SawExprAgain(id.map(content)),
+            ExprRet(..)              => SawExprRet,
+            ExprInlineAsm(ref asm)   => SawExprInlineAsm(asm),
+            ExprStruct(..)           => SawExprStruct,
+            ExprRepeat(..)           => SawExprRepeat,
+            ExprParen(..)            => SawExprParen,
+
+            // just syntactic artifacts, expanded away by time of SVH.
+            ExprForLoop(..)          => unreachable!(),
+            ExprMac(..)              => unreachable!(),
+        }
+    }
+
+    /// SawStmtComponent is analogous to SawExprComponent, but for statements.
+    #[deriving(Hash)]
+    pub enum SawStmtComponent {
+        SawStmtDecl,
+        SawStmtExpr,
+        SawStmtSemi,
+    }
+
+    fn saw_stmt(node: &Stmt_) -> SawStmtComponent {
+        match *node {
+            StmtDecl(..) => SawStmtDecl,
+            StmtExpr(..) => SawStmtExpr,
+            StmtSemi(..) => SawStmtSemi,
+            StmtMac(..)  => unreachable!(),
+        }
+    }
+
+    // Ad-hoc overloading between Ident and Name to their intern table lookups.
+    trait InternKey { fn get_content(self) -> token::InternedString; }
+    impl InternKey for Ident {
+        fn get_content(self) -> token::InternedString { token::get_ident(self) }
+    }
+    impl InternKey for Name {
+        fn get_content(self) -> token::InternedString { token::get_name(self) }
+    }
+    fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() }
+
+    // local short-hand eases writing signatures of syntax::visit mod.
+    type E = ();
+
+    impl<'a> Visitor<E> for StrictVersionHashVisitor<'a> {
+
+        fn visit_mac(&mut self, macro: &Mac, e: E) {
+            // macro invocations, namely macro_rules definitions,
+            // *can* appear as items, even in the expanded crate AST.
+
+            if macro_name(macro).get() == "macro_rules" {
+                // Pretty-printing definition to a string strips out
+                // surface artifacts (currently), such as the span
+                // information, yielding a content-based hash.
+
+                // FIXME (#14132): building temporary string is
+                // expensive; a direct content-based hash on token
+                // trees might be faster. Implementing this is far
+                // easier in short term.
+                let macro_defn_as_string =
+                    pprust::to_string(|pp_state| pp_state.print_mac(macro));
+                macro_defn_as_string.hash(self.st);
+            } else {
+                // It is not possible to observe any kind of macro
+                // invocation at this stage except `macro_rules!`.
+                fail!("reached macro somehow: {}",
+                      pprust::to_string(|pp_state| pp_state.print_mac(macro)));
+            }
+
+            visit::walk_mac(self, macro, e);
+
+            fn macro_name(macro: &Mac) -> token::InternedString {
+                match &macro.node {
+                    &MacInvocTT(ref path, ref _tts, ref _stx_ctxt) => {
+                        let s = path.segments.as_slice();
+                        assert_eq!(s.len(), 1);
+                        content(s[0].identifier)
+                    }
+                }
+            }
+        }
+
+        fn visit_struct_def(&mut self, s: &StructDef, ident: Ident,
+                            g: &Generics, _: NodeId, e: E) {
+            SawStructDef(content(ident)).hash(self.st);
+            visit::walk_generics(self, g, e.clone());
+            visit::walk_struct_def(self, s, e)
+        }
+
+        fn visit_variant(&mut self, v: &Variant, g: &Generics, e: E) {
+            SawVariant.hash(self.st);
+            // walk_variant does not call walk_generics, so do it here.
+            visit::walk_generics(self, g, e.clone());
+            visit::walk_variant(self, v, g, e)
+        }
+
+        fn visit_opt_lifetime_ref(&mut self, _: Span, l: &Option<Lifetime>, env: E) {
+            SawOptLifetimeRef.hash(self.st);
+            // (This is a strange method in the visitor trait, in that
+            // it does not expose a walk function to do the subroutine
+            // calls.)
+            match *l {
+                Some(ref l) => self.visit_lifetime_ref(l, env),
+                None => ()
+            }
+        }
+
+        // All of the remaining methods just record (in the hash
+        // SipState) that the visitor saw that particular variant
+        // (with its payload), and continue walking as the default
+        // visitor would.
+        //
+        // Some of the implementations have some notes as to how one
+        // might try to make their SVH computation less discerning
+        // (e.g. by incorporating reachability analysis).  But
+        // currently all of their implementations are uniform and
+        // uninteresting.
+        //
+        // (If you edit a method such that it deviates from the
+        // pattern, please move that method up above this comment.)
+
+        fn visit_ident(&mut self, _: Span, ident: Ident, _: E) {
+            SawIdent(content(ident)).hash(self.st);
+        }
+
+        fn visit_lifetime_ref(&mut self, l: &Lifetime, _: E) {
+            SawLifetimeRef(content(l.name)).hash(self.st);
+        }
+
+        fn visit_lifetime_decl(&mut self, l: &Lifetime, _: E) {
+            SawLifetimeDecl(content(l.name)).hash(self.st);
+        }
+
+        // We do recursively walk the bodies of functions/methods
+        // (rather than omitting their bodies from the hash) since
+        // monomorphization and cross-crate inlining generally implies
+        // that a change to a crate body will require downstream
+        // crates to be recompiled.
+        fn visit_expr(&mut self, ex: &Expr, e: E) {
+            SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex, e)
+        }
+
+        fn visit_stmt(&mut self, s: &Stmt, e: E) {
+            SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s, e)
+        }
+
+        fn visit_view_item(&mut self, i: &ViewItem, e: E) {
+            // Two kinds of view items can affect the ABI for a crate:
+            // exported `pub use` view items (since that may expose
+            // items that downstream crates can call), and `use
+            // foo::Trait`, since changing that may affect method
+            // resolution.
+            //
+            // The simplest approach to handling both of the above is
+            // just to adopt the same simple-minded (fine-grained)
+            // hash that I am deploying elsewhere here.
+            SawViewItem.hash(self.st); visit::walk_view_item(self, i, e)
+        }
+
+        fn visit_foreign_item(&mut self, i: &ForeignItem, e: E) {
+            // FIXME (#14132) ideally we would incorporate privacy (or
+            // perhaps reachability) somewhere here, so foreign items
+            // that do not leak into downstream crates would not be
+            // part of the ABI.
+            SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i, e)
+        }
+
+        fn visit_item(&mut self, i: &Item, e: E) {
+            // FIXME (#14132) ideally would incorporate reachability
+            // analysis somewhere here, so items that never leak into
+            // downstream crates (e.g. via monomorphisation or
+            // inlining) would not be part of the ABI.
+            SawItem.hash(self.st); visit::walk_item(self, i, e)
+        }
+
+        fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId, e: E) {
+            SawMod.hash(self.st); visit::walk_mod(self, m, e)
+        }
+
+        fn visit_decl(&mut self, d: &Decl, e: E) {
+            SawDecl.hash(self.st); visit::walk_decl(self, d, e)
+        }
+
+        fn visit_ty(&mut self, t: &Ty, e: E) {
+            SawTy.hash(self.st); visit::walk_ty(self, t, e)
+        }
+
+        fn visit_generics(&mut self, g: &Generics, e: E) {
+            SawGenerics.hash(self.st); visit::walk_generics(self, g, e)
+        }
+
+        fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId, e: E) {
+            SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s, e)
+        }
+
+        fn visit_ty_method(&mut self, t: &TypeMethod, e: E) {
+            SawTyMethod.hash(self.st); visit::walk_ty_method(self, t, e)
+        }
+
+        fn visit_trait_method(&mut self, t: &TraitMethod, e: E) {
+            SawTraitMethod.hash(self.st); visit::walk_trait_method(self, t, e)
+        }
+
+        fn visit_struct_field(&mut self, s: &StructField, e: E) {
+            SawStructField.hash(self.st); visit::walk_struct_field(self, s, e)
+        }
+
+        fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) {
+            SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es, e)
+        }
+
+        fn visit_path(&mut self, path: &Path, _: ast::NodeId, e: E) {
+            SawPath.hash(self.st); visit::walk_path(self, path, e)
+        }
+
+        fn visit_block(&mut self, b: &Block, e: E) {
+            SawBlock.hash(self.st); visit::walk_block(self, b, e)
+        }
+
+        fn visit_pat(&mut self, p: &Pat, e: E) {
+            SawPat.hash(self.st); visit::walk_pat(self, p, e)
+        }
+
+        fn visit_local(&mut self, l: &Local, e: E) {
+            SawLocal.hash(self.st); visit::walk_local(self, l, e)
+        }
+
+        fn visit_arm(&mut self, a: &Arm, e: E) {
+            SawArm.hash(self.st); visit::walk_arm(self, a, e)
+        }
+    }
+}
diff --git a/src/librustc_back/target_strs.rs b/src/librustc_back/target_strs.rs
new file mode 100644 (file)
index 0000000..7928f3d
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(non_camel_case_types)]
+
+pub struct t {
+    pub module_asm: String,
+    pub data_layout: String,
+    pub target_triple: String,
+    pub cc_args: Vec<String> ,
+}
diff --git a/src/librustc_back/x86.rs b/src/librustc_back/x86.rs
new file mode 100644 (file)
index 0000000..b4d67bc
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os)
+                       -> target_strs::t {
+    return target_strs::t {
+        module_asm: "".to_string(),
+
+        data_layout: match target_os {
+          abi::OsMacos => {
+            "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
+                -i32:32:32-i64:32:64\
+                -f32:32:32-f64:32:64-v64:64:64\
+                -v128:128:128-a0:0:64-f80:128:128\
+                -n8:16:32".to_string()
+          }
+
+          abi::OsiOS => {
+            "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
+                -i32:32:32-i64:32:64\
+                -f32:32:32-f64:32:64-v64:64:64\
+                -v128:128:128-a0:0:64-f80:128:128\
+                -n8:16:32".to_string()
+          }
+
+          abi::OsWin32 => {
+            "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32".to_string()
+          }
+
+          abi::OsLinux => {
+            "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
+          }
+          abi::OsAndroid => {
+            "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
+          }
+
+          abi::OsFreebsd => {
+            "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
+          }
+        },
+
+        target_triple: target_triple,
+
+        cc_args: vec!("-m32".to_string()),
+    };
+}
diff --git a/src/librustc_back/x86_64.rs b/src/librustc_back/x86_64.rs
new file mode 100644 (file)
index 0000000..70807ed
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
+    return target_strs::t {
+        module_asm: "".to_string(),
+
+        data_layout: match target_os {
+          abi::OsMacos => {
+            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+                s0:64:64-f80:128:128-n8:16:32:64".to_string()
+          }
+
+          abi::OsiOS => {
+            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+                s0:64:64-f80:128:128-n8:16:32:64".to_string()
+          }
+
+          abi::OsWin32 => {
+            // FIXME: Test this. Copied from linux (#2398)
+            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
+          }
+
+          abi::OsLinux => {
+            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
+          }
+          abi::OsAndroid => {
+            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
+          }
+
+          abi::OsFreebsd => {
+            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
+          }
+        },
+
+        target_triple: target_triple,
+
+        cc_args: vec!("-m64".to_string()),
+    };
+}
diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs
new file mode 100644 (file)
index 0000000..6c37787
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright 2013-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.
+
+//! A wrapper around LLVM's archive (.a) code
+
+use libc;
+use ArchiveRef;
+
+use std::raw;
+use std::mem;
+
+pub struct ArchiveRO {
+    ptr: ArchiveRef,
+}
+
+impl ArchiveRO {
+    /// Opens a static archive for read-only purposes. This is more optimized
+    /// than the `open` method because it uses LLVM's internal `Archive` class
+    /// rather than shelling out to `ar` for everything.
+    ///
+    /// If this archive is used with a mutable method, then an error will be
+    /// raised.
+    pub fn open(dst: &Path) -> Option<ArchiveRO> {
+        unsafe {
+            let ar = dst.with_c_str(|dst| {
+                ::LLVMRustOpenArchive(dst)
+            });
+            if ar.is_null() {
+                None
+            } else {
+                Some(ArchiveRO { ptr: ar })
+            }
+        }
+    }
+
+    /// Reads a file in the archive
+    pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
+        unsafe {
+            let mut size = 0 as libc::size_t;
+            let ptr = file.with_c_str(|file| {
+                ::LLVMRustArchiveReadSection(self.ptr, file, &mut size)
+            });
+            if ptr.is_null() {
+                None
+            } else {
+                Some(mem::transmute(raw::Slice {
+                    data: ptr,
+                    len: size as uint,
+                }))
+            }
+        }
+    }
+}
+
+impl Drop for ArchiveRO {
+    fn drop(&mut self) {
+        unsafe {
+            ::LLVMRustDestroyArchive(self.ptr);
+        }
+    }
+}
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
new file mode 100644 (file)
index 0000000..9ee8fa9
--- /dev/null
@@ -0,0 +1,2003 @@
+// Copyright 2012-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.
+
+#![allow(non_uppercase_pattern_statics)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case_functions)]
+#![allow(dead_code)]
+
+#![crate_id = "rustc_llvm#0.11.0"]
+#![crate_name = "rustc_llvm"]
+#![experimental]
+#![license = "MIT/ASL2"]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+       html_root_url = "http://doc.rust-lang.org/")]
+
+#![feature(globs)]
+#![feature(link_args)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
+
+extern crate libc;
+
+use std::c_str::ToCStr;
+use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char};
+use libc::{c_longlong, c_ulonglong};
+use debuginfo::{DIBuilderRef, DIDescriptor,
+                DIFile, DILexicalBlock, DISubprogram, DIType,
+                DIBasicType, DIDerivedType, DICompositeType,
+                DIVariable, DIGlobalVariable, DIArray, DISubrange};
+
+pub mod archive_ro;
+
+pub type Opcode = u32;
+pub type Bool = c_uint;
+
+pub static True: Bool = 1 as Bool;
+pub static False: Bool = 0 as Bool;
+
+// Consts for the LLVM CallConv type, pre-cast to uint.
+
+#[deriving(PartialEq)]
+pub enum CallConv {
+    CCallConv = 0,
+    FastCallConv = 8,
+    ColdCallConv = 9,
+    X86StdcallCallConv = 64,
+    X86FastcallCallConv = 65,
+    X86_64_Win64 = 79,
+}
+
+pub enum Visibility {
+    LLVMDefaultVisibility = 0,
+    HiddenVisibility = 1,
+    ProtectedVisibility = 2,
+}
+
+// This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
+// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
+// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
+// they've been removed in upstream LLVM commit r203866.
+pub enum Linkage {
+    ExternalLinkage = 0,
+    AvailableExternallyLinkage = 1,
+    LinkOnceAnyLinkage = 2,
+    LinkOnceODRLinkage = 3,
+    WeakAnyLinkage = 5,
+    WeakODRLinkage = 6,
+    AppendingLinkage = 7,
+    InternalLinkage = 8,
+    PrivateLinkage = 9,
+    ExternalWeakLinkage = 12,
+    CommonLinkage = 14,
+}
+
+#[deriving(Clone)]
+pub enum Attribute {
+    ZExtAttribute = 1 << 0,
+    SExtAttribute = 1 << 1,
+    NoReturnAttribute = 1 << 2,
+    InRegAttribute = 1 << 3,
+    StructRetAttribute = 1 << 4,
+    NoUnwindAttribute = 1 << 5,
+    NoAliasAttribute = 1 << 6,
+    ByValAttribute = 1 << 7,
+    NestAttribute = 1 << 8,
+    ReadNoneAttribute = 1 << 9,
+    ReadOnlyAttribute = 1 << 10,
+    NoInlineAttribute = 1 << 11,
+    AlwaysInlineAttribute = 1 << 12,
+    OptimizeForSizeAttribute = 1 << 13,
+    StackProtectAttribute = 1 << 14,
+    StackProtectReqAttribute = 1 << 15,
+    AlignmentAttribute = 31 << 16,
+    NoCaptureAttribute = 1 << 21,
+    NoRedZoneAttribute = 1 << 22,
+    NoImplicitFloatAttribute = 1 << 23,
+    NakedAttribute = 1 << 24,
+    InlineHintAttribute = 1 << 25,
+    StackAttribute = 7 << 26,
+    ReturnsTwiceAttribute = 1 << 29,
+    UWTableAttribute = 1 << 30,
+    NonLazyBindAttribute = 1 << 31,
+}
+
+#[repr(u64)]
+pub enum OtherAttribute {
+    // The following are not really exposed in
+    // the LLVM c api so instead to add these
+    // we call a wrapper function in RustWrapper
+    // that uses the C++ api.
+    SanitizeAddressAttribute = 1 << 32,
+    MinSizeAttribute = 1 << 33,
+    NoDuplicateAttribute = 1 << 34,
+    StackProtectStrongAttribute = 1 << 35,
+    SanitizeThreadAttribute = 1 << 36,
+    SanitizeMemoryAttribute = 1 << 37,
+    NoBuiltinAttribute = 1 << 38,
+    ReturnedAttribute = 1 << 39,
+    ColdAttribute = 1 << 40,
+    BuiltinAttribute = 1 << 41,
+    OptimizeNoneAttribute = 1 << 42,
+    InAllocaAttribute = 1 << 43,
+    NonNullAttribute = 1 << 44,
+}
+
+#[repr(C)]
+pub enum AttributeSet {
+    ReturnIndex = 0,
+    FunctionIndex = !0
+}
+
+// enum for the LLVM IntPredicate type
+pub enum IntPredicate {
+    IntEQ = 32,
+    IntNE = 33,
+    IntUGT = 34,
+    IntUGE = 35,
+    IntULT = 36,
+    IntULE = 37,
+    IntSGT = 38,
+    IntSGE = 39,
+    IntSLT = 40,
+    IntSLE = 41,
+}
+
+// enum for the LLVM RealPredicate type
+pub enum RealPredicate {
+    RealPredicateFalse = 0,
+    RealOEQ = 1,
+    RealOGT = 2,
+    RealOGE = 3,
+    RealOLT = 4,
+    RealOLE = 5,
+    RealONE = 6,
+    RealORD = 7,
+    RealUNO = 8,
+    RealUEQ = 9,
+    RealUGT = 10,
+    RealUGE = 11,
+    RealULT = 12,
+    RealULE = 13,
+    RealUNE = 14,
+    RealPredicateTrue = 15,
+}
+
+// The LLVM TypeKind type - must stay in sync with the def of
+// LLVMTypeKind in llvm/include/llvm-c/Core.h
+#[deriving(PartialEq)]
+#[repr(C)]
+pub enum TypeKind {
+    Void      = 0,
+    Half      = 1,
+    Float     = 2,
+    Double    = 3,
+    X86_FP80  = 4,
+    FP128     = 5,
+    PPC_FP128 = 6,
+    Label     = 7,
+    Integer   = 8,
+    Function  = 9,
+    Struct    = 10,
+    Array     = 11,
+    Pointer   = 12,
+    Vector    = 13,
+    Metadata  = 14,
+    X86_MMX   = 15,
+}
+
+#[repr(C)]
+pub enum AtomicBinOp {
+    Xchg = 0,
+    Add  = 1,
+    Sub  = 2,
+    And  = 3,
+    Nand = 4,
+    Or   = 5,
+    Xor  = 6,
+    Max  = 7,
+    Min  = 8,
+    UMax = 9,
+    UMin = 10,
+}
+
+#[repr(C)]
+pub enum AtomicOrdering {
+    NotAtomic = 0,
+    Unordered = 1,
+    Monotonic = 2,
+    // Consume = 3,  // Not specified yet.
+    Acquire = 4,
+    Release = 5,
+    AcquireRelease = 6,
+    SequentiallyConsistent = 7
+}
+
+// Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
+#[repr(C)]
+pub enum FileType {
+    AssemblyFile = 0,
+    ObjectFile = 1
+}
+
+pub enum Metadata {
+    MD_dbg = 0,
+    MD_tbaa = 1,
+    MD_prof = 2,
+    MD_fpmath = 3,
+    MD_range = 4,
+    MD_tbaa_struct = 5
+}
+
+// Inline Asm Dialect
+pub enum AsmDialect {
+    AD_ATT   = 0,
+    AD_Intel = 1
+}
+
+#[deriving(PartialEq)]
+#[repr(C)]
+pub enum CodeGenOptLevel {
+    CodeGenLevelNone = 0,
+    CodeGenLevelLess = 1,
+    CodeGenLevelDefault = 2,
+    CodeGenLevelAggressive = 3,
+}
+
+#[repr(C)]
+pub enum RelocMode {
+    RelocDefault = 0,
+    RelocStatic = 1,
+    RelocPIC = 2,
+    RelocDynamicNoPic = 3,
+}
+
+#[repr(C)]
+pub enum CodeGenModel {
+    CodeModelDefault = 0,
+    CodeModelJITDefault = 1,
+    CodeModelSmall = 2,
+    CodeModelKernel = 3,
+    CodeModelMedium = 4,
+    CodeModelLarge = 5,
+}
+
+// Opaque pointer types
+pub enum Module_opaque {}
+pub type ModuleRef = *mut Module_opaque;
+pub enum Context_opaque {}
+pub type ContextRef = *mut Context_opaque;
+pub enum Type_opaque {}
+pub type TypeRef = *mut Type_opaque;
+pub enum Value_opaque {}
+pub type ValueRef = *mut Value_opaque;
+pub enum BasicBlock_opaque {}
+pub type BasicBlockRef = *mut BasicBlock_opaque;
+pub enum Builder_opaque {}
+pub type BuilderRef = *mut Builder_opaque;
+pub enum ExecutionEngine_opaque {}
+pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
+pub enum MemoryBuffer_opaque {}
+pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
+pub enum PassManager_opaque {}
+pub type PassManagerRef = *mut PassManager_opaque;
+pub enum PassManagerBuilder_opaque {}
+pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
+pub enum Use_opaque {}
+pub type UseRef = *mut Use_opaque;
+pub enum TargetData_opaque {}
+pub type TargetDataRef = *mut TargetData_opaque;
+pub enum ObjectFile_opaque {}
+pub type ObjectFileRef = *mut ObjectFile_opaque;
+pub enum SectionIterator_opaque {}
+pub type SectionIteratorRef = *mut SectionIterator_opaque;
+pub enum Pass_opaque {}
+pub type PassRef = *mut Pass_opaque;
+pub enum TargetMachine_opaque {}
+pub type TargetMachineRef = *mut TargetMachine_opaque;
+pub enum Archive_opaque {}
+pub type ArchiveRef = *mut Archive_opaque;
+
+pub mod debuginfo {
+    use super::{ValueRef};
+
+    pub enum DIBuilder_opaque {}
+    pub type DIBuilderRef = *mut DIBuilder_opaque;
+
+    pub type DIDescriptor = ValueRef;
+    pub type DIScope = DIDescriptor;
+    pub type DILocation = DIDescriptor;
+    pub type DIFile = DIScope;
+    pub type DILexicalBlock = DIScope;
+    pub type DISubprogram = DIScope;
+    pub type DIType = DIDescriptor;
+    pub type DIBasicType = DIType;
+    pub type DIDerivedType = DIType;
+    pub type DICompositeType = DIDerivedType;
+    pub type DIVariable = DIDescriptor;
+    pub type DIGlobalVariable = DIDescriptor;
+    pub type DIArray = DIDescriptor;
+    pub type DISubrange = DIDescriptor;
+
+    pub enum DIDescriptorFlags {
+      FlagPrivate            = 1 << 0,
+      FlagProtected          = 1 << 1,
+      FlagFwdDecl            = 1 << 2,
+      FlagAppleBlock         = 1 << 3,
+      FlagBlockByrefStruct   = 1 << 4,
+      FlagVirtual            = 1 << 5,
+      FlagArtificial         = 1 << 6,
+      FlagExplicit           = 1 << 7,
+      FlagPrototyped         = 1 << 8,
+      FlagObjcClassComplete  = 1 << 9,
+      FlagObjectPointer      = 1 << 10,
+      FlagVector             = 1 << 11,
+      FlagStaticMember       = 1 << 12
+    }
+}
+
+
+// Link to our native llvm bindings (things that we need to use the C++ api
+// for) and because llvm is written in C++ we need to link against libstdc++
+//
+// You'll probably notice that there is an omission of all LLVM libraries
+// from this location. This is because the set of LLVM libraries that we
+// link to is mostly defined by LLVM, and the `llvm-config` tool is used to
+// figure out the exact set of libraries. To do this, the build system
+// generates an llvmdeps.rs file next to this one which will be
+// automatically updated whenever LLVM is updated to include an up-to-date
+// set of the libraries we need to link to LLVM for.
+#[link(name = "rustllvm", kind = "static")]
+extern {
+    /* Create and destroy contexts. */
+    pub fn LLVMContextCreate() -> ContextRef;
+    pub fn LLVMContextDispose(C: ContextRef);
+    pub fn LLVMGetMDKindIDInContext(C: ContextRef,
+                                    Name: *const c_char,
+                                    SLen: c_uint)
+                                    -> c_uint;
+
+    /* Create and destroy modules. */
+    pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char,
+                                             C: ContextRef)
+                                             -> ModuleRef;
+    pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
+    pub fn LLVMDisposeModule(M: ModuleRef);
+
+    /** Data layout. See Module::getDataLayout. */
+    pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char;
+    pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char);
+
+    /** Target triple. See Module::getTargetTriple. */
+    pub fn LLVMGetTarget(M: ModuleRef) -> *const c_char;
+    pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char);
+
+    /** See Module::dump. */
+    pub fn LLVMDumpModule(M: ModuleRef);
+
+    /** See Module::setModuleInlineAsm. */
+    pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
+
+    /** See llvm::LLVMTypeKind::getTypeID. */
+    pub fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
+
+    /** See llvm::LLVMType::getContext. */
+    pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
+
+    /* Operations on integer types */
+    pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint)
+                                -> TypeRef;
+
+    pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
+
+    /* Operations on real types */
+    pub fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
+
+    /* Operations on function types */
+    pub fn LLVMFunctionType(ReturnType: TypeRef,
+                            ParamTypes: *const TypeRef,
+                            ParamCount: c_uint,
+                            IsVarArg: Bool)
+                            -> TypeRef;
+    pub fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
+    pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
+    pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
+    pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *const TypeRef);
+
+    /* Operations on struct types */
+    pub fn LLVMStructTypeInContext(C: ContextRef,
+                                   ElementTypes: *const TypeRef,
+                                   ElementCount: c_uint,
+                                   Packed: Bool)
+                                   -> TypeRef;
+    pub fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
+    pub fn LLVMGetStructElementTypes(StructTy: TypeRef,
+                                     Dest: *mut TypeRef);
+    pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
+
+    /* Operations on array, pointer, and vector types (sequence types) */
+    pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
+    pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint)
+                           -> TypeRef;
+    pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint)
+                          -> TypeRef;
+
+    pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
+    pub fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
+    pub fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
+    pub fn LLVMGetPointerToGlobal(EE: ExecutionEngineRef, V: ValueRef)
+                                  -> *const ();
+    pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
+
+    /* Operations on other types */
+    pub fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
+    pub fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
+
+    /* Operations on all values */
+    pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
+    pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
+    pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
+    pub fn LLVMDumpValue(Val: ValueRef);
+    pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
+    pub fn LLVMHasMetadata(Val: ValueRef) -> c_int;
+    pub fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
+    pub fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
+
+    /* Operations on Uses */
+    pub fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
+    pub fn LLVMGetNextUse(U: UseRef) -> UseRef;
+    pub fn LLVMGetUser(U: UseRef) -> ValueRef;
+    pub fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
+
+    /* Operations on Users */
+    pub fn LLVMGetNumOperands(Val: ValueRef) -> c_int;
+    pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
+    pub fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
+
+    /* Operations on constants of any type */
+    pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
+    /* all zeroes */
+    pub fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
+    pub fn LLVMConstICmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstFCmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
+                         -> ValueRef;
+    /* only for int/vector */
+    pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
+    pub fn LLVMIsConstant(Val: ValueRef) -> Bool;
+    pub fn LLVMIsNull(Val: ValueRef) -> Bool;
+    pub fn LLVMIsUndef(Val: ValueRef) -> Bool;
+    pub fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
+
+    /* Operations on metadata */
+    pub fn LLVMMDStringInContext(C: ContextRef,
+                                 Str: *const c_char,
+                                 SLen: c_uint)
+                                 -> ValueRef;
+    pub fn LLVMMDNodeInContext(C: ContextRef,
+                               Vals: *const ValueRef,
+                               Count: c_uint)
+                               -> ValueRef;
+    pub fn LLVMAddNamedMetadataOperand(M: ModuleRef,
+                                       Str: *const c_char,
+                                       Val: ValueRef);
+
+    /* Operations on scalar constants */
+    pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool)
+                        -> ValueRef;
+    pub fn LLVMConstIntOfString(IntTy: TypeRef, Text: *const c_char, Radix: u8)
+                                -> ValueRef;
+    pub fn LLVMConstIntOfStringAndSize(IntTy: TypeRef,
+                                       Text: *const c_char,
+                                       SLen: c_uint,
+                                       Radix: u8)
+                                       -> ValueRef;
+    pub fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
+    pub fn LLVMConstRealOfString(RealTy: TypeRef, Text: *const c_char)
+                                 -> ValueRef;
+    pub fn LLVMConstRealOfStringAndSize(RealTy: TypeRef,
+                                        Text: *const c_char,
+                                        SLen: c_uint)
+                                        -> ValueRef;
+    pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
+    pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
+
+
+    /* Operations on composite constants */
+    pub fn LLVMConstStringInContext(C: ContextRef,
+                                    Str: *const c_char,
+                                    Length: c_uint,
+                                    DontNullTerminate: Bool)
+                                    -> ValueRef;
+    pub fn LLVMConstStructInContext(C: ContextRef,
+                                    ConstantVals: *const ValueRef,
+                                    Count: c_uint,
+                                    Packed: Bool)
+                                    -> ValueRef;
+
+    pub fn LLVMConstArray(ElementTy: TypeRef,
+                          ConstantVals: *const ValueRef,
+                          Length: c_uint)
+                          -> ValueRef;
+    pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint)
+                           -> ValueRef;
+
+    /* Constant expressions */
+    pub fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
+    pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
+    pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
+    pub fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstNUWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstNSWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstNUWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstNSWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstNUWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstExactSDiv(LHSConstant: ValueRef,
+                              RHSConstant: ValueRef)
+                              -> ValueRef;
+    pub fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                       -> ValueRef;
+    pub fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+    pub fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+    pub fn LLVMConstGEP(ConstantVal: ValueRef,
+                        ConstantIndices: *const ValueRef,
+                        NumIndices: c_uint)
+                        -> ValueRef;
+    pub fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
+                                ConstantIndices: *const ValueRef,
+                                NumIndices: c_uint)
+                                -> ValueRef;
+    pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef)
+                          -> ValueRef;
+    pub fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef)
+                         -> ValueRef;
+    pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef)
+                         -> ValueRef;
+    pub fn LLVMConstFPTrunc(ConstantVal: ValueRef, ToType: TypeRef)
+                            -> ValueRef;
+    pub fn LLVMConstFPExt(ConstantVal: ValueRef, ToType: TypeRef)
+                          -> ValueRef;
+    pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef)
+                             -> ValueRef;
+    pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef)
+                             -> ValueRef;
+    pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                            -> ValueRef;
+    pub fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                  -> ValueRef;
+    pub fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                  -> ValueRef;
+    pub fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                   -> ValueRef;
+    pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                -> ValueRef;
+    pub fn LLVMConstIntCast(ConstantVal: ValueRef,
+                            ToType: TypeRef,
+                            isSigned: Bool)
+                            -> ValueRef;
+    pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMConstSelect(ConstantCondition: ValueRef,
+                           ConstantIfTrue: ValueRef,
+                           ConstantIfFalse: ValueRef)
+                           -> ValueRef;
+    pub fn LLVMConstExtractElement(VectorConstant: ValueRef,
+                                   IndexConstant: ValueRef)
+                                   -> ValueRef;
+    pub fn LLVMConstInsertElement(VectorConstant: ValueRef,
+                                  ElementValueConstant: ValueRef,
+                                  IndexConstant: ValueRef)
+                                  -> ValueRef;
+    pub fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
+                                  VectorBConstant: ValueRef,
+                                  MaskConstant: ValueRef)
+                                  -> ValueRef;
+    pub fn LLVMConstExtractValue(AggConstant: ValueRef,
+                                 IdxList: *const c_uint,
+                                 NumIdx: c_uint)
+                                 -> ValueRef;
+    pub fn LLVMConstInsertValue(AggConstant: ValueRef,
+                                ElementValueConstant: ValueRef,
+                                IdxList: *const c_uint,
+                                NumIdx: c_uint)
+                                -> ValueRef;
+    pub fn LLVMConstInlineAsm(Ty: TypeRef,
+                              AsmString: *const c_char,
+                              Constraints: *const c_char,
+                              HasSideEffects: Bool,
+                              IsAlignStack: Bool)
+                              -> ValueRef;
+    pub fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
+
+
+
+    /* Operations on global variables, functions, and aliases (globals) */
+    pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
+    pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
+    pub fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
+    pub fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
+    pub fn LLVMGetSection(Global: ValueRef) -> *const c_char;
+    pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char);
+    pub fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
+    pub fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
+    pub fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
+    pub fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
+
+
+    /* Operations on global variables */
+    pub fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMAddGlobalInAddressSpace(M: ModuleRef,
+                                       Ty: TypeRef,
+                                       Name: *const c_char,
+                                       AddressSpace: c_uint)
+                                       -> ValueRef;
+    pub fn LLVMGetNamedGlobal(M: ModuleRef, Name: *const c_char) -> ValueRef;
+    pub fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
+    pub fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
+    pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
+    pub fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
+    pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
+    pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
+    pub fn LLVMSetInitializer(GlobalVar: ValueRef,
+                              ConstantVal: ValueRef);
+    pub fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
+    pub fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
+    pub fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
+    pub fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
+
+    /* Operations on aliases */
+    pub fn LLVMAddAlias(M: ModuleRef,
+                        Ty: TypeRef,
+                        Aliasee: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+
+    /* Operations on functions */
+    pub fn LLVMAddFunction(M: ModuleRef,
+                           Name: *const c_char,
+                           FunctionTy: TypeRef)
+                           -> ValueRef;
+    pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
+    pub fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
+    pub fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
+    pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
+    pub fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
+    pub fn LLVMDeleteFunction(Fn: ValueRef);
+    pub fn LLVMGetOrInsertFunction(M: ModuleRef,
+                                   Name: *const c_char,
+                                   FunctionTy: TypeRef)
+                                   -> ValueRef;
+    pub fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
+    pub fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
+    pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
+    pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
+    pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
+    pub fn LLVMAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: uint64_t);
+    pub fn LLVMAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
+    pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
+    pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
+
+    /* Operations on parameters */
+    pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
+    pub fn LLVMGetParams(Fn: ValueRef, Params: *const ValueRef);
+    pub fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
+    pub fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
+    pub fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
+    pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
+    pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
+    pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
+    pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
+    pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
+    pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
+    pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
+
+    /* Operations on basic blocks */
+    pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
+    pub fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
+    pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
+    pub fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *const ValueRef);
+    pub fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+    pub fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+    pub fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+    pub fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+    pub fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+
+    pub fn LLVMAppendBasicBlockInContext(C: ContextRef,
+                                         Fn: ValueRef,
+                                         Name: *const c_char)
+                                         -> BasicBlockRef;
+    pub fn LLVMInsertBasicBlockInContext(C: ContextRef,
+                                         BB: BasicBlockRef,
+                                         Name: *const c_char)
+                                         -> BasicBlockRef;
+    pub fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
+
+    pub fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef,
+                                   MoveAfter: BasicBlockRef);
+
+    pub fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef,
+                                    MoveBefore: BasicBlockRef);
+
+    /* Operations on instructions */
+    pub fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
+    pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
+    pub fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
+    pub fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
+    pub fn LLVMInstructionEraseFromParent(Inst: ValueRef);
+
+    /* Operations on call sites */
+    pub fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
+    pub fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
+    pub fn LLVMAddInstrAttribute(Instr: ValueRef,
+                                 index: c_uint,
+                                 IA: c_uint);
+    pub fn LLVMRemoveInstrAttribute(Instr: ValueRef,
+                                    index: c_uint,
+                                    IA: c_uint);
+    pub fn LLVMSetInstrParamAlignment(Instr: ValueRef,
+                                      index: c_uint,
+                                      align: c_uint);
+    pub fn LLVMAddCallSiteAttribute(Instr: ValueRef,
+                                    index: c_uint,
+                                    Val: uint64_t);
+
+    /* Operations on call instructions (only) */
+    pub fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
+    pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
+
+    /* Operations on load/store instructions (only) */
+    pub fn LLVMGetVolatile(MemoryAccessInst: ValueRef) -> Bool;
+    pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool);
+
+    /* Operations on phi nodes */
+    pub fn LLVMAddIncoming(PhiNode: ValueRef,
+                           IncomingValues: *const ValueRef,
+                           IncomingBlocks: *const BasicBlockRef,
+                           Count: c_uint);
+    pub fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
+    pub fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint)
+                                -> ValueRef;
+    pub fn LLVMGetIncomingBlock(PhiNode: ValueRef, Index: c_uint)
+                                -> BasicBlockRef;
+
+    /* Instruction builders */
+    pub fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
+    pub fn LLVMPositionBuilder(Builder: BuilderRef,
+                               Block: BasicBlockRef,
+                               Instr: ValueRef);
+    pub fn LLVMPositionBuilderBefore(Builder: BuilderRef,
+                                     Instr: ValueRef);
+    pub fn LLVMPositionBuilderAtEnd(Builder: BuilderRef,
+                                    Block: BasicBlockRef);
+    pub fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
+    pub fn LLVMClearInsertionPosition(Builder: BuilderRef);
+    pub fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
+    pub fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
+                                         Instr: ValueRef,
+                                         Name: *const c_char);
+    pub fn LLVMDisposeBuilder(Builder: BuilderRef);
+    pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef);
+
+    /* Metadata */
+    pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
+    pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
+    pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
+
+    /* Terminators */
+    pub fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
+    pub fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
+    pub fn LLVMBuildAggregateRet(B: BuilderRef,
+                                 RetVals: *const ValueRef,
+                                 N: c_uint)
+                                 -> ValueRef;
+    pub fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
+    pub fn LLVMBuildCondBr(B: BuilderRef,
+                           If: ValueRef,
+                           Then: BasicBlockRef,
+                           Else: BasicBlockRef)
+                           -> ValueRef;
+    pub fn LLVMBuildSwitch(B: BuilderRef,
+                           V: ValueRef,
+                           Else: BasicBlockRef,
+                           NumCases: c_uint)
+                           -> ValueRef;
+    pub fn LLVMBuildIndirectBr(B: BuilderRef,
+                               Addr: ValueRef,
+                               NumDests: c_uint)
+                               -> ValueRef;
+    pub fn LLVMBuildInvoke(B: BuilderRef,
+                           Fn: ValueRef,
+                           Args: *const ValueRef,
+                           NumArgs: c_uint,
+                           Then: BasicBlockRef,
+                           Catch: BasicBlockRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildLandingPad(B: BuilderRef,
+                               Ty: TypeRef,
+                               PersFn: ValueRef,
+                               NumClauses: c_uint,
+                               Name: *const c_char)
+                               -> ValueRef;
+    pub fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
+    pub fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
+
+    /* Add a case to the switch instruction */
+    pub fn LLVMAddCase(Switch: ValueRef,
+                       OnVal: ValueRef,
+                       Dest: BasicBlockRef);
+
+    /* Add a destination to the indirectbr instruction */
+    pub fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
+
+    /* Add a clause to the landing pad instruction */
+    pub fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
+
+    /* Set the cleanup on a landing pad instruction */
+    pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
+
+    /* Arithmetic */
+    pub fn LLVMBuildAdd(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildNSWAdd(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildNUWAdd(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFAdd(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildSub(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildNSWSub(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildNUWSub(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFSub(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildMul(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildNSWMul(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildNUWMul(B: BuilderRef,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFMul(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildUDiv(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildSDiv(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildExactSDiv(B: BuilderRef,
+                              LHS: ValueRef,
+                              RHS: ValueRef,
+                              Name: *const c_char)
+                              -> ValueRef;
+    pub fn LLVMBuildFDiv(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildURem(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildSRem(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildFRem(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildShl(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildLShr(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildAShr(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildAnd(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildOr(B: BuilderRef,
+                       LHS: ValueRef,
+                       RHS: ValueRef,
+                       Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildXor(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildBinOp(B: BuilderRef,
+                          Op: Opcode,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+    pub fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                        -> ValueRef;
+
+    /* Memory */
+    pub fn LLVMBuildMalloc(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildArrayMalloc(B: BuilderRef,
+                                Ty: TypeRef,
+                                Val: ValueRef,
+                                Name: *const c_char)
+                                -> ValueRef;
+    pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildArrayAlloca(B: BuilderRef,
+                                Ty: TypeRef,
+                                Val: ValueRef,
+                                Name: *const c_char)
+                                -> ValueRef;
+    pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
+    pub fn LLVMBuildLoad(B: BuilderRef,
+                         PointerVal: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+
+    pub fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef)
+                          -> ValueRef;
+
+    pub fn LLVMBuildGEP(B: BuilderRef,
+                        Pointer: ValueRef,
+                        Indices: *const ValueRef,
+                        NumIndices: c_uint,
+                        Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildInBoundsGEP(B: BuilderRef,
+                                Pointer: ValueRef,
+                                Indices: *const ValueRef,
+                                NumIndices: c_uint,
+                                Name: *const c_char)
+                                -> ValueRef;
+    pub fn LLVMBuildStructGEP(B: BuilderRef,
+                              Pointer: ValueRef,
+                              Idx: c_uint,
+                              Name: *const c_char)
+                              -> ValueRef;
+    pub fn LLVMBuildGlobalString(B: BuilderRef,
+                                 Str: *const c_char,
+                                 Name: *const c_char)
+                                 -> ValueRef;
+    pub fn LLVMBuildGlobalStringPtr(B: BuilderRef,
+                                    Str: *const c_char,
+                                    Name: *const c_char)
+                                    -> ValueRef;
+
+    /* Casts */
+    pub fn LLVMBuildTrunc(B: BuilderRef,
+                          Val: ValueRef,
+                          DestTy: TypeRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+    pub fn LLVMBuildZExt(B: BuilderRef,
+                         Val: ValueRef,
+                         DestTy: TypeRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildSExt(B: BuilderRef,
+                         Val: ValueRef,
+                         DestTy: TypeRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildFPToUI(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFPToSI(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildUIToFP(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildSIToFP(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildFPTrunc(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+    pub fn LLVMBuildFPExt(B: BuilderRef,
+                          Val: ValueRef,
+                          DestTy: TypeRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+    pub fn LLVMBuildPtrToInt(B: BuilderRef,
+                             Val: ValueRef,
+                             DestTy: TypeRef,
+                             Name: *const c_char)
+                             -> ValueRef;
+    pub fn LLVMBuildIntToPtr(B: BuilderRef,
+                             Val: ValueRef,
+                             DestTy: TypeRef,
+                             Name: *const c_char)
+                             -> ValueRef;
+    pub fn LLVMBuildBitCast(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+    pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
+                                  Val: ValueRef,
+                                  DestTy: TypeRef,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+    pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
+                                  Val: ValueRef,
+                                  DestTy: TypeRef,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+    pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
+                                   Val: ValueRef,
+                                   DestTy: TypeRef,
+                                   Name: *const c_char)
+                                   -> ValueRef;
+    pub fn LLVMBuildCast(B: BuilderRef,
+                         Op: Opcode,
+                         Val: ValueRef,
+                         DestTy: TypeRef,
+                         Name: *const c_char) -> ValueRef;
+    pub fn LLVMBuildPointerCast(B: BuilderRef,
+                                Val: ValueRef,
+                                DestTy: TypeRef,
+                                Name: *const c_char)
+                                -> ValueRef;
+    pub fn LLVMBuildIntCast(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+    pub fn LLVMBuildFPCast(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+
+    /* Comparisons */
+    pub fn LLVMBuildICmp(B: BuilderRef,
+                         Op: c_uint,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildFCmp(B: BuilderRef,
+                         Op: c_uint,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+
+    /* Miscellaneous instructions */
+    pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+                        -> ValueRef;
+    pub fn LLVMBuildCall(B: BuilderRef,
+                         Fn: ValueRef,
+                         Args: *const ValueRef,
+                         NumArgs: c_uint,
+                         Name: *const c_char)
+                         -> ValueRef;
+    pub fn LLVMBuildSelect(B: BuilderRef,
+                           If: ValueRef,
+                           Then: ValueRef,
+                           Else: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildVAArg(B: BuilderRef,
+                          list: ValueRef,
+                          Ty: TypeRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+    pub fn LLVMBuildExtractElement(B: BuilderRef,
+                                   VecVal: ValueRef,
+                                   Index: ValueRef,
+                                   Name: *const c_char)
+                                   -> ValueRef;
+    pub fn LLVMBuildInsertElement(B: BuilderRef,
+                                  VecVal: ValueRef,
+                                  EltVal: ValueRef,
+                                  Index: ValueRef,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+    pub fn LLVMBuildShuffleVector(B: BuilderRef,
+                                  V1: ValueRef,
+                                  V2: ValueRef,
+                                  Mask: ValueRef,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+    pub fn LLVMBuildExtractValue(B: BuilderRef,
+                                 AggVal: ValueRef,
+                                 Index: c_uint,
+                                 Name: *const c_char)
+                                 -> ValueRef;
+    pub fn LLVMBuildInsertValue(B: BuilderRef,
+                                AggVal: ValueRef,
+                                EltVal: ValueRef,
+                                Index: c_uint,
+                                Name: *const c_char)
+                                -> ValueRef;
+
+    pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
+                           -> ValueRef;
+    pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
+                              -> ValueRef;
+    pub fn LLVMBuildPtrDiff(B: BuilderRef,
+                            LHS: ValueRef,
+                            RHS: ValueRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+
+    /* Atomic Operations */
+    pub fn LLVMBuildAtomicLoad(B: BuilderRef,
+                               PointerVal: ValueRef,
+                               Name: *const c_char,
+                               Order: AtomicOrdering,
+                               Alignment: c_uint)
+                               -> ValueRef;
+
+    pub fn LLVMBuildAtomicStore(B: BuilderRef,
+                                Val: ValueRef,
+                                Ptr: ValueRef,
+                                Order: AtomicOrdering,
+                                Alignment: c_uint)
+                                -> ValueRef;
+
+    pub fn LLVMBuildAtomicCmpXchg(B: BuilderRef,
+                                  LHS: ValueRef,
+                                  CMP: ValueRef,
+                                  RHS: ValueRef,
+                                  Order: AtomicOrdering,
+                                  FailureOrder: AtomicOrdering)
+                                  -> ValueRef;
+    pub fn LLVMBuildAtomicRMW(B: BuilderRef,
+                              Op: AtomicBinOp,
+                              LHS: ValueRef,
+                              RHS: ValueRef,
+                              Order: AtomicOrdering,
+                              SingleThreaded: Bool)
+                              -> ValueRef;
+
+    pub fn LLVMBuildAtomicFence(B: BuilderRef, Order: AtomicOrdering);
+
+
+    /* Selected entries from the downcasts. */
+    pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
+    pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef;
+
+    /** Writes a module to the specified path. Returns 0 on success. */
+    pub fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *const c_char) -> c_int;
+
+    /** Creates target data from a target layout string. */
+    pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef;
+    /// Adds the target data to the given pass manager. The pass manager
+    /// references the target data only weakly.
+    pub fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
+    /** Number of bytes clobbered when doing a Store to *T. */
+    pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
+                               -> c_ulonglong;
+
+    /** Number of bytes clobbered when doing a Store to *T. */
+    pub fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
+                                -> c_ulonglong;
+
+    /** Distance between successive elements in an array of T.
+    Includes ABI padding. */
+    pub fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_uint;
+
+    /** Returns the preferred alignment of a type. */
+    pub fn LLVMPreferredAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+                                        -> c_uint;
+    /** Returns the minimum alignment of a type. */
+    pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+                                  -> c_uint;
+
+    /// Computes the byte offset of the indexed struct element for a
+    /// target.
+    pub fn LLVMOffsetOfElement(TD: TargetDataRef,
+                               StructTy: TypeRef,
+                               Element: c_uint)
+                               -> c_ulonglong;
+
+    /**
+     * Returns the minimum alignment of a type when part of a call frame.
+     */
+    pub fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+                                        -> c_uint;
+
+    /** Disposes target data. */
+    pub fn LLVMDisposeTargetData(TD: TargetDataRef);
+
+    /** Creates a pass manager. */
+    pub fn LLVMCreatePassManager() -> PassManagerRef;
+
+    /** Creates a function-by-function pass manager */
+    pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef)
+                                                  -> PassManagerRef;
+
+    /** Disposes a pass manager. */
+    pub fn LLVMDisposePassManager(PM: PassManagerRef);
+
+    /** Runs a pass manager on a module. */
+    pub fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
+
+    /** Runs the function passes on the provided function. */
+    pub fn LLVMRunFunctionPassManager(FPM: PassManagerRef, F: ValueRef)
+                                      -> Bool;
+
+    /** Initializes all the function passes scheduled in the manager */
+    pub fn LLVMInitializeFunctionPassManager(FPM: PassManagerRef) -> Bool;
+
+    /** Finalizes all the function passes scheduled in the manager */
+    pub fn LLVMFinalizeFunctionPassManager(FPM: PassManagerRef) -> Bool;
+
+    pub fn LLVMInitializePasses();
+
+    /** Adds a verification pass. */
+    pub fn LLVMAddVerifierPass(PM: PassManagerRef);
+
+    pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
+    pub fn LLVMAddIPSCCPPass(PM: PassManagerRef);
+    pub fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
+    pub fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
+    pub fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
+    pub fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
+    pub fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
+    pub fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
+    pub fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
+    pub fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
+    pub fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
+    pub fn LLVMAddReassociatePass(PM: PassManagerRef);
+    pub fn LLVMAddLoopRotatePass(PM: PassManagerRef);
+    pub fn LLVMAddLICMPass(PM: PassManagerRef);
+    pub fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
+    pub fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
+    pub fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
+    pub fn LLVMAddGVNPass(PM: PassManagerRef);
+    pub fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
+    pub fn LLVMAddSCCPPass(PM: PassManagerRef);
+    pub fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
+    pub fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
+    pub fn LLVMAddConstantMergePass(PM: PassManagerRef);
+    pub fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
+    pub fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
+    pub fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
+    pub fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
+    pub fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
+    pub fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
+    pub fn LLVMAddPruneEHPass(PM: PassManagerRef);
+    pub fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
+    pub fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
+    pub fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
+    pub fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
+    pub fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
+
+    pub fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
+    pub fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
+    pub fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
+                                             OptimizationLevel: c_uint);
+    pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
+                                              Value: Bool);
+    pub fn LLVMPassManagerBuilderSetDisableUnitAtATime(
+        PMB: PassManagerBuilderRef,
+        Value: Bool);
+    pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(
+        PMB: PassManagerBuilderRef,
+        Value: Bool);
+    pub fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls(
+        PMB: PassManagerBuilderRef,
+        Value: Bool);
+    pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(
+        PMB: PassManagerBuilderRef,
+        threshold: c_uint);
+    pub fn LLVMPassManagerBuilderPopulateModulePassManager(
+        PMB: PassManagerBuilderRef,
+        PM: PassManagerRef);
+
+    pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(
+        PMB: PassManagerBuilderRef,
+        PM: PassManagerRef);
+    pub fn LLVMPassManagerBuilderPopulateLTOPassManager(
+        PMB: PassManagerBuilderRef,
+        PM: PassManagerRef,
+        Internalize: Bool,
+        RunInliner: Bool);
+
+    /** Destroys a memory buffer. */
+    pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
+
+
+    /* Stuff that's in rustllvm/ because it's not upstream yet. */
+
+    /** Opens an object file. */
+    pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
+    /** Closes an object file. */
+    pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
+
+    /** Enumerates the sections in an object file. */
+    pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
+    /** Destroys a section iterator. */
+    pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
+    /** Returns true if the section iterator is at the end of the section
+    list: */
+    pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
+                                      SI: SectionIteratorRef)
+                                      -> Bool;
+    /** Moves the section iterator to point to the next section. */
+    pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
+    /** Returns the current section size. */
+    pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
+    /** Returns the current section contents as a string buffer. */
+    pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char;
+
+    /** Reads the given file and returns it as a memory buffer. Use
+    LLVMDisposeMemoryBuffer() to get rid of it. */
+    pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char)
+                                                        -> MemoryBufferRef;
+    /** Borrows the contents of the memory buffer (doesn't copy it) */
+    pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *const c_char,
+                                                 InputDataLength: size_t,
+                                                 BufferName: *const c_char,
+                                                 RequiresNull: Bool)
+                                                 -> MemoryBufferRef;
+    pub fn LLVMCreateMemoryBufferWithMemoryRangeCopy(InputData: *const c_char,
+                                                     InputDataLength: size_t,
+                                                     BufferName: *const c_char)
+                                                     -> MemoryBufferRef;
+
+    pub fn LLVMIsMultithreaded() -> Bool;
+    pub fn LLVMStartMultithreaded() -> Bool;
+
+    /** Returns a string describing the last error caused by an LLVMRust*
+    call. */
+    pub fn LLVMRustGetLastError() -> *const c_char;
+
+    /// Print the pass timings since static dtors aren't picking them up.
+    pub fn LLVMRustPrintPassTimings();
+
+    pub fn LLVMStructCreateNamed(C: ContextRef, Name: *const c_char) -> TypeRef;
+
+    pub fn LLVMStructSetBody(StructTy: TypeRef,
+                             ElementTypes: *const TypeRef,
+                             ElementCount: c_uint,
+                             Packed: Bool);
+
+    pub fn LLVMConstNamedStruct(S: TypeRef,
+                                ConstantVals: *const ValueRef,
+                                Count: c_uint)
+                                -> ValueRef;
+
+    /** Enables LLVM debug output. */
+    pub fn LLVMSetDebug(Enabled: c_int);
+
+    /** Prepares inline assembly. */
+    pub fn LLVMInlineAsm(Ty: TypeRef,
+                         AsmString: *const c_char,
+                         Constraints: *const c_char,
+                         SideEffects: Bool,
+                         AlignStack: Bool,
+                         Dialect: c_uint)
+                         -> ValueRef;
+
+    pub static LLVMRustDebugMetadataVersion: u32;
+
+    pub fn LLVMRustAddModuleFlag(M: ModuleRef,
+                                 name: *const c_char,
+                                 value: u32);
+
+    pub fn LLVMDIBuilderCreate(M: ModuleRef) -> DIBuilderRef;
+
+    pub fn LLVMDIBuilderDispose(Builder: DIBuilderRef);
+
+    pub fn LLVMDIBuilderFinalize(Builder: DIBuilderRef);
+
+    pub fn LLVMDIBuilderCreateCompileUnit(Builder: DIBuilderRef,
+                                          Lang: c_uint,
+                                          File: *const c_char,
+                                          Dir: *const c_char,
+                                          Producer: *const c_char,
+                                          isOptimized: bool,
+                                          Flags: *const c_char,
+                                          RuntimeVer: c_uint,
+                                          SplitName: *const c_char);
+
+    pub fn LLVMDIBuilderCreateFile(Builder: DIBuilderRef,
+                                   Filename: *const c_char,
+                                   Directory: *const c_char)
+                                   -> DIFile;
+
+    pub fn LLVMDIBuilderCreateSubroutineType(Builder: DIBuilderRef,
+                                             File: DIFile,
+                                             ParameterTypes: DIArray)
+                                             -> DICompositeType;
+
+    pub fn LLVMDIBuilderCreateFunction(Builder: DIBuilderRef,
+                                       Scope: DIDescriptor,
+                                       Name: *const c_char,
+                                       LinkageName: *const c_char,
+                                       File: DIFile,
+                                       LineNo: c_uint,
+                                       Ty: DIType,
+                                       isLocalToUnit: bool,
+                                       isDefinition: bool,
+                                       ScopeLine: c_uint,
+                                       Flags: c_uint,
+                                       isOptimized: bool,
+                                       Fn: ValueRef,
+                                       TParam: ValueRef,
+                                       Decl: ValueRef)
+                                       -> DISubprogram;
+
+    pub fn LLVMDIBuilderCreateBasicType(Builder: DIBuilderRef,
+                                        Name: *const c_char,
+                                        SizeInBits: c_ulonglong,
+                                        AlignInBits: c_ulonglong,
+                                        Encoding: c_uint)
+                                        -> DIBasicType;
+
+    pub fn LLVMDIBuilderCreatePointerType(Builder: DIBuilderRef,
+                                          PointeeTy: DIType,
+                                          SizeInBits: c_ulonglong,
+                                          AlignInBits: c_ulonglong,
+                                          Name: *const c_char)
+                                          -> DIDerivedType;
+
+    pub fn LLVMDIBuilderCreateStructType(Builder: DIBuilderRef,
+                                         Scope: DIDescriptor,
+                                         Name: *const c_char,
+                                         File: DIFile,
+                                         LineNumber: c_uint,
+                                         SizeInBits: c_ulonglong,
+                                         AlignInBits: c_ulonglong,
+                                         Flags: c_uint,
+                                         DerivedFrom: DIType,
+                                         Elements: DIArray,
+                                         RunTimeLang: c_uint,
+                                         VTableHolder: ValueRef,
+                                         UniqueId: *const c_char)
+                                         -> DICompositeType;
+
+    pub fn LLVMDIBuilderCreateMemberType(Builder: DIBuilderRef,
+                                         Scope: DIDescriptor,
+                                         Name: *const c_char,
+                                         File: DIFile,
+                                         LineNo: c_uint,
+                                         SizeInBits: c_ulonglong,
+                                         AlignInBits: c_ulonglong,
+                                         OffsetInBits: c_ulonglong,
+                                         Flags: c_uint,
+                                         Ty: DIType)
+                                         -> DIDerivedType;
+
+    pub fn LLVMDIBuilderCreateLexicalBlock(Builder: DIBuilderRef,
+                                           Scope: DIDescriptor,
+                                           File: DIFile,
+                                           Line: c_uint,
+                                           Col: c_uint,
+                                           Discriminator: c_uint)
+                                           -> DILexicalBlock;
+
+    pub fn LLVMDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
+                                             Context: DIDescriptor,
+                                             Name: *const c_char,
+                                             LinkageName: *const c_char,
+                                             File: DIFile,
+                                             LineNo: c_uint,
+                                             Ty: DIType,
+                                             isLocalToUnit: bool,
+                                             Val: ValueRef,
+                                             Decl: ValueRef)
+                                             -> DIGlobalVariable;
+
+    pub fn LLVMDIBuilderCreateLocalVariable(Builder: DIBuilderRef,
+                                            Tag: c_uint,
+                                            Scope: DIDescriptor,
+                                            Name: *const c_char,
+                                            File: DIFile,
+                                            LineNo: c_uint,
+                                            Ty: DIType,
+                                            AlwaysPreserve: bool,
+                                            Flags: c_uint,
+                                            ArgNo: c_uint)
+                                            -> DIVariable;
+
+    pub fn LLVMDIBuilderCreateArrayType(Builder: DIBuilderRef,
+                                        Size: c_ulonglong,
+                                        AlignInBits: c_ulonglong,
+                                        Ty: DIType,
+                                        Subscripts: DIArray)
+                                        -> DIType;
+
+    pub fn LLVMDIBuilderCreateVectorType(Builder: DIBuilderRef,
+                                         Size: c_ulonglong,
+                                         AlignInBits: c_ulonglong,
+                                         Ty: DIType,
+                                         Subscripts: DIArray)
+                                         -> DIType;
+
+    pub fn LLVMDIBuilderGetOrCreateSubrange(Builder: DIBuilderRef,
+                                            Lo: c_longlong,
+                                            Count: c_longlong)
+                                            -> DISubrange;
+
+    pub fn LLVMDIBuilderGetOrCreateArray(Builder: DIBuilderRef,
+                                         Ptr: *const DIDescriptor,
+                                         Count: c_uint)
+                                         -> DIArray;
+
+    pub fn LLVMDIBuilderInsertDeclareAtEnd(Builder: DIBuilderRef,
+                                           Val: ValueRef,
+                                           VarInfo: DIVariable,
+                                           InsertAtEnd: BasicBlockRef)
+                                           -> ValueRef;
+
+    pub fn LLVMDIBuilderInsertDeclareBefore(Builder: DIBuilderRef,
+                                            Val: ValueRef,
+                                            VarInfo: DIVariable,
+                                            InsertBefore: ValueRef)
+                                            -> ValueRef;
+
+    pub fn LLVMDIBuilderCreateEnumerator(Builder: DIBuilderRef,
+                                         Name: *const c_char,
+                                         Val: c_ulonglong)
+                                         -> ValueRef;
+
+    pub fn LLVMDIBuilderCreateEnumerationType(Builder: DIBuilderRef,
+                                              Scope: ValueRef,
+                                              Name: *const c_char,
+                                              File: ValueRef,
+                                              LineNumber: c_uint,
+                                              SizeInBits: c_ulonglong,
+                                              AlignInBits: c_ulonglong,
+                                              Elements: ValueRef,
+                                              ClassType: ValueRef)
+                                              -> ValueRef;
+
+    pub fn LLVMDIBuilderCreateUnionType(Builder: DIBuilderRef,
+                                        Scope: ValueRef,
+                                        Name: *const c_char,
+                                        File: ValueRef,
+                                        LineNumber: c_uint,
+                                        SizeInBits: c_ulonglong,
+                                        AlignInBits: c_ulonglong,
+                                        Flags: c_uint,
+                                        Elements: ValueRef,
+                                        RunTimeLang: c_uint,
+                                        UniqueId: *const c_char)
+                                        -> ValueRef;
+
+    pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
+
+    pub fn LLVMDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef,
+                                                    Scope: ValueRef,
+                                                    Name: *const c_char,
+                                                    Ty: ValueRef,
+                                                    File: ValueRef,
+                                                    LineNo: c_uint,
+                                                    ColumnNo: c_uint)
+                                                    -> ValueRef;
+
+    pub fn LLVMDIBuilderCreateOpDeref(IntType: TypeRef) -> ValueRef;
+
+    pub fn LLVMDIBuilderCreateOpPlus(IntType: TypeRef) -> ValueRef;
+
+    pub fn LLVMDIBuilderCreateComplexVariable(Builder: DIBuilderRef,
+                                              Tag: c_uint,
+                                              Scope: ValueRef,
+                                              Name: *const c_char,
+                                              File: ValueRef,
+                                              LineNo: c_uint,
+                                              Ty: ValueRef,
+                                              AddrOps: *const ValueRef,
+                                              AddrOpsCount: c_uint,
+                                              ArgNo: c_uint)
+                                              -> ValueRef;
+
+    pub fn LLVMDIBuilderCreateNameSpace(Builder: DIBuilderRef,
+                                        Scope: ValueRef,
+                                        Name: *const c_char,
+                                        File: ValueRef,
+                                        LineNo: c_uint)
+                                        -> ValueRef;
+
+    pub fn LLVMDICompositeTypeSetTypeArray(CompositeType: ValueRef, TypeArray: ValueRef);
+    pub fn LLVMTypeToString(Type: TypeRef) -> *const c_char;
+    pub fn LLVMValueToString(value_ref: ValueRef) -> *const c_char;
+
+    pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
+
+    pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
+
+    pub fn LLVMInitializeX86TargetInfo();
+    pub fn LLVMInitializeX86Target();
+    pub fn LLVMInitializeX86TargetMC();
+    pub fn LLVMInitializeX86AsmPrinter();
+    pub fn LLVMInitializeX86AsmParser();
+    pub fn LLVMInitializeARMTargetInfo();
+    pub fn LLVMInitializeARMTarget();
+    pub fn LLVMInitializeARMTargetMC();
+    pub fn LLVMInitializeARMAsmPrinter();
+    pub fn LLVMInitializeARMAsmParser();
+    pub fn LLVMInitializeMipsTargetInfo();
+    pub fn LLVMInitializeMipsTarget();
+    pub fn LLVMInitializeMipsTargetMC();
+    pub fn LLVMInitializeMipsAsmPrinter();
+    pub fn LLVMInitializeMipsAsmParser();
+
+    pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: *const c_char) -> bool;
+    pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
+                                       CPU: *const c_char,
+                                       Features: *const c_char,
+                                       Model: CodeGenModel,
+                                       Reloc: RelocMode,
+                                       Level: CodeGenOptLevel,
+                                       EnableSegstk: bool,
+                                       UseSoftFP: bool,
+                                       NoFramePointerElim: bool,
+                                       FunctionSections: bool,
+                                       DataSections: bool) -> TargetMachineRef;
+    pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
+    pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef,
+                                     PM: PassManagerRef,
+                                     M: ModuleRef);
+    pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
+                                         M: ModuleRef,
+                                         DisableSimplifyLibCalls: bool);
+    pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef,
+                                  DisableSimplifyLibCalls: bool);
+    pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef);
+    pub fn LLVMRustWriteOutputFile(T: TargetMachineRef,
+                                   PM: PassManagerRef,
+                                   M: ModuleRef,
+                                   Output: *const c_char,
+                                   FileType: FileType) -> bool;
+    pub fn LLVMRustPrintModule(PM: PassManagerRef,
+                               M: ModuleRef,
+                               Output: *const c_char);
+    pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
+    pub fn LLVMRustPrintPasses();
+    pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char);
+    pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef,
+                                       AddLifetimes: bool);
+    pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef,
+                                         bc: *const c_char,
+                                         len: size_t) -> bool;
+    pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
+                                      syms: *const *const c_char,
+                                      len: size_t);
+    pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
+
+    pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef;
+    pub fn LLVMRustArchiveReadSection(AR: ArchiveRef, name: *const c_char,
+                                      out_len: *mut size_t) -> *const c_char;
+    pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
+
+    pub fn LLVMRustSetDLLExportStorageClass(V: ValueRef);
+    pub fn LLVMVersionMajor() -> c_int;
+    pub fn LLVMVersionMinor() -> c_int;
+
+    pub fn LLVMRustGetSectionName(SI: SectionIteratorRef,
+                                  data: *mut *const c_char) -> c_int;
+}
+
+pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
+    unsafe {
+        LLVMSetInstructionCallConv(instr, cc as c_uint);
+    }
+}
+pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
+    unsafe {
+        LLVMSetFunctionCallConv(fn_, cc as c_uint);
+    }
+}
+pub fn SetLinkage(global: ValueRef, link: Linkage) {
+    unsafe {
+        LLVMSetLinkage(global, link as c_uint);
+    }
+}
+
+pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) {
+    unsafe {
+        LLVMSetUnnamedAddr(global, unnamed as Bool);
+    }
+}
+
+pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
+    unsafe {
+        LLVMSetThreadLocal(global, is_thread_local as Bool);
+    }
+}
+
+pub fn ConstICmp(pred: IntPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
+    unsafe {
+        LLVMConstICmp(pred as c_ushort, v1, v2)
+    }
+}
+pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
+    unsafe {
+        LLVMConstFCmp(pred as c_ushort, v1, v2)
+    }
+}
+
+pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
+    unsafe {
+        LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr as uint64_t)
+    }
+}
+
+/* Memory-managed interface to target data. */
+
+pub struct TargetData {
+    pub lltd: TargetDataRef
+}
+
+impl Drop for TargetData {
+    fn drop(&mut self) {
+        unsafe {
+            LLVMDisposeTargetData(self.lltd);
+        }
+    }
+}
+
+pub fn mk_target_data(string_rep: &str) -> TargetData {
+    TargetData {
+        lltd: string_rep.with_c_str(|buf| {
+            unsafe { LLVMCreateTargetData(buf) }
+        })
+    }
+}
+
+/* Memory-managed interface to object files. */
+
+pub struct ObjectFile {
+    pub llof: ObjectFileRef,
+}
+
+impl ObjectFile {
+    // This will take ownership of llmb
+    pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
+        unsafe {
+            let llof = LLVMCreateObjectFile(llmb);
+            if llof as int == 0 {
+                // LLVMCreateObjectFile took ownership of llmb
+                return None
+            }
+
+            Some(ObjectFile {
+                llof: llof,
+            })
+        }
+    }
+}
+
+impl Drop for ObjectFile {
+    fn drop(&mut self) {
+        unsafe {
+            LLVMDisposeObjectFile(self.llof);
+        }
+    }
+}
+
+/* Memory-managed interface to section iterators. */
+
+pub struct SectionIter {
+    pub llsi: SectionIteratorRef
+}
+
+impl Drop for SectionIter {
+    fn drop(&mut self) {
+        unsafe {
+            LLVMDisposeSectionIterator(self.llsi);
+        }
+    }
+}
+
+pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter {
+    unsafe {
+        SectionIter {
+            llsi: LLVMGetSections(llof)
+        }
+    }
+}
+
+// FIXME #15460 - create a public function that actually calls our
+// static LLVM symbols. Otherwise the linker will just throw llvm
+// away.  We're just calling lots of stuff until we transitively get
+// all of LLVM. This is worse than anything.
+pub unsafe fn static_link_hack_this_sucks() {
+    LLVMInitializePasses();
+
+    LLVMInitializeX86TargetInfo();
+    LLVMInitializeX86Target();
+    LLVMInitializeX86TargetMC();
+    LLVMInitializeX86AsmPrinter();
+    LLVMInitializeX86AsmParser();
+
+    LLVMInitializeARMTargetInfo();
+    LLVMInitializeARMTarget();
+    LLVMInitializeARMTargetMC();
+    LLVMInitializeARMAsmPrinter();
+    LLVMInitializeARMAsmParser();
+
+    LLVMInitializeMipsTargetInfo();
+    LLVMInitializeMipsTarget();
+    LLVMInitializeMipsTargetMC();
+    LLVMInitializeMipsAsmPrinter();
+    LLVMInitializeMipsAsmParser();
+
+    LLVMRustSetLLVMOptions(0 as c_int,
+                                       0 as *const _);
+
+    LLVMPassManagerBuilderPopulateModulePassManager(0 as *mut _, 0 as *mut _);
+    LLVMPassManagerBuilderPopulateLTOPassManager(0 as *mut _, 0 as *mut _, False, False);
+    LLVMPassManagerBuilderPopulateFunctionPassManager(0 as *mut _, 0 as *mut _);
+    LLVMPassManagerBuilderSetOptLevel(0 as *mut _, 0 as c_uint);
+    LLVMPassManagerBuilderUseInlinerWithThreshold(0 as *mut _, 0 as c_uint);
+    LLVMWriteBitcodeToFile(0 as *mut _, 0 as *const _);
+    LLVMPassManagerBuilderCreate();
+    LLVMPassManagerBuilderDispose(0 as *mut _);
+
+    LLVMRustLinkInExternalBitcode(0 as *mut _, 0 as *const _, 0 as size_t);
+
+    LLVMLinkInJIT();
+    LLVMLinkInMCJIT();
+    LLVMLinkInInterpreter();
+
+    extern {
+        fn LLVMLinkInJIT();
+        fn LLVMLinkInMCJIT();
+        fn LLVMLinkInInterpreter();
+    }
+}
+
+// The module containing the native LLVM dependencies, generated by the build system
+// Note that this must come after the rustllvm extern declaration so that
+// parts of LLVM that rustllvm depends on aren't thrown away by the linker.
+// Works to the above fix for #15460 to ensure LLVM dependencies that
+// are only used by rustllvm don't get stripped by the linker.
+mod llvmdeps;
+
index 2d498e7f302d3fca3330b0182ea547608eac6c68..b3891432e2146e280317216cdedcb4f2aa877c16 100644 (file)
@@ -99,7 +99,7 @@ fn try_inline_def(cx: &core::DocContext,
     cx.inlined.borrow_mut().get_mut_ref().insert(did);
     ret.push(clean::Item {
         source: clean::Span::empty(),
-        name: Some(fqn.last().unwrap().to_str()),
+        name: Some(fqn.last().unwrap().to_string()),
         attrs: load_attrs(tcx, did),
         inner: inner,
         visibility: Some(ast::Public),
@@ -136,7 +136,7 @@ pub fn record_extern_fqn(cx: &core::DocContext,
     match cx.maybe_typed {
         core::Typed(ref tcx) => {
             let fqn = csearch::get_item_path(tcx, did);
-            let fqn = fqn.move_iter().map(|i| i.to_str()).collect();
+            let fqn = fqn.move_iter().map(|i| i.to_string()).collect();
             cx.external_paths.borrow_mut().get_mut_ref().insert(did, (fqn, kind));
         }
         core::NotTyped(..) => {}
index 4808cbdb4b09b332986c01c64214088562e7a098..2e3bb2eef7d9df7b77f14a9f1895854ad0bcc5d9 100644 (file)
@@ -119,13 +119,7 @@ fn clean(&self) -> Crate {
 
         // Figure out the name of this crate
         let input = driver::FileInput(cx.src.clone());
-        let t_outputs = driver::build_output_filenames(&input,
-                                                       &None,
-                                                       &None,
-                                                       self.attrs.as_slice(),
-                                                       cx.sess());
-        let id = link::find_crate_id(self.attrs.as_slice(),
-                                     t_outputs.out_filestem.as_slice());
+        let name = link::find_crate_name(None, self.attrs.as_slice(), &input);
 
         // Clean the crate, translating the entire libsyntax AST to one that is
         // understood by rustdoc.
@@ -188,7 +182,7 @@ fn clean(&self) -> Crate {
         }
 
         Crate {
-            name: id.name.to_string(),
+            name: name.to_string(),
             module: Some(module),
             externs: externs,
             primitives: primitives,
@@ -414,7 +408,7 @@ fn clean(&self) -> Attribute {
                 List(s.get().to_string(), l.clean().move_iter().collect())
             }
             ast::MetaNameValue(ref s, ref v) => {
-                NameValue(s.get().to_string(), lit_to_str(v))
+                NameValue(s.get().to_string(), lit_to_string(v))
             }
         }
     }
@@ -505,11 +499,12 @@ fn clean(&self) -> TyParamBound {
 }
 
 fn external_path(name: &str, substs: &subst::Substs) -> Path {
-    let lifetimes = substs.regions().get_vec(subst::TypeSpace)
+    let lifetimes = substs.regions().get_slice(subst::TypeSpace)
                     .iter()
                     .filter_map(|v| v.clean())
                     .collect();
-    let types = substs.types.get_vec(subst::TypeSpace).clean();
+    let types = Vec::from_slice(substs.types.get_slice(subst::TypeSpace));
+    let types = types.clean();
     Path {
         global: false,
         segments: vec![PathSegment {
@@ -544,7 +539,7 @@ fn clean(&self) -> TyParamBound {
                  external_path("Share", &empty)),
         };
         let fqn = csearch::get_item_path(tcx, did);
-        let fqn = fqn.move_iter().map(|i| i.to_str()).collect();
+        let fqn = fqn.move_iter().map(|i| i.to_string()).collect();
         cx.external_paths.borrow_mut().get_mut_ref().insert(did,
                                                             (fqn, TypeTrait));
         TraitBound(ResolvedPath {
@@ -563,7 +558,7 @@ fn clean(&self) -> TyParamBound {
             core::NotTyped(_) => return RegionBound,
         };
         let fqn = csearch::get_item_path(tcx, self.def_id);
-        let fqn = fqn.move_iter().map(|i| i.to_str())
+        let fqn = fqn.move_iter().map(|i| i.to_string())
                      .collect::<Vec<String>>();
         let path = external_path(fqn.last().unwrap().as_slice(),
                                  &self.substs);
@@ -674,8 +669,8 @@ fn clean(&self) -> Generics {
         // is implicit.
 
         let space = {
-            if !self.types.get_vec(subst::FnSpace).is_empty() ||
-                !self.regions.get_vec(subst::FnSpace).is_empty()
+            if !self.types.is_empty_in(subst::FnSpace) ||
+                !self.regions.is_empty_in(subst::FnSpace)
             {
                 subst::FnSpace
             } else {
@@ -684,8 +679,8 @@ fn clean(&self) -> Generics {
         };
 
         Generics {
-            type_params: self.types.get_vec(space).clean(),
-            lifetimes: self.regions.get_vec(space).clean(),
+            type_params: Vec::from_slice(self.types.get_slice(space)).clean(),
+            lifetimes: Vec::from_slice(self.regions.get_slice(space)).clean(),
         }
     }
 }
@@ -700,29 +695,30 @@ pub struct Method {
 
 impl Clean<Item> for ast::Method {
     fn clean(&self) -> Item {
-        let inputs = match self.explicit_self.node {
-            ast::SelfStatic => self.decl.inputs.as_slice(),
-            _ => self.decl.inputs.slice_from(1)
+        let fn_decl = ast_util::method_fn_decl(self);
+        let inputs = match ast_util::method_explicit_self(self).node {
+            ast::SelfStatic => fn_decl.inputs.as_slice(),
+            _ => fn_decl.inputs.slice_from(1)
         };
         let decl = FnDecl {
             inputs: Arguments {
                 values: inputs.iter().map(|x| x.clean()).collect(),
             },
-            output: (self.decl.output.clean()),
-            cf: self.decl.cf.clean(),
+            output: (fn_decl.output.clean()),
+            cf: fn_decl.cf.clean(),
             attrs: Vec::new()
         };
         Item {
-            name: Some(self.ident.clean()),
+            name: Some(ast_util::method_ident(self).clean()),
             attrs: self.attrs.clean().move_iter().collect(),
             source: self.span.clean(),
             def_id: ast_util::local_def(self.id),
-            visibility: self.vis.clean(),
+            visibility: ast_util::method_vis(self).clean(),
             stability: get_stability(ast_util::local_def(self.id)),
             inner: MethodItem(Method {
-                generics: self.generics.clean(),
-                self_: self.explicit_self.node.clean(),
-                fn_style: self.fn_style.clone(),
+                generics: ast_util::method_generics(self).clean(),
+                self_: ast_util::method_explicit_self(self).node.clean(),
+                fn_style: ast_util::method_fn_style(self).clone(),
                 decl: decl,
             }),
         }
@@ -780,9 +776,9 @@ impl Clean<SelfTy> for ast::ExplicitSelf_ {
     fn clean(&self) -> SelfTy {
         match *self {
             ast::SelfStatic => SelfStatic,
-            ast::SelfValue => SelfValue,
-            ast::SelfUniq => SelfOwned,
-            ast::SelfRegion(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
+            ast::SelfValue(_) => SelfValue,
+            ast::SelfUniq(_) => SelfOwned,
+            ast::SelfRegion(lt, mt, _) => SelfBorrowed(lt.clean(), mt.clean()),
         }
     }
 }
@@ -1142,7 +1138,7 @@ fn find(attrs: &[Attribute]) -> Option<Primitive> {
         return None
     }
 
-    pub fn to_str(&self) -> &'static str {
+    pub fn to_string(&self) -> &'static str {
         match *self {
             Int => "int",
             I8 => "i8",
@@ -1168,7 +1164,7 @@ pub fn to_str(&self) -> &'static str {
     pub fn to_url_str(&self) -> &'static str {
         match *self {
             Unit => "unit",
-            other => other.to_str(),
+            other => other.to_string(),
         }
     }
 
@@ -1247,7 +1243,7 @@ fn clean(&self) -> Type {
                     lifetimes: Vec::new(), type_params: Vec::new()
                 },
                 decl: (ast_util::local_def(0), &fty.sig).clean(),
-                abi: fty.abi.to_str(),
+                abi: fty.abi.to_string(),
             }),
             ty::ty_closure(ref fty) => {
                 let decl = box ClosureDecl {
@@ -1267,14 +1263,14 @@ fn clean(&self) -> Type {
             ty::ty_trait(box ty::TyTrait { def_id: did, ref substs, .. }) => {
                 let fqn = csearch::get_item_path(get_cx().tcx(), did);
                 let fqn: Vec<String> = fqn.move_iter().map(|i| {
-                    i.to_str()
+                    i.to_string()
                 }).collect();
                 let kind = match ty::get(*self).sty {
                     ty::ty_struct(..) => TypeStruct,
                     ty::ty_trait(..) => TypeTrait,
                     _ => TypeEnum,
                 };
-                let path = external_path(fqn.last().unwrap().to_str().as_slice(),
+                let path = external_path(fqn.last().unwrap().to_string().as_slice(),
                                          substs);
                 get_cx().external_paths.borrow_mut().get_mut_ref()
                                        .insert(did, (fqn, kind));
@@ -1466,12 +1462,15 @@ fn clean(&self) -> Item {
                             name: Some(name.clean()),
                             attrs: Vec::new(),
                             visibility: Some(ast::Public),
-                            stability: get_stability(self.id),
                             // FIXME: this is not accurate, we need an id for
                             //        the specific field but we're using the id
-                            //        for the whole variant. Nothing currently
-                            //        uses this so we should be good for now.
+                            //        for the whole variant. Thus we read the
+                            //        stability from the whole variant as well.
+                            //        Struct variants are experimental and need
+                            //        more infrastructure work before we can get
+                            //        at the needed information here.
                             def_id: self.id,
+                            stability: get_stability(self.id),
                             inner: StructFieldItem(
                                 TypedStructField(ty.clean())
                             )
@@ -1487,7 +1486,7 @@ fn clean(&self) -> Item {
             visibility: Some(ast::Public),
             def_id: self.id,
             inner: VariantItem(Variant { kind: kind }),
-            stability: None,
+            stability: get_stability(self.id),
         }
     }
 }
@@ -1582,7 +1581,7 @@ fn clean(&self) -> PathSegment {
     }
 }
 
-fn path_to_str(p: &ast::Path) -> String {
+fn path_to_string(p: &ast::Path) -> String {
     let mut s = String::new();
     let mut first = true;
     for i in p.segments.iter().map(|x| token::get_ident(x.identifier)) {
@@ -1648,7 +1647,7 @@ fn clean(&self) -> BareFunctionDecl {
                 type_params: Vec::new(),
             },
             decl: self.decl.clean(),
-            abi: self.abi.to_str(),
+            abi: self.abi.to_string(),
         }
     }
 }
@@ -1895,7 +1894,7 @@ fn clean(&self) -> Item {
             source: self.span.clean(),
             def_id: ast_util::local_def(self.id),
             visibility: self.vis.clean(),
-            stability: None,
+            stability: get_stability(ast_util::local_def(self.id)),
             inner: inner,
         }
     }
@@ -1921,7 +1920,7 @@ fn to_src(&self) -> String {
     }
 }
 
-fn lit_to_str(lit: &ast::Lit) -> String {
+fn lit_to_string(lit: &ast::Lit) -> String {
     match lit.node {
         ast::LitStr(ref st, _) => st.get().to_string(),
         ast::LitBinary(ref data) => format!("{:?}", data.as_slice()),
@@ -1934,12 +1933,12 @@ fn lit_to_str(lit: &ast::Lit) -> String {
             res
         },
         ast::LitChar(c) => format!("'{}'", c),
-        ast::LitInt(i, _t) => i.to_str(),
-        ast::LitUint(u, _t) => u.to_str(),
-        ast::LitIntUnsuffixed(i) => i.to_str(),
+        ast::LitInt(i, _t) => i.to_string(),
+        ast::LitUint(u, _t) => u.to_string(),
+        ast::LitIntUnsuffixed(i) => i.to_string(),
         ast::LitFloat(ref f, _t) => f.get().to_string(),
         ast::LitFloatUnsuffixed(ref f) => f.get().to_string(),
-        ast::LitBool(b) => b.to_str(),
+        ast::LitBool(b) => b.to_string(),
         ast::LitNil => "".to_string(),
     }
 }
@@ -1952,10 +1951,17 @@ fn name_from_pat(p: &ast::Pat) -> String {
         PatWild => "_".to_string(),
         PatWildMulti => "..".to_string(),
         PatIdent(_, ref p, _) => token::get_ident(p.node).get().to_string(),
-        PatEnum(ref p, _) => path_to_str(p),
-        PatStruct(..) => fail!("tried to get argument name from pat_struct, \
-                                which is not allowed in function arguments"),
-        PatTup(..) => "(tuple arg NYI)".to_string(),
+        PatEnum(ref p, _) => path_to_string(p),
+        PatStruct(ref name, ref fields, etc) => {
+            format!("{} {{ {}{} }}", path_to_string(name),
+                fields.iter().map(|fp|
+                                  format!("{}: {}", fp.ident.as_str(), name_from_pat(&*fp.pat)))
+                             .collect::<Vec<String>>().connect(", "),
+                if etc { ", ..." } else { "" }
+            )
+        },
+        PatTup(ref elts) => format!("({})", elts.iter().map(|p| name_from_pat(&**p))
+                                            .collect::<Vec<String>>().connect(", ")),
         PatBox(p) => name_from_pat(&*p),
         PatRegion(p) => name_from_pat(&*p),
         PatLit(..) => {
index 245b2d162a77b02c76632dd77042628834119b65..e62c8b63a294070b0c873f5cccecc9775b22a24f 100644 (file)
@@ -12,6 +12,7 @@
 use rustc::{driver, middle};
 use rustc::middle::{privacy, ty};
 use rustc::lint;
+use rustc::back::link;
 
 use syntax::ast;
 use syntax::parse::token;
@@ -100,7 +101,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
 
 
     let codemap = syntax::codemap::CodeMap::new();
-    let diagnostic_handler = syntax::diagnostic::default_handler(syntax::diagnostic::Auto);
+    let diagnostic_handler = syntax::diagnostic::default_handler(syntax::diagnostic::Auto, None);
     let span_diagnostic_handler =
         syntax::diagnostic::mk_span_handler(diagnostic_handler, codemap);
 
@@ -115,13 +116,17 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
     }
 
     let krate = phase_1_parse_input(&sess, cfg, &input);
+
+    let name = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
+                                     &input);
+
     let (krate, ast_map)
-        = phase_2_configure_and_expand(&sess, krate, &from_str("rustdoc").unwrap())
+        = phase_2_configure_and_expand(&sess, krate, name.as_slice())
             .expect("phase_2_configure_and_expand aborted in rustdoc!");
 
     let driver::driver::CrateAnalysis {
         exported_items, public_items, ty_cx, ..
-    } = phase_3_run_analysis_passes(sess, &krate, ast_map);
+    } = phase_3_run_analysis_passes(sess, &krate, ast_map, name);
 
     debug!("crate: {:?}", krate);
     (DocContext {
index cec665768d1ee86ab4aad758480f60792d7f5283..c549469dcdeaaa19e90ef72caec2f9d438ebf4ea 100644 (file)
@@ -22,6 +22,7 @@
 use syntax::ast_util;
 
 use clean;
+use stability_summary::ModuleSummary;
 use html::item_type;
 use html::item_type::ItemType;
 use html::render;
@@ -37,6 +38,8 @@
 pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
 /// Similar to VisSpace, but used for mutability
 pub struct MutableSpace(pub clean::Mutability);
+/// Similar to VisSpace, but used for mutability
+pub struct RawMutableSpace(pub clean::Mutability);
 /// Wrapper struct for properly emitting the stability level.
 pub struct Stability<'a>(pub &'a Option<clean::Stability>);
 /// Wrapper struct for emitting the stability level concisely.
@@ -351,7 +354,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 tybounds(f, typarams)
             }
             clean::Self(..) => f.write("Self".as_bytes()),
-            clean::Primitive(prim) => primitive_link(f, prim, prim.to_str()),
+            clean::Primitive(prim) => primitive_link(f, prim, prim.to_string()),
             clean::Closure(ref decl, ref region) => {
                 write!(f, "{style}{lifetimes}|{args}|{bounds}{arrow}",
                        style = FnStyleSpace(decl.fn_style),
@@ -405,7 +408,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                        } else {
                            let mut m = decl.bounds
                                            .iter()
-                                           .map(|s| s.to_str());
+                                           .map(|s| s.to_string());
                            format!(
                                ": {}",
                                m.collect::<Vec<String>>().connect(" + "))
@@ -428,7 +431,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             }
             clean::Tuple(ref typs) => {
                 primitive_link(f, clean::PrimitiveTuple,
-                               format!("({:#})", typs).as_slice())
+                               match typs.as_slice() {
+                                    [ref one] => format!("({},)", one),
+                                    many => format!("({:#})", many)
+                               }.as_slice())
             }
             clean::Vector(ref t) => {
                 primitive_link(f, clean::Slice, format!("[{}]", **t).as_slice())
@@ -441,7 +447,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             clean::Unique(ref t) => write!(f, "Box<{}>", **t),
             clean::Managed(ref t) => write!(f, "Gc<{}>", **t),
             clean::RawPointer(m, ref t) => {
-                write!(f, "*{}{}", MutableSpace(m), **t)
+                write!(f, "*{}{}", RawMutableSpace(m), **t)
             }
             clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => {
                 let lt = match *l {
@@ -601,13 +607,22 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+impl fmt::Show for RawMutableSpace {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            RawMutableSpace(clean::Immutable) => write!(f, "const "),
+            RawMutableSpace(clean::Mutable) => write!(f, "mut "),
+        }
+    }
+}
+
 impl<'a> fmt::Show for Stability<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let Stability(stab) = *self;
         match *stab {
             Some(ref stability) => {
                 write!(f, "<a class='stability {lvl}' title='{reason}'>{lvl}</a>",
-                       lvl = stability.level.to_str(),
+                       lvl = stability.level.to_string(),
                        reason = stability.text)
             }
             None => Ok(())
@@ -621,7 +636,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *stab {
             Some(ref stability) => {
                 write!(f, "<a class='stability {lvl}' title='{lvl}{colon}{reason}'></a>",
-                       lvl = stability.level.to_str(),
+                       lvl = stability.level.to_string(),
                        colon = if stability.text.len() > 0 { ": " } else { "" },
                        reason = stability.text)
             }
@@ -631,3 +646,72 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         }
     }
 }
+
+impl fmt::Show for ModuleSummary {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fn fmt_inner<'a>(f: &mut fmt::Formatter,
+                         context: &mut Vec<&'a str>,
+                         m: &'a ModuleSummary)
+                     -> fmt::Result {
+            let cnt = m.counts;
+            let tot = cnt.total();
+            if tot == 0 { return Ok(()) }
+
+            context.push(m.name.as_slice());
+            let path = context.connect("::");
+
+            // the total width of each row's stability summary, in pixels
+            let width = 500;
+
+            try!(write!(f, "<tr>"));
+            try!(write!(f, "<td class='summary'>\
+                            <a class='summary' href='{}'>{}</a></td>",
+                        Vec::from_slice(context.slice_from(1))
+                            .append_one("index.html").connect("/"),
+                        path));
+            try!(write!(f, "<td>"));
+            try!(write!(f, "<span class='summary Stable' \
+                            style='width: {}px; display: inline-block'>&nbsp</span>",
+                        (width * cnt.stable)/tot));
+            try!(write!(f, "<span class='summary Unstable' \
+                            style='width: {}px; display: inline-block'>&nbsp</span>",
+                        (width * cnt.unstable)/tot));
+            try!(write!(f, "<span class='summary Experimental' \
+                            style='width: {}px; display: inline-block'>&nbsp</span>",
+                        (width * cnt.experimental)/tot));
+            try!(write!(f, "<span class='summary Deprecated' \
+                            style='width: {}px; display: inline-block'>&nbsp</span>",
+                        (width * cnt.deprecated)/tot));
+            try!(write!(f, "<span class='summary Unmarked' \
+                            style='width: {}px; display: inline-block'>&nbsp</span>",
+                        (width * cnt.unmarked)/tot));
+            try!(write!(f, "</td></tr>"));
+
+            for submodule in m.submodules.iter() {
+                try!(fmt_inner(f, context, submodule));
+            }
+            context.pop();
+            Ok(())
+        }
+
+        let mut context = Vec::new();
+
+        try!(write!(f,
+r"<h1 class='fqn'>Stability dashboard: crate <a class='mod' href='index.html'>{}</a></h1>
+This dashboard summarizes the stability levels for all of the public modules of
+the crate, according to the total number of items at each level in the module and its children:
+<blockquote>
+<a class='stability Stable'></a> stable,<br/>
+<a class='stability Unstable'></a> unstable,<br/>
+<a class='stability Experimental'></a> experimental,<br/>
+<a class='stability Deprecated'></a> deprecated,<br/>
+<a class='stability Unmarked'></a> unmarked
+</blockquote>
+The counts do not include methods or trait
+implementations that are visible only through a re-exported type.",
+self.name));
+        try!(write!(f, "<table>"))
+        try!(fmt_inner(f, &mut context, self));
+        write!(f, "</table>")
+    }
+}
index daa9ee3da844f88568d20df17b8eccece1425cd5..3cb5cdc04396227677bc8cdfd9e09636e5f8f133 100644 (file)
@@ -18,7 +18,6 @@
 
 use syntax::parse;
 use syntax::parse::lexer;
-use syntax::codemap::{BytePos, Span};
 
 use html::escape::Escape;
 
@@ -59,38 +58,30 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
         None => {}
     }
     try!(write!(out, "class='rust {}'>\n", class.unwrap_or("")));
-    let mut last = BytePos(0);
     let mut is_attribute = false;
     let mut is_macro = false;
     let mut is_macro_nonterminal = false;
     loop {
         let next = lexer.next_token();
-        let test = if next.tok == t::EOF {lexer.pos} else {next.sp.lo};
-
-        // The lexer consumes all whitespace and non-doc-comments when iterating
-        // between tokens. If this token isn't directly adjacent to our last
-        // token, then we need to emit the whitespace/comment.
-        //
-        // If the gap has any '/' characters then we consider the whole thing a
-        // comment. This will classify some whitespace as a comment, but that
-        // doesn't matter too much for syntax highlighting purposes.
-        if test > last {
-            let snip = sess.span_diagnostic.cm.span_to_snippet(Span {
-                lo: last,
-                hi: test,
-                expn_info: None,
-            }).unwrap();
-            if snip.as_slice().contains("/") {
-                try!(write!(out, "<span class='comment'>{}</span>",
-                              Escape(snip.as_slice())));
-            } else {
-                try!(write!(out, "{}", Escape(snip.as_slice())));
-            }
-        }
-        last = next.sp.hi;
+
+        let snip = |sp| sess.span_diagnostic.cm.span_to_snippet(sp).unwrap();
+
         if next.tok == t::EOF { break }
 
         let klass = match next.tok {
+            t::WS => {
+                try!(write!(out, "{}", Escape(snip(next.sp).as_slice())));
+                continue
+            },
+            t::COMMENT => {
+                try!(write!(out, "<span class='comment'>{}</span>",
+                            Escape(snip(next.sp).as_slice())));
+                continue
+            },
+            t::SHEBANG(s) => {
+                try!(write!(out, "{}", Escape(s.as_str())));
+                continue
+            },
             // If this '&' token is directly adjacent to another token, assume
             // that it's the address-of operator instead of the and-operator.
             // This allows us to give all pointers their own class (`Box` and
@@ -110,7 +101,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
             // miscellaneous, no highlighting
             t::DOT | t::DOTDOT | t::DOTDOTDOT | t::COMMA | t::SEMI |
                 t::COLON | t::MOD_SEP | t::LARROW | t::LPAREN |
-                t::RPAREN | t::LBRACKET | t::LBRACE | t::RBRACE => "",
+                t::RPAREN | t::LBRACKET | t::LBRACE | t::RBRACE | t::QUESTION => "",
             t::DOLLAR => {
                 if t::is_ident(&lexer.peek().tok) {
                     is_macro_nonterminal = true;
@@ -144,8 +135,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
                 t::LIT_CHAR(..) | t::LIT_STR(..) | t::LIT_STR_RAW(..) => "string",
 
             // number literals
-            t::LIT_INT(..) | t::LIT_UINT(..) | t::LIT_INT_UNSUFFIXED(..) |
-                t::LIT_FLOAT(..) | t::LIT_FLOAT_UNSUFFIXED(..) => "number",
+            t::LIT_INTEGER(..) | t::LIT_FLOAT(..) => "number",
 
             // keywords are also included in the identifier set
             t::IDENT(ident, _is_mod_sep) => {
index aa298d07780bfe341da75be01175462e3ba40542..356b224e6d5b862fdf66f009f3fc01d09f6c903e 100644 (file)
@@ -42,8 +42,6 @@ pub fn render<T: fmt::Show, S: fmt::Show>(
 
     <title>{title}</title>
 
-    <link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400,600'
-          rel='stylesheet' type='text/css'>
     <link rel="stylesheet" type="text/css" href="{root_path}main.css">
 
     {favicon}
index de4bbeb6e30c8a6439c31d1f46424392796f15cf..19a9bcb9a17ab97878d6d73fe031bb47df1c0da1 100644 (file)
@@ -229,7 +229,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
         // Transform the contents of the header into a hyphenated string
         let id = s.as_slice().words().map(|s| {
             match s.to_ascii_opt() {
-                Some(s) => s.to_lower().into_str(),
+                Some(s) => s.to_lower().into_string(),
                 None => s.to_string()
             }
         }).collect::<Vec<String>>().connect("-");
index 917eab4eeb9918e547fc2e42f105b85c83c2d516..ed047ef629dff600f72ff9cdffe7751c93fa651e 100644 (file)
@@ -43,6 +43,8 @@
 
 use externalfiles::ExternalHtml;
 
+use serialize::json;
+use serialize::Encodable;
 use serialize::json::ToJson;
 use syntax::ast;
 use syntax::ast_util;
@@ -59,6 +61,7 @@
 use html::layout;
 use html::markdown::Markdown;
 use html::markdown;
+use stability_summary;
 
 /// Major driving force in all rustdoc rendering. This contains information
 /// about where in the tree-like hierarchy rendering is occurring and controls
@@ -249,6 +252,11 @@ pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) ->
 
     try!(mkdir(&cx.dst));
 
+    // Crawl the crate, building a summary of the stability levels.  NOTE: this
+    // summary *must* be computed with the original `krate`; the folding below
+    // removes the impls from their modules.
+    let summary = stability_summary::build(&krate);
+
     // Crawl the crate attributes looking for attributes which control how we're
     // going to emit HTML
     match krate.module.as_ref().map(|m| m.doc_list().unwrap_or(&[])) {
@@ -361,7 +369,7 @@ pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) ->
     let krate = try!(render_sources(&mut cx, krate));
 
     // And finally render the whole crate's documentation
-    cx.krate(krate)
+    cx.krate(krate, summary)
 }
 
 fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult<String> {
@@ -428,7 +436,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult<String>
         }
         try!(write!(&mut w, r#"[{:u},"{}","{}",{}"#,
                     item.ty, item.name, path,
-                    item.desc.to_json().to_str()));
+                    item.desc.to_json().to_string()));
         match item.parent {
             Some(nodeid) => {
                 let pathid = *nodeid_to_pathid.find(&nodeid).unwrap();
@@ -478,12 +486,16 @@ fn write_shared(cx: &Context,
                include_bin!("static/FiraSans-Regular.woff")));
     try!(write(cx.dst.join("FiraSans-Medium.woff"),
                include_bin!("static/FiraSans-Medium.woff")));
-    try!(write(cx.dst.join("Heuristica-Regular.woff"),
-               include_bin!("static/Heuristica-Regular.woff")));
     try!(write(cx.dst.join("Heuristica-Italic.woff"),
                include_bin!("static/Heuristica-Italic.woff")));
-    try!(write(cx.dst.join("Heuristica-Bold.woff"),
-               include_bin!("static/Heuristica-Bold.woff")));
+    try!(write(cx.dst.join("SourceSerifPro-Regular.woff"),
+               include_bin!("static/SourceSerifPro-Regular.woff")));
+    try!(write(cx.dst.join("SourceSerifPro-Bold.woff"),
+               include_bin!("static/SourceSerifPro-Bold.woff")));
+    try!(write(cx.dst.join("SourceCodePro-Regular.woff"),
+               include_bin!("static/SourceCodePro-Regular.woff")));
+    try!(write(cx.dst.join("SourceCodePro-Semibold.woff"),
+               include_bin!("static/SourceCodePro-Semibold.woff")));
 
     fn collect(path: &Path, krate: &str,
                key: &str) -> io::IoResult<Vec<String>> {
@@ -1041,13 +1053,34 @@ fn recurse<T>(&mut self, s: String, f: |&mut Context| -> T) -> T {
     ///
     /// This currently isn't parallelized, but it'd be pretty easy to add
     /// parallelization to this function.
-    fn krate(self, mut krate: clean::Crate) -> io::IoResult<()> {
+    fn krate(mut self, mut krate: clean::Crate,
+             stability: stability_summary::ModuleSummary) -> io::IoResult<()> {
         let mut item = match krate.module.take() {
             Some(i) => i,
             None => return Ok(())
         };
         item.name = Some(krate.name);
 
+        // render stability dashboard
+        try!(self.recurse(stability.name.clone(), |this| {
+            let json_dst = &this.dst.join("stability.json");
+            let mut json_out = BufferedWriter::new(try!(File::create(json_dst)));
+            try!(stability.encode(&mut json::Encoder::new(&mut json_out)));
+
+            let title = stability.name.clone().append(" - Stability dashboard");
+            let page = layout::Page {
+                ty: "mod",
+                root_path: this.root_path.as_slice(),
+                title: title.as_slice(),
+            };
+            let html_dst = &this.dst.join("stability.html");
+            let mut html_out = BufferedWriter::new(try!(File::create(html_dst)));
+            layout::render(&mut html_out, &this.layout, &page,
+                           &Sidebar{ cx: this, item: &item },
+                           &stability)
+        }));
+
+        // render the crate documentation
         let mut work = vec!((self, item));
         loop {
             match work.pop() {
@@ -1057,6 +1090,7 @@ fn krate(self, mut krate: clean::Crate) -> io::IoResult<()> {
                 None => break,
             }
         }
+
         Ok(())
     }
 
@@ -1229,6 +1263,8 @@ fn href(&self) -> Option<String> {
     }
 }
 
+
+
 impl<'a> fmt::Show for Item<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         // Write the breadcrumb trail header for the top
@@ -1265,6 +1301,17 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         // Write stability level
         try!(write!(fmt, "{}", Stability(&self.item.stability)));
 
+        // Links to out-of-band information, i.e. src and stability dashboard
+        try!(write!(fmt, "<span class='out-of-band'>"));
+
+        // Write stability dashboard link
+        match self.item.inner {
+            clean::ModuleItem(ref m) if m.is_crate => {
+                try!(write!(fmt, "<a href='stability.html'>[stability dashboard]</a> "));
+            }
+            _ => {}
+        };
+
         // Write `src` tag
         //
         // When this item is part of a `pub use` in a downstream crate, the
@@ -1274,14 +1321,15 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         if self.cx.include_sources && !is_primitive {
             match self.href() {
                 Some(l) => {
-                    try!(write!(fmt,
-                                "<a class='source' id='src-{}' \
-                                    href='{}'>[src]</a>",
+                    try!(write!(fmt, "<a id='src-{}' href='{}'>[src]</a>",
                                 self.item.def_id.node, l));
                 }
                 None => {}
             }
         }
+
+        try!(write!(fmt, "</span>"));
+
         try!(write!(fmt, "</h1>\n"));
 
         match self.item.inner {
@@ -1351,6 +1399,7 @@ fn document(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
 fn item_module(w: &mut fmt::Formatter, cx: &Context,
                item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
     try!(document(w, item));
+
     let mut indices = range(0, items.len()).filter(|i| {
         !ignore_private_item(&items[*i])
     }).collect::<Vec<uint>>();
@@ -1510,6 +1559,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             }
         }
     }
+
     write!(w, "</table>")
 }
 
diff --git a/src/librustdoc/html/static/FiraSans-LICENSE.txt b/src/librustdoc/html/static/FiraSans-LICENSE.txt
new file mode 100644 (file)
index 0000000..b4a3967
--- /dev/null
@@ -0,0 +1,99 @@
+Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
+with Reserved Font Name Fira Sans.
+
+Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
+with Reserved Font Name Fira Mono.
+
+Copyright (c) 2014, Telefonica S.A.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/src/librustdoc/html/static/Heuristica-Bold.woff b/src/librustdoc/html/static/Heuristica-Bold.woff
deleted file mode 100644 (file)
index 1c952d1..0000000
Binary files a/src/librustdoc/html/static/Heuristica-Bold.woff and /dev/null differ
diff --git a/src/librustdoc/html/static/Heuristica-LICENSE.txt b/src/librustdoc/html/static/Heuristica-LICENSE.txt
new file mode 100644 (file)
index 0000000..9693dc1
--- /dev/null
@@ -0,0 +1,101 @@
+Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved.
+Utopia is either a registered trademark or trademark of Adobe Systems
+Incorporated in the United States and/or other countries. Used under
+license. 
+
+Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net
+
+Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru),
+with Reserved Font Name Heuristica.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/src/librustdoc/html/static/Heuristica-Regular.woff b/src/librustdoc/html/static/Heuristica-Regular.woff
deleted file mode 100644 (file)
index 8d824e6..0000000
Binary files a/src/librustdoc/html/static/Heuristica-Regular.woff and /dev/null differ
diff --git a/src/librustdoc/html/static/SourceCodePro-LICENSE.txt b/src/librustdoc/html/static/SourceCodePro-LICENSE.txt
new file mode 100644 (file)
index 0000000..1177330
--- /dev/null
@@ -0,0 +1,93 @@
+Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+
+This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/src/librustdoc/html/static/SourceCodePro-Regular.woff b/src/librustdoc/html/static/SourceCodePro-Regular.woff
new file mode 100644 (file)
index 0000000..5576670
Binary files /dev/null and b/src/librustdoc/html/static/SourceCodePro-Regular.woff differ
diff --git a/src/librustdoc/html/static/SourceCodePro-Semibold.woff b/src/librustdoc/html/static/SourceCodePro-Semibold.woff
new file mode 100644 (file)
index 0000000..ca972a1
Binary files /dev/null and b/src/librustdoc/html/static/SourceCodePro-Semibold.woff differ
diff --git a/src/librustdoc/html/static/SourceSerifPro-Bold.woff b/src/librustdoc/html/static/SourceSerifPro-Bold.woff
new file mode 100644 (file)
index 0000000..435a6f9
Binary files /dev/null and b/src/librustdoc/html/static/SourceSerifPro-Bold.woff differ
diff --git a/src/librustdoc/html/static/SourceSerifPro-LICENSE.txt b/src/librustdoc/html/static/SourceSerifPro-LICENSE.txt
new file mode 100644 (file)
index 0000000..14b5481
--- /dev/null
@@ -0,0 +1,93 @@
+Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+
+This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/src/librustdoc/html/static/SourceSerifPro-Regular.woff b/src/librustdoc/html/static/SourceSerifPro-Regular.woff
new file mode 100644 (file)
index 0000000..e8c43b8
Binary files /dev/null and b/src/librustdoc/html/static/SourceSerifPro-Regular.woff differ
index 97048229ac4c1842180a90c6ace19b7c5dff06a0..4f790f96750286c9442ded17339bf560d92b7915 100644 (file)
     src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
 }
 @font-face {
-    font-family: 'Heuristica';
+    font-family: 'Source Serif Pro';
     font-style: normal;
     font-weight: 400;
-    src: local('Heuristica Regular'), url("Heuristica-Regular.woff") format('woff');
+    src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
 }
 @font-face {
-    font-family: 'Heuristica';
+    font-family: 'Source Serif Pro';
     font-style: italic;
     font-weight: 400;
-    src: local('Heuristica Italic'), url("Heuristica-Italic.woff") format('woff');
+    src: url("Heuristica-Italic.woff") format('woff');
 }
 @font-face {
-    font-family: 'Heuristica';
+    font-family: 'Source Serif Pro';
     font-style: normal;
     font-weight: 700;
-    src: local('Heuristica Bold'), url("Heuristica-Bold.woff") format('woff');
+    src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
+}
+@font-face {
+    font-family: 'Source Code Pro';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff');
+}
+@font-face {
+    font-family: 'Source Code Pro';
+    font-style: normal;
+    font-weight: 600;
+    src: local('Source Code Pro Semibold'), url("SourceCodePro-Semibold.woff") format('woff');
 }
 
 @import "normalize.css";
@@ -53,7 +65,7 @@
 body {
     color: #333;
     min-width: 500px;
-    font: 15.5px/1.4 "Heuristica", "Helvetica Neue", Helvetica, Arial, sans-serif;
+    font: 16px/1.4 "Source Serif Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
     margin: 0;
     position: relative;
     padding: 10px 15px 20px 15px;
@@ -226,7 +238,7 @@ nav.sub {
 .docblock h2 { font-size: 1.15em; }
 .docblock h3, .docblock h4, .docblock h5 { font-size: 1em; }
 
-.content .source {
+.content .out-of-band {
     float: right;
     font-size: 23px;
 }
@@ -397,6 +409,15 @@ h1 .stability {
 .stability.Locked { border-color: #0084B6; color: #00668c; }
 .stability.Unmarked { border-color: #FFFFFF; }
 
+.summary {
+    padding-right: 0px;
+}
+.summary.Deprecated { background-color: #A071A8; }
+.summary.Experimental { background-color: #D46D6A; }
+.summary.Unstable { background-color: #D4B16A; }
+.summary.Stable { background-color: #54A759; }
+.summary.Unmarked { background-color: #FFFFFF; }
+
 :target { background: #FDFFD3; }
 
 /* Code highlighting */
index d878313ee28995c0e8e2f9507ff7d540ed3ad957..76b9f11089f9bb5c78ef6153ddeaafa572ff9193 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "rustdoc#0.11.0"]
+#![crate_name = "rustdoc"]
 #![experimental]
 #![desc = "rustdoc, the Rust documentation extractor"]
 #![license = "MIT/ASL2"]
@@ -56,6 +56,7 @@ pub mod html {
 pub mod markdown;
 pub mod passes;
 pub mod plugins;
+pub mod stability_summary;
 pub mod visit_ast;
 pub mod test;
 mod flock;
@@ -365,7 +366,7 @@ fn json_input(input: &str) -> Result<Output, String> {
         }
     };
     match json::from_reader(&mut input) {
-        Err(s) => Err(s.to_str()),
+        Err(s) => Err(s.to_string()),
         Ok(json::Object(obj)) => {
             let mut obj = obj;
             // Make sure the schema is what we expect
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
new file mode 100644 (file)
index 0000000..18e90d5
--- /dev/null
@@ -0,0 +1,174 @@
+// 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.
+
+//! This module crawls a `clean::Crate` and produces a summarization of the
+//! stability levels within the crate. The summary contains the module
+//! hierarchy, with item counts for every stability level per module. A parent
+//! module's count includes its childrens's.
+
+use std::ops::Add;
+use std::num::Zero;
+use std::iter::AdditiveIterator;
+
+use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
+use syntax::ast::Public;
+
+use clean::{Crate, Item, ModuleItem, Module, StructItem, Struct, EnumItem, Enum};
+use clean::{ImplItem, Impl, TraitItem, Trait, TraitMethod, Provided, Required};
+use clean::{ViewItemItem, PrimitiveItem};
+
+#[deriving(Zero, Encodable, Decodable, PartialEq, Eq)]
+/// The counts for each stability level.
+pub struct Counts {
+    pub deprecated: uint,
+    pub experimental: uint,
+    pub unstable: uint,
+    pub stable: uint,
+    pub frozen: uint,
+    pub locked: uint,
+
+    /// No stability level, inherited or otherwise.
+    pub unmarked: uint,
+}
+
+impl Add<Counts, Counts> for Counts {
+    fn add(&self, other: &Counts) -> Counts {
+        Counts {
+            deprecated:   self.deprecated   + other.deprecated,
+            experimental: self.experimental + other.experimental,
+            unstable:     self.unstable     + other.unstable,
+            stable:       self.stable       + other.stable,
+            frozen:       self.frozen       + other.frozen,
+            locked:       self.locked       + other.locked,
+            unmarked:     self.unmarked     + other.unmarked,
+        }
+    }
+}
+
+impl Counts {
+    pub fn total(&self) -> uint {
+        self.deprecated + self.experimental + self.unstable + self.stable +
+            self.frozen + self.locked + self.unmarked
+    }
+}
+
+#[deriving(Encodable, Decodable, PartialEq, Eq)]
+/// A summarized module, which includes total counts and summarized chilcren
+/// modules.
+pub struct ModuleSummary {
+    pub name: String,
+    pub counts: Counts,
+    pub submodules: Vec<ModuleSummary>,
+}
+
+impl PartialOrd for ModuleSummary {
+    fn partial_cmp(&self, other: &ModuleSummary) -> Option<Ordering> {
+        self.name.partial_cmp(&other.name)
+    }
+}
+
+impl Ord for ModuleSummary {
+    fn cmp(&self, other: &ModuleSummary) -> Ordering {
+        self.name.cmp(&other.name)
+    }
+}
+
+// is the item considered publically visible?
+fn visible(item: &Item) -> bool {
+    match item.inner {
+        ImplItem(_) => true,
+        _ => item.visibility == Some(Public)
+    }
+}
+
+// Produce the summary for an arbitrary item. If the item is a module, include a
+// module summary. The counts for items with nested items (e.g. modules, traits,
+// impls) include all children counts.
+fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
+    // count this item
+    let item_counts = match item.stability {
+        None             => Counts { unmarked: 1,     .. Zero::zero() },
+        Some(ref stab) => match stab.level {
+            Deprecated   => Counts { deprecated: 1,   .. Zero::zero() },
+            Experimental => Counts { experimental: 1, .. Zero::zero() },
+            Unstable     => Counts { unstable: 1,     .. Zero::zero() },
+            Stable       => Counts { stable: 1,       .. Zero::zero() },
+            Frozen       => Counts { frozen: 1,       .. Zero::zero() },
+            Locked       => Counts { locked: 1,       .. Zero::zero() },
+        }
+    };
+
+    // Count this item's children, if any. Note that a trait impl is
+    // considered to have no children.
+    match item.inner {
+        // Require explicit `pub` to be visible
+        StructItem(Struct { fields: ref subitems, .. }) |
+        ImplItem(Impl { methods: ref subitems, trait_: None, .. }) => {
+            let subcounts = subitems.iter().filter(|i| visible(*i))
+                                           .map(summarize_item)
+                                           .map(|s| s.val0())
+                                           .sum();
+            (item_counts + subcounts, None)
+        }
+        // `pub` automatically
+        EnumItem(Enum { variants: ref subitems, .. }) => {
+            let subcounts = subitems.iter().map(summarize_item)
+                                           .map(|s| s.val0())
+                                           .sum();
+            (item_counts + subcounts, None)
+        }
+        TraitItem(Trait { methods: ref methods, .. }) => {
+            fn extract_item<'a>(meth: &'a TraitMethod) -> &'a Item {
+                match *meth {
+                    Provided(ref item) | Required(ref item) => item
+                }
+            }
+            let subcounts = methods.iter().map(extract_item)
+                                          .map(summarize_item)
+                                          .map(|s| s.val0())
+                                          .sum();
+            (item_counts + subcounts, None)
+        }
+        ModuleItem(Module { items: ref items, .. }) => {
+            let mut counts = item_counts;
+            let mut submodules = Vec::new();
+
+            for (subcounts, submodule) in items.iter().filter(|i| visible(*i))
+                                                      .map(summarize_item) {
+                counts = counts + subcounts;
+                submodule.map(|m| submodules.push(m));
+            }
+            submodules.sort();
+
+            (counts, Some(ModuleSummary {
+                name: item.name.as_ref().map_or("".to_string(), |n| n.clone()),
+                counts: counts,
+                submodules: submodules,
+            }))
+        }
+        // no stability information for the following items:
+        ViewItemItem(_) | PrimitiveItem(_) => (Zero::zero(), None),
+        _ => (item_counts, None)
+    }
+}
+
+/// Summarizes the stability levels in a crate.
+pub fn build(krate: &Crate) -> ModuleSummary {
+    match krate.module {
+        None => ModuleSummary {
+            name: krate.name.clone(),
+            counts: Zero::zero(),
+            submodules: Vec::new(),
+        },
+        Some(ref item) => ModuleSummary {
+            name: krate.name.clone(), .. summarize_item(item).val1().unwrap()
+        }
+    }
+}
index 7e7f10f71783dd9d07171e2512dcfbda8e774b89..055019aa481ffebaf06edc9aab9f3a467be8efd8 100644 (file)
@@ -54,7 +54,7 @@ pub fn run(input: &str,
 
 
     let codemap = CodeMap::new();
-    let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto);
+    let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto, None);
     let span_diagnostic_handler =
     diagnostic::mk_span_handler(diagnostic_handler, codemap);
 
@@ -69,7 +69,7 @@ pub fn run(input: &str,
     }));
     let krate = driver::phase_1_parse_input(&sess, cfg, &input);
     let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
-            &from_str("rustdoc-test").unwrap())
+                                                          "rustdoc-test")
         .expect("phase_2_configure_and_expand aborted in rustdoc!");
 
     let ctx = box(GC) core::DocContext {
@@ -150,7 +150,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
         };
         io::util::copy(&mut p, &mut err).unwrap();
     });
-    let emitter = diagnostic::EmitterWriter::new(box w2);
+    let emitter = diagnostic::EmitterWriter::new(box w2, None);
 
     // Compile the code
     let codemap = CodeMap::new();
@@ -176,26 +176,15 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
     // environment to ensure that the target loads the right libraries at
     // runtime. It would be a sad day if the *host* libraries were loaded as a
     // mistake.
-    let exe = outdir.path().join("rust_out");
-    let env = {
+    let mut cmd = Command::new(outdir.path().join("rust_out"));
+    let newpath = {
         let mut path = DynamicLibrary::search_path();
         path.insert(0, libdir.clone());
-
-        // Remove the previous dylib search path var
-        let var = DynamicLibrary::envvar();
-        let mut env: Vec<(String,String)> = os::env().move_iter().collect();
-        match env.iter().position(|&(ref k, _)| k.as_slice() == var) {
-            Some(i) => { env.remove(i); }
-            None => {}
-        };
-
-        // Add the new dylib search path var
-        let newpath = DynamicLibrary::create_path(path.as_slice());
-        env.push((var.to_string(),
-                  str::from_utf8(newpath.as_slice()).unwrap().to_string()));
-        env
+        DynamicLibrary::create_path(path.as_slice())
     };
-    match Command::new(exe).env(env.as_slice()).output() {
+    cmd.env(DynamicLibrary::envvar(), newpath.as_slice());
+
+    match cmd.output() {
         Err(e) => fail!("couldn't run the test: {}{}", e,
                         if e.kind == io::PermissionDenied {
                             " - maybe your tempdir is mounted with noexec?"
index 3c0a4aae251dbd90506a5af37a829274eec771e1..af6de0cf605a204119deefbe2ebf8b683d8c2cb1 100644 (file)
@@ -45,7 +45,7 @@ pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() }
 mod imp {
     use core::prelude::*;
 
-    use alloc::owned::Box;
+    use alloc::boxed::Box;
     use collections::vec::Vec;
     use core::mem;
     use core::slice;
index dcba7fb7cb6a6255d51b295c6c9f2d6d3e2d2d17..1faf492e498ace09860dd8fc0ccd65091c892a82 100644 (file)
@@ -14,7 +14,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use collections::vec::Vec;
 use core::atomics;
 use core::mem;
index 161d3ed5e65e1cf70b259481e2321f7b2ebbb754..396d51f4fcb13a4128d62046199608646d72c385 100644 (file)
@@ -69,6 +69,7 @@ fn main() {
 
 use alloc::libc_heap::malloc_raw;
 use collections::string::String;
+use collections::hash;
 use core::kinds::marker;
 use core::mem;
 use core::ptr;
@@ -116,6 +117,22 @@ fn eq(&self, other: &CString) -> bool {
     }
 }
 
+impl PartialOrd for CString {
+    #[inline]
+    fn partial_cmp(&self, other: &CString) -> Option<Ordering> {
+        self.as_bytes().partial_cmp(&other.as_bytes())
+    }
+}
+
+impl Eq for CString {}
+
+impl<S: hash::Writer> hash::Hash<S> for CString {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        self.as_bytes().hash(state)
+    }
+}
+
 impl CString {
     /// Create a C String from a pointer.
     pub unsafe fn new(buf: *const libc::c_char, owns_buffer: bool) -> CString {
@@ -804,7 +821,7 @@ fn check(s: &str, c_str: *const libc::c_char) {
         Mary had a little lamb, Little lamb
         Mary had a little lamb, Little lamb";
 
-    fn bench_to_str(b: &mut Bencher, s: &str) {
+    fn bench_to_string(b: &mut Bencher, s: &str) {
         b.iter(|| {
             let c_str = s.to_c_str();
             check(s, c_str.as_ptr());
@@ -813,17 +830,17 @@ fn bench_to_str(b: &mut Bencher, s: &str) {
 
     #[bench]
     fn bench_to_c_str_short(b: &mut Bencher) {
-        bench_to_str(b, s_short)
+        bench_to_string(b, s_short)
     }
 
     #[bench]
     fn bench_to_c_str_medium(b: &mut Bencher) {
-        bench_to_str(b, s_medium)
+        bench_to_string(b, s_medium)
     }
 
     #[bench]
     fn bench_to_c_str_long(b: &mut Bencher) {
-        bench_to_str(b, s_long)
+        bench_to_string(b, s_long)
     }
 
     fn bench_to_c_str_unchecked(b: &mut Bencher, s: &str) {
index fabef24e06ac724f5e7d2f5a0f839dabcafff553..a150408ac2e6c0b39e53e5d0f17c6c654657ffec 100644 (file)
@@ -8,16 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "rustrt#0.11.0"]
+#![crate_name = "rustrt"]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 
 #![feature(macro_rules, phase, globs, thread_local, managed_boxes, asm)]
-#![feature(linkage, lang_items, unsafe_destructor)]
+#![feature(linkage, lang_items, unsafe_destructor, default_type_params)]
 #![no_std]
 #![experimental]
 
@@ -37,7 +37,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::any::Any;
 
 use task::{Task, BlockedTask, TaskOpts};
index 7fe9dbc6d4ff554d81cbe5a3e375d40ed988de38..bdb1c60b6d6f8db7acedcbb32d2aeb0d1ffe3f49 100644 (file)
@@ -10,7 +10,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use local_ptr;
 use task::Task;
 
index d4c87e9fc05c14e458ff110237360935b2baa28b..ace53478d0a034b5b2aa329318b1d2a0f31ef710 100644 (file)
@@ -40,7 +40,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use collections::vec::Vec;
 use core::kinds::marker;
 use core::mem;
index 813ea0f30f38b71afbb3655ccc7d82646ca1840c..c94e5c6187b3a93e308801b3ea0feb21c64a617e 100644 (file)
@@ -20,7 +20,7 @@
 use core::prelude::*;
 
 use core::mem;
-use alloc::owned::Box;
+use alloc::boxed::Box;
 
 #[cfg(windows)]               // mingw-w32 doesn't like thread_local things
 #[cfg(target_os = "android")] // see #10686
@@ -86,7 +86,7 @@ pub unsafe fn borrow<T>() -> Borrowed<T> {
 pub mod compiled {
     use core::prelude::*;
 
-    use alloc::owned::Box;
+    use alloc::boxed::Box;
     use core::mem;
 
     #[cfg(test)]
@@ -237,7 +237,7 @@ pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
 pub mod native {
     use core::prelude::*;
 
-    use alloc::owned::Box;
+    use alloc::boxed::Box;
     use core::mem;
     use core::ptr;
     use tls = thread_local_storage;
index 0205f2405f9ce8e1345f214a103e39fad5cde3b3..343b911fb83f3d775e9312fa34b7ef3794d82fa0 100644 (file)
@@ -11,7 +11,7 @@
 //! The EventLoop and internal synchronous I/O interface.
 
 use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use collections::string::String;
 use collections::vec::Vec;
 use core::fmt;
@@ -75,7 +75,7 @@ pub struct ProcessConfig<'a> {
 
     /// Optional environment to specify for the program. If this is None, then
     /// it will inherit the current process's environment.
-    pub env: Option<&'a [(CString, CString)]>,
+    pub env: Option<&'a [(&'a CString, &'a CString)]>,
 
     /// Optional working directory for the new process. If this is None, then
     /// the current directory of the running process is inherited.
index 8e637207d2209c07879c581112e507c33c68296b..0eacd40f01cee052d45bcf48e9fe47cfa19a21b2 100644 (file)
@@ -56,7 +56,7 @@
 #[lang = "stack_exhausted"]
 extern fn stack_exhausted() {
     use core::prelude::*;
-    use alloc::owned::Box;
+    use alloc::boxed::Box;
     use local::Local;
     use task::Task;
     use core::intrinsics;
index 59401a8b66604f0568c80a293bf0421e9ed1ecee..78c32889277b2230d131838f694b24933fc789f5 100644 (file)
@@ -16,7 +16,7 @@
 use core::prelude::*;
 
 use alloc::arc::Arc;
-use alloc::owned::{AnyOwnExt, Box};
+use alloc::boxed::{BoxAny, Box};
 use core::any::Any;
 use core::atomics::{AtomicUint, SeqCst};
 use core::iter::Take;
@@ -376,7 +376,7 @@ pub fn maybe_take_runtime<T: 'static>(&mut self) -> Option<Box<T>> {
         unsafe {
             let imp = self.imp.take_unwrap();
             let vtable = mem::transmute::<_, &raw::TraitObject>(&imp).vtable;
-            match imp.wrap().move::<T>() {
+            match imp.wrap().downcast::<T>() {
                 Ok(t) => Some(t),
                 Err(t) => {
                     let data = mem::transmute::<_, raw::TraitObject>(t).data;
index 59784328cdb50c02448a3893b1a4776e947415e3..7bc991cf72f3a85b98fa3595cda8a5812168500d 100644 (file)
@@ -18,7 +18,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::mem;
 use core::uint;
 use libc;
@@ -147,7 +147,7 @@ fn drop(&mut self) {
 mod imp {
     use core::prelude::*;
 
-    use alloc::owned::Box;
+    use alloc::boxed::Box;
     use core::cmp;
     use core::mem;
     use core::ptr;
@@ -215,7 +215,7 @@ fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES,
 mod imp {
     use core::prelude::*;
 
-    use alloc::owned::Box;
+    use alloc::boxed::Box;
     use core::cmp;
     use core::mem;
     use core::ptr;
index 18688cbcc64ca788668db469d231b520b562533d..f26cccdd3ed9085fa372a8aa97f8f0a6a6a284b5 100644 (file)
@@ -59,7 +59,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use collections::string::String;
 use collections::vec::Vec;
 use core::any::Any;
index 76b2c22e86e0f3c1281c1d964220c6374ba231a0..26ba601f73ec1cbddf6fa613a3e9c9ac7d0b8a3d 100644 (file)
@@ -547,7 +547,7 @@ fn file_test_mk_rm_dir() {
         let path = &"./tmp/mk_rm_dir".to_c_str();
         let mode = S_IWUSR | S_IRUSR;
 
-        let result = FsRequest::mkdir(l(), path, mode);
+        let result = FsRequest::mkdir(l(), path, mode as c_int);
         assert!(result.is_ok());
 
         let result = FsRequest::rmdir(l(), path);
index c13263680aac7986a93ef11601c0e124866d3a03..2c2e134d882cb9af73fb9c9605ddb85572f8a0fc 100644 (file)
 
 */
 
-#![crate_id = "rustuv#0.11.0"]
+#![crate_name = "rustuv"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, unsafe_destructor)]
@@ -391,7 +391,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[test]
 fn error_smoke_test() {
     let err: UvError = UvError(uvll::EOF);
-    assert_eq!(err.to_str(), "EOF: end of file".to_string());
+    assert_eq!(err.to_string(), "EOF: end of file".to_string());
 }
 
 #[cfg(unix)]
@@ -420,6 +420,7 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
             uvll::EADDRNOTAVAIL => libc::WSAEADDRNOTAVAIL,
             uvll::ECANCELED => libc::ERROR_OPERATION_ABORTED,
             uvll::EADDRINUSE => libc::WSAEADDRINUSE,
+            uvll::EPERM => libc::ERROR_ACCESS_DENIED,
             err => {
                 uvdebug!("uverr.code {}", err as int);
                 // FIXME: Need to map remaining uv error types
index ddcaeccbc190f9927235259a31b0f3fddba16032..45f93d9d1289801e52a1cd5c66b9acdab06aba3b 100644 (file)
@@ -676,7 +676,7 @@ fn send_to(&mut self, buf: &[u8], dst: rtio::SocketAddr) -> Result<(), IoError>
     fn join_multicast(&mut self, multi: rtio::IpAddr) -> Result<(), IoError> {
         let _m = self.fire_homing_missile();
         status_to_io_result(unsafe {
-            multi.to_str().with_c_str(|m_addr| {
+            multi.to_string().with_c_str(|m_addr| {
                 uvll::uv_udp_set_membership(self.handle,
                                             m_addr, ptr::null(),
                                             uvll::UV_JOIN_GROUP)
@@ -687,7 +687,7 @@ fn join_multicast(&mut self, multi: rtio::IpAddr) -> Result<(), IoError> {
     fn leave_multicast(&mut self, multi: rtio::IpAddr) -> Result<(), IoError> {
         let _m = self.fire_homing_missile();
         status_to_io_result(unsafe {
-            multi.to_str().with_c_str(|m_addr| {
+            multi.to_string().with_c_str(|m_addr| {
                 uvll::uv_udp_set_membership(self.handle,
                                             m_addr, ptr::null(),
                                             uvll::UV_LEAVE_GROUP)
index 61325d0ce948eb5bb6926ec4bcee141f30af0f7a..0486f376bc80658bfb0c7bf39480e1db195e32e1 100644 (file)
@@ -193,7 +193,7 @@ fn with_argv<T>(prog: &CString, args: &[CString],
 }
 
 /// Converts the environment to the env array expected by libuv
-fn with_env<T>(env: Option<&[(CString, CString)]>,
+fn with_env<T>(env: Option<&[(&CString, &CString)]>,
                cb: |*const *const libc::c_char| -> T) -> T {
     // We can pass a char** for envp, which is a null-terminated array
     // of "k=v\0" strings. Since we must create these strings locally,
index 863536a4111018c2d6919b96b3b8f64dfa058743..a59bc21d792a9ba175ed28e5999ccc4c0640ed6f 100644 (file)
@@ -39,7 +39,7 @@
 
 pub use self::errors::{EACCES, ECONNREFUSED, ECONNRESET, EPIPE, ECONNABORTED,
                        ECANCELED, EBADF, ENOTCONN, ENOENT, EADDRNOTAVAIL,
-                       EADDRINUSE};
+                       EADDRINUSE, EPERM};
 
 pub static OK: c_int = 0;
 pub static EOF: c_int = -4095;
@@ -63,6 +63,7 @@ pub mod errors {
     pub static EBADF: c_int = -4083;
     pub static EADDRNOTAVAIL: c_int = -4090;
     pub static EADDRINUSE: c_int = -4091;
+    pub static EPERM: c_int = -4048;
 }
 #[cfg(not(windows))]
 pub mod errors {
@@ -80,6 +81,7 @@ pub mod errors {
     pub static EBADF : c_int = -libc::EBADF;
     pub static EADDRNOTAVAIL : c_int = -libc::EADDRNOTAVAIL;
     pub static EADDRINUSE : c_int = -libc::EADDRINUSE;
+    pub static EPERM: c_int = -libc::EPERM;
 }
 
 pub static PROCESS_SETUID: c_int = 1 << 0;
index fc8aa8ac257a76f2769355979280750791041caa..41f7aa5012d49bab88d1e4bb3808a808f59e57b6 100644 (file)
 //! An example version number with all five components is
 //! `0.8.1-rc.3.0+20130922.linux`.
 
-#![crate_id = "semver#0.11.0"]
+#![crate_name = "semver"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
+#![feature(default_type_params)]
 
 use std::char;
 use std::cmp;
-use std::fmt;
 use std::fmt::Show;
-use std::option::{Option, Some, None};
-use std::string::String;
+use std::fmt;
+use std::hash;
 
 /// An identifier in the pre-release or build metadata. If the identifier can
 /// be parsed as a decimal value, it will be represented with `Numeric`.
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[allow(missing_doc)]
 pub enum Identifier {
     Numeric(uint),
     AlphaNumeric(String)
 }
 
-impl cmp::PartialOrd for Identifier {
-    #[inline]
-    fn partial_cmp(&self, other: &Identifier) -> Option<Ordering> {
-        match (self, other) {
-            (&Numeric(a), &Numeric(ref b)) => a.partial_cmp(b),
-            (&Numeric(_), _) => Some(Less),
-            (&AlphaNumeric(ref a), &AlphaNumeric(ref b)) => a.partial_cmp(b),
-            (&AlphaNumeric(_), _) => Some(Greater)
-        }
-    }
-}
-
 impl fmt::Show for Identifier {
     #[inline]
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -77,7 +65,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 
 /// Represents a version number conforming to the semantic versioning scheme.
-#[deriving(Clone)]
+#[deriving(Clone, Eq)]
 pub struct Version {
     /// The major version, to be incremented on incompatible changes.
     pub major: uint,
@@ -129,20 +117,25 @@ fn eq(&self, other: &Version) -> bool {
 }
 
 impl cmp::PartialOrd for Version {
-    #[inline]
     fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
-        match self.major.partial_cmp(&other.major) {
-            Some(Equal) => {}
+        Some(self.cmp(other))
+    }
+}
+
+impl cmp::Ord for Version {
+    fn cmp(&self, other: &Version) -> Ordering {
+        match self.major.cmp(&other.major) {
+            Equal => {}
             r => return r,
         }
 
-        match self.minor.partial_cmp(&other.minor) {
-            Some(Equal) => {}
+        match self.minor.cmp(&other.minor) {
+            Equal => {}
             r => return r,
         }
 
-        match self.patch.partial_cmp(&other.patch) {
-            Some(Equal) => {}
+        match self.patch.cmp(&other.patch) {
+            Equal => {}
             r => return r,
         }
 
@@ -150,14 +143,23 @@ fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
         // but the version of ord defined for vec
         // says that [] < [pre] so we alter it here
         match (self.pre.len(), other.pre.len()) {
-            (0, 0) => Some(Equal),
-            (0, _) => Some(Greater),
-            (_, 0) => Some(Less),
-            (_, _) => self.pre.partial_cmp(&other.pre)
+            (0, 0) => Equal,
+            (0, _) => Greater,
+            (_, 0) => Less,
+            (_, _) => self.pre.cmp(&other.pre)
         }
     }
 }
 
+impl<S: hash::Writer> hash::Hash<S> for Version {
+    fn hash(&self, into: &mut S) {
+        self.major.hash(into);
+        self.minor.hash(into);
+        self.patch.hash(into);
+        self.pre.hash(into);
+    }
+}
+
 fn take_nonempty_prefix<T:Iterator<char>>(rdr: &mut T, pred: |char| -> bool)
                         -> (String, Option<char>) {
     let mut buf = String::new();
@@ -268,7 +270,7 @@ pub fn parse(s: &str) -> Option<Version> {
     let v = parse_iter(&mut s.chars());
     match v {
         Some(v) => {
-            if v.to_str().equiv(&s) {
+            if v.to_string().equiv(&s) {
                 Some(v)
             } else {
                 None
@@ -389,11 +391,11 @@ fn test_show() {
 }
 
 #[test]
-fn test_to_str() {
-    assert_eq!(parse("1.2.3").unwrap().to_str(), "1.2.3".to_string());
-    assert_eq!(parse("1.2.3-alpha1").unwrap().to_str(), "1.2.3-alpha1".to_string());
-    assert_eq!(parse("1.2.3+build.42").unwrap().to_str(), "1.2.3+build.42".to_string());
-    assert_eq!(parse("1.2.3-alpha1+42").unwrap().to_str(), "1.2.3-alpha1+42".to_string());
+fn test_to_string() {
+    assert_eq!(parse("1.2.3").unwrap().to_string(), "1.2.3".to_string());
+    assert_eq!(parse("1.2.3-alpha1").unwrap().to_string(), "1.2.3-alpha1".to_string());
+    assert_eq!(parse("1.2.3+build.42").unwrap().to_string(), "1.2.3+build.42".to_string());
+    assert_eq!(parse("1.2.3-alpha1+42").unwrap().to_string(), "1.2.3-alpha1+42".to_string());
 }
 
 #[test]
index 832bc9c4e10cbb2c8f6085a2303aaaa92900e8d2..df4d3437b1ce673b9385e2c829cff26325d03b7f 100644 (file)
@@ -130,7 +130,7 @@ fn main() {
     // Serialize using `ToJson`
     let test2 = TestStruct1 {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]};
     let tjson: json::Json = test2.to_json();
-    let json_str: String = tjson.to_str();
+    let json_str: String = tjson.to_string();
 
     // Deserialize like before
     let decoded: TestStruct1 = json::decode(json_str.as_slice()).unwrap();
@@ -256,22 +256,63 @@ fn io_error_to_error(io: io::IoError) -> ParserError {
 pub type EncodeResult = io::IoResult<()>;
 pub type DecodeResult<T> = Result<T, DecoderError>;
 
-fn escape_str(s: &str) -> String {
-    let mut escaped = String::from_str("\"");
-    for c in s.chars() {
-        match c {
-            '"' => escaped.push_str("\\\""),
-            '\\' => escaped.push_str("\\\\"),
-            '\x08' => escaped.push_str("\\b"),
-            '\x0c' => escaped.push_str("\\f"),
-            '\n' => escaped.push_str("\\n"),
-            '\r' => escaped.push_str("\\r"),
-            '\t' => escaped.push_str("\\t"),
-            _ => escaped.push_char(c),
+pub fn escape_bytes(wr: &mut io::Writer, bytes: &[u8]) -> Result<(), io::IoError> {
+    try!(wr.write_str("\""));
+
+    let mut start = 0;
+
+    for (i, byte) in bytes.iter().enumerate() {
+        let escaped = match *byte {
+            b'"' => "\\\"",
+            b'\\' => "\\\\",
+            b'\x08' => "\\b",
+            b'\x0c' => "\\f",
+            b'\n' => "\\n",
+            b'\r' => "\\r",
+            b'\t' => "\\t",
+            _ => { continue; }
+        };
+
+        if start < i {
+            try!(wr.write(bytes.slice(start, i)));
         }
-    };
-    escaped.push_char('"');
-    escaped
+
+        try!(wr.write_str(escaped));
+
+        start = i + 1;
+    }
+
+    if start != bytes.len() {
+        try!(wr.write(bytes.slice_from(start)));
+    }
+
+    wr.write_str("\"")
+}
+
+fn escape_str(writer: &mut io::Writer, v: &str) -> Result<(), io::IoError> {
+    escape_bytes(writer, v.as_bytes())
+}
+
+fn escape_char(writer: &mut io::Writer, v: char) -> Result<(), io::IoError> {
+    let mut buf = [0, .. 4];
+    v.encode_utf8(buf);
+    escape_bytes(writer, buf)
+}
+
+fn spaces(wr: &mut io::Writer, mut n: uint) -> Result<(), io::IoError> {
+    static len: uint = 16;
+    static buf: [u8, ..len] = [b' ', ..len];
+
+    while n >= len {
+        try!(wr.write(buf));
+        n -= len;
+    }
+
+    if n > 0 {
+        wr.write(buf.slice_to(n))
+    } else {
+        Ok(())
+    }
 }
 
 fn fmt_number_or_null(v: f64) -> String {
@@ -281,10 +322,6 @@ fn fmt_number_or_null(v: f64) -> String {
     }
 }
 
-fn spaces(n: uint) -> String {
-    String::from_char(n, ' ')
-}
-
 /// A structure for implementing serialization to JSON.
 pub struct Encoder<'a> {
     writer: &'a mut io::Writer,
@@ -348,10 +385,10 @@ fn emit_f64(&mut self, v: f64) -> EncodeResult {
     fn emit_f32(&mut self, v: f32) -> EncodeResult { self.emit_f64(v as f64) }
 
     fn emit_char(&mut self, v: char) -> EncodeResult {
-        self.emit_str(str::from_char(v).as_slice())
+        escape_char(self.writer, v)
     }
     fn emit_str(&mut self, v: &str) -> EncodeResult {
-        write!(self.writer, "{}", escape_str(v))
+        escape_str(self.writer, v)
     }
 
     fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
@@ -367,10 +404,10 @@ fn emit_enum_variant(&mut self,
         // Bunny => "Bunny"
         // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
         if cnt == 0 {
-            write!(self.writer, "{}", escape_str(name))
+            escape_str(self.writer, name)
         } else {
             try!(write!(self.writer, "{{\"variant\":"));
-            try!(write!(self.writer, "{}", escape_str(name)));
+            try!(escape_str(self.writer, name));
             try!(write!(self.writer, ",\"fields\":["));
             try!(f(self));
             write!(self.writer, "]}}")
@@ -415,7 +452,8 @@ fn emit_struct_field(&mut self,
                          idx: uint,
                          f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
         if idx != 0 { try!(write!(self.writer, ",")); }
-        try!(write!(self.writer, "{}:", escape_str(name)));
+        try!(escape_str(self.writer, name));
+        try!(write!(self.writer, ":"));
         f(self)
     }
 
@@ -541,10 +579,10 @@ fn emit_f32(&mut self, v: f32) -> EncodeResult {
     }
 
     fn emit_char(&mut self, v: char) -> EncodeResult {
-        self.emit_str(str::from_char(v).as_slice())
+        escape_char(self.writer, v)
     }
     fn emit_str(&mut self, v: &str) -> EncodeResult {
-        write!(self.writer, "{}", escape_str(v))
+        escape_str(self.writer, v)
     }
 
     fn emit_enum(&mut self,
@@ -559,14 +597,18 @@ fn emit_enum_variant(&mut self,
                          cnt: uint,
                          f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
         if cnt == 0 {
-            write!(self.writer, "{}", escape_str(name))
+            escape_str(self.writer, name)
         } else {
             self.indent += 2;
-            try!(write!(self.writer, "[\n{}{},\n", spaces(self.indent),
-                          escape_str(name)));
+            try!(write!(self.writer, "[\n"));
+            try!(spaces(self.writer, self.indent));
+            try!(escape_str(self.writer, name));
+            try!(write!(self.writer, ",\n"));
             try!(f(self));
             self.indent -= 2;
-            write!(self.writer, "\n{}]", spaces(self.indent))
+            try!(write!(self.writer, "\n"));
+            try!(spaces(self.writer, self.indent));
+            write!(self.writer, "]")
         }
     }
 
@@ -576,7 +618,7 @@ fn emit_enum_variant_arg(&mut self,
         if idx != 0 {
             try!(write!(self.writer, ",\n"));
         }
-        try!(write!(self.writer, "{}", spaces(self.indent)));
+        try!(spaces(self.writer, self.indent));
         f(self)
     }
 
@@ -607,7 +649,9 @@ fn emit_struct(&mut self,
             self.indent += 2;
             try!(f(self));
             self.indent -= 2;
-            write!(self.writer, "\n{}}}", spaces(self.indent))
+            try!(write!(self.writer, "\n"));
+            try!(spaces(self.writer, self.indent));
+            write!(self.writer, "}}")
         }
     }
 
@@ -620,7 +664,9 @@ fn emit_struct_field(&mut self,
         } else {
             try!(write!(self.writer, ",\n"));
         }
-        try!(write!(self.writer, "{}{}: ", spaces(self.indent), escape_str(name)));
+        try!(spaces(self.writer, self.indent));
+        try!(escape_str(self.writer, name));
+        try!(write!(self.writer, ": "));
         f(self)
     }
 
@@ -665,7 +711,9 @@ fn emit_seq(&mut self,
             self.indent += 2;
             try!(f(self));
             self.indent -= 2;
-            write!(self.writer, "\n{}]", spaces(self.indent))
+            try!(write!(self.writer, "\n"));
+            try!(spaces(self.writer, self.indent));
+            write!(self.writer, "]")
         }
     }
 
@@ -677,7 +725,7 @@ fn emit_seq_elt(&mut self,
         } else {
             try!(write!(self.writer, ",\n"));
         }
-        try!(write!(self.writer, "{}", spaces(self.indent)));
+        try!(spaces(self.writer, self.indent));
         f(self)
     }
 
@@ -691,7 +739,9 @@ fn emit_map(&mut self,
             self.indent += 2;
             try!(f(self));
             self.indent -= 2;
-            write!(self.writer, "\n{}}}", spaces(self.indent))
+            try!(write!(self.writer, "\n"));
+            try!(spaces(self.writer, self.indent));
+            write!(self.writer, "}}")
         }
     }
 
@@ -703,7 +753,7 @@ fn emit_map_elt_key(&mut self,
         } else {
             try!(write!(self.writer, ",\n"));
         }
-        try!(write!(self.writer, "{}", spaces(self.indent)));
+        try!(spaces(self.writer, self.indent));
         // ref #12967, make sure to wrap a key in double quotes,
         // in the event that its of a type that omits them (eg numbers)
         let mut buf = MemWriter::new();
@@ -1118,7 +1168,7 @@ pub fn new(rdr: T) -> Parser<T> {
     /// Provides access to the current position in the logical structure of the
     /// JSON stream.
     pub fn stack<'l>(&'l self) -> &'l Stack {
-        return &'l self.stack;
+        return &self.stack;
     }
 
     fn eof(&self) -> bool { self.ch.is_none() }
@@ -2152,59 +2202,59 @@ fn test_from_str_trait() {
 
     #[test]
     fn test_write_null() {
-        assert_eq!(Null.to_str().into_string(), "null".to_string());
+        assert_eq!(Null.to_string().into_string(), "null".to_string());
         assert_eq!(Null.to_pretty_str().into_string(), "null".to_string());
     }
 
 
     #[test]
     fn test_write_number() {
-        assert_eq!(Number(3.0).to_str().into_string(), "3".to_string());
+        assert_eq!(Number(3.0).to_string().into_string(), "3".to_string());
         assert_eq!(Number(3.0).to_pretty_str().into_string(), "3".to_string());
 
-        assert_eq!(Number(3.1).to_str().into_string(), "3.1".to_string());
+        assert_eq!(Number(3.1).to_string().into_string(), "3.1".to_string());
         assert_eq!(Number(3.1).to_pretty_str().into_string(), "3.1".to_string());
 
-        assert_eq!(Number(-1.5).to_str().into_string(), "-1.5".to_string());
+        assert_eq!(Number(-1.5).to_string().into_string(), "-1.5".to_string());
         assert_eq!(Number(-1.5).to_pretty_str().into_string(), "-1.5".to_string());
 
-        assert_eq!(Number(0.5).to_str().into_string(), "0.5".to_string());
+        assert_eq!(Number(0.5).to_string().into_string(), "0.5".to_string());
         assert_eq!(Number(0.5).to_pretty_str().into_string(), "0.5".to_string());
 
-        assert_eq!(Number(f64::NAN).to_str().into_string(), "null".to_string());
+        assert_eq!(Number(f64::NAN).to_string().into_string(), "null".to_string());
         assert_eq!(Number(f64::NAN).to_pretty_str().into_string(), "null".to_string());
 
-        assert_eq!(Number(f64::INFINITY).to_str().into_string(), "null".to_string());
+        assert_eq!(Number(f64::INFINITY).to_string().into_string(), "null".to_string());
         assert_eq!(Number(f64::INFINITY).to_pretty_str().into_string(), "null".to_string());
 
-        assert_eq!(Number(f64::NEG_INFINITY).to_str().into_string(), "null".to_string());
+        assert_eq!(Number(f64::NEG_INFINITY).to_string().into_string(), "null".to_string());
         assert_eq!(Number(f64::NEG_INFINITY).to_pretty_str().into_string(), "null".to_string());
     }
 
     #[test]
     fn test_write_str() {
-        assert_eq!(String("".to_string()).to_str().into_string(), "\"\"".to_string());
+        assert_eq!(String("".to_string()).to_string().into_string(), "\"\"".to_string());
         assert_eq!(String("".to_string()).to_pretty_str().into_string(), "\"\"".to_string());
 
-        assert_eq!(String("foo".to_string()).to_str().into_string(), "\"foo\"".to_string());
+        assert_eq!(String("foo".to_string()).to_string().into_string(), "\"foo\"".to_string());
         assert_eq!(String("foo".to_string()).to_pretty_str().into_string(), "\"foo\"".to_string());
     }
 
     #[test]
     fn test_write_bool() {
-        assert_eq!(Boolean(true).to_str().into_string(), "true".to_string());
+        assert_eq!(Boolean(true).to_string().into_string(), "true".to_string());
         assert_eq!(Boolean(true).to_pretty_str().into_string(), "true".to_string());
 
-        assert_eq!(Boolean(false).to_str().into_string(), "false".to_string());
+        assert_eq!(Boolean(false).to_string().into_string(), "false".to_string());
         assert_eq!(Boolean(false).to_pretty_str().into_string(), "false".to_string());
     }
 
     #[test]
     fn test_write_list() {
-        assert_eq!(List(vec![]).to_str().into_string(), "[]".to_string());
+        assert_eq!(List(vec![]).to_string().into_string(), "[]".to_string());
         assert_eq!(List(vec![]).to_pretty_str().into_string(), "[]".to_string());
 
-        assert_eq!(List(vec![Boolean(true)]).to_str().into_string(), "[true]".to_string());
+        assert_eq!(List(vec![Boolean(true)]).to_string().into_string(), "[true]".to_string());
         assert_eq!(
             List(vec![Boolean(true)]).to_pretty_str().into_string(),
             "\
@@ -2218,7 +2268,7 @@ fn test_write_list() {
             Null,
             List(vec![String("foo\nbar".to_string()), Number(3.5)])]);
 
-        assert_eq!(long_test_list.to_str().into_string(),
+        assert_eq!(long_test_list.to_string().into_string(),
             "[false,null,[\"foo\\nbar\",3.5]]".to_string());
         assert_eq!(
             long_test_list.to_pretty_str().into_string(),
@@ -2236,13 +2286,13 @@ fn test_write_list() {
 
     #[test]
     fn test_write_object() {
-        assert_eq!(mk_object([]).to_str().into_string(), "{}".to_string());
+        assert_eq!(mk_object([]).to_string().into_string(), "{}".to_string());
         assert_eq!(mk_object([]).to_pretty_str().into_string(), "{}".to_string());
 
         assert_eq!(
             mk_object([
                 ("a".to_string(), Boolean(true))
-            ]).to_str().into_string(),
+            ]).to_string().into_string(),
             "{\"a\":true}".to_string()
         );
         assert_eq!(
@@ -2261,7 +2311,7 @@ fn test_write_object() {
             ]);
 
         assert_eq!(
-            complex_obj.to_str().into_string(),
+            complex_obj.to_string().into_string(),
             "{\
                 \"b\":[\
                     {\"c\":\"\\f\\r\"},\
@@ -2294,7 +2344,7 @@ fn test_write_object() {
 
         // We can't compare the strings directly because the object fields be
         // printed in a different order.
-        assert_eq!(a.clone(), from_str(a.to_str().as_slice()).unwrap());
+        assert_eq!(a.clone(), from_str(a.to_string().as_slice()).unwrap());
         assert_eq!(a.clone(),
                    from_str(a.to_pretty_str().as_slice()).unwrap());
     }
index a2a504132363332e60cffd698e95b38945388cb7..5cb272a19eb886fff9edac35180c253c8dae5088 100644 (file)
 Core encoding and decoding interfaces.
 */
 
-#![crate_id = "serialize#0.11.0"]
+#![crate_name = "serialize"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(macro_rules, managed_boxes, default_type_params, phase)]
 
index 0ed555e392fa1f0e1643eb1be47465e882f9159e..03d9445b9b94bae73032dd1e2bfdd73f43b38177 100644 (file)
@@ -17,6 +17,7 @@
 use std::path;
 use std::rc::Rc;
 use std::gc::{Gc, GC};
+use std::cell::{Cell, RefCell};
 
 pub trait Encoder<E> {
     // Primitive types:
@@ -536,6 +537,35 @@ fn decode(d: &mut D) -> Result<path::windows::Path, E> {
     }
 }
 
+impl<E, S: Encoder<E>, T: Encodable<S, E> + Copy> Encodable<S, E> for Cell<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        self.get().encode(s)
+    }
+}
+
+impl<E, D: Decoder<E>, T: Decodable<D, E> + Copy> Decodable<D, E> for Cell<T> {
+    fn decode(d: &mut D) -> Result<Cell<T>, E> {
+        Ok(Cell::new(try!(Decodable::decode(d))))
+    }
+}
+
+// FIXME: #15036
+// Should use `try_borrow`, returning a
+// `encoder.error("attempting to Encode borrowed RefCell")`
+// from `encode` when `try_borrow` returns `None`.
+
+impl<E, S: Encoder<E>, T: Encodable<S, E>> Encodable<S, E> for RefCell<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        self.borrow().encode(s)
+    }
+}
+
+impl<E, D: Decoder<E>, T: Decodable<D, E>> Decodable<D, E> for RefCell<T> {
+    fn decode(d: &mut D) -> Result<RefCell<T>, E> {
+        Ok(RefCell::new(try!(Decodable::decode(d))))
+    }
+}
+
 // ___________________________________________________________________________
 // Helper routines
 //
index fae1b933210d52a9c2f8f49499583eeb03f49873..796147ce7a05dd0c14a52806c93ceade93da5b45 100644 (file)
@@ -345,10 +345,10 @@ fn eq_ignore_case(self, other: &[Ascii]) -> bool {
 
 impl IntoStr for Vec<Ascii> {
     #[inline]
-    fn into_str(self) -> String {
+    fn into_string(self) -> String {
         unsafe {
             let s: &str = mem::transmute(self.as_slice());
-            s.to_string()
+            String::from_str(s)
         }
     }
 }
@@ -438,12 +438,12 @@ unsafe fn str_map_bytes(string: String, map: &'static [u8]) -> String {
         *b = map[*b as uint];
     }
 
-    str::from_utf8(bytes.as_slice()).unwrap().to_string()
+    String::from_str(str::from_utf8(bytes.as_slice()).unwrap())
 }
 
 #[inline]
 unsafe fn str_copy_map_bytes(string: &str, map: &'static [u8]) -> String {
-    let mut s = string.to_string();
+    let mut s = String::from_str(string);
     for b in s.as_mut_bytes().mut_iter() {
         *b = map[*b as uint];
     }
@@ -578,12 +578,12 @@ fn test_ascii_vec() {
         assert_eq!(v.as_slice().to_ascii(), v2ascii!([40, 32, 59]));
         assert_eq!("( ;".to_string().as_slice().to_ascii(), v2ascii!([40, 32, 59]));
 
-        assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), "abcdef&?#".to_string());
-        assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), "ABCDEF&?#".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_lower().into_string(), "abcdef&?#".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_upper().into_string(), "ABCDEF&?#".to_string());
 
-        assert_eq!("".to_ascii().to_lower().into_str(), "".to_string());
-        assert_eq!("YMCA".to_ascii().to_lower().into_str(), "ymca".to_string());
-        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), "ABCDEFXYZ:.;".to_string());
+        assert_eq!("".to_ascii().to_lower().into_string(), "".to_string());
+        assert_eq!("YMCA".to_ascii().to_lower().into_string(), "ymca".to_string());
+        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_string(), "ABCDEFXYZ:.;".to_string());
 
         assert!("aBcDeF&?#".to_ascii().eq_ignore_case("AbCdEf&?#".to_ascii()));
 
@@ -595,11 +595,11 @@ fn test_ascii_vec() {
 
     #[test]
     fn test_ascii_vec_ng() {
-        assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), "abcdef&?#".to_string());
-        assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), "ABCDEF&?#".to_string());
-        assert_eq!("".to_ascii().to_lower().into_str(), "".to_string());
-        assert_eq!("YMCA".to_ascii().to_lower().into_str(), "ymca".to_string());
-        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), "ABCDEFXYZ:.;".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_lower().into_string(), "abcdef&?#".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_upper().into_string(), "ABCDEF&?#".to_string());
+        assert_eq!("".to_ascii().to_lower().into_string(), "".to_string());
+        assert_eq!("YMCA".to_ascii().to_lower().into_string(), "ymca".to_string());
+        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_string(), "ABCDEFXYZ:.;".to_string());
     }
 
     #[test]
@@ -615,9 +615,9 @@ fn test_ascii_as_str() {
     }
 
     #[test]
-    fn test_ascii_into_str() {
-        assert_eq!(vec2ascii![40, 32, 59].into_str(), "( ;".to_string());
-        assert_eq!(vec2ascii!(40, 32, 59).into_str(), "( ;".to_string());
+    fn test_ascii_into_string() {
+        assert_eq!(vec2ascii![40, 32, 59].into_string(), "( ;".to_string());
+        assert_eq!(vec2ascii!(40, 32, 59).into_string(), "( ;".to_string());
     }
 
     #[test]
@@ -757,8 +757,8 @@ fn test_eq_ignore_ascii_case() {
     }
 
     #[test]
-    fn test_to_str() {
-        let s = Ascii{ chr: 't' as u8 }.to_str();
+    fn test_to_string() {
+        let s = Ascii{ chr: 't' as u8 }.to_string();
         assert_eq!(s, "t".to_string());
     }
 
index 7c01a0342edc71b30bbcaf89597f1bfc10240b4c..098e87243b69cfe8d75824de5e7cc91e744f0748 100644 (file)
@@ -294,8 +294,7 @@ pub fn read<'a>(&'a self, index: &FullIndex) -> (&'a K, &'a V) {
 
             unsafe {
                 debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
-                (&'a *self.keys.offset(idx),
-                 &'a *self.vals.offset(idx))
+                (&*self.keys.offset(idx), &*self.vals.offset(idx))
             }
         }
 
@@ -306,8 +305,7 @@ pub fn read_mut<'a>(&'a mut self, index: &FullIndex) -> (&'a K, &'a mut V) {
 
             unsafe {
                 debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
-                (&'a     *self.keys.offset(idx),
-                 &'a mut *self.vals.offset(idx))
+                (&*self.keys.offset(idx), &mut *self.vals.offset(idx))
             }
         }
 
@@ -319,8 +317,7 @@ pub fn read_all_mut<'a>(&'a mut self, index: &FullIndex)
             unsafe {
                 debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
                 (transmute(self.hashes.offset(idx)),
-                 &'a mut *self.keys.offset(idx),
-                 &'a mut *self.vals.offset(idx))
+                 &mut *self.keys.offset(idx), &mut *self.vals.offset(idx))
             }
         }
 
index 08f11581e838a17a74f5ee8badd66b350e230066..45301737adb3dad902371e20052671c92773552e 100644 (file)
@@ -45,7 +45,7 @@
 use mem;
 use ops::Drop;
 use option::{Some, None, Option};
-use owned::Box;
+use boxed::Box;
 use ptr;
 use result::{Ok, Err};
 
@@ -319,20 +319,20 @@ fn test_change_capacity() {
     }
 
     #[test]
-    fn test_to_str() {
+    fn test_to_string() {
         let mut cache: LruCache<int, int> = LruCache::new(3);
         cache.put(1, 10);
         cache.put(2, 20);
         cache.put(3, 30);
-        assert_eq!(cache.to_str(), "{3: 30, 2: 20, 1: 10}".to_string());
+        assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}".to_string());
         cache.put(2, 22);
-        assert_eq!(cache.to_str(), "{2: 22, 3: 30, 1: 10}".to_string());
+        assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}".to_string());
         cache.put(6, 60);
-        assert_eq!(cache.to_str(), "{6: 60, 2: 22, 3: 30}".to_string());
+        assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}".to_string());
         cache.get(&3);
-        assert_eq!(cache.to_str(), "{3: 30, 6: 60, 2: 22}".to_string());
+        assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}".to_string());
         cache.change_capacity(2);
-        assert_eq!(cache.to_str(), "{3: 30, 6: 60}".to_string());
+        assert_eq!(cache.to_string(), "{3: 30, 6: 60}".to_string());
     }
 
     #[test]
@@ -343,6 +343,6 @@ fn test_clear() {
         cache.clear();
         assert!(cache.get(&1).is_none());
         assert!(cache.get(&2).is_none());
-        assert_eq!(cache.to_str(), "{}".to_string());
+        assert_eq!(cache.to_string(), "{}".to_string());
     }
 }
index 728875ce2601012f3d25b645de37fddae4212a36..86283f03381dd1c68d4c7130f49bd726c57ff3f1 100644 (file)
@@ -209,13 +209,11 @@ fn test_errors_do_not_crash() {
 #[cfg(target_os = "ios")]
 #[cfg(target_os = "freebsd")]
 pub mod dl {
-    use prelude::*;
 
     use c_str::{CString, ToCStr};
     use libc;
     use ptr;
     use result::*;
-    use str::StrAllocating;
     use string::String;
 
     pub unsafe fn open_external<T: ToCStr>(filename: T) -> *mut u8 {
@@ -243,9 +241,8 @@ pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
             let ret = if ptr::null() == last_error {
                 Ok(result)
             } else {
-                Err(CString::new(last_error, false).as_str()
-                                                   .unwrap()
-                                                   .to_string())
+                Err(String::from_str(CString::new(last_error, false).as_str()
+                    .unwrap()))
             };
 
             ret
index 47ff85e2806d562caf77f6e81d12dc1255e36e9f..8c709d20d1904d3ee25e9ba770059bd33de2e770 100644 (file)
@@ -10,7 +10,7 @@
 
 #![experimental]
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use any::{Any, AnyRefExt};
 use fmt;
 use io::{Writer, IoResult};
index 1ca72bca20bdb5cbec9b983e2e90f7f8e7991262..21b1e0560a5dba49ff6d0b715196d0f4d91ba957 100644 (file)
@@ -14,7 +14,6 @@
 
 use option::{Option, Some, None};
 use string::String;
-use str::StrAllocating;
 
 /// A trait to abstract the idea of creating a new instance of a type from a
 /// string.
@@ -55,7 +54,7 @@ fn from_str(s: &str) -> Option<bool> {
 impl FromStr for String {
     #[inline]
     fn from_str(s: &str) -> Option<String> {
-        Some(s.to_string())
+        Some(String::from_str(s))
     }
 }
 
index 2cc7e70747a794403675e44d28ea6a4b0b8d829d..55d1411d77ed2a0d4fb42390f57f47a286b0f4d9 100644 (file)
@@ -61,6 +61,8 @@
  * ```
  */
 
+#![experimental]
+
 pub use core_collections::hash::{Hash, Hasher, Writer, hash, sip};
 
 use default::Default;
index 277aca2332d475cb1b42a9852f0f59b793d2d505..ca3eee01575fd3aca54bbddd85bb875925a0a69b 100644 (file)
@@ -508,14 +508,15 @@ mod bench {
     use prelude::*;
     use self::test::Bencher;
 
+    // why is this a macro? wouldn't an inlined function work just as well?
     macro_rules! u64_from_be_bytes_bench_impl(
-        ($size:expr, $stride:expr, $start_index:expr) =>
+        ($b:expr, $size:expr, $stride:expr, $start_index:expr) =>
         ({
             use super::u64_from_be_bytes;
 
             let data = Vec::from_fn($stride*100+$start_index, |i| i as u8);
             let mut sum = 0u64;
-            b.iter(|| {
+            $b.iter(|| {
                 let mut i = $start_index;
                 while i < data.len() {
                     sum += u64_from_be_bytes(data.as_slice(), i, $size);
@@ -527,31 +528,31 @@ macro_rules! u64_from_be_bytes_bench_impl(
 
     #[bench]
     fn u64_from_be_bytes_4_aligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(4, 4, 0);
+        u64_from_be_bytes_bench_impl!(b, 4, 4, 0);
     }
 
     #[bench]
     fn u64_from_be_bytes_4_unaligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(4, 4, 1);
+        u64_from_be_bytes_bench_impl!(b, 4, 4, 1);
     }
 
     #[bench]
     fn u64_from_be_bytes_7_aligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(7, 8, 0);
+        u64_from_be_bytes_bench_impl!(b, 7, 8, 0);
     }
 
     #[bench]
     fn u64_from_be_bytes_7_unaligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(7, 8, 1);
+        u64_from_be_bytes_bench_impl!(b, 7, 8, 1);
     }
 
     #[bench]
     fn u64_from_be_bytes_8_aligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(8, 8, 0);
+        u64_from_be_bytes_bench_impl!(b, 8, 8, 0);
     }
 
     #[bench]
     fn u64_from_be_bytes_8_unaligned(b: &mut Bencher) {
-        u64_from_be_bytes_bench_impl!(8, 8, 1);
+        u64_from_be_bytes_bench_impl!(b, 8, 8, 1);
     }
 }
index e7f26c7bd910e5d21d61de30a703734684f9f1a4..caff7d5e4c5930a6be9896e226466c5326a23e3e 100644 (file)
@@ -62,7 +62,7 @@
 use kinds::Send;
 use libc;
 use option::{Some, None, Option};
-use owned::Box;
+use boxed::Box;
 use path::{Path, GenericPath};
 use path;
 use result::{Err, Ok};
@@ -275,11 +275,41 @@ pub fn stat(&mut self) -> IoResult<FileStat> {
 /// user lacks permissions to remove the file, or if some other filesystem-level
 /// error occurs.
 pub fn unlink(path: &Path) -> IoResult<()> {
-    let err = LocalIo::maybe_raise(|io| {
-        io.fs_unlink(&path.to_c_str())
-    }).map_err(IoError::from_rtio_error);
-    err.update_err("couldn't unlink path",
-                   |e| format!("{}; path={}", e, path.display()))
+    return match do_unlink(path) {
+        Ok(()) => Ok(()),
+        Err(e) => {
+            // On unix, a readonly file can be successfully removed. On windows,
+            // however, it cannot. To keep the two platforms in line with
+            // respect to their behavior, catch this case on windows, attempt to
+            // change it to read-write, and then remove the file.
+            if cfg!(windows) && e.kind == io::PermissionDenied {
+                let stat = match stat(path) {
+                    Ok(stat) => stat,
+                    Err(..) => return Err(e),
+                };
+                if stat.perm.intersects(io::UserWrite) { return Err(e) }
+
+                match chmod(path, stat.perm | io::UserWrite) {
+                    Ok(()) => do_unlink(path),
+                    Err(..) => {
+                        // Try to put it back as we found it
+                        let _ = chmod(path, stat.perm);
+                        Err(e)
+                    }
+                }
+            } else {
+                Err(e)
+            }
+        }
+    };
+
+    fn do_unlink(path: &Path) -> IoResult<()> {
+        let err = LocalIo::maybe_raise(|io| {
+            io.fs_unlink(&path.to_c_str())
+        }).map_err(IoError::from_rtio_error);
+        err.update_err("couldn't unlink path",
+                       |e| format!("{}; path={}", e, path.display()))
+    }
 }
 
 /// Given a path, query the file system to get information about a file,
@@ -330,6 +360,11 @@ pub fn lstat(path: &Path) -> IoResult<FileStat> {
 }
 
 fn from_rtio(s: rtio::FileStat) -> FileStat {
+    #[cfg(windows)]
+    type Mode = libc::c_int;
+    #[cfg(unix)]
+    type Mode = libc::mode_t;
+
     let rtio::FileStat {
         size, kind, perm, created, modified,
         accessed, device, inode, rdev,
@@ -338,7 +373,7 @@ fn from_rtio(s: rtio::FileStat) -> FileStat {
 
     FileStat {
         size: size,
-        kind: match (kind as libc::c_int) & libc::S_IFMT {
+        kind: match (kind as Mode) & libc::S_IFMT {
             libc::S_IFREG => io::TypeFile,
             libc::S_IFDIR => io::TypeDirectory,
             libc::S_IFIFO => io::TypeNamedPipe,
@@ -915,7 +950,7 @@ macro_rules! check( ($e:expr) => (
     macro_rules! error( ($e:expr, $s:expr) => (
         match $e {
             Ok(val) => fail!("Should have been an error, was {:?}", val),
-            Err(ref err) => assert!(err.to_str().as_slice().contains($s.as_slice()),
+            Err(ref err) => assert!(err.to_string().as_slice().contains($s.as_slice()),
                                     format!("`{}` did not contain `{}`", err, $s))
         }
     ) )
@@ -1167,7 +1202,7 @@ pub fn tmpdir() -> TempDir {
         for n in range(0i,3) {
             let f = dir.join(format!("{}.txt", n));
             let mut w = check!(File::create(&f));
-            let msg_str = format!("{}{}", prefix, n.to_str());
+            let msg_str = format!("{}{}", prefix, n.to_string());
             let msg = msg_str.as_slice().as_bytes();
             check!(w.write(msg));
         }
@@ -1586,4 +1621,12 @@ fn utime_noexist() {
         let actual = check!(File::open(&tmpdir.join("test")).read_to_end());
         assert!(actual.as_slice() == bytes);
     })
+
+    iotest!(fn unlink_readonly() {
+        let tmpdir = tmpdir();
+        let path = tmpdir.join("file");
+        check!(File::create(&path));
+        check!(chmod(&path, io::UserRead));
+        check!(unlink(&path));
+    })
 }
index 3443a85b46819a41a7619ce9f74b64223f2010b5..1c0251c8369dedc4a8709d8f1cc74ae60c7edcc4 100644 (file)
@@ -259,8 +259,8 @@ impl<'a> Writer for BufWriter<'a> {
     #[inline]
     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         // return an error if the entire write does not fit in the buffer
-        let max_size = self.buf.len();
-        if self.pos >= max_size || (self.pos + buf.len()) > max_size {
+        let cap = if self.pos >= self.buf.len() { 0 } else { self.buf.len() - self.pos };
+        if buf.len() > cap {
             return Err(IoError {
                 kind: io::OtherIoError,
                 desc: "Trying to write past end of buffer",
@@ -416,6 +416,8 @@ fn test_buf_writer() {
             writer.write([1, 2, 3]).unwrap();
             writer.write([4, 5, 6, 7]).unwrap();
             assert_eq!(writer.tell(), Ok(8));
+            writer.write([]).unwrap();
+            assert_eq!(writer.tell(), Ok(8));
         }
         assert_eq!(buf.as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7]);
     }
@@ -532,7 +534,7 @@ fn test_write_strings() {
         writer.write_line("testing").unwrap();
         writer.write_str("testing").unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        assert_eq!(r.read_to_str().unwrap(), "testingtesting\ntesting".to_string());
+        assert_eq!(r.read_to_string().unwrap(), "testingtesting\ntesting".to_string());
     }
 
     #[test]
@@ -542,14 +544,14 @@ fn test_write_char() {
         writer.write_char('\n').unwrap();
         writer.write_char('ệ').unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        assert_eq!(r.read_to_str().unwrap(), "a\nệ".to_string());
+        assert_eq!(r.read_to_string().unwrap(), "a\nệ".to_string());
     }
 
     #[test]
     fn test_read_whole_string_bad() {
         let buf = [0xff];
         let mut r = BufReader::new(buf);
-        match r.read_to_str() {
+        match r.read_to_string() {
             Ok(..) => fail!(),
             Err(..) => {}
         }
@@ -607,17 +609,61 @@ fn io_read_at_least() {
         assert_eq!(buf.as_slice(), &[7, 8, 6]);
     }
 
-    #[bench]
-    fn bench_mem_writer(b: &mut Bencher) {
+    fn do_bench_mem_writer(b: &mut Bencher, times: uint, len: uint) {
+        let src: Vec<u8> = Vec::from_elem(len, 5);
+
         b.iter(|| {
             let mut wr = MemWriter::new();
-            for _i in range(0u, 10) {
-                wr.write([5, .. 10]).unwrap();
+            for _ in range(0, times) {
+                wr.write(src.as_slice()).unwrap();
             }
-            assert_eq!(wr.unwrap().as_slice(), [5, .. 100].as_slice());
+
+            let v = wr.unwrap();
+            assert_eq!(v.len(), times * len);
+            assert!(v.iter().all(|x| *x == 5));
         });
     }
 
+    #[bench]
+    fn bench_mem_writer_001_0000(b: &mut Bencher) {
+        do_bench_mem_writer(b, 1, 0)
+    }
+
+    #[bench]
+    fn bench_mem_writer_001_0010(b: &mut Bencher) {
+        do_bench_mem_writer(b, 1, 10)
+    }
+
+    #[bench]
+    fn bench_mem_writer_001_0100(b: &mut Bencher) {
+        do_bench_mem_writer(b, 1, 100)
+    }
+
+    #[bench]
+    fn bench_mem_writer_001_1000(b: &mut Bencher) {
+        do_bench_mem_writer(b, 1, 1000)
+    }
+
+    #[bench]
+    fn bench_mem_writer_100_0000(b: &mut Bencher) {
+        do_bench_mem_writer(b, 100, 0)
+    }
+
+    #[bench]
+    fn bench_mem_writer_100_0010(b: &mut Bencher) {
+        do_bench_mem_writer(b, 100, 10)
+    }
+
+    #[bench]
+    fn bench_mem_writer_100_0100(b: &mut Bencher) {
+        do_bench_mem_writer(b, 100, 100)
+    }
+
+    #[bench]
+    fn bench_mem_writer_100_1000(b: &mut Bencher) {
+        do_bench_mem_writer(b, 100, 1000)
+    }
+
     #[bench]
     fn bench_mem_reader(b: &mut Bencher) {
         b.iter(|| {
index 1d339b03af6717d9eb68e4908f3e6e4e7333bbf8..6ac092fd8c657e4998f19a7b695942bfc65905ef 100644 (file)
@@ -229,14 +229,15 @@ fn file_product(p: &Path) -> IoResult<u32> {
 use ops::{BitOr, BitAnd, Sub, Not};
 use option::{Option, Some, None};
 use os;
-use owned::Box;
+use boxed::Box;
 use result::{Ok, Err, Result};
 use rt::rtio;
 use slice::{Vector, MutableVector, ImmutableVector};
-use str::{Str, StrSlice, StrAllocating};
+use str::{Str, StrSlice};
 use str;
 use string::String;
 use uint;
+use unicode::UnicodeChar;
 use vec::Vec;
 
 // Reexports
@@ -292,7 +293,7 @@ fn file_product(p: &Path) -> IoResult<u32> {
 /// # FIXME
 ///
 /// Is something like this sufficient? It's kind of archaic
-#[deriving(PartialEq, Clone)]
+#[deriving(PartialEq, Eq, Clone)]
 pub struct IoError {
     /// An enumeration which can be matched against for determining the flavor
     /// of error.
@@ -434,7 +435,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 }
 
 /// A list specifying general categories of I/O error.
-#[deriving(PartialEq, Clone, Show)]
+#[deriving(PartialEq, Eq, Clone, Show)]
 pub enum IoErrorKind {
     /// Any I/O error not part of this list.
     OtherIoError,
@@ -566,7 +567,7 @@ pub trait Reader {
     fn read_at_least(&mut self, min: uint, buf: &mut [u8]) -> IoResult<uint> {
         if min > buf.len() {
             return Err(IoError {
-                detail: Some("the buffer is too short".to_string()),
+                detail: Some(String::from_str("the buffer is too short")),
                 ..standard_error(InvalidInput)
             });
         }
@@ -634,7 +635,7 @@ fn push(&mut self, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
     fn push_at_least(&mut self, min: uint, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
         if min > len {
             return Err(IoError {
-                detail: Some("the buffer is too short".to_string()),
+                detail: Some(String::from_str("the buffer is too short")),
                 ..standard_error(InvalidInput)
             });
         }
@@ -702,10 +703,10 @@ fn read_to_end(&mut self) -> IoResult<Vec<u8>> {
     /// This function returns all of the same errors as `read_to_end` with an
     /// additional error if the reader's contents are not a valid sequence of
     /// UTF-8 bytes.
-    fn read_to_str(&mut self) -> IoResult<String> {
+    fn read_to_string(&mut self) -> IoResult<String> {
         self.read_to_end().and_then(|s| {
             match str::from_utf8(s.as_slice()) {
-                Some(s) => Ok(s.to_string()),
+                Some(s) => Ok(String::from_str(s)),
                 None => Err(standard_error(InvalidInput)),
             }
         })
@@ -1440,7 +1441,7 @@ pub trait Buffer: Reader {
     fn read_line(&mut self) -> IoResult<String> {
         self.read_until('\n' as u8).and_then(|line|
             match str::from_utf8(line.as_slice()) {
-                Some(s) => Ok(s.to_string()),
+                Some(s) => Ok(String::from_str(s)),
                 None => Err(standard_error(InvalidInput)),
             }
         )
index ca59849202b08677e03943747fb2617d6eb6a687..79caded6711a22219d7c97af256b9df07da58653 100644 (file)
@@ -443,10 +443,11 @@ fn test_from_str_socket_addr() {
     }
 
     #[test]
-    fn ipv6_addr_to_str() {
+    fn ipv6_addr_to_string() {
         let a1 = Ipv6Addr(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
-        assert!(a1.to_str() == "::ffff:192.0.2.128".to_string() ||
-                a1.to_str() == "::FFFF:192.0.2.128".to_string());
-        assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_str(), "8:9:a:b:c:d:e:f".to_string());
+        assert!(a1.to_string() == "::ffff:192.0.2.128".to_string() ||
+                a1.to_string() == "::FFFF:192.0.2.128".to_string());
+        assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_string(),
+                   "8:9:a:b:c:d:e:f".to_string());
     }
 }
index baf53251fbe082e5e485ac2df70e64d7dc36c72d..642654ba6ed815252e62df30ebb2ac6729061235 100644 (file)
@@ -29,7 +29,7 @@
 use from_str::FromStr;
 use kinds::Send;
 use option::{None, Some, Option};
-use owned::Box;
+use boxed::Box;
 use rt::rtio::{IoFactory, LocalIo, RtioSocket, RtioTcpListener};
 use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
 use rt::rtio;
@@ -467,7 +467,7 @@ mod test {
 
     iotest!(fn listen_ip4_localhost() {
         let socket_addr = next_test_ip4();
-        let ip_str = socket_addr.ip.to_str();
+        let ip_str = socket_addr.ip.to_string();
         let port = socket_addr.port;
         let listener = TcpListener::bind(ip_str.as_slice(), port);
         let mut acceptor = listener.listen();
@@ -485,7 +485,7 @@ mod test {
 
     iotest!(fn connect_localhost() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -502,7 +502,7 @@ mod test {
 
     iotest!(fn connect_ip4_loopback() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -519,7 +519,7 @@ mod test {
 
     iotest!(fn connect_ip6_loopback() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -536,7 +536,7 @@ mod test {
 
     iotest!(fn smoke_test_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -553,7 +553,7 @@ mod test {
 
     iotest!(fn smoke_test_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -570,7 +570,7 @@ mod test {
 
     iotest!(fn read_eof_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -587,7 +587,7 @@ mod test {
 
     iotest!(fn read_eof_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -604,7 +604,7 @@ mod test {
 
     iotest!(fn read_eof_twice_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -629,7 +629,7 @@ mod test {
 
     iotest!(fn read_eof_twice_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -654,7 +654,7 @@ mod test {
 
     iotest!(fn write_close_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -681,7 +681,7 @@ mod test {
 
     iotest!(fn write_close_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -708,7 +708,7 @@ mod test {
 
     iotest!(fn multiple_connect_serial_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let max = 10u;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
@@ -729,7 +729,7 @@ mod test {
 
     iotest!(fn multiple_connect_serial_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let max = 10u;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
@@ -750,7 +750,7 @@ mod test {
 
     iotest!(fn multiple_connect_interleaved_greedy_schedule_ip4() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         static MAX: int = 10;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
@@ -772,7 +772,7 @@ mod test {
         connect(0, addr);
 
         fn connect(i: int, addr: SocketAddr) {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let port = addr.port;
             if i == MAX { return }
 
@@ -789,7 +789,7 @@ fn connect(i: int, addr: SocketAddr) {
 
     iotest!(fn multiple_connect_interleaved_greedy_schedule_ip6() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         static MAX: int = 10;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
@@ -811,7 +811,7 @@ fn connect(i: int, addr: SocketAddr) {
         connect(0, addr);
 
         fn connect(i: int, addr: SocketAddr) {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let port = addr.port;
             if i == MAX { return }
 
@@ -829,7 +829,7 @@ fn connect(i: int, addr: SocketAddr) {
     iotest!(fn multiple_connect_interleaved_lazy_schedule_ip4() {
         static MAX: int = 10;
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -850,7 +850,7 @@ fn connect(i: int, addr: SocketAddr) {
         connect(0, addr);
 
         fn connect(i: int, addr: SocketAddr) {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let port = addr.port;
             if i == MAX { return }
 
@@ -868,7 +868,7 @@ fn connect(i: int, addr: SocketAddr) {
     iotest!(fn multiple_connect_interleaved_lazy_schedule_ip6() {
         static MAX: int = 10;
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -889,7 +889,7 @@ fn connect(i: int, addr: SocketAddr) {
         connect(0, addr);
 
         fn connect(i: int, addr: SocketAddr) {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let port = addr.port;
             if i == MAX { return }
 
@@ -905,7 +905,7 @@ fn connect(i: int, addr: SocketAddr) {
     })
 
     pub fn socket_name(addr: SocketAddr) {
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut listener = TcpListener::bind(ip_str.as_slice(), port).unwrap();
 
@@ -917,7 +917,7 @@ pub fn socket_name(addr: SocketAddr) {
     }
 
     pub fn peer_name(addr: SocketAddr) {
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
         spawn(proc() {
@@ -954,7 +954,7 @@ pub fn peer_name(addr: SocketAddr) {
         let port = addr.port;
         let (tx, rx) = channel();
         spawn(proc() {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let mut srv = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
             tx.send(());
             let mut cl = srv.accept().unwrap();
@@ -965,7 +965,7 @@ pub fn peer_name(addr: SocketAddr) {
         });
 
         rx.recv();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let mut c = TcpStream::connect(ip_str.as_slice(), port).unwrap();
         let mut b = [0, ..10];
         assert_eq!(c.read(b), Ok(1));
@@ -975,7 +975,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn double_bind() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let listener = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen();
         assert!(listener.is_ok());
@@ -994,7 +994,7 @@ pub fn peer_name(addr: SocketAddr) {
         let (tx, rx) = channel();
 
         spawn(proc() {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             rx.recv();
             let _stream = TcpStream::connect(ip_str.as_slice(), port).unwrap();
             // Close
@@ -1002,7 +1002,7 @@ pub fn peer_name(addr: SocketAddr) {
         });
 
         {
-            let ip_str = addr.ip.to_str();
+            let ip_str = addr.ip.to_string();
             let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
             tx.send(());
             {
@@ -1012,12 +1012,12 @@ pub fn peer_name(addr: SocketAddr) {
             }
             // Close listener
         }
-        let _listener = TcpListener::bind(addr.ip.to_str().as_slice(), port);
+        let _listener = TcpListener::bind(addr.ip.to_string().as_slice(), port);
     })
 
     iotest!(fn tcp_clone_smoke() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -1048,7 +1048,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn tcp_clone_two_read() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
         let (tx1, rx) = channel();
@@ -1082,7 +1082,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn tcp_clone_two_write() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
 
@@ -1111,7 +1111,7 @@ pub fn peer_name(addr: SocketAddr) {
         use rt::rtio::RtioTcpStream;
 
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let a = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen();
         spawn(proc() {
@@ -1129,7 +1129,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn accept_timeout() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen().unwrap();
 
@@ -1150,7 +1150,7 @@ pub fn peer_name(addr: SocketAddr) {
         if !cfg!(target_os = "freebsd") {
             let (tx, rx) = channel();
             spawn(proc() {
-                tx.send(TcpStream::connect(addr.ip.to_str().as_slice(),
+                tx.send(TcpStream::connect(addr.ip.to_string().as_slice(),
                                            port).unwrap());
             });
             let _l = rx.recv();
@@ -1168,7 +1168,7 @@ pub fn peer_name(addr: SocketAddr) {
         // Unset the timeout and make sure that this always blocks.
         a.set_timeout(None);
         spawn(proc() {
-            drop(TcpStream::connect(addr.ip.to_str().as_slice(),
+            drop(TcpStream::connect(addr.ip.to_string().as_slice(),
                                     port).unwrap());
         });
         a.accept().unwrap();
@@ -1176,7 +1176,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn close_readwrite_smoke() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (_tx, rx) = channel::<()>();
@@ -1214,7 +1214,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn close_read_wakes_up() {
         let addr = next_test_ip4();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (_tx, rx) = channel::<()>();
@@ -1241,7 +1241,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn readwrite_timeouts() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (tx, rx) = channel::<()>();
@@ -1275,7 +1275,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn read_timeouts() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (tx, rx) = channel::<()>();
@@ -1305,7 +1305,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn write_timeouts() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (tx, rx) = channel::<()>();
@@ -1334,7 +1334,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn timeout_concurrent_read() {
         let addr = next_test_ip6();
-        let ip_str = addr.ip.to_str();
+        let ip_str = addr.ip.to_string();
         let port = addr.port;
         let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
         let (tx, rx) = channel::<()>();
@@ -1363,7 +1363,7 @@ pub fn peer_name(addr: SocketAddr) {
 
     iotest!(fn clone_while_reading() {
         let addr = next_test_ip6();
-        let listen = TcpListener::bind(addr.ip.to_str().as_slice(), addr.port);
+        let listen = TcpListener::bind(addr.ip.to_string().as_slice(), addr.port);
         let mut accept = listen.listen().unwrap();
 
         // Enqueue a task to write to a socket
@@ -1371,7 +1371,7 @@ pub fn peer_name(addr: SocketAddr) {
         let (txdone, rxdone) = channel();
         let txdone2 = txdone.clone();
         spawn(proc() {
-            let mut tcp = TcpStream::connect(addr.ip.to_str().as_slice(),
+            let mut tcp = TcpStream::connect(addr.ip.to_string().as_slice(),
                                              addr.port).unwrap();
             rx.recv();
             tcp.write_u8(0).unwrap();
index 21903eb26439cc30c79b60d90acdd8ff29bf51a9..5f7563e7467ba6644e9399dac350f2d3b82c1c03 100644 (file)
@@ -19,7 +19,7 @@
 use io::net::ip::{SocketAddr, IpAddr};
 use io::{Reader, Writer, IoResult, IoError};
 use kinds::Send;
-use owned::Box;
+use boxed::Box;
 use option::Option;
 use result::{Ok, Err};
 use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
index c5ddda9945de1f82b86b287b468fba37647228df..5e7c421497772faa7f7244326a6a238c3ee10b4e 100644 (file)
@@ -30,7 +30,7 @@
 use clone::Clone;
 use io::{Listener, Acceptor, Reader, Writer, IoResult, IoError};
 use kinds::Send;
-use owned::Box;
+use boxed::Box;
 use rt::rtio::{IoFactory, LocalIo, RtioUnixListener};
 use rt::rtio::{RtioUnixAcceptor, RtioPipe};
 
index a968f41a91563ce9c7d7a66bf7a551fa9db94f13..c476a99fee9dc465d3d31b23ec40ef775c29a26d 100644 (file)
@@ -20,7 +20,7 @@
 use io::{IoResult, IoError};
 use libc;
 use os;
-use owned::Box;
+use boxed::Box;
 use rt::rtio::{RtioPipe, LocalIo};
 
 /// A synchronous, in-memory pipe.
index 8e1747146e42eb31b9048b4d1daed112f13492f0..07574b726457985af06b1f217403493d5e7ac431 100644 (file)
 
 use str;
 use fmt;
+use os;
 use io::{IoResult, IoError};
 use io;
 use libc;
 use mem;
-use owned::Box;
+use boxed::Box;
 use rt::rtio::{RtioProcess, ProcessConfig, IoFactory, LocalIo};
 use rt::rtio;
 use c_str::CString;
+use collections::HashMap;
 
 /// Signal a process to exit, without forcibly killing it. Corresponds to
 /// SIGTERM on unix platforms.
@@ -78,6 +80,9 @@ pub struct Process {
     pub extra_io: Vec<Option<io::PipeStream>>,
 }
 
+/// A HashMap representation of environment variables.
+pub type EnvMap = HashMap<CString, CString>;
+
 /// The `Command` type acts as a process builder, providing fine-grained control
 /// over how a new process should be spawned. A default configuration can be
 /// generated using `Command::new(program)`, where `program` gives a path to the
@@ -94,12 +99,13 @@ pub struct Process {
 ///
 /// let output = process.stdout.get_mut_ref().read_to_end();
 /// ```
+#[deriving(Clone)]
 pub struct Command {
     // The internal data for the builder. Documented by the builder
     // methods below, and serialized into rt::rtio::ProcessConfig.
     program: CString,
     args: Vec<CString>,
-    env: Option<Vec<(CString, CString)>>,
+    env: Option<EnvMap>,
     cwd: Option<CString>,
     stdin: StdioContainer,
     stdout: StdioContainer,
@@ -146,31 +152,53 @@ pub fn new<T:ToCStr>(program: T) -> Command {
     }
 
     /// Add an argument to pass to the program.
-    pub fn arg<'a, T:ToCStr>(&'a mut self, arg: T) -> &'a mut Command {
+    pub fn arg<'a, T: ToCStr>(&'a mut self, arg: T) -> &'a mut Command {
         self.args.push(arg.to_c_str());
         self
     }
 
     /// Add multiple arguments to pass to the program.
-    pub fn args<'a, T:ToCStr>(&'a mut self, args: &[T]) -> &'a mut Command {
+    pub fn args<'a, T: ToCStr>(&'a mut self, args: &[T]) -> &'a mut Command {
         self.args.extend(args.iter().map(|arg| arg.to_c_str()));;
         self
     }
+    // Get a mutable borrow of the environment variable map for this `Command`.
+    fn get_env_map<'a>(&'a mut self) -> &'a mut EnvMap {
+        match self.env {
+            Some(ref mut map) => map,
+            None => {
+                // if the env is currently just inheriting from the parent's,
+                // materialize the parent's env into a hashtable.
+                self.env = Some(os::env_as_bytes().move_iter()
+                                   .map(|(k, v)| (k.as_slice().to_c_str(),
+                                                  v.as_slice().to_c_str()))
+                                   .collect());
+                self.env.as_mut().unwrap()
+            }
+        }
+    }
 
-    /// Sets the environment for the child process (rather than inheriting it
-    /// from the current process).
-
-    // FIXME (#13851): We should change this interface to allow clients to (1)
-    // build up the env vector incrementally and (2) allow both inheriting the
-    // current process's environment AND overriding/adding additional
-    // environment variables. The underlying syscalls assume that the
-    // environment has no duplicate names, so we really want to use a hashtable
-    // to compute the environment to pass down to the syscall; resolving issue
-    // #13851 will make it possible to use the standard hashtable.
-    pub fn env<'a, T:ToCStr>(&'a mut self, env: &[(T,T)]) -> &'a mut Command {
-        self.env = Some(env.iter().map(|&(ref name, ref val)| {
-            (name.to_c_str(), val.to_c_str())
-        }).collect());
+    /// Inserts or updates an environment variable mapping.
+    pub fn env<'a, T: ToCStr, U: ToCStr>(&'a mut self, key: T, val: U)
+                                         -> &'a mut Command {
+        self.get_env_map().insert(key.to_c_str(), val.to_c_str());
+        self
+    }
+
+    /// Removes an environment variable mapping.
+    pub fn env_remove<'a, T: ToCStr>(&'a mut self, key: T) -> &'a mut Command {
+        self.get_env_map().remove(&key.to_c_str());
+        self
+    }
+
+    /// Sets the entire environment map for the child process.
+    ///
+    /// If the given slice contains multiple instances of an environment
+    /// variable, the *rightmost* instance will determine the value.
+    pub fn env_set_all<'a, T: ToCStr, U: ToCStr>(&'a mut self, env: &[(T,U)])
+                                                 -> &'a mut Command {
+        self.env = Some(env.iter().map(|&(ref k, ref v)| (k.to_c_str(), v.to_c_str()))
+                                  .collect());
         self
     }
 
@@ -244,10 +272,15 @@ fn to_rtio(p: StdioContainer) -> rtio::StdioContainer {
         let extra_io: Vec<rtio::StdioContainer> =
             self.extra_io.iter().map(|x| to_rtio(*x)).collect();
         LocalIo::maybe_raise(|io| {
+            let env = match self.env {
+                None => None,
+                Some(ref env_map) =>
+                    Some(env_map.iter().collect::<Vec<_>>())
+            };
             let cfg = ProcessConfig {
                 program: &self.program,
                 args: self.args.as_slice(),
-                env: self.env.as_ref().map(|env| env.as_slice()),
+                env: env.as_ref().map(|e| e.as_slice()),
                 cwd: self.cwd.as_ref(),
                 stdin: to_rtio(self.stdin),
                 stdout: to_rtio(self.stdout),
@@ -340,6 +373,7 @@ pub struct ProcessOutput {
 }
 
 /// Describes what to do with a standard io stream for a child process.
+#[deriving(Clone)]
 pub enum StdioContainer {
     /// This stream will be ignored. This is the equivalent of attaching the
     /// stream to `/dev/null`
@@ -615,7 +649,7 @@ mod tests {
     })
 
     pub fn read_all(input: &mut Reader) -> String {
-        input.read_to_str().unwrap()
+        input.read_to_string().unwrap()
     }
 
     pub fn run_output(cmd: Command) -> String {
@@ -870,9 +904,9 @@ pub fn env_cmd() -> Command {
         }
     })
 
-    iotest!(fn test_add_to_env() {
+    iotest!(fn test_override_env() {
         let new_env = vec![("RUN_TEST_NEW_ENV", "123")];
-        let prog = env_cmd().env(new_env.as_slice()).spawn().unwrap();
+        let prog = env_cmd().env_set_all(new_env.as_slice()).spawn().unwrap();
         let result = prog.wait_with_output().unwrap();
         let output = str::from_utf8_lossy(result.output.as_slice()).into_string();
 
@@ -880,6 +914,40 @@ pub fn env_cmd() -> Command {
                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
     })
 
+    iotest!(fn test_add_to_env() {
+        let prog = env_cmd().env("RUN_TEST_NEW_ENV", "123").spawn().unwrap();
+        let result = prog.wait_with_output().unwrap();
+        let output = str::from_utf8_lossy(result.output.as_slice()).into_string();
+
+        assert!(output.as_slice().contains("RUN_TEST_NEW_ENV=123"),
+                "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
+    })
+
+    iotest!(fn test_remove_from_env() {
+        use os;
+
+        // save original environment
+        let old_env = os::getenv("RUN_TEST_NEW_ENV");
+
+        os::setenv("RUN_TEST_NEW_ENV", "123");
+        let prog = env_cmd().env_remove("RUN_TEST_NEW_ENV").spawn().unwrap();
+        let result = prog.wait_with_output().unwrap();
+        let output = str::from_utf8_lossy(result.output.as_slice()).into_string();
+
+        // restore original environment
+        match old_env {
+            None => {
+                os::unsetenv("RUN_TEST_NEW_ENV");
+            }
+            Some(val) => {
+                os::setenv("RUN_TEST_NEW_ENV", val.as_slice());
+            }
+        }
+
+        assert!(!output.as_slice().contains("RUN_TEST_NEW_ENV"),
+                "found RUN_TEST_NEW_ENV inside of:\n\n{}", output);
+    })
+
     #[cfg(unix)]
     pub fn sleeper() -> Process {
         Command::new("sleep").arg("1000").spawn().unwrap()
index 4a7655a63ce8c257a27f6a482173de26bc3bc82b..d46f437cddd50a500badf5021657b7528866b4b7 100644 (file)
@@ -26,7 +26,7 @@
 use kinds::Send;
 use mem::drop;
 use option::{Some, None};
-use owned::Box;
+use boxed::Box;
 use result::{Ok, Err};
 use rt::rtio::{IoFactory, LocalIo, RtioSignal, Callback};
 use slice::ImmutableVector;
index e5a64f785ce9640643911ef9c55fb8a76f44b77c..45c084b3459613370e5aeac03d2f00fb4e73410a 100644 (file)
@@ -35,7 +35,7 @@
 use kinds::Send;
 use libc;
 use option::{Option, Some, None};
-use owned::Box;
+use boxed::Box;
 use result::{Ok, Err};
 use rt;
 use rt::local::Local;
@@ -391,7 +391,7 @@ mod tests {
             set_stdout(box w);
             println!("hello!");
         });
-        assert_eq!(r.read_to_str().unwrap(), "hello!\n".to_string());
+        assert_eq!(r.read_to_string().unwrap(), "hello!\n".to_string());
     })
 
     iotest!(fn capture_stderr() {
@@ -404,7 +404,7 @@ mod tests {
             ::realstd::io::stdio::set_stderr(box w);
             fail!("my special message");
         });
-        let s = r.read_to_str().unwrap();
+        let s = r.read_to_string().unwrap();
         assert!(s.as_slice().contains("my special message"));
     })
 }
index 432461c46063493f4e471d5b42fb29bb0b1d2f07..1c9e428dcad82e897897ddcc4f40ba6c2c3a913b 100644 (file)
@@ -20,7 +20,7 @@
 use comm::{Receiver, Sender, channel};
 use io::{IoResult, IoError};
 use kinds::Send;
-use owned::Box;
+use boxed::Box;
 use rt::rtio::{IoFactory, LocalIo, RtioTimer, Callback};
 
 /// A synchronous timer object
index 83a01feee9017865f0c13878ca2282b28f805be2..e928323030c4f5f34ca5e485af1ae8a9eed1d27a 100644 (file)
@@ -13,7 +13,7 @@
 use prelude::*;
 use cmp;
 use io;
-use owned::Box;
+use boxed::Box;
 use slice::bytes::MutableByteVector;
 
 /// Wraps a `Reader`, limiting the number of bytes that can be read from it.
@@ -263,7 +263,7 @@ fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
 mod test {
     use io::{MemReader, MemWriter, BufReader};
     use io;
-    use owned::Box;
+    use boxed::Box;
     use super::*;
     use prelude::*;
 
@@ -379,21 +379,21 @@ fn limit_reader_buffer() {
         let mut r = BufReader::new(data.as_bytes());
         {
             let mut r = LimitReader::new(r.by_ref(), 3);
-            assert_eq!(r.read_line(), Ok("012".to_str()));
+            assert_eq!(r.read_line(), Ok("012".to_string()));
             assert_eq!(r.limit(), 0);
             assert_eq!(r.read_line().err().unwrap().kind, io::EndOfFile);
         }
         {
             let mut r = LimitReader::new(r.by_ref(), 9);
-            assert_eq!(r.read_line(), Ok("3456789\n".to_str()));
+            assert_eq!(r.read_line(), Ok("3456789\n".to_string()));
             assert_eq!(r.limit(), 1);
-            assert_eq!(r.read_line(), Ok("0".to_str()));
+            assert_eq!(r.read_line(), Ok("0".to_string()));
         }
         {
             let mut r = LimitReader::new(r.by_ref(), 100);
             assert_eq!(r.read_char(), Ok('1'));
             assert_eq!(r.limit(), 99);
-            assert_eq!(r.read_line(), Ok("23456789\n".to_str()));
+            assert_eq!(r.read_line(), Ok("23456789\n".to_string()));
         }
     }
 
index 0e6f848fce85ab19fa9fc3d5b1d6aceba1db522c..ad6942712ac9af3f484a3619a6e5d2d88cfcb937 100644 (file)
@@ -78,7 +78,7 @@
 //! passing. [`sync`](sync/index.html) contains further, primitive, shared
 //! memory types, including [`atomics`](sync/atomics/index.html).
 //!
-//! Common types of I/O, including files, TCP, UPD, pipes, Unix domain sockets,
+//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets,
 //! timers, and process spawning, are defined in the [`io`](io/index.html) module.
 //!
 //! Rust's I/O and concurrency depends on a small runtime interface
@@ -94,7 +94,7 @@
 //! all the standard macros, such as `assert!`, `fail!`, `println!`,
 //! and `format!`, also available to all Rust code.
 
-#![crate_id = "std#0.11.0"]
+#![crate_name = "std"]
 #![unstable]
 #![comment = "The Rust standard library"]
 #![license = "MIT/ASL2"]
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, globs, managed_boxes, linkage)]
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 
 extern crate alloc;
+extern crate unicode;
 extern crate core;
 extern crate core_collections = "collections";
 extern crate core_rand = "rand";
 #[cfg(test)] pub use realstd::ops;
 #[cfg(test)] pub use realstd::cmp;
 #[cfg(test)] pub use realstd::ty;
-#[cfg(test)] pub use realstd::owned;
+#[cfg(test)] pub use realstd::boxed;
 #[cfg(test)] pub use realstd::gc;
 
 
 pub use core::any;
 pub use core::bool;
 pub use core::cell;
-pub use core::char;
 pub use core::clone;
 #[cfg(not(test))] pub use core::cmp;
 pub use core::default;
 pub use core::result;
 pub use core::option;
 
-pub use alloc::owned;
+pub use alloc::boxed;
+#[deprecated = "use boxed instead"]
+pub use owned = boxed;
+
 pub use alloc::rc;
 
 pub use core_collections::slice;
 pub use rustrt::c_str;
 pub use rustrt::local_data;
 
+pub use unicode::char;
+
 pub use core_sync::comm;
 
 // Run tests with libgreen instead of libnative.
@@ -284,11 +289,3 @@ mod std {
     // The test runner requires std::slice::Vector, so re-export std::slice just for it.
     #[cfg(test)] pub use slice;
 }
-
-#[deprecated]
-#[allow(missing_doc)]
-#[doc(hiden)]
-pub mod unstable {
-    #[deprecated = "use std::dynamic_lib"]
-    pub use dynamic_lib;
-}
index 2b2ffb9f4e281706052a95a1797d3c10b984cf00..680620f5a752fdd0e455d7578d0b81c18006bf96 100644 (file)
@@ -245,7 +245,7 @@ fn atanh(self) -> f32 {
 ///
 /// * num - The float value
 #[inline]
-pub fn to_str(num: f32) -> String {
+pub fn to_string(num: f32) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
     r
index e156d2ce553240b629b6594429b60ef3eb303725..3180ee28c6fee19442d8278894c852f3ff556dbb 100644 (file)
@@ -253,7 +253,7 @@ fn atanh(self) -> f64 {
 ///
 /// * num - The float value
 #[inline]
-pub fn to_str(num: f64) -> String {
+pub fn to_string(num: f64) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
     r
index a4200b55a5906f575aa1bc6942f6a7a7f7cc4a47..3c01edf233925986005a4803c3dd1148191fd4e3 100644 (file)
@@ -55,7 +55,7 @@ fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
 
 /// Convert to a string as a byte slice in a given base.
 ///
-/// Use in place of x.to_str() when you do not need to store the string permanently
+/// Use in place of x.to_string() when you do not need to store the string permanently
 ///
 /// # Examples
 ///
@@ -143,7 +143,7 @@ fn test_parse_bytes() {
     }
 
     #[test]
-    fn test_to_str() {
+    fn test_to_string() {
         assert_eq!((0 as $T).to_str_radix(10u), "0".to_string());
         assert_eq!((1 as $T).to_str_radix(10u), "1".to_string());
         assert_eq!((-1 as $T).to_str_radix(10u), "-1".to_string());
@@ -155,28 +155,28 @@ fn test_to_str() {
     #[test]
     fn test_int_to_str_overflow() {
         let mut i8_val: i8 = 127_i8;
-        assert_eq!(i8_val.to_str(), "127".to_string());
+        assert_eq!(i8_val.to_string(), "127".to_string());
 
         i8_val += 1 as i8;
-        assert_eq!(i8_val.to_str(), "-128".to_string());
+        assert_eq!(i8_val.to_string(), "-128".to_string());
 
         let mut i16_val: i16 = 32_767_i16;
-        assert_eq!(i16_val.to_str(), "32767".to_string());
+        assert_eq!(i16_val.to_string(), "32767".to_string());
 
         i16_val += 1 as i16;
-        assert_eq!(i16_val.to_str(), "-32768".to_string());
+        assert_eq!(i16_val.to_string(), "-32768".to_string());
 
         let mut i32_val: i32 = 2_147_483_647_i32;
-        assert_eq!(i32_val.to_str(), "2147483647".to_string());
+        assert_eq!(i32_val.to_string(), "2147483647".to_string());
 
         i32_val += 1 as i32;
-        assert_eq!(i32_val.to_str(), "-2147483648".to_string());
+        assert_eq!(i32_val.to_string(), "-2147483648".to_string());
 
         let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
-        assert_eq!(i64_val.to_str(), "9223372036854775807".to_string());
+        assert_eq!(i64_val.to_string(), "9223372036854775807".to_string());
 
         i64_val += 1 as i64;
-        assert_eq!(i64_val.to_str(), "-9223372036854775808".to_string());
+        assert_eq!(i64_val.to_string(), "-9223372036854775808".to_string());
     }
 
     #[test]
index 5028987f44fdd239e85d9421e6867e5482d68fb1..88fc6e1ffd85f743be2e01d6365887f3643ecbf7 100644 (file)
@@ -146,7 +146,7 @@ impl NumStrConv for $t {
 /**
  * Converts an integral number to its string representation as a byte vector.
  * This is meant to be a common base implementation for all integral string
- * conversion functions like `to_str()` or `to_str_radix()`.
+ * conversion functions like `to_string()` or `to_str_radix()`.
  *
  * # Arguments
  * - `num`           - The number to convert. Accepts any number that
@@ -226,7 +226,7 @@ pub fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f:
 /**
  * Converts a number to its string representation as a byte vector.
  * This is meant to be a common base implementation for all numeric string
- * conversion functions like `to_str()` or `to_str_radix()`.
+ * conversion functions like `to_string()` or `to_str_radix()`.
  *
  * # Arguments
  * - `num`           - The number to convert. Accepts any number that
@@ -894,9 +894,9 @@ mod f64 {
         use f64;
 
         #[bench]
-        fn float_to_str(b: &mut Bencher) {
+        fn float_to_string(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { f64::to_str(rng.gen()); })
+            b.iter(|| { f64::to_string(rng.gen()); })
         }
     }
 }
index 7f2efe034a24a77b8c4acb8ae83e1abef89eff64..cfcaf0fa8daa35d61ebaa203ecaf86446964fa0e 100644 (file)
@@ -56,7 +56,7 @@ fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
 
 /// Convert to a string as a byte slice in a given base.
 ///
-/// Use in place of x.to_str() when you do not need to store the string permanently
+/// Use in place of x.to_string() when you do not need to store the string permanently
 ///
 /// # Examples
 ///
@@ -101,7 +101,7 @@ mod tests {
     use u16;
 
     #[test]
-    pub fn test_to_str() {
+    pub fn test_to_string() {
         assert_eq!((0 as $T).to_str_radix(10u), "0".to_string());
         assert_eq!((1 as $T).to_str_radix(10u), "1".to_string());
         assert_eq!((2 as $T).to_str_radix(10u), "2".to_string());
@@ -141,28 +141,28 @@ pub fn test_parse_bytes() {
     #[test]
     fn test_uint_to_str_overflow() {
         let mut u8_val: u8 = 255_u8;
-        assert_eq!(u8_val.to_str(), "255".to_string());
+        assert_eq!(u8_val.to_string(), "255".to_string());
 
         u8_val += 1 as u8;
-        assert_eq!(u8_val.to_str(), "0".to_string());
+        assert_eq!(u8_val.to_string(), "0".to_string());
 
         let mut u16_val: u16 = 65_535_u16;
-        assert_eq!(u16_val.to_str(), "65535".to_string());
+        assert_eq!(u16_val.to_string(), "65535".to_string());
 
         u16_val += 1 as u16;
-        assert_eq!(u16_val.to_str(), "0".to_string());
+        assert_eq!(u16_val.to_string(), "0".to_string());
 
         let mut u32_val: u32 = 4_294_967_295_u32;
-        assert_eq!(u32_val.to_str(), "4294967295".to_string());
+        assert_eq!(u32_val.to_string(), "4294967295".to_string());
 
         u32_val += 1 as u32;
-        assert_eq!(u32_val.to_str(), "0".to_string());
+        assert_eq!(u32_val.to_string(), "0".to_string());
 
         let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
-        assert_eq!(u64_val.to_str(), "18446744073709551615".to_string());
+        assert_eq!(u64_val.to_string(), "18446744073709551615".to_string());
 
         u64_val += 1 as u64;
-        assert_eq!(u64_val.to_str(), "0".to_string());
+        assert_eq!(u64_val.to_string(), "0".to_string());
     }
 
     #[test]
index b3f25914c8f568768c22fd62c6523e837895e9c0..86577a9840d04d07620bd171548cbe0d41d416f6 100644 (file)
@@ -223,8 +223,8 @@ fn with_env_lock<T>(f: || -> T) -> T {
 /// ```
 pub fn env() -> Vec<(String,String)> {
     env_as_bytes().move_iter().map(|(k,v)| {
-        let k = str::from_utf8_lossy(k.as_slice()).to_string();
-        let v = str::from_utf8_lossy(v.as_slice()).to_string();
+        let k = String::from_str(str::from_utf8_lossy(k.as_slice()).as_slice());
+        let v = String::from_str(str::from_utf8_lossy(v.as_slice()).as_slice());
         (k,v)
     }).collect()
 }
@@ -334,7 +334,7 @@ fn env_convert(input: Vec<Vec<u8>>) -> Vec<(Vec<u8>, Vec<u8>)> {
 /// }
 /// ```
 pub fn getenv(n: &str) -> Option<String> {
-    getenv_as_bytes(n).map(|v| str::from_utf8_lossy(v.as_slice()).to_string())
+    getenv_as_bytes(n).map(|v| String::from_str(str::from_utf8_lossy(v.as_slice()).as_slice()))
 }
 
 #[cfg(unix)]
@@ -837,13 +837,24 @@ fn lookup() -> Path {
     }
 }
 
-/**
- * Convert a relative path to an absolute path
- *
- * If the given path is relative, return it prepended with the current working
- * directory. If the given path is already an absolute path, return it
- * as is.
- */
+///
+/// Convert a relative path to an absolute path
+///
+/// If the given path is relative, return it prepended with the current working
+/// directory. If the given path is already an absolute path, return it
+/// as is.
+///
+/// # Example
+/// ```rust
+/// use std::os;
+/// use std::path::Path;
+///
+/// // Assume we're in a path like /home/someuser
+/// let rel_path = Path::new("..");
+/// let abs_path = os::make_absolute(&rel_path);
+/// println!("The absolute path is {}", abs_path.display());
+/// // Prints "The absolute path is /home"
+/// ```
 // NB: this is here rather than in path because it is a form of environment
 // querying; what it does depends on the process working directory, not just
 // the input paths.
@@ -859,6 +870,16 @@ pub fn make_absolute(p: &Path) -> Path {
 
 /// Changes the current working directory to the specified path, returning
 /// whether the change was completed successfully or not.
+///
+/// # Example
+/// ```rust
+/// use std::os;
+/// use std::path::Path;
+///
+/// let root = Path::new("/");
+/// assert!(os::change_dir(&root));
+/// println!("Succesfully changed working directory to {}!", root.display());
+/// ```
 pub fn change_dir(p: &Path) -> bool {
     return chdir(p);
 
@@ -930,6 +951,13 @@ pub fn errno() -> uint {
 }
 
 /// Return the string corresponding to an `errno()` value of `errnum`.
+/// # Example
+/// ```rust
+/// use std::os;
+///
+/// // Same as println!("{}", last_os_error());
+/// println!("{}", os::error_string(os::errno() as uint));
+/// ```
 pub fn error_string(errnum: uint) -> String {
     return strerror(errnum);
 
@@ -1217,6 +1245,16 @@ fn CommandLineToArgvW(lpCmdLine: LPCWSTR,
 ///
 /// The arguments are interpreted as utf-8, with invalid bytes replaced with \uFFFD.
 /// See `str::from_utf8_lossy` for details.
+/// # Example
+///
+/// ```rust
+/// use std::os;
+///
+/// // Prints each argument on a separate line
+/// for argument in os::args().iter() {
+///     println!("{}", argument);
+/// }
+/// ```
 pub fn args() -> Vec<String> {
     real_args()
 }
@@ -1277,12 +1315,9 @@ pub fn page_size() -> uint {
 /// The memory map is released (unmapped) when the destructor is run, so don't
 /// let it leave scope by accident if you want it to stick around.
 pub struct MemoryMap {
-    /// Pointer to the memory created or modified by this map.
-    pub data: *mut u8,
-    /// Number of bytes this map applies to
-    pub len: uint,
-    /// Type of mapping
-    pub kind: MemoryMapKind,
+    data: *mut u8,
+    len: uint,
+    kind: MemoryMapKind,
 }
 
 /// Type of memory map
@@ -1617,6 +1652,15 @@ fn drop(&mut self) {
     }
 }
 
+impl MemoryMap {
+    /// Returns the pointer to the memory created or modified by this map.
+    pub fn data(&self) -> *mut u8 { self.data }
+    /// Returns the number of bytes this map applies to.
+    pub fn len(&self) -> uint { self.len }
+    /// Returns the type of mapping this represents.
+    pub fn kind(&self) -> MemoryMapKind { self.kind }
+}
+
 #[cfg(target_os = "linux")]
 pub mod consts {
     pub use os::arch_consts::ARCH;
index d98cfb7d8eece0c35396db2b1a5dd2cb48614a6e..007686aa05cd5865cf03a4f4d52344653ff462df 100644 (file)
@@ -12,7 +12,7 @@
 
 use c_str::{CString, ToCStr};
 use clone::Clone;
-use cmp::{PartialEq, Eq};
+use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
 use collections::Collection;
 use from_str::FromStr;
 use hash;
@@ -68,6 +68,18 @@ fn eq(&self, other: &Path) -> bool {
 
 impl Eq for Path {}
 
+impl PartialOrd for Path {
+    fn partial_cmp(&self, other: &Path) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Path {
+    fn cmp(&self, other: &Path) -> Ordering {
+        self.repr.cmp(&other.repr)
+    }
+}
+
 impl FromStr for Path {
     fn from_str(s: &str) -> Option<Path> {
         Path::new_opt(s)
@@ -545,7 +557,7 @@ macro_rules! t(
             ($path:expr, $disp:ident, $exp:expr) => (
                 {
                     let path = Path::new($path);
-                    assert!(path.$disp().to_str().as_slice() == $exp);
+                    assert!(path.$disp().to_string().as_slice() == $exp);
                 }
             )
         )
index 113b0410875af7ad0d068d0b394554320715de96..88ae0d4837e569febda914a30ad4ab82d9a31800 100644 (file)
@@ -13,7 +13,7 @@
 use ascii::AsciiCast;
 use c_str::{CString, ToCStr};
 use clone::Clone;
-use cmp::{PartialEq, Eq};
+use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
 use collections::Collection;
 use from_str::FromStr;
 use hash;
@@ -24,6 +24,7 @@
 use slice::{Vector, ImmutableVector};
 use str::{CharSplits, Str, StrAllocating, StrVector, StrSlice};
 use string::String;
+use unicode::UnicodeChar;
 use vec::Vec;
 
 use super::{contains_nul, BytesContainer, GenericPath, GenericPathUnsafe};
@@ -89,6 +90,18 @@ fn eq(&self, other: &Path) -> bool {
 
 impl Eq for Path {}
 
+impl PartialOrd for Path {
+    fn partial_cmp(&self, other: &Path) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Path {
+    fn cmp(&self, other: &Path) -> Ordering {
+        self.repr.cmp(&other.repr)
+    }
+}
+
 impl FromStr for Path {
     fn from_str(s: &str) -> Option<Path> {
         Path::new_opt(s)
@@ -997,7 +1010,7 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
                 let idx = path.find('\\');
                 if idx == Some(2) && path.as_bytes()[1] == ':' as u8 {
                     let c = path.as_bytes()[0];
-                    if c.is_ascii() && ::char::is_alphabetic(c as char) {
+                    if c.is_ascii() && (c as char).is_alphabetic() {
                         // \\?\C:\ path
                         return Some(VerbatimDiskPrefix);
                     }
@@ -1021,7 +1034,7 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
     } else if path.len() > 1 && path.as_bytes()[1] == ':' as u8 {
         // C:
         let c = path.as_bytes()[0];
-        if c.is_ascii() && ::char::is_alphabetic(c as char) {
+        if c.is_ascii() && (c as char).is_alphabetic() {
             return Some(DiskPrefix);
         }
     }
@@ -1314,9 +1327,9 @@ fn test_not_utf8_fail() {
     #[test]
     fn test_display_str() {
         let path = Path::new("foo");
-        assert_eq!(path.display().to_str(), "foo".to_string());
+        assert_eq!(path.display().to_string(), "foo".to_string());
         let path = Path::new(b"\\");
-        assert_eq!(path.filename_display().to_str(), "".to_string());
+        assert_eq!(path.filename_display().to_string(), "".to_string());
 
         let path = Path::new("foo");
         let mo = path.display().as_maybe_owned();
index 61e8b63af359ef6d042d511d7b785a049a82f0c3..a20ac112ac52cc7270faf777d9de12bbf90a357d 100644 (file)
@@ -44,7 +44,8 @@
 #[doc(no_inline)] pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
 #[doc(no_inline)] pub use ops::{BitAnd, BitOr, BitXor};
 #[doc(no_inline)] pub use ops::{Drop, Deref, DerefMut};
-#[doc(no_inline)] pub use ops::{Shl, Shr, Index};
+#[doc(no_inline)] pub use ops::{Shl, Shr};
+#[doc(no_inline)] pub use ops::{Index, IndexMut};
 #[doc(no_inline)] pub use option::{Option, Some, None};
 #[doc(no_inline)] pub use result::{Result, Ok, Err};
 
 #[doc(no_inline)] pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
 #[doc(no_inline)] pub use num::{Signed, Unsigned, Primitive, Int, Float};
 #[doc(no_inline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive};
-#[doc(no_inline)] pub use owned::Box;
+#[doc(no_inline)] pub use boxed::Box;
 #[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath};
 #[doc(no_inline)] pub use ptr::RawPtr;
 #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek};
 #[doc(no_inline)] pub use str::{Str, StrVector, StrSlice, OwnedStr};
 #[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating};
-#[doc(no_inline)] pub use to_str::{ToStr, IntoStr};
+#[doc(no_inline)] pub use to_str::{ToString, IntoStr};
 #[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
 #[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
 #[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
@@ -88,6 +89,7 @@
 #[doc(no_inline)] pub use slice::{Vector, VectorVector};
 #[doc(no_inline)] pub use slice::MutableVectorAllocating;
 #[doc(no_inline)] pub use string::String;
+#[doc(no_inline)] pub use unicode::{UnicodeChar, UnicodeStrSlice};
 #[doc(no_inline)] pub use vec::Vec;
 
 // Reexported runtime types
index 2e0dcdd8eb69f83588a353615eba5a3cb8f7e344..09922b5ad76154bc81c0c57a5ad6b9e0ad144f09 100644 (file)
@@ -12,7 +12,6 @@
 
 #![allow(non_camel_case_types)]
 
-use char::Char;
 use collections::Collection;
 use from_str::from_str;
 use io::{IoResult, Writer};
@@ -22,6 +21,7 @@
 use result::{Ok, Err};
 use str::StrSlice;
 use sync::atomics;
+use unicode::UnicodeChar;
 
 pub use self::imp::write;
 
@@ -261,7 +261,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
         use slice::{MutableVector};
 
         extern {
-            fn backtrace(buf: *mut *const libc::c_void,
+            fn backtrace(buf: *mut *mut libc::c_void,
                          sz: libc::c_int) -> libc::c_int;
         }
 
@@ -274,7 +274,7 @@ fn backtrace(buf: *mut *const libc::c_void,
         try!(writeln!(w, "stack backtrace:"));
         // 100 lines should be enough
         static SIZE: libc::c_int = 100;
-        let mut buf: [*const libc::c_void, ..SIZE] = unsafe {mem::zeroed()};
+        let mut buf: [*mut libc::c_void, ..SIZE] = unsafe {mem::zeroed()};
         let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE) as uint};
 
         // skipping the first one as it is write itself
index c20cbea0ae7cced97332673d8e1eda74ea934486..d7af92024eb5e6fe753f16e34885543086c4433a 100644 (file)
@@ -98,7 +98,7 @@
 use io::{Writer, stdio};
 use kinds::{Send, marker};
 use option::{None, Some, Option};
-use owned::Box;
+use boxed::Box;
 use result::Result;
 use rt::local::Local;
 use rt::task;
@@ -374,7 +374,7 @@ pub fn failing() -> bool {
 #[cfg(test)]
 mod test {
     use any::{Any, AnyRefExt};
-    use owned::AnyOwnExt;
+    use boxed::BoxAny;
     use result;
     use result::{Ok, Err};
     use str::StrAllocating;
@@ -578,7 +578,7 @@ fn test_try_fail_message_static_str() {
             Err(e) => {
                 type T = &'static str;
                 assert!(e.is::<T>());
-                assert_eq!(*e.move::<T>().unwrap(), "static string");
+                assert_eq!(*e.downcast::<T>().unwrap(), "static string");
             }
             Ok(()) => fail!()
         }
@@ -592,7 +592,7 @@ fn test_try_fail_message_owned_str() {
             Err(e) => {
                 type T = String;
                 assert!(e.is::<T>());
-                assert_eq!(*e.move::<T>().unwrap(), "owned string".to_string());
+                assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
             }
             Ok(()) => fail!()
         }
@@ -606,9 +606,9 @@ fn test_try_fail_message_any() {
             Err(e) => {
                 type T = Box<Any + Send>;
                 assert!(e.is::<T>());
-                let any = e.move::<T>().unwrap();
+                let any = e.downcast::<T>().unwrap();
                 assert!(any.is::<u16>());
-                assert_eq!(*any.move::<u16>().unwrap(), 413u16);
+                assert_eq!(*any.downcast::<u16>().unwrap(), 413u16);
             }
             Ok(()) => fail!()
         }
@@ -638,7 +638,7 @@ fn test_stdout() {
             });
         assert!(r.is_ok());
 
-        let output = reader.read_to_str().unwrap();
+        let output = reader.read_to_string().unwrap();
         assert_eq!(output, "Hello, world!".to_string());
     }
 
index e51e2c4d9ce5e5acbff2437c02d9e37d26bc2a2e..c19fd81b5705667185f8a8a9391fca11a9114dba 100644 (file)
@@ -10,7 +10,7 @@
 
 /*!
 
-The `ToStr` trait for converting to strings
+The `ToString` trait for converting to strings
 
 */
 
 use string::String;
 
 /// A generic trait for converting a value to a string
-pub trait ToStr {
+pub trait ToString {
     /// Converts the value of `self` to an owned string
-    fn to_str(&self) -> String;
+    fn to_string(&self) -> String;
 }
 
 /// Trait for converting a type to a string, consuming it in the process.
 pub trait IntoStr {
     /// Consume and convert to a string.
-    fn into_str(self) -> String;
+    fn into_string(self) -> String;
 }
 
-impl<T: fmt::Show> ToStr for T {
-    fn to_str(&self) -> String {
+impl<T: fmt::Show> ToString for T {
+    fn to_string(&self) -> String {
         format!("{}", *self)
     }
 }
@@ -44,23 +44,23 @@ mod tests {
 
     #[test]
     fn test_simple_types() {
-        assert_eq!(1i.to_str(), "1".to_string());
-        assert_eq!((-1i).to_str(), "-1".to_string());
-        assert_eq!(200u.to_str(), "200".to_string());
-        assert_eq!(2u8.to_str(), "2".to_string());
-        assert_eq!(true.to_str(), "true".to_string());
-        assert_eq!(false.to_str(), "false".to_string());
-        assert_eq!(().to_str(), "()".to_string());
-        assert_eq!(("hi".to_string()).to_str(), "hi".to_string());
+        assert_eq!(1i.to_string(), "1".to_string());
+        assert_eq!((-1i).to_string(), "-1".to_string());
+        assert_eq!(200u.to_string(), "200".to_string());
+        assert_eq!(2u8.to_string(), "2".to_string());
+        assert_eq!(true.to_string(), "true".to_string());
+        assert_eq!(false.to_string(), "false".to_string());
+        assert_eq!(().to_string(), "()".to_string());
+        assert_eq!(("hi".to_string()).to_string(), "hi".to_string());
     }
 
     #[test]
     fn test_vectors() {
         let x: Vec<int> = vec![];
-        assert_eq!(x.to_str(), "[]".to_string());
-        assert_eq!((vec![1i]).to_str(), "[1]".to_string());
-        assert_eq!((vec![1i, 2, 3]).to_str(), "[1, 2, 3]".to_string());
-        assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_str() ==
+        assert_eq!(x.to_string(), "[]".to_string());
+        assert_eq!((vec![1i]).to_string(), "[1]".to_string());
+        assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]".to_string());
+        assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
                "[[], [1], [1, 1]]".to_string());
     }
 }
index 195efb844a78328fe3bc0535cece16307d057492..0be124ad58408d6f9cf375af5fb6f83021f0853c 100644 (file)
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::mem;
 
 pub use core::atomics::{AtomicBool, AtomicInt, AtomicUint, AtomicPtr};
index 6c09a021c4338212efe8056a38efd07f76f6229e..e9a303634fe37c0ac34dd26186862f7582407555 100644 (file)
 use core::prelude::*;
 
 use alloc::arc::Arc;
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::cell::Cell;
 use core::kinds::marker;
 use core::mem;
index 742686069e283531461e68cd7852e9f6d88bbc58..c9782db5c24b66e2a1de511c0e69ae99344a3b8c 100644 (file)
@@ -34,7 +34,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::mem;
 use rustrt::local::Local;
 use rustrt::task::{Task, BlockedTask};
index 230bca624f5a7f61ae80f9c2a4ef0f74f8b6b316..737a4bfe29916fab400b184b8877d985bc38f7ab 100644 (file)
@@ -54,7 +54,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::cell::Cell;
 use core::kinds::marker;
 use core::mem;
index 5ad4dea5d2a89bc52df8a319d19cdecb1703ca94..d13b2c32978c41e4d11cdf26ea7af4dca1e3cb7b 100644 (file)
@@ -20,7 +20,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::cmp;
 use core::int;
 use rustrt::local::Local;
index 6f337f1730950d3cfb9288d32e76c028fe4c1fa4..9747c207a22612fdce2a6fa71f8b6f8dc23389a3 100644 (file)
@@ -19,7 +19,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::cmp;
 use core::int;
 use rustrt::local::Local;
index 4d54df2fc19e58e5544efc09fb9340895bdccd4f..cc3c2197c13f03368adf77a6e75647e5463c07a1 100644 (file)
@@ -35,7 +35,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use collections::Vec;
 use collections::Collection;
 use core::mem;
index 8d2192aeb537ed19b823b1ed62eeebb34774fd4d..913a58010d496b9db4c010e393a048a93ce07056 100644 (file)
@@ -54,7 +54,7 @@
 
 use alloc::arc::Arc;
 use alloc::heap::{allocate, deallocate};
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use collections::Vec;
 use core::kinds::marker;
 use core::mem::{forget, min_align_of, size_of, transmute};
index 4f6d1a261c4917696b56d99a628f7a4cbb69333c..f6a1684b669404b421c3cae502d1b0a8c0c2706c 100644 (file)
 //! use this crate specifically. Instead, its functionality is reexported
 //! through `std::sync`.
 
-#![crate_id = "sync#0.11.0"]
+#![crate_name = "sync"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(phase, globs, macro_rules, unsafe_destructor)]
index ecd37e68880555dba3a43d41d955d4762e71f685..759695fe5b6dd2520d691861f7810c6065e88748 100644 (file)
@@ -42,7 +42,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::mem;
 use core::ty::Unsafe;
 
index a10ec7458690abcbf20e68bd12c2e4730dea4f76..990d743465d6998e483a51f633adfe745de1b89d 100644 (file)
@@ -59,7 +59,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::atomics;
 use core::kinds::marker;
 use core::mem;
index 2834d404c1879e7de75b7b45577edbfbfcd01d7e..cf4d3222ed0ed8527636ab11f450b7794e13c088 100644 (file)
@@ -37,7 +37,7 @@
 
 use core::prelude::*;
 
-use alloc::owned::Box;
+use alloc::boxed::Box;
 use core::mem;
 use core::ty::Unsafe;
 
index 9771bc9386b169ed89bb8728f5f058eea0f088a9..8b01002831b7e69634dbd6b53bc0e8c23acdf0b3 100644 (file)
@@ -60,9 +60,12 @@ pub struct AbiData {
 }
 
 pub enum AbiArchitecture {
-    RustArch,   // Not a real ABI (e.g., intrinsic)
-    AllArch,    // An ABI that specifies cross-platform defaults (e.g., "C")
-    Archs(u32)  // Multiple architectures (bitset)
+    /// Not a real ABI (e.g., intrinsic)
+    RustArch,
+    /// An ABI that specifies cross-platform defaults (e.g., "C")
+    AllArch,
+    /// Multiple architectures (bitset)
+    Archs(u32)
 }
 
 static AbiDatas: &'static [AbiData] = &[
@@ -84,32 +87,9 @@ pub enum AbiArchitecture {
     AbiData {abi: RustIntrinsic, name: "rust-intrinsic", abi_arch: RustArch},
 ];
 
-fn each_abi(op: |abi: Abi| -> bool) -> bool {
-    /*!
-     *
-     * Iterates through each of the defined ABIs.
-     */
-
-    AbiDatas.iter().advance(|abi_data| op(abi_data.abi))
-}
-
+/// Returns the ABI with the given name (if any).
 pub fn lookup(name: &str) -> Option<Abi> {
-    /*!
-     *
-     * Returns the ABI with the given name (if any).
-     */
-
-    let mut res = None;
-
-    each_abi(|abi| {
-        if name == abi.data().name {
-            res = Some(abi);
-            false
-        } else {
-            true
-        }
-    });
-    res
+    AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
 }
 
 pub fn all_names() -> Vec<&'static str> {
index 237d0660a41dcca5edb5f15875cd41bdc5fd2f5a..c7154da494f7161ce2fd38627f0dfb56fb95aa9d 100644 (file)
@@ -14,7 +14,7 @@
 use abi::Abi;
 use ast_util;
 use owned_slice::OwnedSlice;
-use parse::token::{InternedString, special_idents, str_to_ident};
+use parse::token::{InternedString, str_to_ident};
 use parse::token;
 
 use std::fmt;
@@ -24,7 +24,8 @@
 use std::gc::{Gc, GC};
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
-/// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future.
+/// A pointer abstraction.
+// FIXME(eddyb) #10676 use Rc<T> in the future.
 pub type P<T> = Gc<T>;
 
 #[allow(non_snake_case_functions)]
@@ -36,11 +37,11 @@ pub fn P<T: 'static>(value: T) -> P<T> {
 // FIXME #6993: in librustc, uses of "ident" should be replaced
 // by just "Name".
 
-// an identifier contains a Name (index into the interner
-// table) and a SyntaxContext to track renaming and
-// macro expansion per Flatt et al., "Macros
-// That Work Together"
-#[deriving(Clone, Hash, PartialOrd, Eq, Ord, Show)]
+/// An identifier contains a Name (index into the interner
+/// table) and a SyntaxContext to track renaming and
+/// macro expansion per Flatt et al., "Macros
+/// That Work Together"
+#[deriving(Clone, Hash, PartialOrd, Eq, Ord)]
 pub struct Ident {
     pub name: Name,
     pub ctxt: SyntaxContext
@@ -49,6 +50,23 @@ pub struct Ident {
 impl Ident {
     /// Construct an identifier with the given name and an empty context:
     pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
+
+    pub fn as_str<'a>(&'a self) -> &'a str {
+        self.name.as_str()
+    }
+}
+
+impl Show for Ident {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}#{}", self.name, self.ctxt)
+    }
+}
+
+impl Show for Name {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let Name(nm) = *self;
+        write!(f, "\"{}\"({})", token::get_name(*self).get(), nm)
+    }
 }
 
 impl PartialEq for Ident {
@@ -95,7 +113,26 @@ fn ne(&self, other: &Ident) -> bool {
 
 /// A name is a part of an identifier, representing a string or gensym. It's
 /// the result of interning.
-pub type Name = u32;
+#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Encodable, Decodable, Clone)]
+pub struct Name(pub u32);
+
+impl Name {
+    pub fn as_str<'a>(&'a self) -> &'a str {
+        unsafe {
+            // FIXME #12938: can't use copy_lifetime since &str isn't a &T
+            ::std::mem::transmute(token::get_name(*self).get())
+        }
+    }
+
+    pub fn uint(&self) -> uint {
+        let Name(nm) = *self;
+        nm as uint
+    }
+
+    pub fn ident(&self) -> Ident {
+        Ident { name: *self, ctxt: 0 }
+    }
+}
 
 /// A mark represents a unique id associated with a macro expansion
 pub type Mrk = u32;
@@ -122,10 +159,9 @@ pub struct Lifetime {
     pub name: Name
 }
 
-// a "Path" is essentially Rust's notion of a name;
-// for instance: std::cmp::PartialEq  .  It's represented
-// as a sequence of identifiers, along with a bunch
-// of supporting information.
+/// A "Path" is essentially Rust's notion of a name; for instance:
+/// std::cmp::PartialEq  .  It's represented as a sequence of identifiers,
+/// along with a bunch of supporting information.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct Path {
     pub span: Span,
@@ -163,15 +199,15 @@ pub struct DefId {
 pub static LOCAL_CRATE: CrateNum = 0;
 pub static CRATE_NODE_ID: NodeId = 0;
 
-// When parsing and doing expansions, we initially give all AST nodes this AST
-// node value. Then later, in the renumber pass, we renumber them to have
-// small, positive ids.
+/// When parsing and doing expansions, we initially give all AST nodes this AST
+/// node value. Then later, in the renumber pass, we renumber them to have
+/// small, positive ids.
 pub static DUMMY_NODE_ID: NodeId = -1;
 
-// The AST represents all type param bounds as types.
-// typeck::collect::compute_bounds matches these against
-// the "special" built-in traits (see middle::lang_items) and
-// detects Copy, Send and Share.
+/// The AST represents all type param bounds as types.
+/// typeck::collect::compute_bounds matches these against
+/// the "special" built-in traits (see middle::lang_items) and
+/// detects Copy, Send and Share.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum TyParamBound {
     TraitTyParamBound(TraitRef),
@@ -184,12 +220,14 @@ pub enum TyParamBound {
 pub struct TyParam {
     pub ident: Ident,
     pub id: NodeId,
-    pub sized: Sized,
     pub bounds: OwnedSlice<TyParamBound>,
+    pub unbound: Option<TyParamBound>,
     pub default: Option<P<Ty>>,
     pub span: Span
 }
 
+/// Represents lifetimes and type parameters attached to a declaration
+/// of a function, enum, trait, etc.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct Generics {
     pub lifetimes: Vec<Lifetime>,
@@ -208,9 +246,9 @@ pub fn is_type_parameterized(&self) -> bool {
     }
 }
 
-// The set of MetaItems that define the compilation environment of the crate,
-// used to drive conditional compilation
-pub type CrateConfig = Vec<Gc<MetaItem>>;
+/// The set of MetaItems that define the compilation environment of the crate,
+/// used to drive conditional compilation
+pub type CrateConfig = Vec<Gc<MetaItem>> ;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct Crate {
@@ -218,6 +256,7 @@ pub struct Crate {
     pub attrs: Vec<Attribute>,
     pub config: CrateConfig,
     pub span: Span,
+    pub exported_macros: Vec<Span>
 }
 
 pub type MetaItem = Spanned<MetaItem_>;
@@ -287,13 +326,13 @@ pub enum BindingMode {
 pub enum Pat_ {
     PatWild,
     PatWildMulti,
-    // A PatIdent may either be a new bound variable,
-    // or a nullary enum (in which case the second field
-    // is None).
-    // In the nullary enum case, the parser can't determine
-    // which it is. The resolver determines this, and
-    // records this pattern's NodeId in an auxiliary
-    // set (of "PatIdents that refer to nullary enums")
+    /// A PatIdent may either be a new bound variable,
+    /// or a nullary enum (in which case the third field
+    /// is None).
+    /// In the nullary enum case, the parser can't determine
+    /// which it is. The resolver determines this, and
+    /// records this pattern's NodeId in an auxiliary
+    /// set (of "PatIdents that refer to nullary enums")
     PatIdent(BindingMode, SpannedIdent, Option<Gc<Pat>>),
     PatEnum(Path, Option<Vec<Gc<Pat>>>), /* "none" means a * pattern where
                                      * we don't bind the fields to names */
@@ -303,8 +342,8 @@ pub enum Pat_ {
     PatRegion(Gc<Pat>), // reference pattern
     PatLit(Gc<Expr>),
     PatRange(Gc<Expr>, Gc<Expr>),
-    // [a, b, ..i, y, z] is represented as
-    // PatVec(~[a, b], Some(i), ~[y, z])
+    /// [a, b, ..i, y, z] is represented as:
+    ///     PatVec(~[a, b], Some(i), ~[y, z])
     PatVec(Vec<Gc<Pat>>, Option<Gc<Pat>>, Vec<Gc<Pat>>),
     PatMac(Mac),
 }
@@ -317,9 +356,12 @@ pub enum Mutability {
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum ExprVstore {
-    ExprVstoreUniq,                 // ~[1,2,3,4]
-    ExprVstoreSlice,                // &[1,2,3,4]
-    ExprVstoreMutSlice,             // &mut [1,2,3,4]
+    /// ~[1, 2, 3, 4]
+    ExprVstoreUniq,
+    /// &[1, 2, 3, 4]
+    ExprVstoreSlice,
+    /// &mut [1, 2, 3, 4]
+    ExprVstoreMutSlice,
 }
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@@ -357,16 +399,16 @@ pub enum UnOp {
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum Stmt_ {
-    // could be an item or a local (let) binding:
+    /// Could be an item or a local (let) binding:
     StmtDecl(Gc<Decl>, NodeId),
 
-    // expr without trailing semi-colon (must have unit type):
+    /// Expr without trailing semi-colon (must have unit type):
     StmtExpr(Gc<Expr>, NodeId),
 
-    // expr with trailing semi-colon (may have any type):
+    /// Expr with trailing semi-colon (may have any type):
     StmtSemi(Gc<Expr>, NodeId),
 
-    // bool: is there a trailing sem-colon?
+    /// bool: is there a trailing sem-colon?
     StmtMac(Mac, bool),
 }
 
@@ -395,9 +437,9 @@ pub struct Local {
 
 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum Decl_ {
-    // a local (let) binding:
+    /// A local (let) binding:
     DeclLocal(Gc<Local>),
-    // an item binding:
+    /// An item binding:
     DeclItem(Gc<Item>),
 }
 
@@ -441,7 +483,7 @@ pub struct Expr {
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum Expr_ {
     ExprVstore(Gc<Expr>, ExprVstore),
-    // First expr is the place; second expr is the value.
+    /// First expr is the place; second expr is the value.
     ExprBox(Gc<Expr>, Gc<Expr>),
     ExprVec(Vec<Gc<Expr>>),
     ExprCall(Gc<Expr>, Vec<Gc<Expr>>),
@@ -453,10 +495,10 @@ pub enum Expr_ {
     ExprCast(Gc<Expr>, P<Ty>),
     ExprIf(Gc<Expr>, P<Block>, Option<Gc<Expr>>),
     ExprWhile(Gc<Expr>, P<Block>),
-    // FIXME #6993: change to Option<Name>
+    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprForLoop(Gc<Pat>, Gc<Expr>, P<Block>, Option<Ident>),
     // Conditionless loop (can be exited with break, cont, or ret)
-    // FIXME #6993: change to Option<Name>
+    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprLoop(P<Block>, Option<Ident>),
     ExprMatch(Gc<Expr>, Vec<Arm>),
     ExprFnBlock(P<FnDecl>, P<Block>),
@@ -468,9 +510,8 @@ pub enum Expr_ {
     ExprField(Gc<Expr>, SpannedIdent, Vec<P<Ty>>),
     ExprIndex(Gc<Expr>, Gc<Expr>),
 
-    /// Expression that looks like a "name". For example,
-    /// `std::slice::from_elem::<uint>` is an ExprPath that's the "name" part
-    /// of a function call.
+    /// Variable reference, possibly containing `::` and/or
+    /// type parameters, e.g. foo::bar::<baz>
     ExprPath(Path),
 
     ExprAddrOf(Mutability, Gc<Expr>),
@@ -482,54 +523,52 @@ pub enum Expr_ {
 
     ExprMac(Mac),
 
-    // A struct literal expression.
+    /// A struct literal expression.
     ExprStruct(Path, Vec<Field> , Option<Gc<Expr>> /* base */),
 
-    // A vector literal constructed from one repeated element.
+    /// A vector literal constructed from one repeated element.
     ExprRepeat(Gc<Expr> /* element */, Gc<Expr> /* count */),
 
-    // No-op: used solely so we can pretty-print faithfully
+    /// No-op: used solely so we can pretty-print faithfully
     ExprParen(Gc<Expr>)
 }
 
-// When the main rust parser encounters a syntax-extension invocation, it
-// parses the arguments to the invocation as a token-tree. This is a very
-// loose structure, such that all sorts of different AST-fragments can
-// be passed to syntax extensions using a uniform type.
-//
-// If the syntax extension is an MBE macro, it will attempt to match its
-// LHS "matchers" against the provided token tree, and if it finds a
-// match, will transcribe the RHS token tree, splicing in any captured
-// macro_parser::matched_nonterminals into the TTNonterminals it finds.
-//
-// The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
-// makes any real sense. You could write them elsewhere but nothing
-// else knows what to do with them, so you'll probably get a syntax
-// error.
-//
+/// When the main rust parser encounters a syntax-extension invocation, it
+/// parses the arguments to the invocation as a token-tree. This is a very
+/// loose structure, such that all sorts of different AST-fragments can
+/// be passed to syntax extensions using a uniform type.
+///
+/// If the syntax extension is an MBE macro, it will attempt to match its
+/// LHS "matchers" against the provided token tree, and if it finds a
+/// match, will transcribe the RHS token tree, splicing in any captured
+/// macro_parser::matched_nonterminals into the TTNonterminals it finds.
+///
+/// The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
+/// makes any real sense. You could write them elsewhere but nothing
+/// else knows what to do with them, so you'll probably get a syntax
+/// error.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 #[doc="For macro invocations; parsing is delegated to the macro"]
 pub enum TokenTree {
-    // a single token
+    /// A single token
     TTTok(Span, ::parse::token::Token),
-    // a delimited sequence (the delimiters appear as the first
-    // and last elements of the vector)
+    /// A delimited sequence (the delimiters appear as the first
+    /// and last elements of the vector)
     // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
     TTDelim(Rc<Vec<TokenTree>>),
 
     // These only make sense for right-hand-sides of MBE macros:
 
-    // a kleene-style repetition sequence with a span, a TTForest,
-    // an optional separator, and a boolean where true indicates
-    // zero or more (..), and false indicates one or more (+).
+    /// A kleene-style repetition sequence with a span, a TTForest,
+    /// an optional separator, and a boolean where true indicates
+    /// zero or more (..), and false indicates one or more (+).
     // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
     TTSeq(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, bool),
 
-    // a syntactic variable that will be filled in by macro expansion.
+    /// A syntactic variable that will be filled in by macro expansion.
     TTNonterminal(Span, Ident)
 }
 
-//
 // Matchers are nodes defined-by and recognized-by the main rust parser and
 // language, but they're only ever found inside syntax-extension invocations;
 // indeed, the only thing that ever _activates_ the rules in the rust parser
@@ -578,34 +617,35 @@ pub enum TokenTree {
 //
 //                   $( $lhs:matchers => $rhs:tt );+
 //
-// If you understand that, you have closed to loop and understand the whole
+// If you understand that, you have closed the loop and understand the whole
 // macro system. Congratulations.
-//
 pub type Matcher = Spanned<Matcher_>;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum Matcher_ {
-    // match one token
+    /// Match one token
     MatchTok(::parse::token::Token),
-    // match repetitions of a sequence: body, separator, zero ok?,
-    // lo, hi position-in-match-array used:
+    /// Match repetitions of a sequence: body, separator, zero ok?,
+    /// lo, hi position-in-match-array used:
     MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, bool, uint, uint),
-    // parse a Rust NT: name to bind, name of NT, position in match array:
+    /// Parse a Rust NT: name to bind, name of NT, position in match array:
     MatchNonterminal(Ident, Ident, uint)
 }
 
 pub type Mac = Spanned<Mac_>;
 
-// represents a macro invocation. The Path indicates which macro
-// is being invoked, and the vector of token-trees contains the source
-// of the macro invocation.
-// There's only one flavor, now, so this could presumably be simplified.
+/// Represents a macro invocation. The Path indicates which macro
+/// is being invoked, and the vector of token-trees contains the source
+/// of the macro invocation.
+/// There's only one flavor, now, so this could presumably be simplified.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum Mac_ {
+    // NB: the additional ident for a macro_rules-style macro is actually
+    // stored in the enclosing item. Oog.
     MacInvocTT(Path, Vec<TokenTree> , SyntaxContext),   // new macro-invocation
 }
 
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum StrStyle {
     CookedStr,
     RawStr(uint)
@@ -613,7 +653,7 @@ pub enum StrStyle {
 
 pub type Lit = Spanned<Lit_>;
 
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum Lit_ {
     LitStr(InternedString, StrStyle),
     LitBinary(Rc<Vec<u8> >),
@@ -643,6 +683,8 @@ pub struct TypeField {
     pub span: Span,
 }
 
+/// Represents a required method in a trait declaration,
+/// one without a default implementation
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct TypeMethod {
     pub ident: Ident,
@@ -656,9 +698,10 @@ pub struct TypeMethod {
     pub vis: Visibility,
 }
 
-// A trait method is either required (meaning it doesn't have an
-// implementation, just a signature) or provided (meaning it has a default
-// implementation).
+/// Represents a method declaration in a trait declaration, possibly including
+/// a default implementation A trait method is either required (meaning it
+/// doesn't have an implementation, just a signature) or provided (meaning it
+/// has a default implementation).
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum TraitMethod {
     Required(TypeMethod),
@@ -676,7 +719,17 @@ pub enum IntTy {
 
 impl fmt::Show for IntTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", ast_util::int_ty_to_str(*self, None))
+        write!(f, "{}", ast_util::int_ty_to_string(*self, None))
+    }
+}
+
+impl IntTy {
+    pub fn suffix_len(&self) -> uint {
+        match *self {
+            TyI => 1,
+            TyI8 => 2,
+            TyI16 | TyI32 | TyI64  => 3,
+        }
     }
 }
 
@@ -689,9 +742,19 @@ pub enum UintTy {
     TyU64,
 }
 
+impl UintTy {
+    pub fn suffix_len(&self) -> uint {
+        match *self {
+            TyU => 1,
+            TyU8 => 2,
+            TyU16 | TyU32 | TyU64  => 3,
+        }
+    }
+}
+
 impl fmt::Show for UintTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", ast_util::uint_ty_to_str(*self, None))
+        write!(f, "{}", ast_util::uint_ty_to_string(*self, None))
     }
 }
 
@@ -703,7 +766,15 @@ pub enum FloatTy {
 
 impl fmt::Show for FloatTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", ast_util::float_ty_to_str(*self))
+        write!(f, "{}", ast_util::float_ty_to_string(*self))
+    }
+}
+
+impl FloatTy {
+    pub fn suffix_len(&self) -> uint {
+        match *self {
+            TyF32 | TyF64 => 3, // add F128 handling here
+        }
     }
 }
 
@@ -715,7 +786,7 @@ pub struct Ty {
     pub span: Span,
 }
 
-// Not represented directly in the AST, referred to by name through a ty_path.
+/// Not represented directly in the AST, referred to by name through a ty_path.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum PrimTy {
     TyInt(IntTy),
@@ -741,16 +812,17 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+/// Represents the type of a closure
 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct ClosureTy {
     pub lifetimes: Vec<Lifetime>,
     pub fn_style: FnStyle,
     pub onceness: Onceness,
     pub decl: P<FnDecl>,
-    // Optional optvec distinguishes between "fn()" and "fn:()" so we can
-    // implement issue #7264. None means "fn()", which means infer a default
-    // bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
-    // which means use no bounds (e.g., not even Owned on a ~fn()).
+    /// Optional optvec distinguishes between "fn()" and "fn:()" so we can
+    /// implement issue #7264. None means "fn()", which means infer a default
+    /// bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
+    /// which means use no bounds (e.g., not even Owned on a ~fn()).
     pub bounds: Option<OwnedSlice<TyParamBound>>,
 }
 
@@ -783,11 +855,11 @@ pub enum Ty_ {
     TyUnboxedFn(Gc<UnboxedFnTy>),
     TyTup(Vec<P<Ty>> ),
     TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
-    // No-op; kept solely so that we can pretty-print faithfully
+    /// No-op; kept solely so that we can pretty-print faithfully
     TyParen(P<Ty>),
     TyTypeof(Gc<Expr>),
-    // TyInfer means the type should be inferred instead of it having been
-    // specified. This can appear anywhere in a type.
+    /// TyInfer means the type should be inferred instead of it having been
+    /// specified. This can appear anywhere in a type.
     TyInfer,
 }
 
@@ -809,6 +881,7 @@ pub struct InlineAsm {
     pub dialect: AsmDialect
 }
 
+/// represents an argument in a function header
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct Arg {
     pub ty: P<Ty>,
@@ -817,8 +890,8 @@ pub struct Arg {
 }
 
 impl Arg {
-    pub fn new_self(span: Span, mutability: Mutability) -> Arg {
-        let path = Spanned{span:span,node:special_idents::self_};
+    pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
+        let path = Spanned{span:span,node:self_ident};
         Arg {
             // HACK(eddyb) fake type for the self argument.
             ty: P(Ty {
@@ -836,7 +909,7 @@ pub fn new_self(span: Span, mutability: Mutability) -> Arg {
     }
 }
 
-// represents the header (not the body) of a function declaration
+/// represents the header (not the body) of a function declaration
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct FnDecl {
     pub inputs: Vec<Arg>,
@@ -847,8 +920,10 @@ pub struct FnDecl {
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum FnStyle {
-    UnsafeFn, // declared with "unsafe fn"
-    NormalFn, // declared with "fn"
+    /// Declared with "unsafe fn"
+    UnsafeFn,
+    /// Declared with "fn"
+    NormalFn,
 }
 
 impl fmt::Show for FnStyle {
@@ -862,33 +937,42 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum RetStyle {
-    NoReturn, // functions with return type _|_ that always
-              // raise an error or exit (i.e. never return to the caller)
-    Return, // everything else
+    /// Functions with return type ! that always
+    /// raise an error or exit (i.e. never return to the caller)
+    NoReturn,
+    /// Everything else
+    Return,
 }
 
+/// Represents the kind of 'self' associated with a method
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum ExplicitSelf_ {
-    SelfStatic,                                // no self
-    SelfValue,                                 // `self`
-    SelfRegion(Option<Lifetime>, Mutability),  // `&'lt self`, `&'lt mut self`
-    SelfUniq                                   // `~self`
+    /// No self
+    SelfStatic,
+    /// `self
+    SelfValue(Ident),
+    /// `&'lt self`, `&'lt mut self`
+    SelfRegion(Option<Lifetime>, Mutability, Ident),
+    /// `~self`
+    SelfUniq(Ident)
 }
 
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
 
 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct Method {
-    pub ident: Ident,
     pub attrs: Vec<Attribute>,
-    pub generics: Generics,
-    pub explicit_self: ExplicitSelf,
-    pub fn_style: FnStyle,
-    pub decl: P<FnDecl>,
-    pub body: P<Block>,
     pub id: NodeId,
     pub span: Span,
-    pub vis: Visibility,
+    pub node: Method_
+}
+
+#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
+pub enum Method_ {
+    /// Represents a method declaration
+    MethDecl(Ident, Generics, ExplicitSelf, FnStyle, P<FnDecl>, P<Block>, Visibility),
+    /// Represents a macro in method position
+    MethMac(Mac),
 }
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@@ -950,17 +1034,17 @@ pub struct PathListIdent_ {
 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum ViewPath_ {
 
-    // quux = foo::bar::baz
-    //
-    // or just
-    //
-    // foo::bar::baz  (with 'baz =' implicitly on the left)
+    /// `quux = foo::bar::baz`
+    ///
+    /// or just
+    ///
+    /// `foo::bar::baz ` (with 'baz =' implicitly on the left)
     ViewPathSimple(Ident, Path, NodeId),
 
-    // foo::bar::*
+    /// `foo::bar::*`
     ViewPathGlob(Path, NodeId),
 
-    // foo::bar::{a,b,c}
+    /// `foo::bar::{a,b,c}`
     ViewPathList(Path, Vec<PathListIdent> , NodeId)
 }
 
@@ -974,20 +1058,20 @@ pub struct ViewItem {
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum ViewItem_ {
-    // ident: name used to refer to this crate in the code
-    // optional (InternedString,StrStyle): if present, this is a location
-    // (containing arbitrary characters) from which to fetch the crate sources
-    // For example, extern crate whatever = "github.com/rust-lang/rust"
+    /// Ident: name used to refer to this crate in the code
+    /// optional (InternedString,StrStyle): if present, this is a location
+    /// (containing arbitrary characters) from which to fetch the crate sources
+    /// For example, extern crate whatever = "github.com/rust-lang/rust"
     ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
     ViewItemUse(Gc<ViewPath>),
 }
 
-// Meta-data associated with an item
+/// Meta-data associated with an item
 pub type Attribute = Spanned<Attribute_>;
 
-// Distinguishes between Attributes that decorate items and Attributes that
-// are contained as statements within items. These two cases need to be
-// distinguished for pretty-printing.
+/// Distinguishes between Attributes that decorate items and Attributes that
+/// are contained as statements within items. These two cases need to be
+/// distinguished for pretty-printing.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum AttrStyle {
     AttrOuter,
@@ -997,7 +1081,7 @@ pub enum AttrStyle {
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct AttrId(pub uint);
 
-// doc-comments are promoted to attributes that have is_sugared_doc = true
+/// Doc-comments are promoted to attributes that have is_sugared_doc = true
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct Attribute_ {
     pub id: AttrId,
@@ -1006,13 +1090,12 @@ pub struct Attribute_ {
     pub is_sugared_doc: bool,
 }
 
-/*
-  TraitRef's appear in impls.
-  resolve maps each TraitRef's ref_id to its defining trait; that's all
-  that the ref_id is for. The impl_id maps to the "self type" of this impl.
-  If this impl is an ItemImpl, the impl_id is redundant (it could be the
-  same as the impl's node id).
- */
+
+/// TraitRef's appear in impls.
+/// resolve maps each TraitRef's ref_id to its defining trait; that's all
+/// that the ref_id is for. The impl_id maps to the "self type" of this impl.
+/// If this impl is an ItemImpl, the impl_id is redundant (it could be the
+/// same as the impl's node id).
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct TraitRef {
     pub path: Path,
@@ -1034,12 +1117,6 @@ pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
     }
 }
 
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
-pub enum Sized {
-    DynSize,
-    StaticSize,
-}
-
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct StructField_ {
     pub kind: StructFieldKind,
@@ -1062,7 +1139,8 @@ pub fn ident(&self) -> Option<Ident> {
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum StructFieldKind {
     NamedField(Ident, Visibility),
-    UnnamedField(Visibility), // element of a tuple-like struct
+    /// Element of a tuple-like struct
+    UnnamedField(Visibility),
 }
 
 impl StructFieldKind {
@@ -1076,12 +1154,15 @@ pub fn is_unnamed(&self) -> bool {
 
 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct StructDef {
-    pub fields: Vec<StructField>, /* fields, not including ctor */
-    /* ID of the constructor. This is only used for tuple- or enum-like
-     * structs. */
+    /// Fields, not including ctor
+    pub fields: Vec<StructField>,
+    /// ID of the constructor. This is only used for tuple- or enum-like
+    /// structs.
     pub ctor_id: Option<NodeId>,
-    pub super_struct: Option<P<Ty>>, // Super struct, if specified.
-    pub is_virtual: bool,            // True iff the struct may be inherited from.
+    /// Super struct, if specified.
+    pub super_struct: Option<P<Ty>>,
+    /// True iff the struct may be inherited from.
+    pub is_virtual: bool,
 }
 
 /*
@@ -1107,12 +1188,17 @@ pub enum Item_ {
     ItemTy(P<Ty>, Generics),
     ItemEnum(EnumDef, Generics),
     ItemStruct(Gc<StructDef>, Generics),
-    ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ),
+    /// Represents a Trait Declaration
+    ItemTrait(Generics,
+              Option<TyParamBound>, // (optional) default bound not required for Self.
+                                    // Currently, only Sized makes sense here.
+              Vec<TraitRef> ,
+              Vec<TraitMethod>),
     ItemImpl(Generics,
              Option<TraitRef>, // (optional) trait this impl implements
              P<Ty>, // self
              Vec<Gc<Method>>),
-    // a macro invocation (which includes macro definition)
+    /// A macro invocation (which includes macro definition)
     ItemMac(Mac),
 }
 
@@ -1132,9 +1218,9 @@ pub enum ForeignItem_ {
     ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
 }
 
-// The data we save and restore about an inlined item or method.  This is not
-// part of the AST that we parse from a file, but it becomes part of the tree
-// that we trans.
+/// The data we save and restore about an inlined item or method.  This is not
+/// part of the AST that we parse from a file, but it becomes part of the tree
+/// that we trans.
 #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum InlinedItem {
     IIItem(Gc<Item>),
@@ -1170,6 +1256,7 @@ fn check_asts_encodable() {
                 hi: BytePos(20),
                 expn_info: None,
             },
+            exported_macros: Vec::new(),
         };
         // doesn't matter which encoder we use....
         let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
deleted file mode 100644 (file)
index 1a9a910..0000000
+++ /dev/null
@@ -1,734 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use abi;
-use ast::*;
-use ast_util;
-use codemap::Span;
-use fold::Folder;
-use fold;
-use parse::token;
-use print::pprust;
-use util::small_vector::SmallVector;
-
-use std::cell::RefCell;
-use std::fmt;
-use std::gc::{Gc, GC};
-use std::iter;
-use std::slice;
-
-#[deriving(Clone, PartialEq)]
-pub enum PathElem {
-    PathMod(Name),
-    PathName(Name)
-}
-
-impl PathElem {
-    pub fn name(&self) -> Name {
-        match *self {
-            PathMod(name) | PathName(name) => name
-        }
-    }
-}
-
-impl fmt::Show for PathElem {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let slot = token::get_name(self.name());
-        write!(f, "{}", slot)
-    }
-}
-
-#[deriving(Clone)]
-struct LinkedPathNode<'a> {
-    node: PathElem,
-    next: LinkedPath<'a>,
-}
-
-type LinkedPath<'a> = Option<&'a LinkedPathNode<'a>>;
-
-impl<'a> Iterator<PathElem> for LinkedPath<'a> {
-    fn next(&mut self) -> Option<PathElem> {
-        match *self {
-            Some(node) => {
-                *self = node.next;
-                Some(node.node)
-            }
-            None => None
-        }
-    }
-}
-
-// HACK(eddyb) move this into libstd (value wrapper for slice::Items).
-#[deriving(Clone)]
-pub struct Values<'a, T>(pub slice::Items<'a, T>);
-
-impl<'a, T: Copy> Iterator<T> for Values<'a, T> {
-    fn next(&mut self) -> Option<T> {
-        let &Values(ref mut items) = self;
-        items.next().map(|&x| x)
-    }
-}
-
-/// The type of the iterator used by with_path.
-pub type PathElems<'a, 'b> = iter::Chain<Values<'a, PathElem>, LinkedPath<'b>>;
-
-pub fn path_to_str<PI: Iterator<PathElem>>(mut path: PI) -> String {
-    let itr = token::get_ident_interner();
-
-    path.fold(String::new(), |mut s, e| {
-        let e = itr.get(e.name());
-        if !s.is_empty() {
-            s.push_str("::");
-        }
-        s.push_str(e.as_slice());
-        s
-    }).to_string()
-}
-
-#[deriving(Clone)]
-pub enum Node {
-    NodeItem(Gc<Item>),
-    NodeForeignItem(Gc<ForeignItem>),
-    NodeTraitMethod(Gc<TraitMethod>),
-    NodeMethod(Gc<Method>),
-    NodeVariant(P<Variant>),
-    NodeExpr(Gc<Expr>),
-    NodeStmt(Gc<Stmt>),
-    NodeArg(Gc<Pat>),
-    NodeLocal(Gc<Pat>),
-    NodePat(Gc<Pat>),
-    NodeBlock(P<Block>),
-
-    /// NodeStructCtor represents a tuple struct.
-    NodeStructCtor(Gc<StructDef>),
-
-    NodeLifetime(Gc<Lifetime>),
-}
-
-// The odd layout is to bring down the total size.
-#[deriving(Clone)]
-enum MapEntry {
-    // Placeholder for holes in the map.
-    NotPresent,
-
-    // All the node types, with a parent ID.
-    EntryItem(NodeId, Gc<Item>),
-    EntryForeignItem(NodeId, Gc<ForeignItem>),
-    EntryTraitMethod(NodeId, Gc<TraitMethod>),
-    EntryMethod(NodeId, Gc<Method>),
-    EntryVariant(NodeId, P<Variant>),
-    EntryExpr(NodeId, Gc<Expr>),
-    EntryStmt(NodeId, Gc<Stmt>),
-    EntryArg(NodeId, Gc<Pat>),
-    EntryLocal(NodeId, Gc<Pat>),
-    EntryPat(NodeId, Gc<Pat>),
-    EntryBlock(NodeId, P<Block>),
-    EntryStructCtor(NodeId, Gc<StructDef>),
-    EntryLifetime(NodeId, Gc<Lifetime>),
-
-    // Roots for node trees.
-    RootCrate,
-    RootInlinedParent(P<InlinedParent>)
-}
-
-struct InlinedParent {
-    path: Vec<PathElem> ,
-    // Required by NodeTraitMethod and NodeMethod.
-    def_id: DefId
-}
-
-impl MapEntry {
-    fn parent(&self) -> Option<NodeId> {
-        Some(match *self {
-            EntryItem(id, _) => id,
-            EntryForeignItem(id, _) => id,
-            EntryTraitMethod(id, _) => id,
-            EntryMethod(id, _) => id,
-            EntryVariant(id, _) => id,
-            EntryExpr(id, _) => id,
-            EntryStmt(id, _) => id,
-            EntryArg(id, _) => id,
-            EntryLocal(id, _) => id,
-            EntryPat(id, _) => id,
-            EntryBlock(id, _) => id,
-            EntryStructCtor(id, _) => id,
-            EntryLifetime(id, _) => id,
-            _ => return None
-        })
-    }
-
-    fn to_node(&self) -> Option<Node> {
-        Some(match *self {
-            EntryItem(_, p) => NodeItem(p),
-            EntryForeignItem(_, p) => NodeForeignItem(p),
-            EntryTraitMethod(_, p) => NodeTraitMethod(p),
-            EntryMethod(_, p) => NodeMethod(p),
-            EntryVariant(_, p) => NodeVariant(p),
-            EntryExpr(_, p) => NodeExpr(p),
-            EntryStmt(_, p) => NodeStmt(p),
-            EntryArg(_, p) => NodeArg(p),
-            EntryLocal(_, p) => NodeLocal(p),
-            EntryPat(_, p) => NodePat(p),
-            EntryBlock(_, p) => NodeBlock(p),
-            EntryStructCtor(_, p) => NodeStructCtor(p),
-            EntryLifetime(_, p) => NodeLifetime(p),
-            _ => return None
-        })
-    }
-}
-
-pub struct Map {
-    /// NodeIds are sequential integers from 0, so we can be
-    /// super-compact by storing them in a vector. Not everything with
-    /// a NodeId is in the map, but empirically the occupancy is about
-    /// 75-80%, so there's not too much overhead (certainly less than
-    /// a hashmap, since they (at the time of writing) have a maximum
-    /// of 75% occupancy).
-    ///
-    /// Also, indexing is pretty quick when you've got a vector and
-    /// plain old integers.
-    map: RefCell<Vec<MapEntry> >
-}
-
-impl Map {
-    fn find_entry(&self, id: NodeId) -> Option<MapEntry> {
-        let map = self.map.borrow();
-        if map.len() > id as uint {
-            Some(*map.get(id as uint))
-        } else {
-            None
-        }
-    }
-
-    /// Retrieve the Node corresponding to `id`, failing if it cannot
-    /// be found.
-    pub fn get(&self, id: NodeId) -> Node {
-        match self.find(id) {
-            Some(node) => node,
-            None => fail!("couldn't find node id {} in the AST map", id)
-        }
-    }
-
-    /// Retrieve the Node corresponding to `id`, returning None if
-    /// cannot be found.
-    pub fn find(&self, id: NodeId) -> Option<Node> {
-        self.find_entry(id).and_then(|x| x.to_node())
-    }
-
-    /// Retrieve the parent NodeId for `id`, or `id` itself if no
-    /// parent is registered in this map.
-    pub fn get_parent(&self, id: NodeId) -> NodeId {
-        self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id)
-    }
-
-    pub fn get_parent_did(&self, id: NodeId) -> DefId {
-        let parent = self.get_parent(id);
-        match self.find_entry(parent) {
-            Some(RootInlinedParent(data)) => data.def_id,
-            _ => ast_util::local_def(parent)
-        }
-    }
-
-    pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi {
-        let parent = self.get_parent(id);
-        let abi = match self.find_entry(parent) {
-            Some(EntryItem(_, i)) => match i.node {
-                ItemForeignMod(ref nm) => Some(nm.abi),
-                _ => None
-            },
-            // Wrong but OK, because the only inlined foreign items are intrinsics.
-            Some(RootInlinedParent(_)) => Some(abi::RustIntrinsic),
-            _ => None
-        };
-        match abi {
-            Some(abi) => abi,
-            None => fail!("expected foreign mod or inlined parent, found {}",
-                          self.node_to_str(parent))
-        }
-    }
-
-    pub fn get_foreign_vis(&self, id: NodeId) -> Visibility {
-        let vis = self.expect_foreign_item(id).vis;
-        match self.find(self.get_parent(id)) {
-            Some(NodeItem(i)) => vis.inherit_from(i.vis),
-            _ => vis
-        }
-    }
-
-    pub fn expect_item(&self, id: NodeId) -> Gc<Item> {
-        match self.find(id) {
-            Some(NodeItem(item)) => item,
-            _ => fail!("expected item, found {}", self.node_to_str(id))
-        }
-    }
-
-    pub fn expect_struct(&self, id: NodeId) -> Gc<StructDef> {
-        match self.find(id) {
-            Some(NodeItem(i)) => {
-                match i.node {
-                    ItemStruct(struct_def, _) => struct_def,
-                    _ => fail!("struct ID bound to non-struct")
-                }
-            }
-            Some(NodeVariant(ref variant)) => {
-                match (*variant).node.kind {
-                    StructVariantKind(struct_def) => struct_def,
-                    _ => fail!("struct ID bound to enum variant that isn't struct-like"),
-                }
-            }
-            _ => fail!(format!("expected struct, found {}", self.node_to_str(id))),
-        }
-    }
-
-    pub fn expect_variant(&self, id: NodeId) -> P<Variant> {
-        match self.find(id) {
-            Some(NodeVariant(variant)) => variant,
-            _ => fail!(format!("expected variant, found {}", self.node_to_str(id))),
-        }
-    }
-
-    pub fn expect_foreign_item(&self, id: NodeId) -> Gc<ForeignItem> {
-        match self.find(id) {
-            Some(NodeForeignItem(item)) => item,
-            _ => fail!("expected foreign item, found {}", self.node_to_str(id))
-        }
-    }
-
-    pub fn get_path_elem(&self, id: NodeId) -> PathElem {
-        match self.get(id) {
-            NodeItem(item) => {
-                match item.node {
-                    ItemMod(_) | ItemForeignMod(_) => {
-                        PathMod(item.ident.name)
-                    }
-                    _ => PathName(item.ident.name)
-                }
-            }
-            NodeForeignItem(i) => PathName(i.ident.name),
-            NodeMethod(m) => PathName(m.ident.name),
-            NodeTraitMethod(tm) => match *tm {
-                Required(ref m) => PathName(m.ident.name),
-                Provided(ref m) => PathName(m.ident.name)
-            },
-            NodeVariant(v) => PathName(v.node.name.name),
-            node => fail!("no path elem for {:?}", node)
-        }
-    }
-
-    pub fn with_path<T>(&self, id: NodeId, f: |PathElems| -> T) -> T {
-        self.with_path_next(id, None, f)
-    }
-
-    pub fn path_to_str(&self, id: NodeId) -> String {
-        self.with_path(id, |path| path_to_str(path))
-    }
-
-    fn path_to_str_with_ident(&self, id: NodeId, i: Ident) -> String {
-        self.with_path(id, |path| {
-            path_to_str(path.chain(Some(PathName(i.name)).move_iter()))
-        })
-    }
-
-    fn with_path_next<T>(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -> T {
-        let parent = self.get_parent(id);
-        let parent = match self.find_entry(id) {
-            Some(EntryForeignItem(..)) | Some(EntryVariant(..)) => {
-                // Anonymous extern items, enum variants and struct ctors
-                // go in the parent scope.
-                self.get_parent(parent)
-            }
-            // But tuple struct ctors don't have names, so use the path of its
-            // parent, the struct item. Similarly with closure expressions.
-            Some(EntryStructCtor(..)) | Some(EntryExpr(..)) => {
-                return self.with_path_next(parent, next, f);
-            }
-            _ => parent
-        };
-        if parent == id {
-            match self.find_entry(id) {
-                Some(RootInlinedParent(data)) => {
-                    f(Values(data.path.iter()).chain(next))
-                }
-                _ => f(Values([].iter()).chain(next))
-            }
-        } else {
-            self.with_path_next(parent, Some(&LinkedPathNode {
-                node: self.get_path_elem(id),
-                next: next
-            }), f)
-        }
-    }
-
-    pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
-        let node = self.get(id);
-        let attrs = match node {
-            NodeItem(ref i) => Some(i.attrs.as_slice()),
-            NodeForeignItem(ref fi) => Some(fi.attrs.as_slice()),
-            NodeTraitMethod(ref tm) => match **tm {
-                Required(ref type_m) => Some(type_m.attrs.as_slice()),
-                Provided(ref m) => Some(m.attrs.as_slice())
-            },
-            NodeMethod(ref m) => Some(m.attrs.as_slice()),
-            NodeVariant(ref v) => Some(v.node.attrs.as_slice()),
-            // unit/tuple structs take the attributes straight from
-            // the struct definition.
-            // FIXME(eddyb) make this work again (requires access to the map).
-            NodeStructCtor(_) => {
-                return self.with_attrs(self.get_parent(id), f);
-            }
-            _ => None
-        };
-        f(attrs)
-    }
-
-    pub fn opt_span(&self, id: NodeId) -> Option<Span> {
-        let sp = match self.find(id) {
-            Some(NodeItem(item)) => item.span,
-            Some(NodeForeignItem(foreign_item)) => foreign_item.span,
-            Some(NodeTraitMethod(trait_method)) => {
-                match *trait_method {
-                    Required(ref type_method) => type_method.span,
-                    Provided(ref method) => method.span,
-                }
-            }
-            Some(NodeMethod(method)) => method.span,
-            Some(NodeVariant(variant)) => variant.span,
-            Some(NodeExpr(expr)) => expr.span,
-            Some(NodeStmt(stmt)) => stmt.span,
-            Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
-            Some(NodePat(pat)) => pat.span,
-            Some(NodeBlock(block)) => block.span,
-            Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
-            _ => return None,
-        };
-        Some(sp)
-    }
-
-    pub fn span(&self, id: NodeId) -> Span {
-        self.opt_span(id)
-            .unwrap_or_else(|| fail!("AstMap.span: could not find span for id {}", id))
-    }
-
-    pub fn node_to_str(&self, id: NodeId) -> String {
-        node_id_to_str(self, id)
-    }
-}
-
-pub trait FoldOps {
-    fn new_id(&self, id: NodeId) -> NodeId {
-        id
-    }
-    fn new_span(&self, span: Span) -> Span {
-        span
-    }
-}
-
-pub struct Ctx<'a, F> {
-    map: &'a Map,
-    // The node in which we are currently mapping (an item or a method).
-    // When equal to DUMMY_NODE_ID, the next mapped node becomes the parent.
-    parent: NodeId,
-    fold_ops: F
-}
-
-impl<'a, F> Ctx<'a, F> {
-    fn insert(&self, id: NodeId, entry: MapEntry) {
-        (*self.map.map.borrow_mut()).grow_set(id as uint, &NotPresent, entry);
-    }
-}
-
-impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
-    fn new_id(&mut self, id: NodeId) -> NodeId {
-        let id = self.fold_ops.new_id(id);
-        if self.parent == DUMMY_NODE_ID {
-            self.parent = id;
-        }
-        id
-    }
-
-    fn new_span(&mut self, span: Span) -> Span {
-        self.fold_ops.new_span(span)
-    }
-
-    fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
-        let parent = self.parent;
-        self.parent = DUMMY_NODE_ID;
-
-        let i = fold::noop_fold_item(&*i, self).expect_one("expected one item");
-        assert_eq!(self.parent, i.id);
-
-        match i.node {
-            ItemImpl(_, _, _, ref ms) => {
-                for &m in ms.iter() {
-                    self.insert(m.id, EntryMethod(self.parent, m));
-                }
-            }
-            ItemEnum(ref enum_definition, _) => {
-                for &v in enum_definition.variants.iter() {
-                    self.insert(v.node.id, EntryVariant(self.parent, v));
-                }
-            }
-            ItemForeignMod(ref nm) => {
-                for nitem in nm.items.iter() {
-                    self.insert(nitem.id, EntryForeignItem(self.parent,
-                                                           nitem.clone()));
-                }
-            }
-            ItemStruct(ref struct_def, _) => {
-                // If this is a tuple-like struct, register the constructor.
-                match struct_def.ctor_id {
-                    Some(ctor_id) => {
-                        self.insert(ctor_id, EntryStructCtor(self.parent,
-                                                             struct_def.clone()));
-                    }
-                    None => {}
-                }
-            }
-            ItemTrait(_, _, ref traits, ref methods) => {
-                for t in traits.iter() {
-                    self.insert(t.ref_id, EntryItem(self.parent, i));
-                }
-
-                for tm in methods.iter() {
-                    match *tm {
-                        Required(ref m) => {
-                            self.insert(m.id, EntryTraitMethod(self.parent,
-                                                               box(GC) (*tm).clone()));
-                        }
-                        Provided(m) => {
-                            self.insert(m.id, EntryTraitMethod(self.parent,
-                                                               box(GC) Provided(m)));
-                        }
-                    }
-                }
-            }
-            _ => {}
-        }
-
-        self.parent = parent;
-        self.insert(i.id, EntryItem(self.parent, i));
-
-        SmallVector::one(i)
-    }
-
-    fn fold_pat(&mut self, pat: Gc<Pat>) -> Gc<Pat> {
-        let pat = fold::noop_fold_pat(pat, self);
-        match pat.node {
-            PatIdent(..) => {
-                // Note: this is at least *potentially* a pattern...
-                self.insert(pat.id, EntryLocal(self.parent, pat));
-            }
-            _ => {
-                self.insert(pat.id, EntryPat(self.parent, pat));
-            }
-        }
-
-        pat
-    }
-
-    fn fold_expr(&mut self, expr: Gc<Expr>) -> Gc<Expr> {
-        let expr = fold::noop_fold_expr(expr, self);
-
-        self.insert(expr.id, EntryExpr(self.parent, expr));
-
-        expr
-    }
-
-    fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<Gc<Stmt>> {
-        let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement");
-        self.insert(ast_util::stmt_id(&*stmt), EntryStmt(self.parent, stmt));
-        SmallVector::one(stmt)
-    }
-
-    fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod {
-        let parent = self.parent;
-        self.parent = DUMMY_NODE_ID;
-        let m = fold::noop_fold_type_method(m, self);
-        assert_eq!(self.parent, m.id);
-        self.parent = parent;
-        m
-    }
-
-    fn fold_method(&mut self, m: Gc<Method>) -> Gc<Method> {
-        let parent = self.parent;
-        self.parent = DUMMY_NODE_ID;
-        let m = fold::noop_fold_method(&*m, self);
-        assert_eq!(self.parent, m.id);
-        self.parent = parent;
-        m
-    }
-
-    fn fold_fn_decl(&mut self, decl: &FnDecl) -> P<FnDecl> {
-        let decl = fold::noop_fold_fn_decl(decl, self);
-        for a in decl.inputs.iter() {
-            self.insert(a.id, EntryArg(self.parent, a.pat));
-        }
-        decl
-    }
-
-    fn fold_block(&mut self, block: P<Block>) -> P<Block> {
-        let block = fold::noop_fold_block(block, self);
-        self.insert(block.id, EntryBlock(self.parent, block));
-        block
-    }
-
-    fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
-        let lifetime = fold::noop_fold_lifetime(lifetime, self);
-        self.insert(lifetime.id, EntryLifetime(self.parent, box(GC) lifetime));
-        lifetime
-    }
-}
-
-pub fn map_crate<F: FoldOps>(krate: Crate, fold_ops: F) -> (Crate, Map) {
-    let map = Map { map: RefCell::new(Vec::new()) };
-    let krate = {
-        let mut cx = Ctx {
-            map: &map,
-            parent: CRATE_NODE_ID,
-            fold_ops: fold_ops
-        };
-        cx.insert(CRATE_NODE_ID, RootCrate);
-        cx.fold_crate(krate)
-    };
-
-    if log_enabled!(::log::DEBUG) {
-        let map = map.map.borrow();
-        // This only makes sense for ordered stores; note the
-        // enumerate to count the number of entries.
-        let (entries_less_1, _) = (*map).iter().filter(|&x| {
-            match *x {
-                NotPresent => false,
-                _ => true
-            }
-        }).enumerate().last().expect("AST map was empty after folding?");
-
-        let entries = entries_less_1 + 1;
-        let vector_length = (*map).len();
-        debug!("The AST map has {} entries with a maximum of {}: occupancy {:.1}%",
-              entries, vector_length, (entries as f64 / vector_length as f64) * 100.);
-    }
-
-    (krate, map)
-}
-
-// Used for items loaded from external crate that are being inlined into this
-// crate.  The `path` should be the path to the item but should not include
-// the item itself.
-pub fn map_decoded_item<F: FoldOps>(map: &Map,
-                                    path: Vec<PathElem> ,
-                                    fold_ops: F,
-                                    fold: |&mut Ctx<F>| -> InlinedItem)
-                                    -> InlinedItem {
-    let mut cx = Ctx {
-        map: map,
-        parent: DUMMY_NODE_ID,
-        fold_ops: fold_ops
-    };
-
-    // Generate a NodeId for the RootInlinedParent inserted below.
-    cx.new_id(DUMMY_NODE_ID);
-
-    // Methods get added to the AST map when their impl is visited.  Since we
-    // don't decode and instantiate the impl, but just the method, we have to
-    // add it to the table now. Likewise with foreign items.
-    let mut def_id = DefId { krate: LOCAL_CRATE, node: DUMMY_NODE_ID };
-    let ii = fold(&mut cx);
-    match ii {
-        IIItem(_) => {}
-        IIMethod(impl_did, is_provided, m) => {
-            let entry = if is_provided {
-                EntryTraitMethod(cx.parent, box(GC) Provided(m))
-            } else {
-                EntryMethod(cx.parent, m)
-            };
-            cx.insert(m.id, entry);
-            def_id = impl_did;
-        }
-        IIForeign(i) => {
-            cx.insert(i.id, EntryForeignItem(cx.parent, i));
-        }
-    }
-
-    cx.insert(cx.parent, RootInlinedParent(P(InlinedParent {
-        path: path,
-        def_id: def_id
-    })));
-
-    ii
-}
-
-fn node_id_to_str(map: &Map, id: NodeId) -> String {
-    match map.find(id) {
-        Some(NodeItem(item)) => {
-            let path_str = map.path_to_str_with_ident(id, item.ident);
-            let item_str = match item.node {
-                ItemStatic(..) => "static",
-                ItemFn(..) => "fn",
-                ItemMod(..) => "mod",
-                ItemForeignMod(..) => "foreign mod",
-                ItemTy(..) => "ty",
-                ItemEnum(..) => "enum",
-                ItemStruct(..) => "struct",
-                ItemTrait(..) => "trait",
-                ItemImpl(..) => "impl",
-                ItemMac(..) => "macro"
-            };
-            format!("{} {} (id={})", item_str, path_str, id)
-        }
-        Some(NodeForeignItem(item)) => {
-            let path_str = map.path_to_str_with_ident(id, item.ident);
-            format!("foreign item {} (id={})", path_str, id)
-        }
-        Some(NodeMethod(m)) => {
-            format!("method {} in {} (id={})",
-                    token::get_ident(m.ident),
-                    map.path_to_str(id), id)
-        }
-        Some(NodeTraitMethod(ref tm)) => {
-            let m = ast_util::trait_method_to_ty_method(&**tm);
-            format!("method {} in {} (id={})",
-                    token::get_ident(m.ident),
-                    map.path_to_str(id), id)
-        }
-        Some(NodeVariant(ref variant)) => {
-            format!("variant {} in {} (id={})",
-                    token::get_ident(variant.node.name),
-                    map.path_to_str(id), id)
-        }
-        Some(NodeExpr(ref expr)) => {
-            format!("expr {} (id={})", pprust::expr_to_str(&**expr), id)
-        }
-        Some(NodeStmt(ref stmt)) => {
-            format!("stmt {} (id={})", pprust::stmt_to_str(&**stmt), id)
-        }
-        Some(NodeArg(ref pat)) => {
-            format!("arg {} (id={})", pprust::pat_to_str(&**pat), id)
-        }
-        Some(NodeLocal(ref pat)) => {
-            format!("local {} (id={})", pprust::pat_to_str(&**pat), id)
-        }
-        Some(NodePat(ref pat)) => {
-            format!("pat {} (id={})", pprust::pat_to_str(&**pat), id)
-        }
-        Some(NodeBlock(ref block)) => {
-            format!("block {} (id={})", pprust::block_to_str(&**block), id)
-        }
-        Some(NodeStructCtor(_)) => {
-            format!("struct_ctor {} (id={})", map.path_to_str(id), id)
-        }
-        Some(NodeLifetime(ref l)) => {
-            format!("lifetime {} (id={})",
-                    pprust::lifetime_to_str(&**l), id)
-        }
-        None => {
-            format!("unknown node (id={})", id)
-        }
-    }
-}
diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs
new file mode 100644 (file)
index 0000000..1280b88
--- /dev/null
@@ -0,0 +1,218 @@
+// 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.
+
+//! This module provides a simplified abstraction for working with
+//! code blocks identified by their integer node-id.  In particular,
+//! it captures a common set of attributes that all "function-like
+//! things" (represented by `FnLike` instances) share.  For example,
+//! all `FnLike` instances have a type signature (be it explicit or
+//! inferred).  And all `FnLike` instances have a body, i.e. the code
+//! that is run when the function-like thing it represents is invoked.
+//!
+//! With the above abstraction in place, one can treat the program
+//! text as a collection of blocks of code (and most such blocks are
+//! nested within a uniquely determined `FnLike`), and users can ask
+//! for the `Code` associated with a particular NodeId.
+
+use abi;
+use ast::{P, Block, FnDecl, NodeId};
+use ast;
+use ast_map::{Node};
+use ast_map;
+use ast_util;
+use codemap::Span;
+use visit;
+
+/// An FnLikeNode is a Node that is like a fn, in that it has a decl
+/// and a body (as well as a NodeId, a span, etc).
+///
+/// More specifically, it is one of either:
+///   - A function item,
+///   - A closure expr (i.e. an ExprFnBlock or ExprProc), or
+///   - The default implementation for a trait method.
+///
+/// To construct one, use the `Code::from_node` function.
+pub struct FnLikeNode { node: ast_map::Node }
+
+/// MaybeFnLike wraps a method that indicates if an object
+/// corresponds to some FnLikeNode.
+pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
+
+/// Components shared by fn-like things (fn items, methods, closures).
+pub struct FnParts<'a> {
+    pub decl: P<FnDecl>,
+    pub body: P<Block>,
+    pub kind: visit::FnKind<'a>,
+    pub span: Span,
+    pub id:   NodeId,
+}
+
+impl MaybeFnLike for ast::Item {
+    fn is_fn_like(&self) -> bool {
+        match self.node { ast::ItemFn(..) => true, _ => false, }
+    }
+}
+
+impl MaybeFnLike for ast::TraitMethod {
+    fn is_fn_like(&self) -> bool {
+        match *self { ast::Provided(_) => true, _ => false, }
+    }
+}
+
+impl MaybeFnLike for ast::Expr {
+    fn is_fn_like(&self) -> bool {
+        match self.node {
+            ast::ExprFnBlock(..) | ast::ExprProc(..) => true,
+            _ => false,
+        }
+    }
+}
+
+/// Carries either an FnLikeNode or a Block, as these are the two
+/// constructs that correspond to "code" (as in, something from which
+/// we can construct a control-flow graph).
+pub enum Code {
+    FnLikeCode(FnLikeNode),
+    BlockCode(P<Block>),
+}
+
+impl Code {
+    pub fn id(&self) -> ast::NodeId {
+        match *self {
+            FnLikeCode(node) => node.id(),
+            BlockCode(block) => block.id,
+        }
+    }
+
+    /// Attempts to construct a Code from presumed FnLike or Block node input.
+    pub fn from_node(node: Node) -> Option<Code> {
+        fn new(node: Node) -> FnLikeNode { FnLikeNode { node: node } }
+        match node {
+            ast_map::NodeItem(item) if item.is_fn_like() =>
+                Some(FnLikeCode(new(node))),
+            ast_map::NodeTraitMethod(tm) if tm.is_fn_like() =>
+                Some(FnLikeCode(new(node))),
+            ast_map::NodeMethod(_) =>
+                Some(FnLikeCode(new(node))),
+            ast_map::NodeExpr(e) if e.is_fn_like() =>
+                Some(FnLikeCode(new(node))),
+            ast_map::NodeBlock(block) =>
+                Some(BlockCode(block)),
+            _ =>
+                None,
+        }
+    }
+}
+
+/// These are all the components one can extract from a fn item for
+/// use when implementing FnLikeNode operations.
+struct ItemFnParts<'a> {
+    ident:    ast::Ident,
+    decl:     P<ast::FnDecl>,
+    style:    ast::FnStyle,
+    abi:      abi::Abi,
+    generics: &'a ast::Generics,
+    body:     P<Block>,
+    id:       ast::NodeId,
+    span:     Span
+}
+
+/// These are all the components one can extract from a closure expr
+/// for use when implementing FnLikeNode operations.
+struct ClosureParts {
+    decl: P<FnDecl>,
+    body: P<Block>,
+    id: NodeId,
+    span: Span
+}
+
+impl ClosureParts {
+    fn new(d: P<FnDecl>, b: P<Block>, id: NodeId, s: Span) -> ClosureParts {
+        ClosureParts { decl: d, body: b, id: id, span: s }
+    }
+}
+
+impl FnLikeNode {
+    pub fn to_fn_parts<'a>(&'a self) -> FnParts<'a> {
+        FnParts {
+            decl: self.decl(),
+            body: self.body(),
+            kind: self.kind(),
+            span: self.span(),
+            id:   self.id(),
+        }
+    }
+
+    pub fn body<'a>(&'a self) -> P<Block> {
+        self.handle(|i: ItemFnParts|     i.body,
+                    |m: &'a ast::Method| ast_util::method_body(m),
+                    |c: ClosureParts|    c.body)
+    }
+
+    pub fn decl<'a>(&'a self) -> P<FnDecl> {
+        self.handle(|i: ItemFnParts|     i.decl,
+                    |m: &'a ast::Method| ast_util::method_fn_decl(m),
+                    |c: ClosureParts|    c.decl)
+    }
+
+    pub fn span<'a>(&'a self) -> Span {
+        self.handle(|i: ItemFnParts|     i.span,
+                    |m: &'a ast::Method| m.span,
+                    |c: ClosureParts|    c.span)
+    }
+
+    pub fn id<'a>(&'a self) -> NodeId {
+        self.handle(|i: ItemFnParts|     i.id,
+                    |m: &'a ast::Method| m.id,
+                    |c: ClosureParts|    c.id)
+    }
+
+    pub fn kind<'a>(&'a self) -> visit::FnKind<'a> {
+        let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> {
+            visit::FkItemFn(p.ident, p.generics, p.style, p.abi)
+        };
+        let closure = |_: ClosureParts| {
+            visit::FkFnBlock
+        };
+        let method = |m: &'a ast::Method| {
+            visit::FkMethod(ast_util::method_ident(m), ast_util::method_generics(m), m)
+        };
+        self.handle(item, method, closure)
+    }
+
+    fn handle<'a, A>(&'a self,
+                     item_fn: |ItemFnParts<'a>| -> A,
+                     method: |&'a ast::Method| -> A,
+                     closure: |ClosureParts| -> A) -> A {
+        match self.node {
+            ast_map::NodeItem(ref i) => match i.node {
+                ast::ItemFn(decl, style, abi, ref generics, block) =>
+                    item_fn(ItemFnParts{
+                        ident: i.ident, decl: decl, style: style, body: block,
+                        generics: generics, abi: abi, id: i.id, span: i.span
+                    }),
+                _ => fail!("item FnLikeNode that is not fn-like"),
+            },
+            ast_map::NodeTraitMethod(ref t) => match **t {
+                ast::Provided(ref m) => method(&**m),
+                _ => fail!("trait method FnLikeNode that is not fn-like"),
+            },
+            ast_map::NodeMethod(ref m) => method(&**m),
+            ast_map::NodeExpr(ref e) => match e.node {
+                ast::ExprFnBlock(ref decl, ref block) =>
+                    closure(ClosureParts::new(*decl, *block, e.id, e.span)),
+                ast::ExprProc(ref decl, ref block) =>
+                    closure(ClosureParts::new(*decl, *block, e.id, e.span)),
+                _ => fail!("expr FnLikeNode that is not fn-like"),
+            },
+            _ => fail!("other FnLikeNode that is not fn-like"),
+        }
+    }
+}
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
new file mode 100644 (file)
index 0000000..50e487b
--- /dev/null
@@ -0,0 +1,760 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use abi;
+use ast::*;
+use ast_util;
+use codemap::Span;
+use fold::Folder;
+use fold;
+use parse::token;
+use print::pprust;
+use util::small_vector::SmallVector;
+
+use std::cell::RefCell;
+use std::fmt;
+use std::gc::{Gc, GC};
+use std::iter;
+use std::slice;
+
+pub mod blocks;
+
+#[deriving(Clone, PartialEq)]
+pub enum PathElem {
+    PathMod(Name),
+    PathName(Name)
+}
+
+impl PathElem {
+    pub fn name(&self) -> Name {
+        match *self {
+            PathMod(name) | PathName(name) => name
+        }
+    }
+}
+
+impl fmt::Show for PathElem {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let slot = token::get_name(self.name());
+        write!(f, "{}", slot)
+    }
+}
+
+#[deriving(Clone)]
+struct LinkedPathNode<'a> {
+    node: PathElem,
+    next: LinkedPath<'a>,
+}
+
+type LinkedPath<'a> = Option<&'a LinkedPathNode<'a>>;
+
+impl<'a> Iterator<PathElem> for LinkedPath<'a> {
+    fn next(&mut self) -> Option<PathElem> {
+        match *self {
+            Some(node) => {
+                *self = node.next;
+                Some(node.node)
+            }
+            None => None
+        }
+    }
+}
+
+// HACK(eddyb) move this into libstd (value wrapper for slice::Items).
+#[deriving(Clone)]
+pub struct Values<'a, T>(pub slice::Items<'a, T>);
+
+impl<'a, T: Copy> Iterator<T> for Values<'a, T> {
+    fn next(&mut self) -> Option<T> {
+        let &Values(ref mut items) = self;
+        items.next().map(|&x| x)
+    }
+}
+
+/// The type of the iterator used by with_path.
+pub type PathElems<'a, 'b> = iter::Chain<Values<'a, PathElem>, LinkedPath<'b>>;
+
+pub fn path_to_string<PI: Iterator<PathElem>>(mut path: PI) -> String {
+    let itr = token::get_ident_interner();
+
+    path.fold(String::new(), |mut s, e| {
+        let e = itr.get(e.name());
+        if !s.is_empty() {
+            s.push_str("::");
+        }
+        s.push_str(e.as_slice());
+        s
+    }).to_string()
+}
+
+#[deriving(Clone)]
+pub enum Node {
+    NodeItem(Gc<Item>),
+    NodeForeignItem(Gc<ForeignItem>),
+    NodeTraitMethod(Gc<TraitMethod>),
+    NodeMethod(Gc<Method>),
+    NodeVariant(P<Variant>),
+    NodeExpr(Gc<Expr>),
+    NodeStmt(Gc<Stmt>),
+    NodeArg(Gc<Pat>),
+    NodeLocal(Gc<Pat>),
+    NodePat(Gc<Pat>),
+    NodeBlock(P<Block>),
+
+    /// NodeStructCtor represents a tuple struct.
+    NodeStructCtor(Gc<StructDef>),
+
+    NodeLifetime(Gc<Lifetime>),
+}
+
+/// Represents an entry and its parent Node ID
+/// The odd layout is to bring down the total size.
+#[deriving(Clone)]
+enum MapEntry {
+    /// Placeholder for holes in the map.
+    NotPresent,
+
+    /// All the node types, with a parent ID.
+    EntryItem(NodeId, Gc<Item>),
+    EntryForeignItem(NodeId, Gc<ForeignItem>),
+    EntryTraitMethod(NodeId, Gc<TraitMethod>),
+    EntryMethod(NodeId, Gc<Method>),
+    EntryVariant(NodeId, P<Variant>),
+    EntryExpr(NodeId, Gc<Expr>),
+    EntryStmt(NodeId, Gc<Stmt>),
+    EntryArg(NodeId, Gc<Pat>),
+    EntryLocal(NodeId, Gc<Pat>),
+    EntryPat(NodeId, Gc<Pat>),
+    EntryBlock(NodeId, P<Block>),
+    EntryStructCtor(NodeId, Gc<StructDef>),
+    EntryLifetime(NodeId, Gc<Lifetime>),
+
+    /// Roots for node trees.
+    RootCrate,
+    RootInlinedParent(P<InlinedParent>)
+}
+
+struct InlinedParent {
+    path: Vec<PathElem> ,
+    /// Required by NodeTraitMethod and NodeMethod.
+    def_id: DefId
+}
+
+impl MapEntry {
+    fn parent(&self) -> Option<NodeId> {
+        Some(match *self {
+            EntryItem(id, _) => id,
+            EntryForeignItem(id, _) => id,
+            EntryTraitMethod(id, _) => id,
+            EntryMethod(id, _) => id,
+            EntryVariant(id, _) => id,
+            EntryExpr(id, _) => id,
+            EntryStmt(id, _) => id,
+            EntryArg(id, _) => id,
+            EntryLocal(id, _) => id,
+            EntryPat(id, _) => id,
+            EntryBlock(id, _) => id,
+            EntryStructCtor(id, _) => id,
+            EntryLifetime(id, _) => id,
+            _ => return None
+        })
+    }
+
+    fn to_node(&self) -> Option<Node> {
+        Some(match *self {
+            EntryItem(_, p) => NodeItem(p),
+            EntryForeignItem(_, p) => NodeForeignItem(p),
+            EntryTraitMethod(_, p) => NodeTraitMethod(p),
+            EntryMethod(_, p) => NodeMethod(p),
+            EntryVariant(_, p) => NodeVariant(p),
+            EntryExpr(_, p) => NodeExpr(p),
+            EntryStmt(_, p) => NodeStmt(p),
+            EntryArg(_, p) => NodeArg(p),
+            EntryLocal(_, p) => NodeLocal(p),
+            EntryPat(_, p) => NodePat(p),
+            EntryBlock(_, p) => NodeBlock(p),
+            EntryStructCtor(_, p) => NodeStructCtor(p),
+            EntryLifetime(_, p) => NodeLifetime(p),
+            _ => return None
+        })
+    }
+}
+
+/// Represents a mapping from Node IDs to AST elements and their parent
+/// Node IDs
+pub struct Map {
+    /// NodeIds are sequential integers from 0, so we can be
+    /// super-compact by storing them in a vector. Not everything with
+    /// a NodeId is in the map, but empirically the occupancy is about
+    /// 75-80%, so there's not too much overhead (certainly less than
+    /// a hashmap, since they (at the time of writing) have a maximum
+    /// of 75% occupancy).
+    ///
+    /// Also, indexing is pretty quick when you've got a vector and
+    /// plain old integers.
+    map: RefCell<Vec<MapEntry> >
+}
+
+impl Map {
+    fn find_entry(&self, id: NodeId) -> Option<MapEntry> {
+        let map = self.map.borrow();
+        if map.len() > id as uint {
+            Some(*map.get(id as uint))
+        } else {
+            None
+        }
+    }
+
+    /// Retrieve the Node corresponding to `id`, failing if it cannot
+    /// be found.
+    pub fn get(&self, id: NodeId) -> Node {
+        match self.find(id) {
+            Some(node) => node,
+            None => fail!("couldn't find node id {} in the AST map", id)
+        }
+    }
+
+    /// Retrieve the Node corresponding to `id`, returning None if
+    /// cannot be found.
+    pub fn find(&self, id: NodeId) -> Option<Node> {
+        self.find_entry(id).and_then(|x| x.to_node())
+    }
+
+    /// Retrieve the parent NodeId for `id`, or `id` itself if no
+    /// parent is registered in this map.
+    pub fn get_parent(&self, id: NodeId) -> NodeId {
+        self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id)
+    }
+
+    pub fn get_parent_did(&self, id: NodeId) -> DefId {
+        let parent = self.get_parent(id);
+        match self.find_entry(parent) {
+            Some(RootInlinedParent(data)) => data.def_id,
+            _ => ast_util::local_def(parent)
+        }
+    }
+
+    pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi {
+        let parent = self.get_parent(id);
+        let abi = match self.find_entry(parent) {
+            Some(EntryItem(_, i)) => match i.node {
+                ItemForeignMod(ref nm) => Some(nm.abi),
+                _ => None
+            },
+            /// Wrong but OK, because the only inlined foreign items are intrinsics.
+            Some(RootInlinedParent(_)) => Some(abi::RustIntrinsic),
+            _ => None
+        };
+        match abi {
+            Some(abi) => abi,
+            None => fail!("expected foreign mod or inlined parent, found {}",
+                          self.node_to_string(parent))
+        }
+    }
+
+    pub fn get_foreign_vis(&self, id: NodeId) -> Visibility {
+        let vis = self.expect_foreign_item(id).vis;
+        match self.find(self.get_parent(id)) {
+            Some(NodeItem(i)) => vis.inherit_from(i.vis),
+            _ => vis
+        }
+    }
+
+    pub fn expect_item(&self, id: NodeId) -> Gc<Item> {
+        match self.find(id) {
+            Some(NodeItem(item)) => item,
+            _ => fail!("expected item, found {}", self.node_to_string(id))
+        }
+    }
+
+    pub fn expect_struct(&self, id: NodeId) -> Gc<StructDef> {
+        match self.find(id) {
+            Some(NodeItem(i)) => {
+                match i.node {
+                    ItemStruct(struct_def, _) => struct_def,
+                    _ => fail!("struct ID bound to non-struct")
+                }
+            }
+            Some(NodeVariant(ref variant)) => {
+                match (*variant).node.kind {
+                    StructVariantKind(struct_def) => struct_def,
+                    _ => fail!("struct ID bound to enum variant that isn't struct-like"),
+                }
+            }
+            _ => fail!(format!("expected struct, found {}", self.node_to_string(id))),
+        }
+    }
+
+    pub fn expect_variant(&self, id: NodeId) -> P<Variant> {
+        match self.find(id) {
+            Some(NodeVariant(variant)) => variant,
+            _ => fail!(format!("expected variant, found {}", self.node_to_string(id))),
+        }
+    }
+
+    pub fn expect_foreign_item(&self, id: NodeId) -> Gc<ForeignItem> {
+        match self.find(id) {
+            Some(NodeForeignItem(item)) => item,
+            _ => fail!("expected foreign item, found {}", self.node_to_string(id))
+        }
+    }
+
+    /// returns the name associated with the given NodeId's AST
+    pub fn get_path_elem(&self, id: NodeId) -> PathElem {
+        let node = self.get(id);
+        match node {
+            NodeItem(item) => {
+                match item.node {
+                    ItemMod(_) | ItemForeignMod(_) => {
+                        PathMod(item.ident.name)
+                    }
+                    _ => PathName(item.ident.name)
+                }
+            }
+            NodeForeignItem(i) => PathName(i.ident.name),
+            NodeMethod(m) => match m.node {
+                MethDecl(ident, _, _, _, _, _, _) => PathName(ident.name),
+                MethMac(_) => fail!("no path elem for {:?}", node)
+            },
+            NodeTraitMethod(tm) => match *tm {
+                Required(ref m) => PathName(m.ident.name),
+                Provided(m) => match m.node {
+                    MethDecl(ident, _, _, _, _, _, _) => PathName(ident.name),
+                    MethMac(_) => fail!("no path elem for {:?}", node),
+                }
+            },
+            NodeVariant(v) => PathName(v.node.name.name),
+            _ => fail!("no path elem for {:?}", node)
+        }
+    }
+
+    pub fn with_path<T>(&self, id: NodeId, f: |PathElems| -> T) -> T {
+        self.with_path_next(id, None, f)
+    }
+
+    pub fn path_to_string(&self, id: NodeId) -> String {
+        self.with_path(id, |path| path_to_string(path))
+    }
+
+    fn path_to_str_with_ident(&self, id: NodeId, i: Ident) -> String {
+        self.with_path(id, |path| {
+            path_to_string(path.chain(Some(PathName(i.name)).move_iter()))
+        })
+    }
+
+    fn with_path_next<T>(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -> T {
+        let parent = self.get_parent(id);
+        let parent = match self.find_entry(id) {
+            Some(EntryForeignItem(..)) | Some(EntryVariant(..)) => {
+                // Anonymous extern items, enum variants and struct ctors
+                // go in the parent scope.
+                self.get_parent(parent)
+            }
+            // But tuple struct ctors don't have names, so use the path of its
+            // parent, the struct item. Similarly with closure expressions.
+            Some(EntryStructCtor(..)) | Some(EntryExpr(..)) => {
+                return self.with_path_next(parent, next, f);
+            }
+            _ => parent
+        };
+        if parent == id {
+            match self.find_entry(id) {
+                Some(RootInlinedParent(data)) => {
+                    f(Values(data.path.iter()).chain(next))
+                }
+                _ => f(Values([].iter()).chain(next))
+            }
+        } else {
+            self.with_path_next(parent, Some(&LinkedPathNode {
+                node: self.get_path_elem(id),
+                next: next
+            }), f)
+        }
+    }
+
+    /// Given a node ID and a closure, apply the closure to the array
+    /// of attributes associated with the AST corresponding to the Node ID
+    pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
+        let node = self.get(id);
+        let attrs = match node {
+            NodeItem(ref i) => Some(i.attrs.as_slice()),
+            NodeForeignItem(ref fi) => Some(fi.attrs.as_slice()),
+            NodeTraitMethod(ref tm) => match **tm {
+                Required(ref type_m) => Some(type_m.attrs.as_slice()),
+                Provided(ref m) => Some(m.attrs.as_slice())
+            },
+            NodeMethod(ref m) => Some(m.attrs.as_slice()),
+            NodeVariant(ref v) => Some(v.node.attrs.as_slice()),
+            // unit/tuple structs take the attributes straight from
+            // the struct definition.
+            // FIXME(eddyb) make this work again (requires access to the map).
+            NodeStructCtor(_) => {
+                return self.with_attrs(self.get_parent(id), f);
+            }
+            _ => None
+        };
+        f(attrs)
+    }
+
+    pub fn opt_span(&self, id: NodeId) -> Option<Span> {
+        let sp = match self.find(id) {
+            Some(NodeItem(item)) => item.span,
+            Some(NodeForeignItem(foreign_item)) => foreign_item.span,
+            Some(NodeTraitMethod(trait_method)) => {
+                match *trait_method {
+                    Required(ref type_method) => type_method.span,
+                    Provided(ref method) => method.span,
+                }
+            }
+            Some(NodeMethod(method)) => method.span,
+            Some(NodeVariant(variant)) => variant.span,
+            Some(NodeExpr(expr)) => expr.span,
+            Some(NodeStmt(stmt)) => stmt.span,
+            Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
+            Some(NodePat(pat)) => pat.span,
+            Some(NodeBlock(block)) => block.span,
+            Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
+            _ => return None,
+        };
+        Some(sp)
+    }
+
+    pub fn span(&self, id: NodeId) -> Span {
+        self.opt_span(id)
+            .unwrap_or_else(|| fail!("AstMap.span: could not find span for id {}", id))
+    }
+
+    pub fn node_to_string(&self, id: NodeId) -> String {
+        node_id_to_string(self, id)
+    }
+}
+
+pub trait FoldOps {
+    fn new_id(&self, id: NodeId) -> NodeId {
+        id
+    }
+    fn new_span(&self, span: Span) -> Span {
+        span
+    }
+}
+
+/// A Folder that walks over an AST and constructs a Node ID Map. Its
+/// fold_ops argument has the opportunity to replace Node IDs and spans.
+pub struct Ctx<'a, F> {
+    map: &'a Map,
+    /// The node in which we are currently mapping (an item or a method).
+    /// When equal to DUMMY_NODE_ID, the next mapped node becomes the parent.
+    parent: NodeId,
+    fold_ops: F
+}
+
+impl<'a, F> Ctx<'a, F> {
+    fn insert(&self, id: NodeId, entry: MapEntry) {
+        (*self.map.map.borrow_mut()).grow_set(id as uint, &NotPresent, entry);
+    }
+}
+
+impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
+    fn new_id(&mut self, id: NodeId) -> NodeId {
+        let id = self.fold_ops.new_id(id);
+        if self.parent == DUMMY_NODE_ID {
+            self.parent = id;
+        }
+        id
+    }
+
+    fn new_span(&mut self, span: Span) -> Span {
+        self.fold_ops.new_span(span)
+    }
+
+    fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
+        let parent = self.parent;
+        self.parent = DUMMY_NODE_ID;
+
+        let i = fold::noop_fold_item(&*i, self).expect_one("expected one item");
+        assert_eq!(self.parent, i.id);
+
+        match i.node {
+            ItemImpl(_, _, _, ref ms) => {
+                for &m in ms.iter() {
+                    self.insert(m.id, EntryMethod(self.parent, m));
+                }
+            }
+            ItemEnum(ref enum_definition, _) => {
+                for &v in enum_definition.variants.iter() {
+                    self.insert(v.node.id, EntryVariant(self.parent, v));
+                }
+            }
+            ItemForeignMod(ref nm) => {
+                for nitem in nm.items.iter() {
+                    self.insert(nitem.id, EntryForeignItem(self.parent,
+                                                           nitem.clone()));
+                }
+            }
+            ItemStruct(ref struct_def, _) => {
+                // If this is a tuple-like struct, register the constructor.
+                match struct_def.ctor_id {
+                    Some(ctor_id) => {
+                        self.insert(ctor_id, EntryStructCtor(self.parent,
+                                                             struct_def.clone()));
+                    }
+                    None => {}
+                }
+            }
+            ItemTrait(_, _, ref traits, ref methods) => {
+                for t in traits.iter() {
+                    self.insert(t.ref_id, EntryItem(self.parent, i));
+                }
+
+                for tm in methods.iter() {
+                    match *tm {
+                        Required(ref m) => {
+                            self.insert(m.id, EntryTraitMethod(self.parent,
+                                                               box(GC) (*tm).clone()));
+                        }
+                        Provided(m) => {
+                            self.insert(m.id, EntryTraitMethod(self.parent,
+                                                               box(GC) Provided(m)));
+                        }
+                    }
+                }
+            }
+            _ => {}
+        }
+
+        self.parent = parent;
+        self.insert(i.id, EntryItem(self.parent, i));
+
+        SmallVector::one(i)
+    }
+
+    fn fold_pat(&mut self, pat: Gc<Pat>) -> Gc<Pat> {
+        let pat = fold::noop_fold_pat(pat, self);
+        match pat.node {
+            PatIdent(..) => {
+                // Note: this is at least *potentially* a pattern...
+                self.insert(pat.id, EntryLocal(self.parent, pat));
+            }
+            _ => {
+                self.insert(pat.id, EntryPat(self.parent, pat));
+            }
+        }
+
+        pat
+    }
+
+    fn fold_expr(&mut self, expr: Gc<Expr>) -> Gc<Expr> {
+        let expr = fold::noop_fold_expr(expr, self);
+
+        self.insert(expr.id, EntryExpr(self.parent, expr));
+
+        expr
+    }
+
+    fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<Gc<Stmt>> {
+        let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement");
+        self.insert(ast_util::stmt_id(&*stmt), EntryStmt(self.parent, stmt));
+        SmallVector::one(stmt)
+    }
+
+    fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod {
+        let parent = self.parent;
+        self.parent = DUMMY_NODE_ID;
+        let m = fold::noop_fold_type_method(m, self);
+        assert_eq!(self.parent, m.id);
+        self.parent = parent;
+        m
+    }
+
+    fn fold_method(&mut self, m: Gc<Method>) -> SmallVector<Gc<Method>> {
+        let parent = self.parent;
+        self.parent = DUMMY_NODE_ID;
+        let m = fold::noop_fold_method(&*m, self).expect_one(
+            "noop_fold_method must produce exactly one method");
+        assert_eq!(self.parent, m.id);
+        self.parent = parent;
+        SmallVector::one(m)
+    }
+
+    fn fold_fn_decl(&mut self, decl: &FnDecl) -> P<FnDecl> {
+        let decl = fold::noop_fold_fn_decl(decl, self);
+        for a in decl.inputs.iter() {
+            self.insert(a.id, EntryArg(self.parent, a.pat));
+        }
+        decl
+    }
+
+    fn fold_block(&mut self, block: P<Block>) -> P<Block> {
+        let block = fold::noop_fold_block(block, self);
+        self.insert(block.id, EntryBlock(self.parent, block));
+        block
+    }
+
+    fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
+        let lifetime = fold::noop_fold_lifetime(lifetime, self);
+        self.insert(lifetime.id, EntryLifetime(self.parent, box(GC) lifetime));
+        lifetime
+    }
+
+    fn fold_mac(&mut self, mac: &Mac) -> Mac {
+        fold::fold_mac(mac, self)
+    }
+}
+
+pub fn map_crate<F: FoldOps>(krate: Crate, fold_ops: F) -> (Crate, Map) {
+    let map = Map { map: RefCell::new(Vec::new()) };
+    let krate = {
+        let mut cx = Ctx {
+            map: &map,
+            parent: CRATE_NODE_ID,
+            fold_ops: fold_ops
+        };
+        cx.insert(CRATE_NODE_ID, RootCrate);
+        cx.fold_crate(krate)
+    };
+
+    if log_enabled!(::log::DEBUG) {
+        let map = map.map.borrow();
+        // This only makes sense for ordered stores; note the
+        // enumerate to count the number of entries.
+        let (entries_less_1, _) = (*map).iter().filter(|&x| {
+            match *x {
+                NotPresent => false,
+                _ => true
+            }
+        }).enumerate().last().expect("AST map was empty after folding?");
+
+        let entries = entries_less_1 + 1;
+        let vector_length = (*map).len();
+        debug!("The AST map has {} entries with a maximum of {}: occupancy {:.1}%",
+              entries, vector_length, (entries as f64 / vector_length as f64) * 100.);
+    }
+
+    (krate, map)
+}
+
+/// Used for items loaded from external crate that are being inlined into this
+/// crate.  The `path` should be the path to the item but should not include
+/// the item itself.
+pub fn map_decoded_item<F: FoldOps>(map: &Map,
+                                    path: Vec<PathElem> ,
+                                    fold_ops: F,
+                                    fold: |&mut Ctx<F>| -> InlinedItem)
+                                    -> InlinedItem {
+    let mut cx = Ctx {
+        map: map,
+        parent: DUMMY_NODE_ID,
+        fold_ops: fold_ops
+    };
+
+    // Generate a NodeId for the RootInlinedParent inserted below.
+    cx.new_id(DUMMY_NODE_ID);
+
+    // Methods get added to the AST map when their impl is visited.  Since we
+    // don't decode and instantiate the impl, but just the method, we have to
+    // add it to the table now. Likewise with foreign items.
+    let mut def_id = DefId { krate: LOCAL_CRATE, node: DUMMY_NODE_ID };
+    let ii = fold(&mut cx);
+    match ii {
+        IIItem(_) => {}
+        IIMethod(impl_did, is_provided, m) => {
+            let entry = if is_provided {
+                EntryTraitMethod(cx.parent, box(GC) Provided(m))
+            } else {
+                EntryMethod(cx.parent, m)
+            };
+            cx.insert(m.id, entry);
+            def_id = impl_did;
+        }
+        IIForeign(i) => {
+            cx.insert(i.id, EntryForeignItem(cx.parent, i));
+        }
+    }
+
+    cx.insert(cx.parent, RootInlinedParent(P(InlinedParent {
+        path: path,
+        def_id: def_id
+    })));
+
+    ii
+}
+
+fn node_id_to_string(map: &Map, id: NodeId) -> String {
+    match map.find(id) {
+        Some(NodeItem(item)) => {
+            let path_str = map.path_to_str_with_ident(id, item.ident);
+            let item_str = match item.node {
+                ItemStatic(..) => "static",
+                ItemFn(..) => "fn",
+                ItemMod(..) => "mod",
+                ItemForeignMod(..) => "foreign mod",
+                ItemTy(..) => "ty",
+                ItemEnum(..) => "enum",
+                ItemStruct(..) => "struct",
+                ItemTrait(..) => "trait",
+                ItemImpl(..) => "impl",
+                ItemMac(..) => "macro"
+            };
+            format!("{} {} (id={})", item_str, path_str, id)
+        }
+        Some(NodeForeignItem(item)) => {
+            let path_str = map.path_to_str_with_ident(id, item.ident);
+            format!("foreign item {} (id={})", path_str, id)
+        }
+        Some(NodeMethod(m)) => match m.node {
+            MethDecl(ident, _, _, _, _, _, _) =>
+                format!("method {} in {} (id={})",
+                        token::get_ident(ident),
+                        map.path_to_string(id), id),
+            MethMac(ref mac) =>
+                format!("method macro {} (id={})",
+                        pprust::mac_to_string(mac), id)
+        },
+        Some(NodeTraitMethod(ref tm)) => {
+            let m = ast_util::trait_method_to_ty_method(&**tm);
+            format!("method {} in {} (id={})",
+                    token::get_ident(m.ident),
+                    map.path_to_string(id), id)
+        }
+        Some(NodeVariant(ref variant)) => {
+            format!("variant {} in {} (id={})",
+                    token::get_ident(variant.node.name),
+                    map.path_to_string(id), id)
+        }
+        Some(NodeExpr(ref expr)) => {
+            format!("expr {} (id={})", pprust::expr_to_string(&**expr), id)
+        }
+        Some(NodeStmt(ref stmt)) => {
+            format!("stmt {} (id={})", pprust::stmt_to_string(&**stmt), id)
+        }
+        Some(NodeArg(ref pat)) => {
+            format!("arg {} (id={})", pprust::pat_to_string(&**pat), id)
+        }
+        Some(NodeLocal(ref pat)) => {
+            format!("local {} (id={})", pprust::pat_to_string(&**pat), id)
+        }
+        Some(NodePat(ref pat)) => {
+            format!("pat {} (id={})", pprust::pat_to_string(&**pat), id)
+        }
+        Some(NodeBlock(ref block)) => {
+            format!("block {} (id={})", pprust::block_to_string(&**block), id)
+        }
+        Some(NodeStructCtor(_)) => {
+            format!("struct_ctor {} (id={})", map.path_to_string(id), id)
+        }
+        Some(NodeLifetime(ref l)) => {
+            format!("lifetime {} (id={})",
+                    pprust::lifetime_to_string(&**l), id)
+        }
+        None => {
+            format!("unknown node (id={})", id)
+        }
+    }
+}
index 036d6b4b43adc62d537c8c0f9dfc745964d6bca3..a18d8a81ef47f7655b9cfb55a99d9656374ae54c 100644 (file)
@@ -48,7 +48,7 @@ pub fn stmt_id(s: &Stmt) -> NodeId {
     }
 }
 
-pub fn binop_to_str(op: BinOp) -> &'static str {
+pub fn binop_to_string(op: BinOp) -> &'static str {
     match op {
         BiAdd => "+",
         BiSub => "-",
@@ -87,7 +87,7 @@ pub fn is_shift_binop(b: BinOp) -> bool {
     }
 }
 
-pub fn unop_to_str(op: UnOp) -> &'static str {
+pub fn unop_to_string(op: UnOp) -> &'static str {
     match op {
       UnBox => "box(GC) ",
       UnUniq => "box() ",
@@ -101,9 +101,9 @@ pub fn is_path(e: Gc<Expr>) -> bool {
     return match e.node { ExprPath(_) => true, _ => false };
 }
 
-// Get a string representation of a signed int type, with its value.
-// We want to avoid "45int" and "-3int" in favor of "45" and "-3"
-pub fn int_ty_to_str(t: IntTy, val: Option<i64>) -> String {
+/// Get a string representation of a signed int type, with its value.
+/// We want to avoid "45int" and "-3int" in favor of "45" and "-3"
+pub fn int_ty_to_string(t: IntTy, val: Option<i64>) -> String {
     let s = match t {
         TyI if val.is_some() => "i",
         TyI => "int",
@@ -131,9 +131,9 @@ pub fn int_ty_max(t: IntTy) -> u64 {
     }
 }
 
-// Get a string representation of an unsigned int type, with its value.
-// We want to avoid "42uint" in favor of "42u"
-pub fn uint_ty_to_str(t: UintTy, val: Option<u64>) -> String {
+/// Get a string representation of an unsigned int type, with its value.
+/// We want to avoid "42uint" in favor of "42u"
+pub fn uint_ty_to_string(t: UintTy, val: Option<u64>) -> String {
     let s = match t {
         TyU if val.is_some() => "u",
         TyU => "uint",
@@ -158,7 +158,7 @@ pub fn uint_ty_max(t: UintTy) -> u64 {
     }
 }
 
-pub fn float_ty_to_str(t: FloatTy) -> String {
+pub fn float_ty_to_string(t: FloatTy) -> String {
     match t {
         TyF32 => "f32".to_string(),
         TyF64 => "f64".to_string(),
@@ -229,43 +229,42 @@ pub fn unguarded_pat(a: &Arm) -> Option<Vec<Gc<Pat>>> {
 /// listed as `__extensions__::method_name::hash`, with no indication
 /// of the type).
 pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
-    let mut pretty = pprust::ty_to_str(ty);
+    let mut pretty = pprust::ty_to_string(ty);
     match *trait_ref {
         Some(ref trait_ref) => {
             pretty.push_char('.');
-            pretty.push_str(pprust::path_to_str(&trait_ref.path).as_slice());
+            pretty.push_str(pprust::path_to_string(&trait_ref.path).as_slice());
         }
         None => {}
     }
     token::gensym_ident(pretty.as_slice())
 }
 
-pub fn public_methods(ms: Vec<Gc<Method>> ) -> Vec<Gc<Method>> {
-    ms.move_iter().filter(|m| {
-        match m.vis {
-            Public => true,
-            _   => false
-        }
-    }).collect()
-}
-
-// extract a TypeMethod from a TraitMethod. if the TraitMethod is
-// a default, pull out the useful fields to make a TypeMethod
+/// extract a TypeMethod from a TraitMethod. if the TraitMethod is
+/// a default, pull out the useful fields to make a TypeMethod
+//
+// NB: to be used only after expansion is complete, and macros are gone.
 pub fn trait_method_to_ty_method(method: &TraitMethod) -> TypeMethod {
     match *method {
         Required(ref m) => (*m).clone(),
-        Provided(ref m) => {
-            TypeMethod {
-                ident: m.ident,
-                attrs: m.attrs.clone(),
-                fn_style: m.fn_style,
-                decl: m.decl,
-                generics: m.generics.clone(),
-                explicit_self: m.explicit_self,
-                id: m.id,
-                span: m.span,
-                vis: m.vis,
+        Provided(m) => {
+            match m.node {
+                MethDecl(ident, ref generics, explicit_self, fn_style, decl, _, vis) => {
+                    TypeMethod {
+                        ident: ident,
+                        attrs: m.attrs.clone(),
+                        fn_style: fn_style,
+                        decl: decl,
+                        generics: generics.clone(),
+                        explicit_self: explicit_self,
+                        id: m.id,
+                        span: m.span,
+                        vis: vis,
+                    }
+                },
+                MethMac(_) => fail!("expected non-macro method declaration")
             }
+
         }
     }
 }
@@ -346,6 +345,9 @@ pub trait IdVisitingOperation {
     fn visit_id(&self, node_id: NodeId);
 }
 
+/// A visitor that applies its operation to all of the node IDs
+/// in a visitable thing.
+
 pub struct IdVisitor<'a, O> {
     pub operation: &'a O,
     pub pass_through_items: bool,
@@ -611,18 +613,18 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
     match pat.node {
         PatIdent(_, _, Some(ref p)) => walk_pat(&**p, it),
         PatStruct(_, ref fields, _) => {
-            fields.iter().advance(|f| walk_pat(&*f.pat, |p| it(p)))
+            fields.iter().all(|field| walk_pat(&*field.pat, |p| it(p)))
         }
         PatEnum(_, Some(ref s)) | PatTup(ref s) => {
-            s.iter().advance(|p| walk_pat(&**p, |p| it(p)))
+            s.iter().all(|p| walk_pat(&**p, |p| it(p)))
         }
         PatBox(ref s) | PatRegion(ref s) => {
             walk_pat(&**s, it)
         }
         PatVec(ref before, ref slice, ref after) => {
-            before.iter().advance(|p| walk_pat(&**p, |p| it(p))) &&
-                slice.iter().advance(|p| walk_pat(&**p, |p| it(p))) &&
-                after.iter().advance(|p| walk_pat(&**p, |p| it(p)))
+            before.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
+            slice.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
+            after.iter().all(|p| walk_pat(&**p, |p| it(p)))
         }
         PatMac(_) => fail!("attempted to analyze unexpanded pattern"),
         PatWild | PatWildMulti | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
@@ -705,7 +707,7 @@ pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> boo
     }
 }
 
-// Returns true if this literal is a string and false otherwise.
+/// Returns true if this literal is a string and false otherwise.
 pub fn lit_is_str(lit: Gc<Lit>) -> bool {
     match lit.node {
         LitStr(..) => true,
@@ -740,6 +742,38 @@ pub fn static_has_significant_address(mutbl: ast::Mutability,
     inline == InlineNever || inline == InlineNone
 }
 
+
+/// Macro invocations are guaranteed not to occur after expansion is complete.
+/// extracting fields of a method requires a dynamic check to make sure that it's
+/// not a macro invocation, though this check is guaranteed to succeed, assuming
+/// that the invocations are indeed gone.
+macro_rules! method_field_extractor {
+    ($fn_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => {
+        /// Returns the ident of a Method. To be used after expansion is complete
+        pub fn $fn_name<'a>(method: &'a ast::Method) -> $field_ty {
+            match method.node {
+                $field_pat => $result,
+                MethMac(_) => {
+                    fail!("expected an AST without macro invocations");
+                }
+            }
+        }
+    }
+}
+
+// Note: this is unhygienic in the lifetime 'a. In order to fix this, we'd have to
+// add :lifetime as a macro argument type, so that the 'a could be supplied by the macro
+// invocation.
+pub method_field_extractor!(method_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_),ident)
+pub method_field_extractor!(method_generics,&'a ast::Generics,
+                            MethDecl(_,ref generics,_,_,_,_,_),generics)
+pub method_field_extractor!(method_explicit_self,&'a ast::ExplicitSelf,
+                            MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
+pub method_field_extractor!(method_fn_style,ast::FnStyle,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
+pub method_field_extractor!(method_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,decl,_,_),decl)
+pub method_field_extractor!(method_body,P<ast::Block>,MethDecl(_,_,_,_,_,body,_),body)
+pub method_field_extractor!(method_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,vis),vis)
+
 #[cfg(test)]
 mod test {
     use ast::*;
@@ -754,14 +788,15 @@ fn ident_to_segment(id : &Ident) -> PathSegment {
 
     #[test] fn idents_name_eq_test() {
         assert!(segments_name_eq(
-            [Ident{name:3,ctxt:4}, Ident{name:78,ctxt:82}]
+            [Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
                 .iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice(),
-            [Ident{name:3,ctxt:104}, Ident{name:78,ctxt:182}]
+            [Ident{name:Name(3),ctxt:104}, Ident{name:Name(78),ctxt:182}]
                 .iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice()));
         assert!(!segments_name_eq(
-            [Ident{name:3,ctxt:4}, Ident{name:78,ctxt:82}]
+            [Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
                 .iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice(),
-            [Ident{name:3,ctxt:104}, Ident{name:77,ctxt:182}]
+            [Ident{name:Name(3),ctxt:104}, Ident{name:Name(77),ctxt:182}]
                 .iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice()));
     }
 }
+
index a037c0ac07e0e14864a0612ac902c60ec8208f6a..e8b9ec9628f7deba896a0b87283faf22dd264842 100644 (file)
@@ -18,7 +18,6 @@
 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use parse::token::InternedString;
 use parse::token;
-use crateid::CrateId;
 
 use std::collections::HashSet;
 use std::collections::BitvSet;
@@ -47,10 +46,8 @@ fn check_name(&self, name: &str) -> bool {
     /// #[foo="bar"] and #[foo(bar)]
     fn name(&self) -> InternedString;
 
-    /**
-     * Gets the string value if self is a MetaNameValue variant
-     * containing a string, otherwise None.
-     */
+    /// Gets the string value if self is a MetaNameValue variant
+    /// containing a string, otherwise None.
     fn value_str(&self) -> Option<InternedString>;
     /// Gets a list of inner meta items from a list MetaItem type.
     fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]>;
@@ -271,11 +268,8 @@ pub fn sort_meta_items(items: &[Gc<MetaItem>]) -> Vec<Gc<MetaItem>> {
     }).collect()
 }
 
-pub fn find_crateid(attrs: &[Attribute]) -> Option<CrateId> {
-    match first_attr_value_str_by_name(attrs, "crate_id") {
-        None => None,
-        Some(id) => from_str::<CrateId>(id.get()),
-    }
+pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
+    first_attr_value_str_by_name(attrs, "crate_name")
 }
 
 #[deriving(PartialEq)]
@@ -424,18 +418,16 @@ pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[Gc<MetaItem>]) {
 }
 
 
-/**
- * Fold this over attributes to parse #[repr(...)] forms.
- *
- * Valid repr contents: any of the primitive integral type names (see
- * `int_type_of_word`, below) to specify the discriminant type; and `C`, to use
- * the same discriminant size that the corresponding C enum would.  These are
- * not allowed on univariant or zero-variant enums, which have no discriminant.
- *
- * If a discriminant type is so specified, then the discriminant will be
- * present (before fields, if any) with that type; reprensentation
- * optimizations which would remove it will not be done.
- */
+/// Fold this over attributes to parse #[repr(...)] forms.
+///
+/// Valid repr contents: any of the primitive integral type names (see
+/// `int_type_of_word`, below) to specify the discriminant type; and `C`, to use
+/// the same discriminant size that the corresponding C enum would.  These are
+/// not allowed on univariant or zero-variant enums, which have no discriminant.
+///
+/// If a discriminant type is so specified, then the discriminant will be
+/// present (before fields, if any) with that type; reprensentation
+/// optimizations which would remove it will not be done.
 pub fn find_repr_attr(diagnostic: &SpanHandler, attr: &Attribute, acc: ReprAttr)
     -> ReprAttr {
     let mut acc = acc;
index c917198e7d4714fa31ab8ac82bee0e3687f7daf8..ef4024a8f83fe0cabb79fda2d0250998c747db17 100644 (file)
@@ -96,7 +96,7 @@ pub struct Span {
 
 pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None };
 
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct Spanned<T> {
     pub node: T,
     pub span: Span,
@@ -252,15 +252,15 @@ pub struct FileMap {
 }
 
 impl FileMap {
-    // EFFECT: register a start-of-line offset in the
-    // table of line-beginnings.
-    // UNCHECKED INVARIANT: these offsets must be added in the right
-    // order and must be in the right places; there is shared knowledge
-    // about what ends a line between this file and parse.rs
-    // WARNING: pos param here is the offset relative to start of CodeMap,
-    // and CodeMap will append a newline when adding a filemap without a newline at the end,
-    // so the safe way to call this is with value calculated as
-    // filemap.start_pos + newline_offset_relative_to_the_start_of_filemap.
+    /// EFFECT: register a start-of-line offset in the
+    /// table of line-beginnings.
+    /// UNCHECKED INVARIANT: these offsets must be added in the right
+    /// order and must be in the right places; there is shared knowledge
+    /// about what ends a line between this file and parse.rs
+    /// WARNING: pos param here is the offset relative to start of CodeMap,
+    /// and CodeMap will append a newline when adding a filemap without a newline at the end,
+    /// so the safe way to call this is with value calculated as
+    /// filemap.start_pos + newline_offset_relative_to_the_start_of_filemap.
     pub fn next_line(&self, pos: BytePos) {
         // the new charpos must be > the last one (or it's the first one).
         let mut lines = self.lines.borrow_mut();;
@@ -269,7 +269,7 @@ pub fn next_line(&self, pos: BytePos) {
         lines.push(pos);
     }
 
-    // get a line from the list of pre-computed line-beginnings
+    /// get a line from the list of pre-computed line-beginnings
     pub fn get_line(&self, line: int) -> String {
         let mut lines = self.lines.borrow_mut();
         let begin: BytePos = *lines.get(line as uint) - self.start_pos;
@@ -367,7 +367,7 @@ pub fn lookup_char_pos_adj(&self, pos: BytePos) -> LocWithOpt {
         }
     }
 
-    pub fn span_to_str(&self, sp: Span) -> String {
+    pub fn span_to_string(&self, sp: Span) -> String {
         if self.files.borrow().len() == 0 && sp == DUMMY_SP {
             return "no-location".to_string();
         }
@@ -428,9 +428,8 @@ pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos {
         FileMapAndBytePos {fm: fm, pos: offset}
     }
 
-    // Converts an absolute BytePos to a CharPos relative to the filemap and above.
+    /// Converts an absolute BytePos to a CharPos relative to the filemap and above.
     pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
-        debug!("codemap: converting {:?} to char pos", bpos);
         let idx = self.lookup_filemap_idx(bpos);
         let files = self.files.borrow();
         let map = files.get(idx);
@@ -439,7 +438,7 @@ pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
         let mut total_extra_bytes = 0;
 
         for mbc in map.multibyte_chars.borrow().iter() {
-            debug!("codemap: {:?}-byte char at {:?}", mbc.bytes, mbc.pos);
+            debug!("{}-byte char at {}", mbc.bytes, mbc.pos);
             if mbc.pos < bpos {
                 // every character is at least one byte, so we only
                 // count the actual extra bytes.
@@ -514,11 +513,11 @@ fn lookup_pos(&self, pos: BytePos) -> Loc {
         let chpos = self.bytepos_to_file_charpos(pos);
         let linebpos = *f.lines.borrow().get(a);
         let linechpos = self.bytepos_to_file_charpos(linebpos);
-        debug!("codemap: byte pos {:?} is on the line at byte pos {:?}",
+        debug!("byte pos {} is on the line at byte pos {}",
                pos, linebpos);
-        debug!("codemap: char pos {:?} is on the line at char pos {:?}",
+        debug!("char pos {} is on the line at char pos {}",
                chpos, linechpos);
-        debug!("codemap: byte is on line: {:?}", line);
+        debug!("byte is on line: {}", line);
         assert!(chpos >= linechpos);
         Loc {
             file: f,
@@ -687,7 +686,7 @@ fn t9() {
         // Test span_to_str for a span ending at the end of filemap
         let cm = init_code_map();
         let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
-        let sstr =  cm.span_to_str(span);
+        let sstr =  cm.span_to_string(span);
 
         assert_eq!(sstr, "blork.rs:2:1: 2:12".to_string());
     }
index dfaa9fb5fcb09507f31144396946f7708b588c40..9bb5eae2ed2d66c893378ee316e419c01e53f90b 100644 (file)
@@ -12,6 +12,7 @@
 
 use codemap::{Pos, Span};
 use codemap;
+use diagnostics;
 
 use std::cell::{RefCell, Cell};
 use std::fmt;
@@ -21,7 +22,7 @@
 use term::WriterWrapper;
 use term;
 
-// maximum number of lines we will print for each error; arbitrary.
+/// maximum number of lines we will print for each error; arbitrary.
 static MAX_LINES: uint = 6u;
 
 #[deriving(Clone)]
@@ -59,7 +60,7 @@ pub enum ColorConfig {
 
 pub trait Emitter {
     fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>,
-            msg: &str, lvl: Level);
+            msg: &str, code: Option<&str>, lvl: Level);
     fn custom_emit(&mut self, cm: &codemap::CodeMap,
                    sp: RenderSpan, msg: &str, lvl: Level);
 }
@@ -73,9 +74,9 @@ fn custom_emit(&mut self, cm: &codemap::CodeMap,
 /// or `.span_bug` rather than a failed assertion, etc.
 pub struct ExplicitBug;
 
-// a span-handler is like a handler but also
-// accepts span information for source-location
-// reporting.
+/// A span-handler is like a handler but also
+/// accepts span information for source-location
+/// reporting.
 pub struct SpanHandler {
     pub handler: Handler,
     pub cm: codemap::CodeMap,
@@ -90,6 +91,10 @@ pub fn span_err(&self, sp: Span, msg: &str) {
         self.handler.emit(Some((&self.cm, sp)), msg, Error);
         self.handler.bump_err_count();
     }
+    pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
+        self.handler.emit_with_code(Some((&self.cm, sp)), msg, code, Error);
+        self.handler.bump_err_count();
+    }
     pub fn span_warn(&self, sp: Span, msg: &str) {
         self.handler.emit(Some((&self.cm, sp)), msg, Warning);
     }
@@ -114,9 +119,9 @@ pub fn handler<'a>(&'a self) -> &'a Handler {
     }
 }
 
-// a handler deals with errors; certain errors
-// (fatal, bug, unimpl) may cause immediate exit,
-// others log errors for later reporting.
+/// A handler deals with errors; certain errors
+/// (fatal, bug, unimpl) may cause immediate exit,
+/// others log errors for later reporting.
 pub struct Handler {
     err_count: Cell<uint>,
     emit: RefCell<Box<Emitter + Send>>,
@@ -124,11 +129,11 @@ pub struct Handler {
 
 impl Handler {
     pub fn fatal(&self, msg: &str) -> ! {
-        self.emit.borrow_mut().emit(None, msg, Fatal);
+        self.emit.borrow_mut().emit(None, msg, None, Fatal);
         fail!(FatalError);
     }
     pub fn err(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, Error);
+        self.emit.borrow_mut().emit(None, msg, None, Error);
         self.bump_err_count();
     }
     pub fn bump_err_count(&self) {
@@ -153,13 +158,13 @@ pub fn abort_if_errors(&self) {
         self.fatal(s.as_slice());
     }
     pub fn warn(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, Warning);
+        self.emit.borrow_mut().emit(None, msg, None, Warning);
     }
     pub fn note(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, Note);
+        self.emit.borrow_mut().emit(None, msg, None, Note);
     }
     pub fn bug(&self, msg: &str) -> ! {
-        self.emit.borrow_mut().emit(None, msg, Bug);
+        self.emit.borrow_mut().emit(None, msg, None, Bug);
         fail!(ExplicitBug);
     }
     pub fn unimpl(&self, msg: &str) -> ! {
@@ -169,7 +174,14 @@ pub fn emit(&self,
                 cmsp: Option<(&codemap::CodeMap, Span)>,
                 msg: &str,
                 lvl: Level) {
-        self.emit.borrow_mut().emit(cmsp, msg, lvl);
+        self.emit.borrow_mut().emit(cmsp, msg, None, lvl);
+    }
+    pub fn emit_with_code(&self,
+                          cmsp: Option<(&codemap::CodeMap, Span)>,
+                          msg: &str,
+                          code: &str,
+                          lvl: Level) {
+        self.emit.borrow_mut().emit(cmsp, msg, Some(code), lvl);
     }
     pub fn custom_emit(&self, cm: &codemap::CodeMap,
                        sp: RenderSpan, msg: &str, lvl: Level) {
@@ -184,8 +196,9 @@ pub fn mk_span_handler(handler: Handler, cm: codemap::CodeMap) -> SpanHandler {
     }
 }
 
-pub fn default_handler(color_config: ColorConfig) -> Handler {
-    mk_handler(box EmitterWriter::stderr(color_config))
+pub fn default_handler(color_config: ColorConfig,
+                       registry: Option<diagnostics::registry::Registry>) -> Handler {
+    mk_handler(box EmitterWriter::stderr(color_config, registry))
 }
 
 pub fn mk_handler(e: Box<Emitter + Send>) -> Handler {
@@ -262,23 +275,42 @@ fn print_maybe_styled(w: &mut EmitterWriter,
     }
 }
 
-fn print_diagnostic(dst: &mut EmitterWriter,
-                    topic: &str, lvl: Level, msg: &str) -> io::IoResult<()> {
+fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
+                    msg: &str, code: Option<&str>) -> io::IoResult<()> {
     if !topic.is_empty() {
         try!(write!(&mut dst.dst, "{} ", topic));
     }
 
     try!(print_maybe_styled(dst,
-                            format!("{}: ", lvl.to_str()).as_slice(),
+                            format!("{}: ", lvl.to_string()).as_slice(),
                             term::attr::ForegroundColor(lvl.color())));
     try!(print_maybe_styled(dst,
-                            format!("{}\n", msg).as_slice(),
+                            format!("{}", msg).as_slice(),
                             term::attr::Bold));
+
+    match code {
+        Some(code) => {
+            let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
+            try!(print_maybe_styled(dst, format!(" [{}]", code.clone()).as_slice(), style));
+            match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
+                Some(_) => {
+                    try!(write!(&mut dst.dst,
+                        " (pass `--explain {}` to see a detailed explanation)",
+                        code
+                    ));
+                }
+                None => ()
+            }
+        }
+        None => ()
+    }
+    try!(dst.dst.write_char('\n'));
     Ok(())
 }
 
 pub struct EmitterWriter {
     dst: Destination,
+    registry: Option<diagnostics::registry::Registry>
 }
 
 enum Destination {
@@ -287,7 +319,8 @@ enum Destination {
 }
 
 impl EmitterWriter {
-    pub fn stderr(color_config: ColorConfig) -> EmitterWriter {
+    pub fn stderr(color_config: ColorConfig,
+                  registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
         let stderr = io::stderr();
 
         let use_color = match color_config {
@@ -301,14 +334,15 @@ pub fn stderr(color_config: ColorConfig) -> EmitterWriter {
                 Some(t) => Terminal(t),
                 None    => Raw(box stderr),
             };
-            EmitterWriter { dst: dst }
+            EmitterWriter { dst: dst, registry: registry }
         } else {
-            EmitterWriter { dst: Raw(box stderr) }
+            EmitterWriter { dst: Raw(box stderr), registry: registry }
         }
     }
 
-    pub fn new(dst: Box<Writer + Send>) -> EmitterWriter {
-        EmitterWriter { dst: Raw(dst) }
+    pub fn new(dst: Box<Writer + Send>,
+               registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
+        EmitterWriter { dst: Raw(dst), registry: registry }
     }
 }
 
@@ -324,11 +358,10 @@ fn write(&mut self, bytes: &[u8]) -> io::IoResult<()> {
 impl Emitter for EmitterWriter {
     fn emit(&mut self,
             cmsp: Option<(&codemap::CodeMap, Span)>,
-            msg: &str,
-            lvl: Level) {
+            msg: &str, code: Option<&str>, lvl: Level) {
         let error = match cmsp {
-            Some((cm, sp)) => emit(self, cm, FullSpan(sp), msg, lvl, false),
-            None => print_diagnostic(self, "", lvl, msg),
+            Some((cm, sp)) => emit(self, cm, FullSpan(sp), msg, code, lvl, false),
+            None => print_diagnostic(self, "", lvl, msg, code),
         };
 
         match error {
@@ -339,7 +372,7 @@ fn emit(&mut self,
 
     fn custom_emit(&mut self, cm: &codemap::CodeMap,
                    sp: RenderSpan, msg: &str, lvl: Level) {
-        match emit(self, cm, sp, msg, lvl, true) {
+        match emit(self, cm, sp, msg, None, lvl, true) {
             Ok(()) => {}
             Err(e) => fail!("failed to print diagnostics: {}", e),
         }
@@ -347,22 +380,22 @@ fn custom_emit(&mut self, cm: &codemap::CodeMap,
 }
 
 fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
-        msg: &str, lvl: Level, custom: bool) -> io::IoResult<()> {
+        msg: &str, code: Option<&str>, lvl: Level, custom: bool) -> io::IoResult<()> {
     let sp = rsp.span();
-    let ss = cm.span_to_str(sp);
+    let ss = cm.span_to_string(sp);
     let lines = cm.span_to_lines(sp);
     if custom {
         // we want to tell compiletest/runtest to look at the last line of the
         // span (since `custom_highlight_lines` displays an arrow to the end of
         // the span)
         let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
-        let ses = cm.span_to_str(span_end);
-        try!(print_diagnostic(dst, ses.as_slice(), lvl, msg));
+        let ses = cm.span_to_string(span_end);
+        try!(print_diagnostic(dst, ses.as_slice(), lvl, msg, code));
         if rsp.is_full_span() {
             try!(custom_highlight_lines(dst, cm, sp, lvl, lines));
         }
     } else {
-        try!(print_diagnostic(dst, ss.as_slice(), lvl, msg));
+        try!(print_diagnostic(dst, ss.as_slice(), lvl, msg, code));
         if rsp.is_full_span() {
             try!(highlight_lines(dst, cm, sp, lvl, lines));
         }
@@ -442,12 +475,12 @@ fn highlight_lines(err: &mut EmitterWriter,
     Ok(())
 }
 
-// Here are the differences between this and the normal `highlight_lines`:
-// `custom_highlight_lines` will always put arrow on the last byte of the
-// span (instead of the first byte). Also, when the span is too long (more
-// than 6 lines), `custom_highlight_lines` will print the first line, then
-// dot dot dot, then last line, whereas `highlight_lines` prints the first
-// six lines.
+/// Here are the differences between this and the normal `highlight_lines`:
+/// `custom_highlight_lines` will always put arrow on the last byte of the
+/// span (instead of the first byte). Also, when the span is too long (more
+/// than 6 lines), `custom_highlight_lines` will print the first line, then
+/// dot dot dot, then last line, whereas `highlight_lines` prints the first
+/// six lines.
 fn custom_highlight_lines(w: &mut EmitterWriter,
                           cm: &codemap::CodeMap,
                           sp: Span,
@@ -493,7 +526,7 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
         let ss = ei.callee
                    .span
                    .as_ref()
-                   .map_or("".to_string(), |span| cm.span_to_str(*span));
+                   .map_or("".to_string(), |span| cm.span_to_string(*span));
         let (pre, post) = match ei.callee.format {
             codemap::MacroAttribute => ("#[", "]"),
             codemap::MacroBang => ("", "!")
@@ -501,9 +534,9 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
         try!(print_diagnostic(w, ss.as_slice(), Note,
                               format!("in expansion of {}{}{}", pre,
                                       ei.callee.name,
-                                      post).as_slice()));
-        let ss = cm.span_to_str(ei.call_site);
-        try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site"));
+                                      post).as_slice(), None));
+        let ss = cm.span_to_string(ei.call_site);
+        try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None));
         try!(print_macro_backtrace(w, cm, ei.call_site));
     }
     Ok(())
diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs
new file mode 100644 (file)
index 0000000..b0260e1
--- /dev/null
@@ -0,0 +1,51 @@
+// 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.
+
+#![macro_escape]
+
+// NOTE: remove after next snapshot
+#[cfg(stage0)]
+#[macro_export]
+macro_rules! __register_diagnostic(
+    ($code:tt, $description:tt) => ();
+    ($code:tt) => ()
+)
+
+#[macro_export]
+macro_rules! register_diagnostic(
+    ($code:tt, $description:tt) => (__register_diagnostic!($code, $description));
+    ($code:tt) => (__register_diagnostic!($code))
+)
+
+// NOTE: remove after next snapshot
+#[cfg(stage0)]
+#[macro_export]
+macro_rules! __build_diagnostic_array(
+    ($name:ident) => {
+        pub static $name: [(&'static str, &'static str), ..0] = [];
+    }
+)
+
+// NOTE: remove after next snapshot
+#[cfg(stage0)]
+#[macro_export]
+macro_rules! __diagnostic_used(
+    ($code:ident) => {
+        ()
+    }
+)
+
+#[macro_export]
+macro_rules! span_err(
+    ($session:expr, $span:expr, $code:ident, $($arg:expr),*) => ({
+        __diagnostic_used!($code);
+        ($session).span_err_with_code($span, format!($($arg),*).as_slice(), stringify!($code))
+    })
+)
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
new file mode 100644 (file)
index 0000000..6582d2e
--- /dev/null
@@ -0,0 +1,132 @@
+// 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 std::cell::RefCell;
+use std::collections::HashMap;
+use std::gc::Gc;
+use ast;
+use ast::{Ident, Name, TokenTree};
+use codemap::Span;
+use ext::base::{ExtCtxt, MacExpr, MacItem, MacResult};
+use ext::build::AstBuilder;
+use parse::token;
+
+local_data_key!(registered_diagnostics: RefCell<HashMap<Name, Option<Name>>>)
+local_data_key!(used_diagnostics: RefCell<HashMap<Name, Span>>)
+
+fn with_registered_diagnostics<T>(f: |&mut HashMap<Name, Option<Name>>| -> T) -> T {
+    match registered_diagnostics.get() {
+        Some(cell) => f(cell.borrow_mut().deref_mut()),
+        None => {
+            let mut map = HashMap::new();
+            let value = f(&mut map);
+            registered_diagnostics.replace(Some(RefCell::new(map)));
+            value
+        }
+    }
+}
+
+fn with_used_diagnostics<T>(f: |&mut HashMap<Name, Span>| -> T) -> T {
+    match used_diagnostics.get() {
+        Some(cell) => f(cell.borrow_mut().deref_mut()),
+        None => {
+            let mut map = HashMap::new();
+            let value = f(&mut map);
+            used_diagnostics.replace(Some(RefCell::new(map)));
+            value
+        }
+    }
+}
+
+pub fn expand_diagnostic_used(ecx: &mut ExtCtxt, span: Span,
+                              token_tree: &[TokenTree]) -> Box<MacResult> {
+    let code = match token_tree {
+        [ast::TTTok(_, token::IDENT(code, _))] => code,
+        _ => unreachable!()
+    };
+    with_registered_diagnostics(|diagnostics| {
+        if !diagnostics.contains_key(&code.name) {
+            ecx.span_err(span, format!(
+                "unknown diagnostic code {}", token::get_ident(code).get()
+            ).as_slice());
+        }
+        ()
+    });
+    with_used_diagnostics(|diagnostics| {
+        match diagnostics.swap(code.name, span) {
+            Some(previous_span) => {
+                ecx.span_warn(span, format!(
+                    "diagnostic code {} already used", token::get_ident(code).get()
+                ).as_slice());
+                ecx.span_note(previous_span, "previous invocation");
+            },
+            None => ()
+        }
+        ()
+    });
+    MacExpr::new(quote_expr!(ecx, ()))
+}
+
+pub fn expand_register_diagnostic(ecx: &mut ExtCtxt, span: Span,
+                                  token_tree: &[TokenTree]) -> Box<MacResult> {
+    let (code, description) = match token_tree {
+        [ast::TTTok(_, token::IDENT(ref code, _))] => {
+            (code, None)
+        },
+        [ast::TTTok(_, token::IDENT(ref code, _)),
+         ast::TTTok(_, token::COMMA),
+         ast::TTTok(_, token::LIT_STR_RAW(description, _))] => {
+            (code, Some(description))
+        }
+        _ => unreachable!()
+    };
+    with_registered_diagnostics(|diagnostics| {
+        if !diagnostics.insert(code.name, description) {
+            ecx.span_err(span, format!(
+                "diagnostic code {} already registered", token::get_ident(*code).get()
+            ).as_slice());
+        }
+    });
+    let sym = Ident::new(token::gensym((
+        "__register_diagnostic_".to_string() + token::get_ident(*code).get()
+    ).as_slice()));
+    MacItem::new(quote_item!(ecx, mod $sym {}).unwrap())
+}
+
+pub fn expand_build_diagnostic_array(ecx: &mut ExtCtxt, span: Span,
+                                     token_tree: &[TokenTree]) -> Box<MacResult> {
+    let name = match token_tree {
+        [ast::TTTok(_, token::IDENT(ref name, _))] => name,
+        _ => unreachable!()
+    };
+
+    let (count, expr) = with_used_diagnostics(|diagnostics_in_use| {
+        with_registered_diagnostics(|diagnostics| {
+            let descriptions: Vec<Gc<ast::Expr>> = diagnostics
+                .iter().filter_map(|(code, description)| {
+                if !diagnostics_in_use.contains_key(code) {
+                    ecx.span_warn(span, format!(
+                        "diagnostic code {} never used", token::get_name(*code).get()
+                    ).as_slice());
+                }
+                description.map(|description| {
+                    ecx.expr_tuple(span, vec![
+                        ecx.expr_str(span, token::get_name(*code)),
+                        ecx.expr_str(span, token::get_name(description))
+                    ])
+                })
+            }).collect();
+            (descriptions.len(), ecx.expr_vec(span, descriptions))
+        })
+    });
+    MacItem::new(quote_item!(ecx,
+        pub static $name: [(&'static str, &'static str), ..$count] = $expr;
+    ).unwrap())
+}
diff --git a/src/libsyntax/diagnostics/registry.rs b/src/libsyntax/diagnostics/registry.rs
new file mode 100644 (file)
index 0000000..7bc191d
--- /dev/null
@@ -0,0 +1,25 @@
+// 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 std::collections::HashMap;
+
+pub struct Registry {
+    descriptions: HashMap<&'static str, &'static str>
+}
+
+impl Registry {
+    pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry {
+        Registry { descriptions: descriptions.iter().map(|&tuple| tuple).collect() }
+    }
+
+    pub fn find_description(&self, code: &str) -> Option<&'static str> {
+        self.descriptions.find_equiv(&code).map(|desc| *desc)
+    }
+}
index f0494e181201375096c9e0417a84bce1ba43fb07..13738e658e9f97fd7edd5563cab06ec71cf1e8b6 100644 (file)
@@ -64,7 +64,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     'statement: loop {
         match state {
             Asm => {
-                let (s, style) = match expr_to_str(cx, p.parse_expr(),
+                let (s, style) = match expr_to_string(cx, p.parse_expr(),
                                                    "inline assembly must be a string literal.") {
                     Some((s, st)) => (s, st),
                     // let compilation continue
@@ -205,7 +205,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     // Append an input operand, with the form of ("0", expr)
     // that links to an output operand.
     for &(i, out) in read_write_operands.iter() {
-        inputs.push((token::intern_and_get_ident(i.to_str().as_slice()),
+        inputs.push((token::intern_and_get_ident(i.to_string().as_slice()),
                                                  out));
     }
 
index d2e69204d333cb5cb0374857bdf9c456a0d22492..56484c4ba59dfbbda0fd1d290ad5e269374260c3 100644 (file)
@@ -19,6 +19,7 @@
 use parse::token;
 use parse::token::{InternedString, intern, str_to_ident};
 use util::small_vector::SmallVector;
+use ext::mtwt;
 
 use std::collections::HashMap;
 use std::gc::{Gc, GC};
@@ -47,7 +48,8 @@ pub struct BasicMacroExpander {
     pub span: Option<Span>
 }
 
-pub trait MacroExpander {
+/// Represents a thing that maps token trees to Macro Results
+pub trait TTMacroExpander {
     fn expand(&self,
               ecx: &mut ExtCtxt,
               span: Span,
@@ -59,7 +61,7 @@ fn expand(&self,
     fn(ecx: &mut ExtCtxt, span: codemap::Span, token_tree: &[ast::TokenTree])
        -> Box<MacResult>;
 
-impl MacroExpander for BasicMacroExpander {
+impl TTMacroExpander for BasicMacroExpander {
     fn expand(&self,
               ecx: &mut ExtCtxt,
               span: Span,
@@ -102,6 +104,9 @@ fn expand(&self,
 /// just into the compiler's internal macro table, for `make_def`).
 pub trait MacResult {
     /// Define a new macro.
+    // this should go away; the idea that a macro might expand into
+    // either a macro definition or an expression, depending on what
+    // the context wants, is kind of silly.
     fn make_def(&self) -> Option<MacroDef> {
         None
     }
@@ -113,6 +118,12 @@ fn make_expr(&self) -> Option<Gc<ast::Expr>> {
     fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
         None
     }
+
+    /// Create zero or more methods.
+    fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> {
+        None
+    }
+
     /// Create a pattern.
     fn make_pat(&self) -> Option<Gc<ast::Pat>> {
         None
@@ -220,6 +231,7 @@ pub fn raw_pat(sp: Span) -> Gc<ast::Pat> {
             span: sp,
         }
     }
+
 }
 
 impl MacResult for DummyResult {
@@ -230,6 +242,14 @@ fn make_pat(&self) -> Option<Gc<ast::Pat>> {
         Some(DummyResult::raw_pat(self.span))
     }
     fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
+        // this code needs a comment... why not always just return the Some() ?
+        if self.expr_only {
+            None
+        } else {
+            Some(SmallVector::zero())
+        }
+    }
+    fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> {
         if self.expr_only {
             None
         } else {
@@ -258,22 +278,29 @@ pub enum SyntaxExtension {
     /// A normal, function-like syntax extension.
     ///
     /// `bytes!` is a `NormalTT`.
-    NormalTT(Box<MacroExpander + 'static>, Option<Span>),
+    NormalTT(Box<TTMacroExpander + 'static>, Option<Span>),
 
     /// A function-like syntax extension that has an extra ident before
     /// the block.
     ///
-    /// `macro_rules!` is an `IdentTT`.
     IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>),
+
+    /// An ident macro that has two properties:
+    /// - it adds a macro definition to the environment, and
+    /// - the definition it adds doesn't introduce any new
+    ///   identifiers.
+    ///
+    /// `macro_rules!` is a LetSyntaxTT
+    LetSyntaxTT(Box<IdentMacroExpander + 'static>, Option<Span>),
 }
 
 pub type NamedSyntaxExtension = (Name, SyntaxExtension);
 
 pub struct BlockInfo {
-    // should macros escape from this scope?
+    /// Should macros escape from this scope?
     pub macros_escape: bool,
-    // what are the pending renames?
-    pub pending_renames: RenameList,
+    /// What are the pending renames?
+    pub pending_renames: mtwt::RenameList,
 }
 
 impl BlockInfo {
@@ -285,11 +312,8 @@ pub fn new() -> BlockInfo {
     }
 }
 
-// a list of ident->name renamings
-pub type RenameList = Vec<(ast::Ident, Name)>;
-
-// The base map of methods for expanding syntax extension
-// AST nodes into full ASTs
+/// The base map of methods for expanding syntax extension
+/// AST nodes into full ASTs
 pub fn syntax_expander_table() -> SyntaxEnv {
     // utility function to simplify creating NormalTT syntax extensions
     fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
@@ -302,7 +326,7 @@ fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
 
     let mut syntax_expanders = SyntaxEnv::new();
     syntax_expanders.insert(intern("macro_rules"),
-                            IdentTT(box BasicIdentMacroExpander {
+                            LetSyntaxTT(box BasicIdentMacroExpander {
                                 expander: ext::tt::macro_rules::add_new_extension,
                                 span: None,
                             },
@@ -393,9 +417,9 @@ fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
     syntax_expanders
 }
 
-// One of these is made during expansion and incrementally updated as we go;
-// when a macro expansion occurs, the resulting nodes have the backtrace()
-// -> expn_info of their expansion context stored into their span.
+/// One of these is made during expansion and incrementally updated as we go;
+/// when a macro expansion occurs, the resulting nodes have the backtrace()
+/// -> expn_info of their expansion context stored into their span.
 pub struct ExtCtxt<'a> {
     pub parse_sess: &'a parse::ParseSess,
     pub cfg: ast::CrateConfig,
@@ -404,6 +428,7 @@ pub struct ExtCtxt<'a> {
 
     pub mod_path: Vec<ast::Ident> ,
     pub trace_mac: bool,
+    pub exported_macros: Vec<codemap::Span>
 }
 
 impl<'a> ExtCtxt<'a> {
@@ -415,7 +440,8 @@ pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
             backtrace: None,
             mod_path: Vec::new(),
             ecfg: ecfg,
-            trace_mac: false
+            trace_mac: false,
+            exported_macros: Vec::new(),
         }
     }
 
@@ -454,7 +480,7 @@ pub fn backtrace(&self) -> Option<Gc<ExpnInfo>> { self.backtrace }
     pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
     pub fn mod_path(&self) -> Vec<ast::Ident> {
         let mut v = Vec::new();
-        v.push(token::str_to_ident(self.ecfg.crate_id.name.as_slice()));
+        v.push(token::str_to_ident(self.ecfg.crate_name.as_slice()));
         v.extend(self.mod_path.iter().map(|a| *a));
         return v;
     }
@@ -530,12 +556,18 @@ pub fn set_trace_macros(&mut self, x: bool) {
     pub fn ident_of(&self, st: &str) -> ast::Ident {
         str_to_ident(st)
     }
+    pub fn name_of(&self, st: &str) -> ast::Name {
+        token::intern(st)
+    }
+    pub fn push_exported_macro(&mut self, span: codemap::Span) {
+        self.exported_macros.push(span);
+    }
 }
 
 /// Extract a string literal from the macro expanded version of `expr`,
 /// emitting `err_msg` if `expr` is not a string literal. This does not stop
 /// compilation on error, merely emits a non-fatal error and returns None.
-pub fn expr_to_str(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str)
+pub fn expr_to_string(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str)
                    -> Option<(InternedString, ast::StrStyle)> {
     // we want to be able to handle e.g. concat("foo", "bar")
     let expr = cx.expand_expr(expr);
@@ -574,9 +606,9 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt,
         cx.span_err(sp, format!("{} takes 1 argument.", name).as_slice());
     } else {
         match tts[0] {
-            ast::TTTok(_, token::LIT_STR(ident))
-            ast::TTTok(_, token::LIT_STR_RAW(ident, _)) => {
-                return Some(token::get_ident(ident).get().to_string())
+            ast::TTTok(_, token::LIT_STR(ident)) => return Some(parse::str_lit(ident.as_str())),
+            ast::TTTok(_, token::LIT_STR_RAW(ident, _)) => {
+                return Some(parse::raw_str_lit(ident.as_str()))
             }
             _ => {
                 cx.span_err(sp,
@@ -607,11 +639,11 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
     Some(es)
 }
 
-// in order to have some notion of scoping for macros,
-// we want to implement the notion of a transformation
-// environment.
+/// In order to have some notion of scoping for macros,
+/// we want to implement the notion of a transformation
+/// environment.
 
-// This environment maps Names to SyntaxExtensions.
+/// This environment maps Names to SyntaxExtensions.
 
 //impl question: how to implement it? Initially, the
 // env will contain only macros, so it might be painful
@@ -628,7 +660,6 @@ struct MapChainFrame {
     map: HashMap<Name, SyntaxExtension>,
 }
 
-// Only generic to make it easy to test
 pub struct SyntaxEnv {
     chain: Vec<MapChainFrame> ,
 }
index 46bc4ec11ce4f044ac14b35d1f603042558bf089..4d3913da3656a2c90e048c6276665be2a045f05b 100644 (file)
@@ -66,8 +66,8 @@ fn ty_rptr(&self, span: Span,
     fn typaram(&self,
                span: Span,
                id: ast::Ident,
-               sized: ast::Sized,
                bounds: OwnedSlice<ast::TyParamBound>,
+               unbound: Option<ast::TyParamBound>,
                default: Option<P<ast::Ty>>) -> ast::TyParam;
 
     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
@@ -148,6 +148,8 @@ fn expr_struct_ident(&self, span: Span, id: ast::Ident,
     fn expr_some(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
     fn expr_none(&self, sp: Span) -> Gc<ast::Expr>;
 
+    fn expr_tuple(&self, sp: Span, exprs: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
+
     fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr>;
     fn expr_unreachable(&self, span: Span) -> Gc<ast::Expr>;
 
@@ -396,14 +398,14 @@ fn ty_nil(&self) -> P<ast::Ty> {
     fn typaram(&self,
                span: Span,
                id: ast::Ident,
-               sized: ast::Sized,
                bounds: OwnedSlice<ast::TyParamBound>,
+               unbound: Option<ast::TyParamBound>,
                default: Option<P<ast::Ty>>) -> ast::TyParam {
         ast::TyParam {
             ident: id,
             id: ast::DUMMY_NODE_ID,
-            sized: sized,
             bounds: bounds,
+            unbound: unbound,
             default: default,
             span: span
         }
@@ -423,7 +425,7 @@ fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>
 
     fn strip_bounds(&self, generics: &Generics) -> Generics {
         let new_params = generics.ty_params.map(|ty_param| {
-            ast::TyParam { bounds: OwnedSlice::empty(), ..*ty_param }
+            ast::TyParam { bounds: OwnedSlice::empty(), unbound: None, ..*ty_param }
         });
         Generics {
             ty_params: new_params,
@@ -674,6 +676,10 @@ fn expr_none(&self, sp: Span) -> Gc<ast::Expr> {
         self.expr_path(none)
     }
 
+    fn expr_tuple(&self, sp: Span, exprs: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr> {
+        self.expr(sp, ast::ExprTup(exprs))
+    }
+
     fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr> {
         let loc = self.codemap().lookup_char_pos(span.lo);
         self.expr_call_global(
index 93e4920bc1de43f5df09cda2be599d4018d10e3c..bbe96018f4b3ddbd080bee76e71ffc5eaddd0b74 100644 (file)
@@ -39,7 +39,6 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                 args: Vec::new(),
                 ret_ty: Self,
                 attributes: attrs,
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|c, s, sub| {
                     cs_clone("Clone", c, s, sub)
                 }),
@@ -69,7 +68,7 @@ fn cs_clone(
             ctor_ident = variant.node.name;
             all_fields = af;
         },
-        EnumNonMatching(..) => {
+        EnumNonMatchingCollapsed (..) => {
             cx.span_bug(trait_span,
                         format!("non-matching enum variants in \
                                  `deriving({})`",
index ef8d477a98e678f83e9ecd3108c5ca5cf3c44857..19a979a5655ba060912d52838fa8b6faabc1701e 100644 (file)
@@ -45,7 +45,6 @@ macro_rules! md (
                 args: vec!(borrowed_self()),
                 ret_ty: Literal(Path::new(vec!("bool"))),
                 attributes: attrs,
-                const_nonmatching: true,
                 combine_substructure: combine_substructure(|a, b, c| {
                     $f(a, b, c)
                 })
index 59cdec1ea88f07f240ad27aca105053111f6b475..dcf59ba820e4cc39c0a81dd85844e00890fed6de 100644 (file)
@@ -35,7 +35,6 @@ macro_rules! md (
                 args: vec!(borrowed_self()),
                 ret_ty: Literal(Path::new(vec!("bool"))),
                 attributes: attrs,
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|cx, span, substr| {
                     cs_op($op, $equal, cx, span, substr)
                 })
@@ -59,7 +58,6 @@ macro_rules! md (
         args: vec![borrowed_self()],
         ret_ty: ret_ty,
         attributes: attrs,
-        const_nonmatching: false,
         combine_substructure: combine_substructure(|cx, span, substr| {
             cs_partial_cmp(cx, span, substr)
         })
@@ -82,24 +80,33 @@ macro_rules! md (
     trait_def.expand(cx, mitem, item, push)
 }
 
-pub fn some_ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> Gc<ast::Expr> {
-    let cnst = match cnst {
-        Less => "Less",
-        Equal => "Equal",
-        Greater => "Greater"
+pub enum OrderingOp {
+    PartialCmpOp, LtOp, LeOp, GtOp, GeOp,
+}
+
+pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
+                               span: Span,
+                               op: OrderingOp,
+                               self_arg_tags: &[ast::Ident]) -> Gc<ast::Expr> {
+    let lft = cx.expr_ident(span, self_arg_tags[0]);
+    let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
+    let op_str = match op {
+        PartialCmpOp => "partial_cmp",
+        LtOp => "lt", LeOp => "le",
+        GtOp => "gt", GeOp => "ge",
     };
-    let ordering = cx.path_global(span,
-                                  vec!(cx.ident_of("std"),
-                                       cx.ident_of("cmp"),
-                                       cx.ident_of(cnst)));
-    let ordering = cx.expr_path(ordering);
-    cx.expr_some(span, ordering)
+    cx.expr_method_call(span, lft, cx.ident_of(op_str), vec![rgt])
 }
 
 pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
               substr: &Substructure) -> Gc<Expr> {
     let test_id = cx.ident_of("__test");
-    let equals_expr = some_ordering_const(cx, span, Equal);
+    let ordering = cx.path_global(span,
+                                  vec!(cx.ident_of("std"),
+                                       cx.ident_of("cmp"),
+                                       cx.ident_of("Equal")));
+    let ordering = cx.expr_path(ordering);
+    let equals_expr = cx.expr_some(span, ordering);
 
     /*
     Builds:
@@ -141,13 +148,11 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
             cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
         },
         equals_expr.clone(),
-        |cx, span, list, _| {
-            match list {
-                // an earlier nonmatching variant is Less than a
-                // later one.
-                [(self_var, _, _), (other_var, _, _)] =>
-                     some_ordering_const(cx, span, self_var.cmp(&other_var)),
-                _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+        |cx, span, (self_args, tag_tuple), _non_self_args| {
+            if self_args.len() != 2 {
+                cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+            } else {
+                some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
             }
         },
         cx, span, substr)
@@ -191,19 +196,15 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span,
             cx.expr_binary(span, ast::BiOr, cmp, and)
         },
         cx.expr_bool(span, equal),
-        |cx, span, args, _| {
-            // nonmatching enums, order by the order the variants are
-            // written
-            match args {
-                [(self_var, _, _),
-                 (other_var, _, _)] =>
-                    cx.expr_bool(span,
-                                 if less {
-                                     self_var < other_var
-                                 } else {
-                                     self_var > other_var
-                                 }),
-                _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+        |cx, span, (self_args, tag_tuple), _non_self_args| {
+            if self_args.len() != 2 {
+                cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+            } else {
+                let op = match (less, equal) {
+                    (true,  true) => LeOp, (true,  false) => LtOp,
+                    (false, true) => GeOp, (false, false) => GtOp,
+                };
+                some_ordering_collapsed(cx, span, op, tag_tuple)
             }
         },
         cx, span, substr)
index 8b1e0498d253c43907b43ce5dc0ae37c2b0ae89d..42365936c9d4f5e56507ef736b2ea6bb8d8ff5bc 100644 (file)
@@ -57,7 +57,6 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span,
                 args: vec!(),
                 ret_ty: nil_ty(),
                 attributes: attrs,
-                const_nonmatching: true,
                 combine_substructure: combine_substructure(|a, b, c| {
                     cs_total_eq_assert(a, b, c)
                 })
index 271aa90cd24a4f5ea1114745a08fdedd16cbc3c7..e010b635fe41a666244d7c82fd45458fceefdcea 100644 (file)
@@ -17,7 +17,6 @@
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 
-use std::cmp::{Ordering, Equal, Less, Greater};
 use std::gc::Gc;
 
 pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
@@ -41,7 +40,6 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
                 args: vec!(borrowed_self()),
                 ret_ty: Literal(Path::new(vec!("std", "cmp", "Ordering"))),
                 attributes: attrs,
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     cs_cmp(a, b, c)
                 }),
@@ -53,22 +51,21 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
 }
 
 
-pub fn ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> ast::Path {
-    let cnst = match cnst {
-        Less => "Less",
-        Equal => "Equal",
-        Greater => "Greater"
-    };
-    cx.path_global(span,
-                   vec!(cx.ident_of("std"),
-                     cx.ident_of("cmp"),
-                     cx.ident_of(cnst)))
+pub fn ordering_collapsed(cx: &mut ExtCtxt,
+                          span: Span,
+                          self_arg_tags: &[ast::Ident]) -> Gc<ast::Expr> {
+    let lft = cx.expr_ident(span, self_arg_tags[0]);
+    let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
+    cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt])
 }
 
 pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
               substr: &Substructure) -> Gc<Expr> {
     let test_id = cx.ident_of("__test");
-    let equals_path = ordering_const(cx, span, Equal);
+    let equals_path = cx.path_global(span,
+                                     vec!(cx.ident_of("std"),
+                                          cx.ident_of("cmp"),
+                                          cx.ident_of("Equal")));
 
     /*
     Builds:
@@ -110,16 +107,11 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
             cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
         },
         cx.expr_path(equals_path.clone()),
-        |cx, span, list, _| {
-            match list {
-                // an earlier nonmatching variant is Less than a
-                // later one.
-                [(self_var, _, _),
-                 (other_var, _, _)] => {
-                    let order = ordering_const(cx, span, self_var.cmp(&other_var));
-                    cx.expr_path(order)
-                }
-                _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+        |cx, span, (self_args, tag_tuple), _non_self_args| {
+            if self_args.len() != 2 {
+                cx.span_bug(span, "not exactly 2 arguments in `deriving(TotalOrd)`")
+            } else {
+                ordering_collapsed(cx, span, tag_tuple)
             }
         },
         cx, span, substr)
index 0c23d65fde046e788da842b10c50008c0160d1b1..d909ffd2b49fb56aa24361e419641ab1113b5642 100644 (file)
@@ -13,7 +13,6 @@
 encodable.rs for more.
 */
 
-use ast;
 use ast::{MetaItem, Item, Expr, MutMutable, Ident};
 use codemap::Span;
 use ext::base::ExtCtxt;
@@ -39,10 +38,10 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
         additional_bounds: Vec::new(),
         generics: LifetimeBounds {
             lifetimes: Vec::new(),
-            bounds: vec!(("__D", ast::StaticSize, vec!(Path::new_(
+            bounds: vec!(("__D", None, vec!(Path::new_(
                             vec!("serialize", "Decoder"), None,
                             vec!(box Literal(Path::new_local("__E"))), true))),
-                         ("__E", ast::StaticSize, vec!()))
+                         ("__E", None, vec!()))
         },
         methods: vec!(
             MethodDef {
@@ -55,7 +54,6 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
                                           vec!(box Self,
                                                box Literal(Path::new_local("__E"))), true)),
                 attributes: Vec::new(),
-                const_nonmatching: true,
                 combine_substructure: combine_substructure(|a, b, c| {
                     decodable_substructure(a, b, c)
                 }),
index dfebc0f5e642111a25a1015b857e67cbd66faf43..f7d0308e1bd21d52cd1b1a401d878c8d9b22e142 100644 (file)
@@ -39,7 +39,6 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
                 args: Vec::new(),
                 ret_ty: Self,
                 attributes: attrs,
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     default_substructure(a, b, c)
                 })
index f57670af1999b3c90be860f84f67907ba012f91a..7e289e7676aa92c908353371364c142bf173de71 100644 (file)
@@ -8,81 +8,77 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
+//! The compiler code necessary to implement the `#[deriving(Encodable)]`
+//! (and `Decodable`, in decodable.rs) extension.  The idea here is that
+//! type-defining items may be tagged with `#[deriving(Encodable, Decodable)]`.
+//!
+//! For example, a type like:
+//!
+//! ```ignore
+//! #[deriving(Encodable, Decodable)]
+//! struct Node { id: uint }
+//! ```
+//!
+//! would generate two implementations like:
+//!
+//! ```ignore
+//! impl<S:serialize::Encoder> Encodable<S> for Node {
+//!     fn encode(&self, s: &S) {
+//!         s.emit_struct("Node", 1, || {
+//!             s.emit_field("id", 0, || s.emit_uint(self.id))
+//!         })
+//!     }
+//! }
+//!
+//! impl<D:Decoder> Decodable for node_id {
+//!     fn decode(d: &D) -> Node {
+//!         d.read_struct("Node", 1, || {
+//!             Node {
+//!                 id: d.read_field("x".to_string(), 0, || decode(d))
+//!             }
+//!         })
+//!     }
+//! }
+//! ```
+//!
+//! Other interesting scenarios are whe the item has type parameters or
+//! references other non-built-in types.  A type definition like:
+//!
+//! ```ignore
+//! #[deriving(Encodable, Decodable)]
+//! struct spanned<T> { node: T, span: Span }
+//! ```
+//!
+//! would yield functions like:
+//!
+//! ```ignore
+//!     impl<
+//!         S: Encoder,
+//!         T: Encodable<S>
+//!     > spanned<T>: Encodable<S> {
+//!         fn encode<S:Encoder>(s: &S) {
+//!             s.emit_rec(|| {
+//!                 s.emit_field("node", 0, || self.node.encode(s));
+//!                 s.emit_field("span", 1, || self.span.encode(s));
+//!             })
+//!         }
+//!     }
+//!
+//!     impl<
+//!         D: Decoder,
+//!         T: Decodable<D>
+//!     > spanned<T>: Decodable<D> {
+//!         fn decode(d: &D) -> spanned<T> {
+//!             d.read_rec(|| {
+//!                 {
+//!                     node: d.read_field("node".to_string(), 0, || decode(d)),
+//!                     span: d.read_field("span".to_string(), 1, || decode(d)),
+//!                 }
+//!             })
+//!         }
+//!     }
+//! ```
 
-The compiler code necessary to implement the `#[deriving(Encodable)]`
-(and `Decodable`, in decodable.rs) extension.  The idea here is that
-type-defining items may be tagged with `#[deriving(Encodable, Decodable)]`.
-
-For example, a type like:
-
-```ignore
-#[deriving(Encodable, Decodable)]
-struct Node { id: uint }
-```
-
-would generate two implementations like:
-
-```ignore
-impl<S:serialize::Encoder> Encodable<S> for Node {
-    fn encode(&self, s: &S) {
-        s.emit_struct("Node", 1, || {
-            s.emit_field("id", 0, || s.emit_uint(self.id))
-        })
-    }
-}
-
-impl<D:Decoder> Decodable for node_id {
-    fn decode(d: &D) -> Node {
-        d.read_struct("Node", 1, || {
-            Node {
-                id: d.read_field("x".to_string(), 0, || decode(d))
-            }
-        })
-    }
-}
-```
-
-Other interesting scenarios are whe the item has type parameters or
-references other non-built-in types.  A type definition like:
-
-```ignore
-#[deriving(Encodable, Decodable)]
-struct spanned<T> { node: T, span: Span }
-```
-
-would yield functions like:
-
-```ignore
-    impl<
-        S: Encoder,
-        T: Encodable<S>
-    > spanned<T>: Encodable<S> {
-        fn encode<S:Encoder>(s: &S) {
-            s.emit_rec(|| {
-                s.emit_field("node", 0, || self.node.encode(s));
-                s.emit_field("span", 1, || self.span.encode(s));
-            })
-        }
-    }
-
-    impl<
-        D: Decoder,
-        T: Decodable<D>
-    > spanned<T>: Decodable<D> {
-        fn decode(d: &D) -> spanned<T> {
-            d.read_rec(|| {
-                {
-                    node: d.read_field("node".to_string(), 0, || decode(d)),
-                    span: d.read_field("span".to_string(), 1, || decode(d)),
-                }
-            })
-        }
-    }
-```
-*/
-
-use ast;
 use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil};
 use codemap::Span;
 use ext::base::ExtCtxt;
@@ -107,10 +103,10 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
         additional_bounds: Vec::new(),
         generics: LifetimeBounds {
             lifetimes: Vec::new(),
-            bounds: vec!(("__S", ast::StaticSize, vec!(Path::new_(
+            bounds: vec!(("__S", None, vec!(Path::new_(
                             vec!("serialize", "Encoder"), None,
                             vec!(box Literal(Path::new_local("__E"))), true))),
-                         ("__E", ast::StaticSize, vec!()))
+                         ("__E", None, vec!()))
         },
         methods: vec!(
             MethodDef {
@@ -125,7 +121,6 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
                                                 box Literal(Path::new_local("__E"))),
                                            true)),
                 attributes: Vec::new(),
-                const_nonmatching: true,
                 combine_substructure: combine_substructure(|a, b, c| {
                     encodable_substructure(a, b, c)
                 }),
index 157b64fb47c0a7fa3d699681bb0d223d7a718f46..46efdccadec8033d16b185da5a534b31dd8a316e 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
-
-Some code that abstracts away much of the boilerplate of writing
-`deriving` instances for traits. Among other things it manages getting
-access to the fields of the 4 different sorts of structs and enum
-variants, as well as creating the method and impl ast instances.
-
-Supported features (fairly exhaustive):
-
-- Methods taking any number of parameters of any type, and returning
-  any type, other than vectors, bottom and closures.
-- Generating `impl`s for types with type parameters and lifetimes
-  (e.g. `Option<T>`), the parameters are automatically given the
-  current trait as a bound. (This includes separate type parameters
-  and lifetimes for methods.)
-- Additional bounds on the type parameters, e.g. the `Ord` instance
-  requires an explicit `PartialEq` bound at the
-  moment. (`TraitDef.additional_bounds`)
-
-Unsupported: FIXME #6257: calling methods on reference fields,
-e.g. deriving Eq/Ord/Clone don't work on `struct A(&int)`,
-because of how the auto-dereferencing happens.
-
-The most important thing for implementers is the `Substructure` and
-`SubstructureFields` objects. The latter groups 5 possibilities of the
-arguments:
-
-- `Struct`, when `Self` is a struct (including tuple structs, e.g
-  `struct T(int, char)`).
-- `EnumMatching`, when `Self` is an enum and all the arguments are the
-  same variant of the enum (e.g. `Some(1)`, `Some(3)` and `Some(4)`)
-- `EnumNonMatching` when `Self` is an enum and the arguments are not
-  the same variant (e.g. `None`, `Some(1)` and `None`). If
-  `const_nonmatching` is true, this will contain an empty list.
-- `StaticEnum` and `StaticStruct` for static methods, where the type
-  being derived upon is either an enum or struct respectively. (Any
-  argument with type Self is just grouped among the non-self
-  arguments.)
-
-In the first two cases, the values from the corresponding fields in
-all the arguments are grouped together. In the `EnumNonMatching` case
-this isn't possible (different variants have different fields), so the
-fields are grouped by which argument they come from. There are no
-fields with values in the static cases, so these are treated entirely
-differently.
-
-The non-static cases have `Option<ident>` in several places associated
-with field `expr`s. This represents the name of the field it is
-associated with. It is only not `None` when the associated field has
-an identifier in the source code. For example, the `x`s in the
-following snippet
-
-```rust
-struct A { x : int }
-
-struct B(int);
-
-enum C {
-    C0(int),
-    C1 { x: int }
-}
-```
-
-The `int`s in `B` and `C0` don't have an identifier, so the
-`Option<ident>`s would be `None` for them.
-
-In the static cases, the structure is summarised, either into the just
-spans of the fields or a list of spans and the field idents (for tuple
-structs and record structs, respectively), or a list of these, for
-enums (one for each variant). For empty struct and empty enum
-variants, it is represented as a count of 0.
-
-# Examples
-
-The following simplified `PartialEq` is used for in-code examples:
-
-```rust
-trait PartialEq {
-    fn eq(&self, other: &Self);
-}
-impl PartialEq for int {
-    fn eq(&self, other: &int) -> bool {
-        *self == *other
-    }
-}
-```
-
-Some examples of the values of `SubstructureFields` follow, using the
-above `PartialEq`, `A`, `B` and `C`.
-
-## Structs
-
-When generating the `expr` for the `A` impl, the `SubstructureFields` is
-
-~~~text
-Struct(~[FieldInfo {
-           span: <span of x>
-           name: Some(<ident of x>),
-           self_: <expr for &self.x>,
-           other: ~[<expr for &other.x]
-         }])
-~~~
-
-For the `B` impl, called with `B(a)` and `B(b)`,
-
-~~~text
-Struct(~[FieldInfo {
-          span: <span of `int`>,
-          name: None,
-          <expr for &a>
-          ~[<expr for &b>]
-         }])
-~~~
-
-## Enums
-
-When generating the `expr` for a call with `self == C0(a)` and `other
-== C0(b)`, the SubstructureFields is
-
-~~~text
-EnumMatching(0, <ast::Variant for C0>,
-             ~[FieldInfo {
-                span: <span of int>
-                name: None,
-                self_: <expr for &a>,
-                other: ~[<expr for &b>]
-              }])
-~~~
-
-For `C1 {x}` and `C1 {x}`,
-
-~~~text
-EnumMatching(1, <ast::Variant for C1>,
-             ~[FieldInfo {
-                span: <span of x>
-                name: Some(<ident of x>),
-                self_: <expr for &self.x>,
-                other: ~[<expr for &other.x>]
-               }])
-~~~
-
-For `C0(a)` and `C1 {x}` ,
-
-~~~text
-EnumNonMatching(~[(0, <ast::Variant for B0>,
-                   ~[(<span of int>, None, <expr for &a>)]),
-                  (1, <ast::Variant for B1>,
-                   ~[(<span of x>, Some(<ident of x>),
-                      <expr for &other.x>)])])
-~~~
-
-(and vice versa, but with the order of the outermost list flipped.)
-
-## Static
-
-A static method on the above would result in,
-
-~~~text
-StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)]))
-
-StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>]))
-
-StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span of int>])),
-                                  (<ident of C1>, <span of C1>,
-                                   Named(~[(<ident of x>, <span of x>)]))])
-~~~
-
-*/
+//! Some code that abstracts away much of the boilerplate of writing
+//! `deriving` instances for traits. Among other things it manages getting
+//! access to the fields of the 4 different sorts of structs and enum
+//! variants, as well as creating the method and impl ast instances.
+//!
+//! Supported features (fairly exhaustive):
+//!
+//! - Methods taking any number of parameters of any type, and returning
+//!   any type, other than vectors, bottom and closures.
+//! - Generating `impl`s for types with type parameters and lifetimes
+//!   (e.g. `Option<T>`), the parameters are automatically given the
+//!   current trait as a bound. (This includes separate type parameters
+//!   and lifetimes for methods.)
+//! - Additional bounds on the type parameters, e.g. the `Ord` instance
+//!   requires an explicit `PartialEq` bound at the
+//!   moment. (`TraitDef.additional_bounds`)
+//!
+//! Unsupported: FIXME #6257: calling methods on reference fields,
+//! e.g. deriving Eq/Ord/Clone don't work on `struct A(&int)`,
+//! because of how the auto-dereferencing happens.
+//!
+//! The most important thing for implementers is the `Substructure` and
+//! `SubstructureFields` objects. The latter groups 5 possibilities of the
+//! arguments:
+//!
+//! - `Struct`, when `Self` is a struct (including tuple structs, e.g
+//!   `struct T(int, char)`).
+//! - `EnumMatching`, when `Self` is an enum and all the arguments are the
+//!   same variant of the enum (e.g. `Some(1)`, `Some(3)` and `Some(4)`)
+//! - `EnumNonMatchingCollapsed` when `Self` is an enum and the arguments
+//!   are not the same variant (e.g. `None`, `Some(1)` and `None`).
+//! - `StaticEnum` and `StaticStruct` for static methods, where the type
+//!   being derived upon is either an enum or struct respectively. (Any
+//!   argument with type Self is just grouped among the non-self
+//!   arguments.)
+//!
+//! In the first two cases, the values from the corresponding fields in
+//! all the arguments are grouped together. For `EnumNonMatchingCollapsed`
+//! this isn't possible (different variants have different fields), so the
+//! fields are inaccessible. (Previous versions of the deriving infrastructure
+//! had a way to expand into code that could access them, at the cost of
+//! generating exponential amounts of code; see issue #15375). There are no
+//! fields with values in the static cases, so these are treated entirely
+//! differently.
+//!
+//! The non-static cases have `Option<ident>` in several places associated
+//! with field `expr`s. This represents the name of the field it is
+//! associated with. It is only not `None` when the associated field has
+//! an identifier in the source code. For example, the `x`s in the
+//! following snippet
+//!
+//! ```rust
+//! struct A { x : int }
+//!
+//! struct B(int);
+//!
+//! enum C {
+//!     C0(int),
+//!     C1 { x: int }
+//! }
+//! ```
+//!
+//! The `int`s in `B` and `C0` don't have an identifier, so the
+//! `Option<ident>`s would be `None` for them.
+//!
+//! In the static cases, the structure is summarised, either into the just
+//! spans of the fields or a list of spans and the field idents (for tuple
+//! structs and record structs, respectively), or a list of these, for
+//! enums (one for each variant). For empty struct and empty enum
+//! variants, it is represented as a count of 0.
+//!
+//! # Examples
+//!
+//! The following simplified `PartialEq` is used for in-code examples:
+//!
+//! ```rust
+//! trait PartialEq {
+//!     fn eq(&self, other: &Self);
+//! }
+//! impl PartialEq for int {
+//!     fn eq(&self, other: &int) -> bool {
+//!         *self == *other
+//!     }
+//! }
+//! ```
+//!
+//! Some examples of the values of `SubstructureFields` follow, using the
+//! above `PartialEq`, `A`, `B` and `C`.
+//!
+//! ## Structs
+//!
+//! When generating the `expr` for the `A` impl, the `SubstructureFields` is
+//!
+//! ~~~text
+//! Struct(~[FieldInfo {
+//!            span: <span of x>
+//!            name: Some(<ident of x>),
+//!            self_: <expr for &self.x>,
+//!            other: ~[<expr for &other.x]
+//!          }])
+//! ~~~
+//!
+//! For the `B` impl, called with `B(a)` and `B(b)`,
+//!
+//! ~~~text
+//! Struct(~[FieldInfo {
+//!           span: <span of `int`>,
+//!           name: None,
+//!           <expr for &a>
+//!           ~[<expr for &b>]
+//!          }])
+//! ~~~
+//!
+//! ## Enums
+//!
+//! When generating the `expr` for a call with `self == C0(a)` and `other
+//! == C0(b)`, the SubstructureFields is
+//!
+//! ~~~text
+//! EnumMatching(0, <ast::Variant for C0>,
+//!              ~[FieldInfo {
+//!                 span: <span of int>
+//!                 name: None,
+//!                 self_: <expr for &a>,
+//!                 other: ~[<expr for &b>]
+//!               }])
+//! ~~~
+//!
+//! For `C1 {x}` and `C1 {x}`,
+//!
+//! ~~~text
+//! EnumMatching(1, <ast::Variant for C1>,
+//!              ~[FieldInfo {
+//!                 span: <span of x>
+//!                 name: Some(<ident of x>),
+//!                 self_: <expr for &self.x>,
+//!                 other: ~[<expr for &other.x>]
+//!                }])
+//! ~~~
+//!
+//! For `C0(a)` and `C1 {x}` ,
+//!
+//! ~~~text
+//! EnumNonMatchingCollapsed(
+//!     ~[<ident of self>, <ident of __arg_1>],
+//!     &[<ast::Variant for C0>, <ast::Variant for C1>],
+//!     &[<ident for self index value>, <ident of __arg_1 index value>])
+//! ~~~
+//!
+//! It is the same for when the arguments are flipped to `C1 {x}` and
+//! `C0(a)`; the only difference is what the values of the identifiers
+//! <ident for self index value> and <ident of __arg_1 index value> will
+//! be in the generated code.
+//!
+//! `EnumNonMatchingCollapsed` deliberately provides far less information
+//! than is generally available for a given pair of variants; see #15375
+//! for discussion.
+//!
+//! ## Static
+//!
+//! A static method on the above would result in,
+//!
+//! ~~~text
+//! StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)]))
+//!
+//! StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>]))
+//!
+//! StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span of int>])),
+//!                                   (<ident of C1>, <span of C1>,
+//!                                    Named(~[(<ident of x>, <span of x>)]))])
+//! ~~~
 
 use std::cell::RefCell;
 use std::gc::{Gc, GC};
@@ -191,6 +194,7 @@ fn eq(&self, other: &int) -> bool {
 use codemap::Span;
 use owned_slice::OwnedSlice;
 use parse::token::InternedString;
+use parse::token::special_idents;
 
 use self::ty::*;
 
@@ -235,10 +239,6 @@ pub struct MethodDef<'a> {
 
     pub attributes: Vec<ast::Attribute>,
 
-    /// if the value of the nonmatching enums is independent of the
-    /// actual enum variants, i.e. can use _ => .. match.
-    pub const_nonmatching: bool,
-
     pub combine_substructure: RefCell<CombineSubstructureFunc<'a>>,
 }
 
@@ -289,12 +289,14 @@ pub enum SubstructureFields<'a> {
     EnumMatching(uint, &'a ast::Variant, Vec<FieldInfo>),
 
     /**
-    non-matching variants of the enum, [(variant index, ast::Variant,
-    [field span, field ident, fields])] \(i.e. all fields for self are in the
-    first tuple, for other1 are in the second tuple, etc.)
+    non-matching variants of the enum, but with all state hidden from
+    the consequent code.  The first component holds Idents for all of
+    the Self arguments; the second component is a slice of all of the
+    variants for the enum itself, and the third component is a list of
+    Idents bound to the variant index values for each of the actual
+    input Self arguments.
     */
-    EnumNonMatching(&'a [(uint, P<ast::Variant>,
-                          Vec<(Span, Option<Ident>, Gc<Expr>)>)]),
+    EnumNonMatchingCollapsed(Vec<Ident>, &'a [Gc<ast::Variant>], &'a [Ident]),
 
     /// A static method where Self is a struct.
     StaticStruct(&'a ast::StructDef, StaticFields),
@@ -312,14 +314,16 @@ pub enum SubstructureFields<'a> {
     |&mut ExtCtxt, Span, &Substructure|: 'a -> Gc<Expr>;
 
 /**
-Deal with non-matching enum variants, the arguments are a list
-representing each variant: (variant index, ast::Variant instance,
-[variant fields]), and a list of the nonself args of the type
+Deal with non-matching enum variants.  The tuple is a list of
+identifiers (one for each Self argument, which could be any of the
+variants since they have been collapsed together) and the identifiers
+holding the variant index value for each of the Self arguments.  The
+last argument is all the non-Self args of the method being derived.
 */
-pub type EnumNonMatchFunc<'a> =
+pub type EnumNonMatchCollapsedFunc<'a> =
     |&mut ExtCtxt,
            Span,
-           &[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, Gc<Expr>)>)],
+           (&[Ident], &[Ident]),
            &[Gc<Expr>]|: 'a
            -> Gc<Expr>;
 
@@ -406,8 +410,8 @@ fn create_derived_impl(&self,
 
             cx.typaram(self.span,
                        ty_param.ident,
-                       ty_param.sized,
                        OwnedSlice::from_vec(bounds),
+                       ty_param.unbound.clone(),
                        None)
         }));
         let trait_generics = Generics {
@@ -519,6 +523,15 @@ fn expand_enum_def(&self,
     }
 }
 
+fn variant_to_pat(cx: &mut ExtCtxt, sp: Span, variant: &ast::Variant)
+                  -> Gc<ast::Pat> {
+    let ident = cx.path_ident(sp, variant.node.name);
+    cx.pat(sp, match variant.node.kind {
+        ast::TupleVariantKind(..) => ast::PatEnum(ident, None),
+        ast::StructVariantKind(..) => ast::PatStruct(ident, Vec::new(), true),
+    })
+}
+
 impl<'a> MethodDef<'a> {
     fn call_substructure_method(&self,
                                 cx: &mut ExtCtxt,
@@ -617,7 +630,8 @@ fn create_method(&self,
 
         let self_arg = match explicit_self.node {
             ast::SelfStatic => None,
-            _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable))
+            // creating fresh self id
+            _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable, special_idents::self_))
         };
         let args = {
             let args = arg_types.move_iter().map(|(name, ty)| {
@@ -634,16 +648,16 @@ fn create_method(&self,
 
         // Create the method.
         box(GC) ast::Method {
-            ident: method_ident,
             attrs: self.attributes.clone(),
-            generics: fn_generics,
-            explicit_self: explicit_self,
-            fn_style: ast::NormalFn,
-            decl: fn_decl,
-            body: body_block,
             id: ast::DUMMY_NODE_ID,
             span: trait_.span,
-            vis: ast::Inherited,
+            node: ast::MethDecl(method_ident,
+                                fn_generics,
+                                explicit_self,
+                                ast::NormalFn,
+                                fn_decl,
+                                body_block,
+                                ast::Inherited)
         }
     }
 
@@ -756,27 +770,32 @@ fn expand_static_struct_method_body(&self,
    ~~~
     #[deriving(PartialEq)]
     enum A {
-        A1
+        A1,
         A2(int)
     }
 
-    // is equivalent to (with const_nonmatching == false)
+    // is equivalent to
 
     impl PartialEq for A {
-        fn eq(&self, __arg_1: &A) {
-            match *self {
-                A1 => match *__arg_1 {
-                    A1 => true
-                    A2(ref __arg_1_1) => false
-                },
-                A2(self_1) => match *__arg_1 {
-                    A1 => false,
-                    A2(ref __arg_1_1) => self_1.eq(__arg_1_1)
+        fn eq(&self, __arg_1: &A) -> ::bool {
+            match (&*self, &*__arg_1) {
+                (&A1, &A1) => true,
+                (&A2(ref __self_0),
+                 &A2(ref __arg_1_0)) => (*__self_0).eq(&(*__arg_1_0)),
+                _ => {
+                    let __self_vi = match *self { A1(..) => 0u, A2(..) => 1u };
+                    let __arg_1_vi = match *__arg_1 { A1(..) => 0u, A2(..) => 1u };
+                    false
                 }
             }
         }
     }
    ~~~
+
+    (Of course `__self_vi` and `__arg_1_vi` are unused for
+     `PartialEq`, and those subcomputations will hopefully be removed
+     as their results are unused.  The point of `__self_vi` and
+     `__arg_1_vi` is for `PartialOrd`; see #15503.)
     */
     fn expand_enum_method_body(&self,
                                cx: &mut ExtCtxt,
@@ -786,190 +805,296 @@ fn expand_enum_method_body(&self,
                                self_args: &[Gc<Expr>],
                                nonself_args: &[Gc<Expr>])
                                -> Gc<Expr> {
-        let mut matches = Vec::new();
-        self.build_enum_match(cx, trait_, enum_def, type_ident,
-                              self_args, nonself_args,
-                              None, &mut matches, 0)
+        self.build_enum_match_tuple(
+            cx, trait_, enum_def, type_ident, self_args, nonself_args)
     }
 
 
     /**
-    Creates the nested matches for an enum definition recursively, i.e.
-
-   ~~~text
-    match self {
-       Variant1 => match other { Variant1 => matching, Variant2 => nonmatching, ... },
-       Variant2 => match other { Variant1 => nonmatching, Variant2 => matching, ... },
-       ...
+    Creates a match for a tuple of all `self_args`, where either all
+    variants match, or it falls into a catch-all for when one variant
+    does not match.
+
+    There are N + 1 cases because is a case for each of the N
+    variants where all of the variants match, and one catch-all for
+    when one does not match.
+
+    The catch-all handler is provided access the variant index values
+    for each of the self-args, carried in precomputed variables. (Nota
+    bene: the variant index values are not necessarily the
+    discriminant values.  See issue #15523.)
+
+    ~~~text
+    match (this, that, ...) {
+      (Variant1, Variant1, Variant1) => ... // delegate Matching on Variant1
+      (Variant2, Variant2, Variant2) => ... // delegate Matching on Variant2
+      ...
+      _ => {
+        let __this_vi = match this { Variant1 => 0u, Variant2 => 1u, ... };
+        let __that_vi = match that { Variant1 => 0u, Variant2 => 1u, ... };
+        ... // catch-all remainder can inspect above variant index values.
+      }
     }
-   ~~~
-
-    It acts in the most naive way, so every branch (and subbranch,
-    subsubbranch, etc) exists, not just the ones where all the variants in
-    the tree are the same. Hopefully the optimisers get rid of any
-    repetition, otherwise derived methods with many Self arguments will be
-    exponentially large.
-
-    `matching` is Some(n) if all branches in the tree above the
-    current position are variant `n`, `None` otherwise (including on
-    the first call).
+    ~~~
     */
-    fn build_enum_match(&self,
-                        cx: &mut ExtCtxt,
-                        trait_: &TraitDef,
-                        enum_def: &EnumDef,
-                        type_ident: Ident,
-                        self_args: &[Gc<Expr>],
-                        nonself_args: &[Gc<Expr>],
-                        matching: Option<uint>,
-                        matches_so_far: &mut Vec<(uint, P<ast::Variant>,
-                                              Vec<(Span, Option<Ident>, Gc<Expr>)>)> ,
-                        match_count: uint) -> Gc<Expr> {
-        if match_count == self_args.len() {
-            // we've matched against all arguments, so make the final
-            // expression at the bottom of the match tree
-            if matches_so_far.len() == 0 {
-                cx.span_bug(trait_.span,
-                                "no self match on an enum in \
-                                generic `deriving`");
-            }
-
-            // `ref` inside let matches is buggy. Causes havoc with rusc.
-            // let (variant_index, ref self_vec) = matches_so_far[0];
-            let (variant, self_vec) = match matches_so_far.get(0) {
-                &(_, v, ref s) => (v, s)
-            };
-
-            // we currently have a vec of vecs, where each
-            // subvec is the fields of one of the arguments,
-            // but if the variants all match, we want this as
-            // vec of tuples, where each tuple represents a
-            // field.
-
-            // most arms don't have matching variants, so do a
-            // quick check to see if they match (even though
-            // this means iterating twice) instead of being
-            // optimistic and doing a pile of allocations etc.
-            let substructure = match matching {
-                Some(variant_index) => {
-                    let mut enum_matching_fields = Vec::from_elem(self_vec.len(), Vec::new());
-
-                    for triple in matches_so_far.tail().iter() {
-                        match triple {
-                            &(_, _, ref other_fields) => {
-                                for (i, &(_, _, e)) in other_fields.iter().enumerate() {
-                                    enum_matching_fields.get_mut(i).push(e);
-                                }
-                            }
-                        }
-                    }
-                    let field_tuples =
-                        self_vec.iter()
-                                .zip(enum_matching_fields.iter())
-                                .map(|(&(span, id, self_f), other)| {
-                        FieldInfo {
-                            span: span,
-                            name: id,
-                            self_: self_f,
-                            other: (*other).clone()
-                        }
-                    }).collect();
-                    EnumMatching(variant_index, &*variant, field_tuples)
-                }
-                None => {
-                    EnumNonMatching(matches_so_far.as_slice())
+    fn build_enum_match_tuple(
+        &self,
+        cx: &mut ExtCtxt,
+        trait_: &TraitDef,
+        enum_def: &EnumDef,
+        type_ident: Ident,
+        self_args: &[Gc<Expr>],
+        nonself_args: &[Gc<Expr>]) -> Gc<Expr> {
+
+        let sp = trait_.span;
+        let variants = &enum_def.variants;
+
+        let self_arg_names = self_args.iter().enumerate()
+            .map(|(arg_count, _self_arg)| {
+                if arg_count == 0 {
+                    "__self".to_string()
+                } else {
+                    format!("__arg_{}", arg_count)
                 }
-            };
-            self.call_substructure_method(cx, trait_, type_ident,
-                                          self_args, nonself_args,
-                                          &substructure)
+            })
+            .collect::<Vec<String>>();
+
+        let self_arg_idents = self_arg_names.iter()
+            .map(|name|cx.ident_of(name.as_slice()))
+            .collect::<Vec<ast::Ident>>();
+
+        // The `vi_idents` will be bound, solely in the catch-all, to
+        // a series of let statements mapping each self_arg to a uint
+        // corresponding to its variant index.
+        let vi_idents : Vec<ast::Ident> = self_arg_names.iter()
+            .map(|name| { let vi_suffix = format!("{:s}_vi", name.as_slice());
+                          cx.ident_of(vi_suffix.as_slice()) })
+            .collect::<Vec<ast::Ident>>();
+
+        // Builds, via callback to call_substructure_method, the
+        // delegated expression that handles the catch-all case,
+        // using `__variants_tuple` to drive logic if necessary.
+        let catch_all_substructure = EnumNonMatchingCollapsed(
+            self_arg_idents, variants.as_slice(), vi_idents.as_slice());
+
+        // These arms are of the form:
+        // (Variant1, Variant1, ...) => Body1
+        // (Variant2, Variant2, ...) => Body2
+        // ...
+        // where each tuple has length = self_args.len()
+        let mut match_arms : Vec<ast::Arm> = variants.iter().enumerate()
+            .map(|(index, &variant)| {
+
+                // These self_pats have form Variant1, Variant2, ...
+                let self_pats : Vec<(Gc<ast::Pat>,
+                                     Vec<(Span, Option<Ident>, Gc<Expr>)>)>;
+                self_pats = self_arg_names.iter()
+                    .map(|self_arg_name|
+                         trait_.create_enum_variant_pattern(
+                             cx, &*variant, self_arg_name.as_slice(),
+                             ast::MutImmutable))
+                    .collect();
+
+                // A single arm has form (&VariantK, &VariantK, ...) => BodyK
+                // (see "Final wrinkle" note below for why.)
+                let subpats = self_pats.iter()
+                    .map(|&(p, ref _idents)| cx.pat(sp, ast::PatRegion(p)))
+                    .collect::<Vec<Gc<ast::Pat>>>();
+
+                // Here is the pat = `(&VariantK, &VariantK, ...)`
+                let single_pat = cx.pat(sp, ast::PatTup(subpats));
+
+                // For the BodyK, we need to delegate to our caller,
+                // passing it an EnumMatching to indicate which case
+                // we are in.
+
+                // All of the Self args have the same variant in these
+                // cases.  So we transpose the info in self_pats to
+                // gather the getter expressions together, in the form
+                // that EnumMatching expects.
+
+                // The transposition is driven by walking across the
+                // arg fields of the variant for the first self pat.
+                let &(_, ref self_arg_fields) = self_pats.get(0);
+
+                let field_tuples : Vec<FieldInfo>;
+
+                field_tuples = self_arg_fields.iter().enumerate()
+                    // For each arg field of self, pull out its getter expr ...
+                    .map(|(field_index, &(sp, opt_ident, self_getter_expr))| {
+                        // ... but FieldInfo also wants getter expr
+                        // for matching other arguments of Self type;
+                        // so walk across the *other* self_pats and
+                        // pull out getter for same field in each of
+                        // them (using `field_index` tracked above).
+                        // That is the heart of the transposition.
+                        let others = self_pats.tail().iter()
+                            .map(|&(_pat, ref fields)| {
+
+                                let &(_, _opt_ident, other_getter_expr) =
+                                    fields.get(field_index);
+
+                                // All Self args have same variant, so
+                                // opt_idents are the same.  (Assert
+                                // here to make it self-evident that
+                                // it is okay to ignore `_opt_ident`.)
+                                assert!(opt_ident == _opt_ident);
+
+                                other_getter_expr
+                            }).collect::<Vec<Gc<Expr>>>();
+
+                        FieldInfo { span: sp,
+                                    name: opt_ident,
+                                    self_: self_getter_expr,
+                                    other: others,
+                        }
+                    }).collect::<Vec<FieldInfo>>();
+
+                // Now, for some given VariantK, we have built up
+                // expressions for referencing every field of every
+                // Self arg, assuming all are instances of VariantK.
+                // Build up code associated with such a case.
+                let substructure = EnumMatching(index, variant, field_tuples);
+                let arm_expr = self.call_substructure_method(
+                    cx, trait_, type_ident, self_args, nonself_args,
+                    &substructure);
+
+                cx.arm(sp, vec![single_pat], arm_expr)
+            }).collect();
 
-        } else {  // there are still matches to create
-            let current_match_str = if match_count == 0 {
-                "__self".to_string()
-            } else {
-                format!("__arg_{}", match_count)
-            };
+        // We will usually need the catch-all after matching the
+        // tuples `(VariantK, VariantK, ...)` for each VariantK of the
+        // enum.  But:
+        //
+        // * when there is only one Self arg, the arms above suffice
+        // (and the deriving we call back into may not be prepared to
+        // handle EnumNonMatchCollapsed), and,
+        //
+        // * when the enum has only one variant, the single arm that
+        // is already present always suffices.
+        //
+        // * In either of the two cases above, if we *did* add a
+        //   catch-all `_` match, it would trigger the
+        //   unreachable-pattern error.
+        //
+        if variants.len() > 1 && self_args.len() > 1 {
+            let arms : Vec<ast::Arm> = variants.iter().enumerate()
+                .map(|(index, &variant)| {
+                    let pat = variant_to_pat(cx, sp, &*variant);
+                    let lit = ast::LitUint(index as u64, ast::TyU);
+                    cx.arm(sp, vec![pat], cx.expr_lit(sp, lit))
+                }).collect();
 
-            let mut arms = Vec::new();
-
-            // the code for nonmatching variants only matters when
-            // we've seen at least one other variant already
-            if self.const_nonmatching && match_count > 0 {
-                // make a matching-variant match, and a _ match.
-                let index = match matching {
-                    Some(i) => i,
-                    None => cx.span_bug(trait_.span,
-                                        "non-matching variants when required to \
-                                        be matching in generic `deriving`")
-                };
-
-                // matching-variant match
-                let variant = *enum_def.variants.get(index);
-                let (pattern, idents) = trait_.create_enum_variant_pattern(
-                    cx,
-                    &*variant,
-                    current_match_str.as_slice(),
-                    ast::MutImmutable);
-
-                matches_so_far.push((index, variant, idents));
-                let arm_expr = self.build_enum_match(cx,
-                                                     trait_,
-                                                     enum_def,
-                                                     type_ident,
-                                                     self_args, nonself_args,
-                                                     matching,
-                                                     matches_so_far,
-                                                     match_count + 1);
-                matches_so_far.pop().unwrap();
-                arms.push(cx.arm(trait_.span, vec!( pattern ), arm_expr));
-
-                if enum_def.variants.len() > 1 {
-                    let e = &EnumNonMatching(&[]);
-                    let wild_expr = self.call_substructure_method(cx, trait_, type_ident,
-                                                                  self_args, nonself_args,
-                                                                  e);
-                    let wild_arm = cx.arm(
-                        trait_.span,
-                        vec!( cx.pat_wild(trait_.span) ),
-                        wild_expr);
-                    arms.push(wild_arm);
-                }
-            } else {
-                // create an arm matching on each variant
-                for (index, &variant) in enum_def.variants.iter().enumerate() {
-                    let (pattern, idents) =
-                        trait_.create_enum_variant_pattern(
-                            cx,
-                            &*variant,
-                            current_match_str.as_slice(),
-                            ast::MutImmutable);
-
-                    matches_so_far.push((index, variant, idents));
-                    let new_matching =
-                        match matching {
-                            _ if match_count == 0 => Some(index),
-                            Some(i) if index == i => Some(i),
-                            _ => None
-                        };
-                    let arm_expr = self.build_enum_match(cx,
-                                                         trait_,
-                                                         enum_def,
-                                                         type_ident,
-                                                         self_args, nonself_args,
-                                                         new_matching,
-                                                         matches_so_far,
-                                                         match_count + 1);
-                    matches_so_far.pop().unwrap();
-
-                    let arm = cx.arm(trait_.span, vec!( pattern ), arm_expr);
-                    arms.push(arm);
-                }
+            // Build a series of let statements mapping each self_arg
+            // to a uint corresponding to its variant index.
+            // i.e. for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
+            // with three Self args, builds three statements:
+            //
+            // ```
+            // let __self0_vi = match   self {
+            //     A => 0u, B(..) => 1u, C(..) => 2u
+            // };
+            // let __self1_vi = match __arg1 {
+            //     A => 0u, B(..) => 1u, C(..) => 2u
+            // };
+            // let __self2_vi = match __arg2 {
+            //     A => 0u, B(..) => 1u, C(..) => 2u
+            // };
+            // ```
+            let mut index_let_stmts : Vec<Gc<ast::Stmt>> = Vec::new();
+            for (&ident, &self_arg) in vi_idents.iter().zip(self_args.iter()) {
+                let variant_idx = cx.expr_match(sp, self_arg, arms.clone());
+                let let_stmt = cx.stmt_let(sp, false, ident, variant_idx);
+                index_let_stmts.push(let_stmt);
             }
 
-            // match foo { arm, arm, arm, ... }
-            cx.expr_match(trait_.span, self_args[match_count], arms)
+            let arm_expr = self.call_substructure_method(
+                cx, trait_, type_ident, self_args, nonself_args,
+                &catch_all_substructure);
+
+            // Builds the expression:
+            // {
+            //   let __self0_vi = ...;
+            //   let __self1_vi = ...;
+            //   ...
+            //   <delegated expression referring to __self0_vi, et al.>
+            // }
+            let arm_expr = cx.expr_block(
+                cx.block_all(sp, Vec::new(), index_let_stmts, Some(arm_expr)));
+
+            // Builds arm:
+            // _ => { let __self0_vi = ...;
+            //        let __self1_vi = ...;
+            //        ...
+            //        <delegated expression as above> }
+            let catch_all_match_arm =
+                cx.arm(sp, vec![cx.pat_wild(sp)], arm_expr);
+
+            match_arms.push(catch_all_match_arm);
+
+        } else if variants.len() == 0 {
+            // As an additional wrinkle, For a zero-variant enum A,
+            // currently the compiler
+            // will accept `fn (a: &Self) { match   *a   { } }`
+            // but rejects `fn (a: &Self) { match (&*a,) { } }`
+            // as well as  `fn (a: &Self) { match ( *a,) { } }`
+            //
+            // This means that the strategy of building up a tuple of
+            // all Self arguments fails when Self is a zero variant
+            // enum: rustc rejects the expanded program, even though
+            // the actual code tends to be impossible to execute (at
+            // least safely), according to the type system.
+            //
+            // The most expedient fix for this is to just let the
+            // code fall through to the catch-all.  But even this is
+            // error-prone, since the catch-all as defined above would
+            // generate code like this:
+            //
+            //     _ => { let __self0 = match *self { };
+            //            let __self1 = match *__arg_0 { };
+            //            <catch-all-expr> }
+            //
+            // Which is yields bindings for variables which type
+            // inference cannot resolve to unique types.
+            //
+            // One option to the above might be to add explicit type
+            // annotations.  But the *only* reason to go down that path
+            // would be to try to make the expanded output consistent
+            // with the case when the number of enum variants >= 1.
+            //
+            // That just isn't worth it.  In fact, trying to generate
+            // sensible code for *any* deriving on a zero-variant enum
+            // does not make sense.  But at the same time, for now, we
+            // do not want to cause a compile failure just because the
+            // user happened to attach a deriving to their
+            // zero-variant enum.
+            //
+            // Instead, just generate a failing expression for the
+            // zero variant case, skipping matches and also skipping
+            // delegating back to the end user code entirely.
+            //
+            // (See also #4499 and #12609; note that some of the
+            // discussions there influence what choice we make here;
+            // e.g. if we feature-gate `match x { ... }` when x refers
+            // to an uninhabited type (e.g. a zero-variant enum or a
+            // type holding such an enum), but do not feature-gate
+            // zero-variant enums themselves, then attempting to
+            // derive Show on such a type could here generate code
+            // that needs the feature gate enabled.)
+
+            return cx.expr_unreachable(sp);
         }
+
+        // Final wrinkle: the self_args are expressions that deref
+        // down to desired l-values, but we cannot actually deref
+        // them when they are fed as r-values into a tuple
+        // expression; here add a layer of borrowing, turning
+        // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
+        let borrowed_self_args = self_args.iter()
+            .map(|&self_arg| cx.expr_addr_of(sp, self_arg))
+            .collect::<Vec<Gc<ast::Expr>>>();
+        let match_arg = cx.expr(sp, ast::ExprTup(borrowed_self_args));
+        cx.expr_match(sp, match_arg, match_arms)
     }
 
     fn expand_static_enum_method_body(&self,
@@ -1170,7 +1295,7 @@ fn create_enum_variant_pattern(&self,
 pub fn cs_fold(use_foldl: bool,
                f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>, &[Gc<Expr>]| -> Gc<Expr>,
                base: Gc<Expr>,
-               enum_nonmatch_f: EnumNonMatchFunc,
+               enum_nonmatch_f: EnumNonMatchCollapsedFunc,
                cx: &mut ExtCtxt,
                trait_span: Span,
                substructure: &Substructure)
@@ -1195,9 +1320,9 @@ pub fn cs_fold(use_foldl: bool,
                 })
             }
         },
-        EnumNonMatching(ref all_enums) => enum_nonmatch_f(cx, trait_span,
-                                                          *all_enums,
-                                                          substructure.nonself_args),
+        EnumNonMatchingCollapsed(ref all_args, _, tuple) =>
+            enum_nonmatch_f(cx, trait_span, (all_args.as_slice(), tuple),
+                            substructure.nonself_args),
         StaticEnum(..) | StaticStruct(..) => {
             cx.span_bug(trait_span, "static function in `deriving`")
         }
@@ -1216,7 +1341,7 @@ pub fn cs_fold(use_foldl: bool,
 */
 #[inline]
 pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<Gc<Expr>>| -> Gc<Expr>,
-                      enum_nonmatch_f: EnumNonMatchFunc,
+                      enum_nonmatch_f: EnumNonMatchCollapsedFunc,
                       cx: &mut ExtCtxt,
                       trait_span: Span,
                       substructure: &Substructure)
@@ -1235,9 +1360,9 @@ pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<Gc<Expr>>| -> Gc<Expr>,
 
             f(cx, trait_span, called)
         },
-        EnumNonMatching(ref all_enums) => enum_nonmatch_f(cx, trait_span,
-                                                          *all_enums,
-                                                          substructure.nonself_args),
+        EnumNonMatchingCollapsed(ref all_self_args, _, tuple) =>
+            enum_nonmatch_f(cx, trait_span, (all_self_args.as_slice(), tuple),
+                            substructure.nonself_args),
         StaticEnum(..) | StaticStruct(..) => {
             cx.span_bug(trait_span, "static function in `deriving`")
         }
@@ -1253,7 +1378,7 @@ pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<Gc<Expr>>| -> Gc<Expr>,
 pub fn cs_same_method_fold(use_foldl: bool,
                            f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>| -> Gc<Expr>,
                            base: Gc<Expr>,
-                           enum_nonmatch_f: EnumNonMatchFunc,
+                           enum_nonmatch_f: EnumNonMatchCollapsedFunc,
                            cx: &mut ExtCtxt,
                            trait_span: Span,
                            substructure: &Substructure)
@@ -1280,7 +1405,7 @@ pub fn cs_same_method_fold(use_foldl: bool,
 */
 #[inline]
 pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
-                enum_nonmatch_f: EnumNonMatchFunc,
+                enum_nonmatch_f: EnumNonMatchCollapsedFunc,
                 cx: &mut ExtCtxt, trait_span: Span,
                 substructure: &Substructure) -> Gc<Expr> {
     cs_same_method_fold(
@@ -1298,7 +1423,7 @@ pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
 
 /// cs_binop with binop == or
 #[inline]
-pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
+pub fn cs_or(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
              cx: &mut ExtCtxt, span: Span,
              substructure: &Substructure) -> Gc<Expr> {
     cs_binop(ast::BiOr, cx.expr_bool(span, false),
@@ -1308,7 +1433,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
 
 /// cs_binop with binop == and
 #[inline]
-pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
+pub fn cs_and(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
               cx: &mut ExtCtxt, span: Span,
               substructure: &Substructure) -> Gc<Expr> {
     cs_binop(ast::BiAnd, cx.expr_bool(span, true),
index 7501b950770c2e0c96f603d7d536a612792265c3..f6a39d7b2e6c1b6dda6c57356f7de62592c1a98e 100644 (file)
 use ext::build::AstBuilder;
 use codemap::{Span,respan};
 use owned_slice::OwnedSlice;
+use parse::token::special_idents;
 
 use std::gc::Gc;
 
 /// The types of pointers
 pub enum PtrTy<'a> {
-    Send, // ~
-    Borrowed(Option<&'a str>, ast::Mutability), // &['lifetime] [mut]
+    /// ~
+    Send,
+    /// &'lifetime mut
+    Borrowed(Option<&'a str>, ast::Mutability),
 }
 
 /// A path, e.g. `::std::option::Option::<int>` (global). Has support
@@ -82,12 +85,12 @@ pub fn to_path(&self,
 /// A type. Supports pointers (except for *), Self, and literals
 pub enum Ty<'a> {
     Self,
-    // &/Box/ Ty
+    /// &/Box/ Ty
     Ptr(Box<Ty<'a>>, PtrTy<'a>),
-    // mod::mod::Type<[lifetime], [Params...]>, including a plain type
-    // parameter, and things like `int`
+    /// mod::mod::Type<[lifetime], [Params...]>, including a plain type
+    /// parameter, and things like `int`
     Literal(Path<'a>),
-    // includes nil
+    /// includes unit
     Tuple(Vec<Ty<'a>> )
 }
 
@@ -188,17 +191,18 @@ pub fn to_path(&self,
 }
 
 
-fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, sized: ast::Sized, bounds: &[Path],
+fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str,
+               bounds: &[Path], unbound: Option<ast::TyParamBound>,
                self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
     let bounds =
         bounds.iter().map(|b| {
             let path = b.to_path(cx, span, self_ident, self_generics);
             cx.typarambound(path)
         }).collect();
-    cx.typaram(span, cx.ident_of(name), sized, bounds, None)
+    cx.typaram(span, cx.ident_of(name), bounds, unbound, None)
 }
 
-fn mk_generics(lifetimes: Vec<ast::Lifetime> ,  ty_params: Vec<ast::TyParam> ) -> Generics {
+fn mk_generics(lifetimes: Vec<ast::Lifetime>, ty_params: Vec<ast::TyParam> ) -> Generics {
     Generics {
         lifetimes: lifetimes,
         ty_params: OwnedSlice::from_vec(ty_params)
@@ -208,7 +212,7 @@ fn mk_generics(lifetimes: Vec<ast::Lifetime> ,  ty_params: Vec<ast::TyParam> ) -
 /// Lifetimes and bounds on type parameters
 pub struct LifetimeBounds<'a> {
     pub lifetimes: Vec<&'a str>,
-    pub bounds: Vec<(&'a str, ast::Sized, Vec<Path<'a>>)>,
+    pub bounds: Vec<(&'a str, Option<ast::TyParamBound>, Vec<Path<'a>>)>,
 }
 
 impl<'a> LifetimeBounds<'a> {
@@ -228,12 +232,12 @@ pub fn to_generics(&self,
         }).collect();
         let ty_params = self.bounds.iter().map(|t| {
             match t {
-                &(ref name, sized, ref bounds) => {
+                &(ref name, ref unbound, ref bounds) => {
                     mk_ty_param(cx,
                                 span,
                                 *name,
-                                sized,
                                 bounds.as_slice(),
+                                unbound.clone(),
                                 self_ty,
                                 self_generics)
                 }
@@ -243,22 +247,23 @@ pub fn to_generics(&self,
     }
 }
 
-
 pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
     -> (Gc<Expr>, ast::ExplicitSelf) {
+    // this constructs a fresh `self` path, which will match the fresh `self` binding
+    // created below.
     let self_path = cx.expr_self(span);
     match *self_ptr {
         None => {
-            (self_path, respan(span, ast::SelfValue))
+            (self_path, respan(span, ast::SelfValue(special_idents::self_)))
         }
         Some(ref ptr) => {
             let self_ty = respan(
                 span,
                 match *ptr {
-                    Send => ast::SelfUniq,
+                    Send => ast::SelfUniq(special_idents::self_),
                     Borrowed(ref lt, mutbl) => {
                         let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
-                        ast::SelfRegion(lt, mutbl)
+                        ast::SelfRegion(lt, mutbl, special_idents::self_)
                     }
                 });
             let self_expr = cx.expr_deref(span, self_path);
index 77fb013b269a222331a368e933bdedbb83e2946b..f469139177a0b24e8ebb2551a036faf4897e797a 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast;
 use ast::{MetaItem, Item, Expr, MutMutable};
 use codemap::Span;
 use ext::base::ExtCtxt;
@@ -30,7 +29,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                     vec!(box Literal(Path::new_local("__S"))), true),
          LifetimeBounds {
              lifetimes: Vec::new(),
-             bounds: vec!(("__S", ast::StaticSize,
+             bounds: vec!(("__S", None,
                            vec!(Path::new(vec!("std", "hash", "Writer"))))),
          },
          Path::new_local("__S"))
@@ -55,7 +54,6 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                 args: vec!(Ptr(box Literal(args), Borrowed(None, MutMutable))),
                 ret_ty: nil_ty(),
                 attributes: attrs,
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     hash_substructure(a, b, c)
                 })
index 735497d9a2cf6ccfd6d50e9473d4545851cda2d5..30dd8e9683ad51b320d3e36d8c462d4d145205c0 100644 (file)
@@ -45,7 +45,6 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                            true)),
                 // #[inline] liable to cause code-bloat
                 attributes: attrs.clone(),
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|c, s, sub| {
                     cs_from("i64", c, s, sub)
                 }),
@@ -62,7 +61,6 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                            true)),
                 // #[inline] liable to cause code-bloat
                 attributes: attrs,
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|c, s, sub| {
                     cs_from("u64", c, s, sub)
                 }),
index f6a15ea917e187c74910ce9563da32f02e07e655..c652b5a5bed9a60c223ee7b6839927c98759d727 100644 (file)
@@ -35,7 +35,7 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                 generics: LifetimeBounds {
                     lifetimes: Vec::new(),
                     bounds: vec!(("R",
-                                  ast::StaticSize,
+                                  None,
                                   vec!( Path::new(vec!("std", "rand", "Rng")) )))
                 },
                 explicit_self: None,
@@ -45,7 +45,6 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                 ),
                 ret_ty: Self,
                 attributes: Vec::new(),
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     rand_substructure(a, b, c)
                 })
index 8e673ff2465980eb5c345c89db2cc4e5c07f8d69..e0dfbb232f554fcf0c7343f29ef89f608f4a4ed0 100644 (file)
@@ -45,7 +45,6 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
                 args: vec!(fmtr),
                 ret_ty: Literal(Path::new(vec!("std", "fmt", "Result"))),
                 attributes: Vec::new(),
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     show_substructure(a, b, c)
                 })
@@ -55,8 +54,8 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
     trait_def.expand(cx, mitem, item, push)
 }
 
-// we construct a format string and then defer to std::fmt, since that
-// knows what's up with formatting at so on.
+/// We construct a format string and then defer to std::fmt, since that
+/// knows what's up with formatting and so on.
 fn show_substructure(cx: &mut ExtCtxt, span: Span,
                      substr: &Substructure) -> Gc<Expr> {
     // build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {},
@@ -66,8 +65,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     let name = match *substr.fields {
         Struct(_) => substr.type_ident,
         EnumMatching(_, v, _) => v.node.name,
-
-        EnumNonMatching(..) | StaticStruct(..) | StaticEnum(..) => {
+        EnumNonMatchingCollapsed(..) | StaticStruct(..) | StaticEnum(..) => {
             cx.span_bug(span, "nonsensical .fields in `#[deriving(Show)]`")
         }
     };
index 93947251223fd18eacc5a2e6f6d3eab521f48f88..973f9d518cd70563c373cce5e0d9e2c50f26c450 100644 (file)
@@ -39,7 +39,6 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                 args: Vec::new(),
                 ret_ty: Self,
                 attributes: attrs.clone(),
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     zero_substructure(a, b, c)
                 })
@@ -51,7 +50,6 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                 args: Vec::new(),
                 ret_ty: Literal(Path::new(vec!("bool"))),
                 attributes: attrs,
-                const_nonmatching: false,
                 combine_substructure: combine_substructure(|cx, span, substr| {
                     cs_and(|cx, span, _, _| cx.span_bug(span,
                                                         "Non-matching enum \
index 9ef7241ca24842ed38292aa1b3c27f7a563b1c85..b24cfb85794edcf2c5754f128f933243429e12d6 100644 (file)
@@ -70,7 +70,7 @@ pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Some(exprs) => exprs
     };
 
-    let var = match expr_to_str(cx,
+    let var = match expr_to_string(cx,
                                 *exprs.get(0),
                                 "expected string literal") {
         None => return DummyResult::expr(sp),
@@ -83,7 +83,7 @@ pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                                                 var).as_slice())
         }
         2 => {
-            match expr_to_str(cx, *exprs.get(1), "expected string literal") {
+            match expr_to_string(cx, *exprs.get(1), "expected string literal") {
                 None => return DummyResult::expr(sp),
                 Some((s, _style)) => s
             }
index c3413293e52ae4b1ac664de13b7246ccffdd5070..58689389769c9979b063793d3cc69131cd251c0a 100644 (file)
@@ -19,8 +19,8 @@
 use attr::AttrMetaMethods;
 use codemap;
 use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
-use crateid::CrateId;
 use ext::base::*;
+use fold;
 use fold::*;
 use parse;
 use parse::token::{fresh_mark, fresh_name, intern};
@@ -37,92 +37,28 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
         // expr_mac should really be expr_ext or something; it's the
         // entry-point for all syntax extensions.
         ExprMac(ref mac) => {
-            match (*mac).node {
-                // it would almost certainly be cleaner to pass the whole
-                // macro invocation in, rather than pulling it apart and
-                // marking the tts and the ctxt separately. This also goes
-                // for the other three macro invocation chunks of code
-                // in this file.
-                // Token-tree macros:
-                MacInvocTT(ref pth, ref tts, _) => {
-                    if pth.segments.len() > 1u {
-                        fld.cx.span_err(pth.span,
-                                        "expected macro name without module \
-                                         separators");
-                        // let compilation continue
-                        return DummyResult::raw_expr(e.span);
-                    }
-                    let extname = pth.segments.get(0).identifier;
-                    let extnamestr = token::get_ident(extname);
-                    let marked_after = match fld.extsbox.find(&extname.name) {
-                        None => {
-                            fld.cx.span_err(
-                                pth.span,
-                                format!("macro undefined: '{}'",
-                                        extnamestr.get()).as_slice());
-
-                            // let compilation continue
-                            return DummyResult::raw_expr(e.span);
-                        }
-                        Some(&NormalTT(ref expandfun, exp_span)) => {
-                            fld.cx.bt_push(ExpnInfo {
-                                call_site: e.span,
-                                callee: NameAndSpan {
-                                    name: extnamestr.get().to_string(),
-                                    format: MacroBang,
-                                    span: exp_span,
-                                },
-                            });
-                            let fm = fresh_mark();
-                            // mark before:
-                            let marked_before = mark_tts(tts.as_slice(), fm);
-
-                            // The span that we pass to the expanders we want to
-                            // be the root of the call stack. That's the most
-                            // relevant span and it's the actual invocation of
-                            // the macro.
-                            let mac_span = original_span(fld.cx);
-
-                            let expanded = match expandfun.expand(fld.cx,
-                                                   mac_span.call_site,
-                                                   marked_before.as_slice()).make_expr() {
-                                Some(e) => e,
-                                None => {
-                                    fld.cx.span_err(
-                                        pth.span,
-                                        format!("non-expression macro in expression position: {}",
-                                                extnamestr.get().as_slice()
-                                        ).as_slice());
-                                    return DummyResult::raw_expr(e.span);
-                                }
-                            };
+            let expanded_expr = match expand_mac_invoc(mac,&e.span,
+                                                       |r|{r.make_expr()},
+                                                       |expr,fm|{mark_expr(expr,fm)},
+                                                       fld) {
+                Some(expr) => expr,
+                None => {
+                    return DummyResult::raw_expr(e.span);
+                }
+            };
 
-                            // mark after:
-                            mark_expr(expanded,fm)
-                        }
-                        _ => {
-                            fld.cx.span_err(
-                                pth.span,
-                                format!("'{}' is not a tt-style macro",
-                                        extnamestr.get()).as_slice());
-                            return DummyResult::raw_expr(e.span);
-                        }
-                    };
+            // Keep going, outside-in.
+            //
+            // FIXME(pcwalton): Is it necessary to clone the
+            // node here?
+            let fully_expanded =
+                fld.fold_expr(expanded_expr).node.clone();
+            fld.cx.bt_pop();
 
-                    // Keep going, outside-in.
-                    //
-                    // FIXME(pcwalton): Is it necessary to clone the
-                    // node here?
-                    let fully_expanded =
-                        fld.fold_expr(marked_after).node.clone();
-                    fld.cx.bt_pop();
-
-                    box(GC) ast::Expr {
-                        id: ast::DUMMY_NODE_ID,
-                        node: fully_expanded,
-                        span: e.span,
-                    }
-                }
+            box(GC) ast::Expr {
+                id: ast::DUMMY_NODE_ID,
+                node: fully_expanded,
+                span: e.span,
             }
         }
 
@@ -228,15 +164,111 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
             fld.cx.expr(e.span, ast::ExprLoop(loop_block, opt_ident))
         }
 
+        ast::ExprFnBlock(fn_decl, block) => {
+            let (rewritten_fn_decl, rewritten_block)
+                = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+            let new_node = ast::ExprFnBlock(rewritten_fn_decl, rewritten_block);
+            box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
+        }
+
+        ast::ExprProc(fn_decl, block) => {
+            let (rewritten_fn_decl, rewritten_block)
+                = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+            let new_node = ast::ExprProc(rewritten_fn_decl, rewritten_block);
+            box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
+        }
+
         _ => noop_fold_expr(e, fld)
     }
 }
 
-// Rename loop label and expand its loop body
-//
-// The renaming procedure for loop is different in the sense that the loop
-// body is in a block enclosed by loop head so the renaming of loop label
-// must be propagated to the enclosed context.
+/// Expand a (not-ident-style) macro invocation. Returns the result
+/// of expansion and the mark which must be applied to the result.
+/// Our current interface doesn't allow us to apply the mark to the
+/// result until after calling make_expr, make_items, etc.
+fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span,
+                       parse_thunk: |Box<MacResult>|->Option<T>,
+                       mark_thunk: |T,Mrk|->T,
+                       fld: &mut MacroExpander)
+    -> Option<T> {
+    match (*mac).node {
+        // it would almost certainly be cleaner to pass the whole
+        // macro invocation in, rather than pulling it apart and
+        // marking the tts and the ctxt separately. This also goes
+        // for the other three macro invocation chunks of code
+        // in this file.
+        // Token-tree macros:
+        MacInvocTT(ref pth, ref tts, _) => {
+            if pth.segments.len() > 1u {
+                fld.cx.span_err(pth.span,
+                                "expected macro name without module \
+                                separators");
+                // let compilation continue
+                return None;
+            }
+            let extname = pth.segments.get(0).identifier;
+            let extnamestr = token::get_ident(extname);
+            match fld.extsbox.find(&extname.name) {
+                None => {
+                    fld.cx.span_err(
+                        pth.span,
+                        format!("macro undefined: '{}!'",
+                                extnamestr.get()).as_slice());
+
+                    // let compilation continue
+                    None
+                }
+                Some(&NormalTT(ref expandfun, exp_span)) => {
+                    fld.cx.bt_push(ExpnInfo {
+                            call_site: *span,
+                            callee: NameAndSpan {
+                                name: extnamestr.get().to_string(),
+                                format: MacroBang,
+                                span: exp_span,
+                            },
+                        });
+                    let fm = fresh_mark();
+                    let marked_before = mark_tts(tts.as_slice(), fm);
+
+                    // The span that we pass to the expanders we want to
+                    // be the root of the call stack. That's the most
+                    // relevant span and it's the actual invocation of
+                    // the macro.
+                    let mac_span = original_span(fld.cx);
+
+                    let expanded = expandfun.expand(fld.cx,
+                                                    mac_span.call_site,
+                                                    marked_before.as_slice());
+                    let parsed = match parse_thunk(expanded) {
+                        Some(e) => e,
+                        None => {
+                            fld.cx.span_err(
+                                pth.span,
+                                format!("non-expression macro in expression position: {}",
+                                        extnamestr.get().as_slice()
+                                        ).as_slice());
+                            return None;
+                        }
+                    };
+                    Some(mark_thunk(parsed,fm))
+                }
+                _ => {
+                    fld.cx.span_err(
+                        pth.span,
+                        format!("'{}' is not a tt-style macro",
+                                extnamestr.get()).as_slice());
+                    None
+                }
+            }
+        }
+    }
+}
+
+/// Rename loop label and expand its loop body
+///
+/// The renaming procedure for loop is different in the sense that the loop
+/// body is in a block enclosed by loop head so the renaming of loop label
+/// must be propagated to the enclosed context.
 fn expand_loop_block(loop_block: P<Block>,
                      opt_ident: Option<Ident>,
                      fld: &mut MacroExpander) -> (P<Block>, Option<Ident>) {
@@ -267,7 +299,8 @@ fn expand_loop_block(loop_block: P<Block>,
     }
 }
 
-// eval $e with a new exts frame:
+// eval $e with a new exts frame.
+// must be a macro so that $e isn't evaluated too early.
 macro_rules! with_exts_frame (
     ($extsboxexpr:expr,$macros_escape:expr,$e:expr) =>
     ({$extsboxexpr.push_frame();
@@ -342,15 +375,16 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
 
 fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
                          -> Gc<ast::Item> {
-    let (modifiers, attrs) = it.attrs.partitioned(|attr| {
+    // partition the attributes into ItemModifiers and others
+    let (modifiers, other_attrs) = it.attrs.partitioned(|attr| {
         match fld.extsbox.find(&intern(attr.name().get())) {
             Some(&ItemModifier(_)) => true,
             _ => false
         }
     });
-
+    // update the attrs, leave everything else alone. Is this mutation really a good idea?
     it = box(GC) ast::Item {
-        attrs: attrs,
+        attrs: other_attrs,
         ..(*it).clone()
     };
 
@@ -383,6 +417,19 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
     expand_item_modifiers(it, fld)
 }
 
+/// Expand item_underscore
+fn expand_item_underscore(item: &ast::Item_, fld: &mut MacroExpander) -> ast::Item_ {
+    match *item {
+        ast::ItemFn(decl, fn_style, abi, ref generics, body) => {
+            let (rewritten_fn_decl, rewritten_body)
+                = expand_and_rename_fn_decl_and_block(decl,body,fld);
+            let expanded_generics = fold::fold_generics(generics,fld);
+            ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body)
+        }
+        _ => noop_fold_item_underscore(&*item, fld)
+    }
+}
+
 // does this attribute list contain "macro_escape" ?
 fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
     attr::contains_name(attrs, "macro_escape")
@@ -455,6 +502,24 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
             let marked_tts = mark_tts(tts.as_slice(), fm);
             expander.expand(fld.cx, it.span, it.ident, marked_tts)
         }
+        Some(&LetSyntaxTT(ref expander, span)) => {
+            if it.ident.name == parse::token::special_idents::invalid.name {
+                fld.cx.span_err(pth.span,
+                                format!("macro {}! expects an ident argument",
+                                        extnamestr.get()).as_slice());
+                return SmallVector::zero();
+            }
+            fld.cx.bt_push(ExpnInfo {
+                call_site: it.span,
+                callee: NameAndSpan {
+                    name: extnamestr.get().to_string(),
+                    format: MacroBang,
+                    span: span
+                }
+            });
+            // DON'T mark before expansion:
+            expander.expand(fld.cx, it.span, it.ident, tts)
+        }
         _ => {
             fld.cx.span_err(it.span,
                             format!("{}! is not legal in item position",
@@ -465,20 +530,21 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
 
     let items = match expanded.make_def() {
         Some(MacroDef { name, ext }) => {
-            // yikes... no idea how to apply the mark to this. I'm afraid
-            // we're going to have to wait-and-see on this one.
+            // hidden invariant: this should only be possible as the
+            // result of expanding a LetSyntaxTT, and thus doesn't
+            // need to be marked. Not that it could be marked anyway.
+            // create issue to recommend refactoring here?
             fld.extsbox.insert(intern(name.as_slice()), ext);
             if attr::contains_name(it.attrs.as_slice(), "macro_export") {
-                SmallVector::one(it)
-            } else {
-                SmallVector::zero()
+                fld.cx.push_exported_macro(it.span);
             }
+            SmallVector::zero()
         }
         None => {
             match expanded.make_items() {
                 Some(items) => {
                     items.move_iter()
-                        .flat_map(|i| mark_item(i, fm).move_iter())
+                        .map(|i| mark_item(i, fm))
                         .flat_map(|i| fld.fold_item(i).move_iter())
                         .collect()
                 }
@@ -495,79 +561,27 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
     return items;
 }
 
-// expand a stmt
+/// Expand a stmt
+//
+// I don't understand why this returns a vector... it looks like we're
+// half done adding machinery to allow macros to expand into multiple statements.
 fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
-    // why the copying here and not in expand_expr?
-    // looks like classic changed-in-only-one-place
-    let (pth, tts, semi) = match s.node {
-        StmtMac(ref mac, semi) => {
-            match mac.node {
-                MacInvocTT(ref pth, ref tts, _) => {
-                    (pth, (*tts).clone(), semi)
-                }
-            }
-        }
+    let (mac, semi) = match s.node {
+        StmtMac(ref mac, semi) => (mac, semi),
         _ => return expand_non_macro_stmt(s, fld)
     };
-    if pth.segments.len() > 1u {
-        fld.cx.span_err(pth.span, "expected macro name without module separators");
-        return SmallVector::zero();
-    }
-    let extname = pth.segments.get(0).identifier;
-    let extnamestr = token::get_ident(extname);
-    let marked_after = match fld.extsbox.find(&extname.name) {
+    let expanded_stmt = match expand_mac_invoc(mac,&s.span,
+                                                |r|{r.make_stmt()},
+                                                |sts,mrk|{mark_stmt(sts,mrk)},
+                                                fld) {
+        Some(stmt) => stmt,
         None => {
-            fld.cx.span_err(pth.span,
-                            format!("macro undefined: '{}'",
-                                    extnamestr).as_slice());
-            return SmallVector::zero();
-        }
-
-        Some(&NormalTT(ref expandfun, exp_span)) => {
-            fld.cx.bt_push(ExpnInfo {
-                call_site: s.span,
-                callee: NameAndSpan {
-                    name: extnamestr.get().to_string(),
-                    format: MacroBang,
-                    span: exp_span,
-                }
-            });
-            let fm = fresh_mark();
-            // mark before expansion:
-            let marked_tts = mark_tts(tts.as_slice(), fm);
-
-            // See the comment in expand_expr for why we want the original span,
-            // not the current mac.span.
-            let mac_span = original_span(fld.cx);
-
-            let expanded = match expandfun.expand(fld.cx,
-                                                  mac_span.call_site,
-                                                  marked_tts.as_slice()).make_stmt() {
-                Some(stmt) => stmt,
-                None => {
-                    fld.cx.span_err(pth.span,
-                                    format!("non-statement macro in statement position: {}",
-                                            extnamestr).as_slice());
-                    return SmallVector::zero();
-                }
-            };
-
-            mark_stmt(&*expanded,fm)
-        }
-
-        _ => {
-            fld.cx.span_err(pth.span, format!("'{}' is not a tt-style macro",
-                                              extnamestr).as_slice());
             return SmallVector::zero();
         }
     };
 
     // Keep going, outside-in.
-    let fully_expanded = fld.fold_stmt(&*marked_after);
-    if fully_expanded.is_empty() {
-        fld.cx.span_err(pth.span, "macro didn't expand to a statement");
-        return SmallVector::zero();
-    }
+    let fully_expanded = fld.fold_stmt(&*expanded_stmt);
     fld.cx.bt_pop();
     let fully_expanded: SmallVector<Gc<Stmt>> = fully_expanded.move_iter()
             .map(|s| box(GC) Spanned { span: s.span, node: s.node.clone() })
@@ -609,7 +623,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
                     } = **local;
                     // expand the pat (it might contain macro uses):
                     let expanded_pat = fld.fold_pat(pat);
-                    // find the pat_idents in the pattern:
+                    // find the PatIdents in the pattern:
                     // oh dear heaven... this is going to include the enum
                     // names, as well... but that should be okay, as long as
                     // the new names are gensyms for the old ones.
@@ -653,6 +667,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
     }
 }
 
+// expand the arm of a 'match', renaming for macro hygiene
 fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
     // expand pats... they might contain macro uses:
     let expanded_pats : Vec<Gc<ast::Pat>> = arm.pats.iter().map(|pat| fld.fold_pat(*pat)).collect();
@@ -662,22 +677,15 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
     // all of the pats must have the same set of bindings, so use the
     // first one to extract them and generate new names:
     let first_pat = expanded_pats.get(0);
-    // code duplicated from 'let', above. Perhaps this can be lifted
-    // into a separate function:
     let idents = pattern_bindings(*first_pat);
-    let mut new_pending_renames =
+    let new_renames =
         idents.iter().map(|id| (*id,fresh_name(id))).collect();
-    // rewrite all of the patterns using the new names (the old
-    // ones have already been applied). Note that we depend here
-    // on the guarantee that after expansion, there can't be any
-    // Path expressions (a.k.a. varrefs) left in the pattern. If
-    // this were false, we'd need to apply this renaming only to
-    // the bindings, and not to the varrefs, using a more targeted
-    // fold-er.
-    let mut rename_fld = IdentRenamer{renames:&mut new_pending_renames};
+    // apply the renaming, but only to the PatIdents:
+    let mut rename_pats_fld = PatIdentRenamer{renames:&new_renames};
     let rewritten_pats =
-        expanded_pats.iter().map(|pat| rename_fld.fold_pat(*pat)).collect();
+        expanded_pats.iter().map(|pat| rename_pats_fld.fold_pat(*pat)).collect();
     // apply renaming and then expansion to the guard and the body:
+    let mut rename_fld = IdentRenamer{renames:&new_renames};
     let rewritten_guard =
         arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g)));
     let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body));
@@ -689,45 +697,46 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
     }
 }
 
-
-
-// a visitor that extracts the pat_ident (binding) paths
-// from a given thingy and puts them in a mutable
-// array
+/// A visitor that extracts the PatIdent (binding) paths
+/// from a given thingy and puts them in a mutable
+/// array
 #[deriving(Clone)]
-struct NameFinderContext {
+struct PatIdentFinder {
     ident_accumulator: Vec<ast::Ident> ,
 }
 
-impl Visitor<()> for NameFinderContext {
+impl Visitor<()> for PatIdentFinder {
     fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
         match *pattern {
-            // we found a pat_ident!
-            ast::Pat {
-                id: _,
-                node: ast::PatIdent(_, ref path1, ref inner),
-                span: _
-            } => {
+            ast::Pat { id: _, node: ast::PatIdent(_, ref path1, ref inner), span: _ } => {
                 self.ident_accumulator.push(path1.node);
-                // visit optional subpattern of pat_ident:
+                // visit optional subpattern of PatIdent:
                 for subpat in inner.iter() {
                     self.visit_pat(&**subpat, ())
                 }
             }
-            // use the default traversal for non-pat_idents
+            // use the default traversal for non-PatIdents
             _ => visit::walk_pat(self, pattern, ())
         }
     }
-
 }
 
-// find the pat_ident paths in a pattern
+/// find the PatIdent paths in a pattern
 fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
-    let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
+    let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
     name_finder.visit_pat(pat,());
     name_finder.ident_accumulator
 }
 
+/// find the PatIdent paths in a
+fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
+    let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
+    for arg in fn_decl.inputs.iter() {
+        pat_idents.visit_pat(arg.pat,());
+    }
+    pat_idents.ident_accumulator
+}
+
 // expand a block. pushes a new exts_frame, then calls expand_block_elts
 fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> {
     // see note below about treatment of exts table
@@ -844,34 +853,117 @@ fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
     }
 }
 
-// a tree-folder that applies every rename in its (mutable) list
-// to every identifier, including both bindings and varrefs
-// (and lots of things that will turn out to be neither)
+/// A tree-folder that applies every rename in its (mutable) list
+/// to every identifier, including both bindings and varrefs
+/// (and lots of things that will turn out to be neither)
 pub struct IdentRenamer<'a> {
-    renames: &'a mut RenameList,
+    renames: &'a mtwt::RenameList,
 }
 
 impl<'a> Folder for IdentRenamer<'a> {
     fn fold_ident(&mut self, id: Ident) -> Ident {
-        let new_ctxt = self.renames.iter().fold(id.ctxt, |ctxt, &(from, to)| {
-            mtwt::new_rename(from, to, ctxt)
-        });
         Ident {
             name: id.name,
-            ctxt: new_ctxt,
+            ctxt: mtwt::apply_renames(self.renames, id.ctxt),
         }
     }
+    fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac {
+        fold::fold_mac(macro, self)
+    }
 }
 
-fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
-    /* this discards information in the case of macro-defining macros */
-    Span {
-        lo: sp.lo,
-        hi: sp.hi,
-        expn_info: cx.backtrace(),
+/// A tree-folder that applies every rename in its list to
+/// the idents that are in PatIdent patterns. This is more narrowly
+/// focused than IdentRenamer, and is needed for FnDecl,
+/// where we want to rename the args but not the fn name or the generics etc.
+pub struct PatIdentRenamer<'a> {
+    renames: &'a mtwt::RenameList,
+}
+
+impl<'a> Folder for PatIdentRenamer<'a> {
+    fn fold_pat(&mut self, pat: Gc<ast::Pat>) -> Gc<ast::Pat> {
+        match pat.node {
+            ast::PatIdent(binding_mode, Spanned{span: ref sp, node: id}, ref sub) => {
+                let new_ident = Ident{name: id.name,
+                                      ctxt: mtwt::apply_renames(self.renames, id.ctxt)};
+                let new_node =
+                    ast::PatIdent(binding_mode,
+                                  Spanned{span: self.new_span(*sp), node: new_ident},
+                                  sub.map(|p| self.fold_pat(p)));
+                box(GC) ast::Pat {
+                    id: pat.id,
+                    span: self.new_span(pat.span),
+                    node: new_node,
+                }
+            },
+            _ => noop_fold_pat(pat, self)
+        }
+    }
+    fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac {
+        fold::fold_mac(macro, self)
+    }
+}
+
+// expand a method
+fn expand_method(m: &ast::Method, fld: &mut MacroExpander) -> SmallVector<Gc<ast::Method>> {
+    let id = fld.new_id(m.id);
+    match m.node {
+        ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
+            let (rewritten_fn_decl, rewritten_body)
+                = expand_and_rename_fn_decl_and_block(decl,body,fld);
+            SmallVector::one(box(GC) ast::Method {
+                    attrs: m.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(),
+                    id: id,
+                    span: fld.new_span(m.span),
+                    node: ast::MethDecl(fld.fold_ident(ident),
+                                        fold_generics(generics, fld),
+                                        fld.fold_explicit_self(explicit_self),
+                                        fn_style,
+                                        rewritten_fn_decl,
+                                        rewritten_body,
+                                        vis)
+                })
+        },
+        ast::MethMac(ref mac) => {
+            let maybe_new_methods =
+                expand_mac_invoc(mac, &m.span,
+                                 |r|{r.make_methods()},
+                                 |meths,mark|{
+                    meths.move_iter().map(|m|{mark_method(m,mark)})
+                        .collect()},
+                                 fld);
+
+            let new_methods = match maybe_new_methods {
+                Some(methods) => methods,
+                None => SmallVector::zero()
+            };
+
+            // expand again if necessary
+            new_methods.move_iter().flat_map(|m| fld.fold_method(m).move_iter()).collect()
+        }
     }
 }
 
+/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
+/// PatIdents in its arguments to perform renaming in the FnDecl and
+/// the block, returning both the new FnDecl and the new Block.
+fn expand_and_rename_fn_decl_and_block(fn_decl: &ast::FnDecl, block: Gc<ast::Block>,
+                                       fld: &mut MacroExpander)
+    -> (Gc<ast::FnDecl>, Gc<ast::Block>) {
+    let expanded_decl = fld.fold_fn_decl(fn_decl);
+    let idents = fn_decl_arg_bindings(expanded_decl);
+    let renames =
+        idents.iter().map(|id : &ast::Ident| (*id,fresh_name(id))).collect();
+    // first, a renamer for the PatIdents, for the fn_decl:
+    let mut rename_pat_fld = PatIdentRenamer{renames: &renames};
+    let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(expanded_decl);
+    // now, a renamer for *all* idents, for the body:
+    let mut rename_fld = IdentRenamer{renames: &renames};
+    let rewritten_body = fld.fold_block(rename_fld.fold_block(block));
+    (rewritten_fn_decl,rewritten_body)
+}
+
+/// A tree-folder that performs macro expansion
 pub struct MacroExpander<'a, 'b> {
     pub extsbox: SyntaxEnv,
     pub cx: &'a mut ExtCtxt<'b>,
@@ -890,6 +982,10 @@ fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
         expand_item(item, self)
     }
 
+    fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
+        expand_item_underscore(item, self)
+    }
+
     fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<Gc<ast::Stmt>> {
         expand_stmt(stmt, self)
     }
@@ -902,14 +998,27 @@ fn fold_arm(&mut self, arm: &ast::Arm) -> ast::Arm {
         expand_arm(arm, self)
     }
 
+    fn fold_method(&mut self, method: Gc<ast::Method>) -> SmallVector<Gc<ast::Method>> {
+        expand_method(method, self)
+    }
+
     fn new_span(&mut self, span: Span) -> Span {
         new_span(self.cx, span)
     }
 }
 
+fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
+    /* this discards information in the case of macro-defining macros */
+    Span {
+        lo: sp.lo,
+        hi: sp.hi,
+        expn_info: cx.backtrace(),
+    }
+}
+
 pub struct ExpansionConfig {
     pub deriving_hash_type_parameter: bool,
-    pub crate_id: CrateId,
+    pub crate_name: String,
 }
 
 pub struct ExportedMacros {
@@ -919,6 +1028,7 @@ pub struct ExportedMacros {
 
 pub fn expand_crate(parse_sess: &parse::ParseSess,
                     cfg: ExpansionConfig,
+                    // these are the macros being imported to this crate:
                     macros: Vec<ExportedMacros>,
                     user_exts: Vec<NamedSyntaxExtension>,
                     c: Crate) -> Crate {
@@ -946,7 +1056,8 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
         expander.extsbox.insert(name, extension);
     }
 
-    let ret = expander.fold_crate(c);
+    let mut ret = expander.fold_crate(c);
+    ret.exported_macros = expander.cx.exported_macros.clone();
     parse_sess.span_diagnostic.handler().abort_if_errors();
     return ret;
 }
@@ -966,7 +1077,7 @@ impl Folder for Marker {
     fn fold_ident(&mut self, id: Ident) -> Ident {
         ast::Ident {
             name: id.name,
-            ctxt: mtwt::new_mark(self.mark, id.ctxt)
+            ctxt: mtwt::apply_mark(self.mark, id.ctxt)
         }
     }
     fn fold_mac(&mut self, m: &ast::Mac) -> ast::Mac {
@@ -974,7 +1085,7 @@ fn fold_mac(&mut self, m: &ast::Mac) -> ast::Mac {
             MacInvocTT(ref path, ref tts, ctxt) => {
                 MacInvocTT(self.fold_path(path),
                            fold_tts(tts.as_slice(), self),
-                           mtwt::new_mark(self.mark, ctxt))
+                           mtwt::apply_mark(self.mark, ctxt))
             }
         };
         Spanned {
@@ -1002,12 +1113,19 @@ fn mark_pat(pat: Gc<ast::Pat>, m: Mrk) -> Gc<ast::Pat> {
 // apply a given mark to the given stmt. Used following the expansion of a macro.
 fn mark_stmt(expr: &ast::Stmt, m: Mrk) -> Gc<ast::Stmt> {
     Marker{mark:m}.fold_stmt(expr)
-            .expect_one("marking a stmt didn't return a stmt")
+        .expect_one("marking a stmt didn't return exactly one stmt")
 }
 
 // apply a given mark to the given item. Used following the expansion of a macro.
-fn mark_item(expr: Gc<ast::Item>, m: Mrk) -> SmallVector<Gc<ast::Item>> {
+fn mark_item(expr: Gc<ast::Item>, m: Mrk) -> Gc<ast::Item> {
     Marker{mark:m}.fold_item(expr)
+        .expect_one("marking an item didn't return exactly one item")
+}
+
+// apply a given mark to the given item. Used following the expansion of a macro.
+fn mark_method(expr: Gc<ast::Method>, m: Mrk) -> Gc<ast::Method> {
+    Marker{mark:m}.fold_method(expr)
+        .expect_one("marking an item didn't return exactly one method")
 }
 
 fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
@@ -1025,16 +1143,36 @@ fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
     return einfo;
 }
 
+/// Check that there are no macro invocations left in the AST:
+pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) {
+    visit::walk_crate(&mut MacroExterminator{sess:sess}, krate, ());
+}
+
+/// A visitor that ensures that no macro invocations remain in an AST.
+struct MacroExterminator<'a>{
+    sess: &'a parse::ParseSess
+}
+
+impl<'a> visit::Visitor<()> for MacroExterminator<'a> {
+    fn visit_mac(&mut self, macro: &ast::Mac, _:()) {
+        self.sess.span_diagnostic.span_bug(macro.span,
+                                           "macro exterminator: expected AST \
+                                           with no macro invocations");
+    }
+}
+
+
 #[cfg(test)]
 mod test {
     use super::{pattern_bindings, expand_crate, contains_macro_escape};
-    use super::{NameFinderContext};
+    use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer};
     use ast;
-    use ast::{Attribute_, AttrOuter, MetaWord};
+    use ast::{Attribute_, AttrOuter, MetaWord, Name};
     use attr;
     use codemap;
     use codemap::Spanned;
     use ext::mtwt;
+    use fold::Folder;
     use parse;
     use parse::token;
     use util::parser_testing::{string_to_parser};
@@ -1072,7 +1210,24 @@ fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
         path_finder.path_accumulator
     }
 
+    /// A Visitor that extracts the identifiers from a thingy.
+    // as a side note, I'm starting to want to abstract over these....
+    struct IdentFinder{
+        ident_accumulator: Vec<ast::Ident>
+    }
 
+    impl Visitor<()> for IdentFinder {
+        fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident, _: ()){
+            self.ident_accumulator.push(id);
+        }
+    }
+
+    /// Find the idents in a crate
+    fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
+        let mut ident_finder = IdentFinder{ident_accumulator: Vec::new()};
+        visit::walk_crate(&mut ident_finder, the_crate, ());
+        ident_finder.ident_accumulator
+    }
 
     // these following tests are quite fragile, in that they don't test what
     // *kind* of failure occurs.
@@ -1090,7 +1245,7 @@ fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
         // should fail:
         let cfg = ::syntax::ext::expand::ExpansionConfig {
             deriving_hash_type_parameter: false,
-            crate_id: from_str("test").unwrap(),
+            crate_name: "test".to_string(),
         };
         expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
     }
@@ -1107,7 +1262,7 @@ fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
             Vec::new(), &sess);
         let cfg = ::syntax::ext::expand::ExpansionConfig {
             deriving_hash_type_parameter: false,
-            crate_id: from_str("test").unwrap(),
+            crate_name: "test".to_string(),
         };
         expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
     }
@@ -1123,7 +1278,7 @@ fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
             Vec::new(), &sess);
         let cfg = ::syntax::ext::expand::ExpansionConfig {
             deriving_hash_type_parameter: false,
-            crate_id: from_str("test").unwrap(),
+            crate_name: "test".to_string(),
         };
         expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
     }
@@ -1160,19 +1315,18 @@ fn expand_crate_str(crate_str: String) -> ast::Crate {
         // the cfg argument actually does matter, here...
         let cfg = ::syntax::ext::expand::ExpansionConfig {
             deriving_hash_type_parameter: false,
-            crate_id: from_str("test").unwrap(),
+            crate_name: "test".to_string(),
         };
         expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
     }
 
     // find the pat_ident paths in a crate
     fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
-        let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
+        let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
         visit::walk_crate(&mut name_finder, the_crate, ());
         name_finder.ident_accumulator
     }
 
-
     //fn expand_and_resolve(crate_str: @str) -> ast::crate {
         //let expanded_ast = expand_crate_str(crate_str);
         // println!("expanded: {:?}\n",expanded_ast);
@@ -1180,7 +1334,7 @@ fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
     //}
     //fn expand_and_resolve_and_pretty_print (crate_str: @str) -> String {
         //let resolved_ast = expand_and_resolve(crate_str);
-        //pprust::to_str(&resolved_ast,fake_print_crate,get_ident_interner())
+        //pprust::to_string(&resolved_ast,fake_print_crate,get_ident_interner())
     //}
 
     #[test] fn macro_tokens_should_match(){
@@ -1188,6 +1342,14 @@ fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
             "macro_rules! m((a)=>(13)) fn main(){m!(a);}".to_string());
     }
 
+    // should be able to use a bound identifier as a literal in a macro definition:
+    #[test] fn self_macro_parsing(){
+        expand_crate_str(
+            "macro_rules! foo ((zz) => (287u;))
+            fn f(zz : int) {foo!(zz);}".to_string()
+            );
+    }
+
     // renaming tests expand a crate and then check that the bindings match
     // the right varrefs. The specification of the test case includes the
     // text of the crate, and also an array of arrays.  Each element in the
@@ -1298,18 +1460,85 @@ macro_rules! outer ( ($e:pat ) => (inner!($e)))
     // but *shouldn't* bind because it was inserted by a different macro....
     // can't write this test case until we have macro-generating macros.
 
-    // FIXME #9383 : lambda var hygiene
-    // interesting... can't even write this test, yet, because the name-finder
-    // only finds pattern vars. Time to upgrade test framework.
-    /*#[test]
-    fn issue_9383(){
+    // method arg hygiene
+    // method expands to fn get_x(&self_0, x_1:int) {self_0 + self_2 + x_3 + x_1}
+    #[test] fn method_arg_hygiene(){
         run_renaming_test(
-            &("macro_rules! bad_macro (($ex:expr) => ({(|_x| { $ex }) (9) }))
-              fn takes_x(_x : int) { assert_eq!(bad_macro!(_x),8); }
-              fn main() { takes_x(8); }",
-              vec!(vec!()),false),
+            &("macro_rules! inject_x (()=>(x))
+              macro_rules! inject_self (()=>(self))
+              struct A;
+              impl A{fn get_x(&self, x: int) {self + inject_self!() + inject_x!() + x;} }",
+              vec!(vec!(0),vec!(3)),
+              true),
             0)
-    }*/
+    }
+
+    // ooh, got another bite?
+    // expands to struct A; impl A {fn thingy(&self_1) {self_1;}}
+    #[test] fn method_arg_hygiene_2(){
+        run_renaming_test(
+            &("struct A;
+              macro_rules! add_method (($T:ty) =>
+              (impl $T {  fn thingy(&self) {self;} }))
+              add_method!(A)",
+              vec!(vec!(0)),
+              true),
+            0)
+    }
+
+    // item fn hygiene
+    // expands to fn q(x_1:int){fn g(x_2:int){x_2 + x_1};}
+    #[test] fn issue_9383(){
+        run_renaming_test(
+            &("macro_rules! bad_macro (($ex:expr) => (fn g(x:int){ x + $ex }))
+              fn q(x:int) { bad_macro!(x); }",
+              vec!(vec!(1),vec!(0)),true),
+            0)
+    }
+
+    // closure arg hygiene (ExprFnBlock)
+    // expands to fn f(){(|x_1 : int| {(x_2 + x_1)})(3);}
+    #[test] fn closure_arg_hygiene(){
+        run_renaming_test(
+            &("macro_rules! inject_x (()=>(x))
+            fn f(){(|x : int| {(inject_x!() + x)})(3);}",
+              vec!(vec!(1)),
+              true),
+            0)
+    }
+
+    // closure arg hygiene (ExprProc)
+    // expands to fn f(){(proc(x_1 : int) {(x_2 + x_1)})(3);}
+    #[test] fn closure_arg_hygiene_2(){
+        run_renaming_test(
+            &("macro_rules! inject_x (()=>(x))
+              fn f(){ (proc(x : int){(inject_x!() + x)})(3); }",
+              vec!(vec!(1)),
+              true),
+            0)
+    }
+
+    // macro_rules in method position. Sadly, unimplemented.
+    #[test] fn macro_in_method_posn(){
+        expand_crate_str(
+            "macro_rules! my_method (() => (fn thirteen(&self) -> int {13}))
+            struct A;
+            impl A{ my_method!()}
+            fn f(){A.thirteen;}".to_string());
+    }
+
+    // another nested macro
+    // expands to impl Entries {fn size_hint(&self_1) {self_1;}
+    #[test] fn item_macro_workaround(){
+        run_renaming_test(
+            &("macro_rules! item { ($i:item) => {$i}}
+              struct Entries;
+              macro_rules! iterator_impl {
+              () => { item!( impl Entries { fn size_hint(&self) { self;}})}}
+              iterator_impl! { }",
+              vec!(vec!(0)), true),
+            0)
+    }
 
     // run one of the renaming tests
     fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
@@ -1330,27 +1559,36 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
             assert!((shouldmatch.len() == 0) ||
                     (varrefs.len() > *shouldmatch.iter().max().unwrap()));
             for (idx,varref) in varrefs.iter().enumerate() {
+                let print_hygiene_debug_info = || {
+                    // good lord, you can't make a path with 0 segments, can you?
+                    let final_varref_ident = match varref.segments.last() {
+                        Some(pathsegment) => pathsegment.identifier,
+                        None => fail!("varref with 0 path segments?")
+                    };
+                    let varref_name = mtwt::resolve(final_varref_ident);
+                    let varref_idents : Vec<ast::Ident>
+                        = varref.segments.iter().map(|s| s.identifier)
+                        .collect();
+                    println!("varref #{}: {}, resolves to {}",idx, varref_idents, varref_name);
+                    let string = token::get_ident(final_varref_ident);
+                    println!("varref's first segment's string: \"{}\"", string.get());
+                    println!("binding #{}: {}, resolves to {}",
+                             binding_idx, *bindings.get(binding_idx), binding_name);
+                    mtwt::with_sctable(|x| mtwt::display_sctable(x));
+                };
                 if shouldmatch.contains(&idx) {
                     // it should be a path of length 1, and it should
                     // be free-identifier=? or bound-identifier=? to the given binding
                     assert_eq!(varref.segments.len(),1);
-                    let varref_name = mtwt::resolve(varref.segments
-                                                          .get(0)
-                                                          .identifier);
+                    let varref_name = mtwt::resolve(varref.segments.get(0).identifier);
                     let varref_marks = mtwt::marksof(varref.segments
                                                            .get(0)
                                                            .identifier
                                                            .ctxt,
                                                      invalid_name);
                     if !(varref_name==binding_name) {
-                        let varref_idents : Vec<ast::Ident>
-                            = varref.segments.iter().map(|s|
-                                                         s.identifier)
-                            .collect();
                         println!("uh oh, should match but doesn't:");
-                        println!("varref #{}: {}",idx, varref_idents);
-                        println!("binding #{}: {}", binding_idx, *bindings.get(binding_idx));
-                        mtwt::with_sctable(|x| mtwt::display_sctable(x));
+                        print_hygiene_debug_info();
                     }
                     assert_eq!(varref_name,binding_name);
                     if bound_ident_check {
@@ -1359,29 +1597,16 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
                         assert_eq!(varref_marks,binding_marks.clone());
                     }
                 } else {
+                    let varref_name = mtwt::resolve(varref.segments.get(0).identifier);
                     let fail = (varref.segments.len() == 1)
-                        && (mtwt::resolve(varref.segments.get(0).identifier)
-                            == binding_name);
+                        && (varref_name == binding_name);
                     // temp debugging:
                     if fail {
-                        let varref_idents : Vec<ast::Ident>
-                            = varref.segments.iter().map(|s|
-                                                         s.identifier)
-                            .collect();
                         println!("failure on test {}",test_idx);
                         println!("text of test case: \"{}\"", teststr);
                         println!("");
                         println!("uh oh, matches but shouldn't:");
-                        println!("varref: {}",varref_idents);
-                        // good lord, you can't make a path with 0 segments, can you?
-                        let string = token::get_ident(varref.segments
-                                                            .get(0)
-                                                            .identifier);
-                        println!("varref's first segment's uint: {}, and string: \"{}\"",
-                                 varref.segments.get(0).identifier.name,
-                                 string.get());
-                        println!("binding: {}", *bindings.get(binding_idx));
-                        mtwt::with_sctable(|x| mtwt::display_sctable(x));
+                        print_hygiene_debug_info();
                     }
                     assert!(!fail);
                 }
@@ -1390,7 +1615,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
     }
 
     #[test] fn fmt_in_macro_used_inside_module_macro() {
-        let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_str()))
+        let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_string()))
 macro_rules! foo_module (() => (mod generated { fn a() { let xx = 147; fmt_wrap!(xx);}}))
 foo_module!()
 ".to_string();
@@ -1443,13 +1668,43 @@ fn pat_idents(){
     // 'None' is listed as an identifier pattern because we don't yet know that
     // it's the name of a 0-ary variant, and that 'i' appears twice in succession.
     #[test]
-    fn crate_idents(){
+    fn crate_bindings_test(){
         let the_crate = string_to_crate("fn main (a : int) -> int {|b| {
         match 34 {None => 3, Some(i) | i => j, Foo{k:z,l:y} => \"banana\"}} }".to_string());
         let idents = crate_bindings(&the_crate);
         assert_eq!(idents, strs_to_idents(vec!("a","b","None","i","i","z","y")));
     }
 
-    //
+    // test the IdentRenamer directly
+    #[test]
+    fn ident_renamer_test () {
+        let the_crate = string_to_crate("fn f(x : int){let x = x; x}".to_string());
+        let f_ident = token::str_to_ident("f");
+        let x_ident = token::str_to_ident("x");
+        let int_ident = token::str_to_ident("int");
+        let renames = vec!((x_ident,Name(16)));
+        let mut renamer = IdentRenamer{renames: &renames};
+        let renamed_crate = renamer.fold_crate(the_crate);
+        let idents = crate_idents(&renamed_crate);
+        let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
+        assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),Name(16),Name(16)));
+    }
+
+    // test the PatIdentRenamer; only PatIdents get renamed
+    #[test]
+    fn pat_ident_renamer_test () {
+        let the_crate = string_to_crate("fn f(x : int){let x = x; x}".to_string());
+        let f_ident = token::str_to_ident("f");
+        let x_ident = token::str_to_ident("x");
+        let int_ident = token::str_to_ident("int");
+        let renames = vec!((x_ident,Name(16)));
+        let mut renamer = PatIdentRenamer{renames: &renames};
+        let renamed_crate = renamer.fold_crate(the_crate);
+        let idents = crate_idents(&renamed_crate);
+        let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
+        let x_name = x_ident.name;
+        assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),x_name,x_name));
+    }
+
 
 }
index f39e50ad1313f63501394e1a31da42b528c2a396..786fd953f8901ca9ccfe5d7799f73882fe9bda81 100644 (file)
@@ -37,24 +37,24 @@ struct Context<'a, 'b> {
     ecx: &'a mut ExtCtxt<'b>,
     fmtsp: Span,
 
-    // Parsed argument expressions and the types that we've found so far for
-    // them.
+    /// Parsed argument expressions and the types that we've found so far for
+    /// them.
     args: Vec<Gc<ast::Expr>>,
     arg_types: Vec<Option<ArgumentType>>,
-    // Parsed named expressions and the types that we've found for them so far.
-    // Note that we keep a side-array of the ordering of the named arguments
-    // found to be sure that we can translate them in the same order that they
-    // were declared in.
+    /// Parsed named expressions and the types that we've found for them so far.
+    /// Note that we keep a side-array of the ordering of the named arguments
+    /// found to be sure that we can translate them in the same order that they
+    /// were declared in.
     names: HashMap<String, Gc<ast::Expr>>,
     name_types: HashMap<String, ArgumentType>,
     name_ordering: Vec<String>,
 
-    // Collection of the compiled `rt::Piece` structures
+    /// Collection of the compiled `rt::Piece` structures
     pieces: Vec<Gc<ast::Expr>>,
     name_positions: HashMap<String, uint>,
     method_statics: Vec<Gc<ast::Item>>,
 
-    // Updated as arguments are consumed or methods are entered
+    /// Updated as arguments are consumed or methods are entered
     nest_level: uint,
     next_arg: uint,
 }
@@ -126,7 +126,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
                 _ => {
                     ecx.span_err(p.span,
                                  format!("expected ident for named argument, but found `{}`",
-                                         p.this_token_to_str()).as_slice());
+                                         p.this_token_to_string()).as_slice());
                     return (invocation, None);
                 }
             };
@@ -690,7 +690,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
         fmtsp: sp,
     };
     cx.fmtsp = efmt.span;
-    let fmt = match expr_to_str(cx.ecx,
+    let fmt = match expr_to_string(cx.ecx,
                                 efmt,
                                 "format argument must be a string literal.") {
         Some((fmt, _)) => fmt,
index 486d060da77bedbefc596b6f70529a6cead6c517..1f4d087abd0fe1669513151ea3f88b3e1688ec5b 100644 (file)
@@ -21,7 +21,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
                          -> Box<base::MacResult> {
 
     cx.print_backtrace();
-    println!("{}", print::pprust::tt_to_str(&ast::TTDelim(
+    println!("{}", print::pprust::tt_to_string(&ast::TTDelim(
                 Rc::new(tt.iter().map(|x| (*x).clone()).collect()))));
 
     // any so that `log_syntax` can be invoked as an expression and item.
index 48895d34022c4c28b9459b2c1b23d48102730073..2c94db5296750523c48277670ec6a44d6ff5f77c 100644 (file)
 use std::rc::Rc;
 use std::collections::HashMap;
 
-// the SCTable contains a table of SyntaxContext_'s. It
-// represents a flattened tree structure, to avoid having
-// managed pointers everywhere (that caused an ICE).
-// the mark_memo and rename_memo fields are side-tables
-// that ensure that adding the same mark to the same context
-// gives you back the same context as before. This shouldn't
-// change the semantics--everything here is immutable--but
-// it should cut down on memory use *a lot*; applying a mark
-// to a tree containing 50 identifiers would otherwise generate
-// 50 new contexts
+/// The SCTable contains a table of SyntaxContext_'s. It
+/// represents a flattened tree structure, to avoid having
+/// managed pointers everywhere (that caused an ICE).
+/// the mark_memo and rename_memo fields are side-tables
+/// that ensure that adding the same mark to the same context
+/// gives you back the same context as before. This shouldn't
+/// change the semantics--everything here is immutable--but
+/// it should cut down on memory use *a lot*; applying a mark
+/// to a tree containing 50 identifiers would otherwise generate
+/// 50 new contexts
 pub struct SCTable {
     table: RefCell<Vec<SyntaxContext_>>,
     mark_memo: RefCell<HashMap<(SyntaxContext,Mrk),SyntaxContext>>,
@@ -41,51 +41,64 @@ pub struct SCTable {
 pub enum SyntaxContext_ {
     EmptyCtxt,
     Mark (Mrk,SyntaxContext),
-    // flattening the name and syntaxcontext into the rename...
-    // HIDDEN INVARIANTS:
-    // 1) the first name in a Rename node
-    // can only be a programmer-supplied name.
-    // 2) Every Rename node with a given Name in the
-    // "to" slot must have the same name and context
-    // in the "from" slot. In essence, they're all
-    // pointers to a single "rename" event node.
+    /// flattening the name and syntaxcontext into the rename...
+    /// HIDDEN INVARIANTS:
+    /// 1) the first name in a Rename node
+    /// can only be a programmer-supplied name.
+    /// 2) Every Rename node with a given Name in the
+    /// "to" slot must have the same name and context
+    /// in the "from" slot. In essence, they're all
+    /// pointers to a single "rename" event node.
     Rename (Ident,Name,SyntaxContext),
-    // actually, IllegalCtxt may not be necessary.
+    /// actually, IllegalCtxt may not be necessary.
     IllegalCtxt
 }
 
+/// A list of ident->name renamings
+pub type RenameList = Vec<(Ident, Name)>;
+
 /// Extend a syntax context with a given mark
-pub fn new_mark(m: Mrk, tail: SyntaxContext) -> SyntaxContext {
-    with_sctable(|table| new_mark_internal(m, tail, table))
+pub fn apply_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext {
+    with_sctable(|table| apply_mark_internal(m, ctxt, table))
 }
 
-// Extend a syntax context with a given mark and table
-fn new_mark_internal(m: Mrk, tail: SyntaxContext, table: &SCTable) -> SyntaxContext {
-    let key = (tail, m);
+/// Extend a syntax context with a given mark and sctable (explicit memoization)
+fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext {
+    let key = (ctxt, m);
     let new_ctxt = |_: &(SyntaxContext, Mrk)|
-                   idx_push(&mut *table.table.borrow_mut(), Mark(m, tail));
+                   idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt));
 
     *table.mark_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
 }
 
 /// Extend a syntax context with a given rename
-pub fn new_rename(id: Ident, to:Name,
-                  tail: SyntaxContext) -> SyntaxContext {
-    with_sctable(|table| new_rename_internal(id, to, tail, table))
+pub fn apply_rename(id: Ident, to:Name,
+                  ctxt: SyntaxContext) -> SyntaxContext {
+    with_sctable(|table| apply_rename_internal(id, to, ctxt, table))
 }
 
-// Extend a syntax context with a given rename and sctable
-fn new_rename_internal(id: Ident,
+/// Extend a syntax context with a given rename and sctable (explicit memoization)
+fn apply_rename_internal(id: Ident,
                        to: Name,
-                       tail: SyntaxContext,
+                       ctxt: SyntaxContext,
                        table: &SCTable) -> SyntaxContext {
-    let key = (tail,id,to);
-    let new_ctxt = |_: &(SyntaxContext, Ident, Mrk)|
-                   idx_push(&mut *table.table.borrow_mut(), Rename(id, to, tail));
+    let key = (ctxt, id, to);
+    let new_ctxt = |_: &(SyntaxContext, Ident, Name)|
+                   idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt));
 
     *table.rename_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
 }
 
+/// Apply a list of renamings to a context
+// if these rename lists get long, it would make sense
+// to consider memoizing this fold. This may come up
+// when we add hygiene to item names.
+pub fn apply_renames(renames: &RenameList, ctxt: SyntaxContext) -> SyntaxContext {
+    renames.iter().fold(ctxt, |ctxt, &(from, to)| {
+        apply_rename(from, to, ctxt)
+    })
+}
+
 /// Fetch the SCTable from TLS, create one if it doesn't yet exist.
 pub fn with_sctable<T>(op: |&SCTable| -> T) -> T {
     local_data_key!(sctable_key: Rc<SCTable>)
@@ -128,8 +141,8 @@ pub fn clear_tables() {
     with_resolve_table_mut(|table| *table = HashMap::new());
 }
 
-// Add a value to the end of a vec, return its index
-fn idx_push<T>(vec: &mut Vec<T> , val: T) -> u32 {
+/// Add a value to the end of a vec, return its index
+fn idx_push<T>(vec: &mut Vec<T>, val: T) -> u32 {
     vec.push(val);
     (vec.len() - 1) as u32
 }
@@ -160,8 +173,8 @@ fn with_resolve_table_mut<T>(op: |&mut ResolveTable| -> T) -> T {
     }
 }
 
-// Resolve a syntax object to a name, per MTWT.
-// adding memoization to resolve 500+ seconds in resolve for librustc (!)
+/// Resolve a syntax object to a name, per MTWT.
+/// adding memoization to resolve 500+ seconds in resolve for librustc (!)
 fn resolve_internal(id: Ident,
                     table: &SCTable,
                     resolve_table: &mut ResolveTable) -> Name {
@@ -251,8 +264,8 @@ pub fn outer_mark(ctxt: SyntaxContext) -> Mrk {
     })
 }
 
-// Push a name... unless it matches the one on top, in which
-// case pop and discard (so two of the same marks cancel)
+/// Push a name... unless it matches the one on top, in which
+/// case pop and discard (so two of the same marks cancel)
 fn xor_push(marks: &mut Vec<Mrk>, mark: Mrk) {
     if (marks.len() > 0) && (*marks.last().unwrap() == mark) {
         marks.pop().unwrap();
@@ -263,9 +276,9 @@ fn xor_push(marks: &mut Vec<Mrk>, mark: Mrk) {
 
 #[cfg(test)]
 mod tests {
-    use ast::*;
-    use super::{resolve, xor_push, new_mark_internal, new_sctable_internal};
-    use super::{new_rename_internal, marksof_internal, resolve_internal};
+    use ast::{EMPTY_CTXT, Ident, Mrk, Name, SyntaxContext};
+    use super::{resolve, xor_push, apply_mark_internal, new_sctable_internal};
+    use super::{apply_rename_internal, apply_renames, marksof_internal, resolve_internal};
     use super::{SCTable, EmptyCtxt, Mark, Rename, IllegalCtxt};
     use std::collections::HashMap;
 
@@ -288,8 +301,8 @@ fn xorpush_test () {
         assert_eq!(s.clone(), vec!(14));
     }
 
-    fn id(n: Name, s: SyntaxContext) -> Ident {
-        Ident {name: n, ctxt: s}
+    fn id(n: u32, s: SyntaxContext) -> Ident {
+        Ident {name: Name(n), ctxt: s}
     }
 
     // because of the SCTable, I now need a tidy way of
@@ -306,8 +319,8 @@ fn unfold_test_sc(tscs : Vec<TestSC> , tail: SyntaxContext, table: &SCTable)
         -> SyntaxContext {
         tscs.iter().rev().fold(tail, |tail : SyntaxContext, tsc : &TestSC|
                   {match *tsc {
-                      M(mrk) => new_mark_internal(mrk,tail,table),
-                      R(ident,name) => new_rename_internal(ident,name,tail,table)}})
+                      M(mrk) => apply_mark_internal(mrk,tail,table),
+                      R(ident,name) => apply_rename_internal(ident,name,tail,table)}})
     }
 
     // gather a SyntaxContext back into a vector of TestSCs
@@ -336,12 +349,12 @@ fn refold_test_sc(mut sc: SyntaxContext, table : &SCTable) -> Vec<TestSC> {
     fn test_unfold_refold(){
         let mut t = new_sctable_internal();
 
-        let test_sc = vec!(M(3),R(id(101,0),14),M(9));
+        let test_sc = vec!(M(3),R(id(101,0),Name(14)),M(9));
         assert_eq!(unfold_test_sc(test_sc.clone(),EMPTY_CTXT,&mut t),4);
         {
             let table = t.table.borrow();
             assert!(*table.get(2) == Mark(9,0));
-            assert!(*table.get(3) == Rename(id(101,0),14,2));
+            assert!(*table.get(3) == Rename(id(101,0),Name(14),2));
             assert!(*table.get(4) == Mark(3,3));
         }
         assert_eq!(refold_test_sc(4,&t),test_sc);
@@ -352,7 +365,7 @@ fn test_unfold_refold(){
     fn unfold_marks(mrks: Vec<Mrk> , tail: SyntaxContext, table: &SCTable)
                     -> SyntaxContext {
         mrks.iter().rev().fold(tail, |tail:SyntaxContext, mrk:&Mrk|
-                   {new_mark_internal(*mrk,tail,table)})
+                   {apply_mark_internal(*mrk,tail,table)})
     }
 
     #[test] fn unfold_marks_test() {
@@ -368,8 +381,8 @@ fn unfold_marks(mrks: Vec<Mrk> , tail: SyntaxContext, table: &SCTable)
 
     #[test]
     fn test_marksof () {
-        let stopname = 242;
-        let name1 = 243;
+        let stopname = Name(242);
+        let name1 = Name(243);
         let mut t = new_sctable_internal();
         assert_eq!(marksof_internal (EMPTY_CTXT,stopname,&t),Vec::new());
         // FIXME #5074: ANF'd to dodge nested calls
@@ -383,16 +396,16 @@ fn test_marksof () {
          assert_eq! (marksof_internal (ans, stopname,&t), vec!(16));}
         // rename where stop doesn't match:
         { let chain = vec!(M(9),
-                        R(id(name1,
-                             new_mark_internal (4, EMPTY_CTXT,&mut t)),
-                          100101102),
+                        R(id(name1.uint() as u32,
+                             apply_mark_internal (4, EMPTY_CTXT,&mut t)),
+                          Name(100101102)),
                         M(14));
          let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t);
          assert_eq! (marksof_internal (ans, stopname, &t), vec!(9,14));}
         // rename where stop does match
-        { let name1sc = new_mark_internal(4, EMPTY_CTXT, &mut t);
+        { let name1sc = apply_mark_internal(4, EMPTY_CTXT, &mut t);
          let chain = vec!(M(9),
-                       R(id(name1, name1sc),
+                       R(id(name1.uint() as u32, name1sc),
                          stopname),
                        M(14));
          let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t);
@@ -406,65 +419,65 @@ fn resolve_tests () {
         let mut t = new_sctable_internal();
         let mut rt = HashMap::new();
         // - ctxt is MT
-        assert_eq!(resolve_internal(id(a,EMPTY_CTXT),&mut t, &mut rt),a);
+        assert_eq!(resolve_internal(id(a,EMPTY_CTXT),&mut t, &mut rt),Name(a));
         // - simple ignored marks
         { let sc = unfold_marks(vec!(1,2,3),EMPTY_CTXT,&mut t);
-         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),a);}
+         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),Name(a));}
         // - orthogonal rename where names don't match
-        { let sc = unfold_test_sc(vec!(R(id(50,EMPTY_CTXT),51),M(12)),EMPTY_CTXT,&mut t);
-         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),a);}
+        { let sc = unfold_test_sc(vec!(R(id(50,EMPTY_CTXT),Name(51)),M(12)),EMPTY_CTXT,&mut t);
+         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),Name(a));}
         // - rename where names do match, but marks don't
-        { let sc1 = new_mark_internal(1,EMPTY_CTXT,&mut t);
-         let sc = unfold_test_sc(vec!(R(id(a,sc1),50),
+        { let sc1 = apply_mark_internal(1,EMPTY_CTXT,&mut t);
+         let sc = unfold_test_sc(vec!(R(id(a,sc1),Name(50)),
                                    M(1),
                                    M(2)),
                                  EMPTY_CTXT,&mut t);
-        assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), a);}
+        assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), Name(a));}
         // - rename where names and marks match
         { let sc1 = unfold_test_sc(vec!(M(1),M(2)),EMPTY_CTXT,&mut t);
-         let sc = unfold_test_sc(vec!(R(id(a,sc1),50),M(1),M(2)),EMPTY_CTXT,&mut t);
-         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), 50); }
+         let sc = unfold_test_sc(vec!(R(id(a,sc1),Name(50)),M(1),M(2)),EMPTY_CTXT,&mut t);
+         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), Name(50)); }
         // - rename where names and marks match by literal sharing
         { let sc1 = unfold_test_sc(vec!(M(1),M(2)),EMPTY_CTXT,&mut t);
-         let sc = unfold_test_sc(vec!(R(id(a,sc1),50)),sc1,&mut t);
-         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), 50); }
+         let sc = unfold_test_sc(vec!(R(id(a,sc1),Name(50))),sc1,&mut t);
+         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), Name(50)); }
         // - two renames of the same var.. can only happen if you use
         // local-expand to prevent the inner binding from being renamed
         // during the rename-pass caused by the first:
         println!("about to run bad test");
-        { let sc = unfold_test_sc(vec!(R(id(a,EMPTY_CTXT),50),
-                                    R(id(a,EMPTY_CTXT),51)),
+        { let sc = unfold_test_sc(vec!(R(id(a,EMPTY_CTXT),Name(50)),
+                                    R(id(a,EMPTY_CTXT),Name(51))),
                                   EMPTY_CTXT,&mut t);
-         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), 51); }
+         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), Name(51)); }
         // the simplest double-rename:
-        { let a_to_a50 = new_rename_internal(id(a,EMPTY_CTXT),50,EMPTY_CTXT,&mut t);
-         let a50_to_a51 = new_rename_internal(id(a,a_to_a50),51,a_to_a50,&mut t);
-         assert_eq!(resolve_internal(id(a,a50_to_a51),&mut t, &mut rt),51);
+        { let a_to_a50 = apply_rename_internal(id(a,EMPTY_CTXT),Name(50),EMPTY_CTXT,&mut t);
+         let a50_to_a51 = apply_rename_internal(id(a,a_to_a50),Name(51),a_to_a50,&mut t);
+         assert_eq!(resolve_internal(id(a,a50_to_a51),&mut t, &mut rt),Name(51));
          // mark on the outside doesn't stop rename:
-         let sc = new_mark_internal(9,a50_to_a51,&mut t);
-         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),51);
+         let sc = apply_mark_internal(9,a50_to_a51,&mut t);
+         assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),Name(51));
          // but mark on the inside does:
-         let a50_to_a51_b = unfold_test_sc(vec!(R(id(a,a_to_a50),51),
+         let a50_to_a51_b = unfold_test_sc(vec!(R(id(a,a_to_a50),Name(51)),
                                               M(9)),
                                            a_to_a50,
                                            &mut t);
-         assert_eq!(resolve_internal(id(a,a50_to_a51_b),&mut t, &mut rt),50);}
+         assert_eq!(resolve_internal(id(a,a50_to_a51_b),&mut t, &mut rt),Name(50));}
     }
 
     #[test]
     fn mtwt_resolve_test(){
         let a = 40;
-        assert_eq!(resolve(id(a,EMPTY_CTXT)),a);
+        assert_eq!(resolve(id(a,EMPTY_CTXT)),Name(a));
     }
 
 
     #[test]
     fn hashing_tests () {
         let mut t = new_sctable_internal();
-        assert_eq!(new_mark_internal(12,EMPTY_CTXT,&mut t),2);
-        assert_eq!(new_mark_internal(13,EMPTY_CTXT,&mut t),3);
+        assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),2);
+        assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),3);
         // using the same one again should result in the same index:
-        assert_eq!(new_mark_internal(12,EMPTY_CTXT,&mut t),2);
+        assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),2);
         // I'm assuming that the rename table will behave the same....
     }
 
@@ -480,4 +493,13 @@ fn resolve_table_hashing_tests() {
         resolve_internal(id(30,EMPTY_CTXT),&mut t, &mut rt);
         assert_eq!(rt.len(),2);
     }
+
+    #[test]
+    fn new_resolves_test() {
+        let renames = vec!((Ident{name:Name(23),ctxt:EMPTY_CTXT},Name(24)),
+                           (Ident{name:Name(29),ctxt:EMPTY_CTXT},Name(29)));
+        let new_ctxt1 = apply_renames(&renames,EMPTY_CTXT);
+        assert_eq!(resolve(Ident{name:Name(23),ctxt:new_ctxt1}),Name(24));
+        assert_eq!(resolve(Ident{name:Name(29),ctxt:new_ctxt1}),Name(29));
+    }
 }
index 7b24b97d5da4dd6be7557657bb8019f0ba816103..696d62838ba799150a68a998929e8277099a9e8e 100644 (file)
@@ -128,13 +128,13 @@ fn to_source(&self) -> String {
         }
     }
 
-    impl_to_source!(ast::Ty, ty_to_str)
-    impl_to_source!(ast::Block, block_to_str)
-    impl_to_source!(ast::Arg, arg_to_str)
-    impl_to_source!(Generics, generics_to_str)
-    impl_to_source!(Gc<ast::Item>, item_to_str)
-    impl_to_source!(Gc<ast::Expr>, expr_to_str)
-    impl_to_source!(Gc<ast::Pat>, pat_to_str)
+    impl_to_source!(ast::Ty, ty_to_string)
+    impl_to_source!(ast::Block, block_to_string)
+    impl_to_source!(ast::Arg, arg_to_string)
+    impl_to_source!(Generics, generics_to_string)
+    impl_to_source!(Gc<ast::Item>, item_to_string)
+    impl_to_source!(Gc<ast::Expr>, expr_to_string)
+    impl_to_source!(Gc<ast::Pat>, pat_to_string)
     impl_to_source_slice!(ast::Ty, ", ")
     impl_to_source_slice!(Gc<ast::Item>, "\n\n")
 
@@ -142,7 +142,7 @@ impl<'a> ToSource for &'a str {
         fn to_source(&self) -> String {
             let lit = dummy_spanned(ast::LitStr(
                     token::intern_and_get_ident(*self), ast::CookedStr));
-            pprust::lit_to_str(&lit)
+            pprust::lit_to_string(&lit)
         }
     }
 
@@ -155,14 +155,14 @@ fn to_source(&self) -> String {
     impl ToSource for bool {
         fn to_source(&self) -> String {
             let lit = dummy_spanned(ast::LitBool(*self));
-            pprust::lit_to_str(&lit)
+            pprust::lit_to_string(&lit)
         }
     }
 
     impl ToSource for char {
         fn to_source(&self) -> String {
             let lit = dummy_spanned(ast::LitChar(*self));
-            pprust::lit_to_str(&lit)
+            pprust::lit_to_string(&lit)
         }
     }
 
@@ -171,7 +171,7 @@ macro_rules! impl_to_source_int(
             impl ToSource for $t {
                 fn to_source(&self) -> String {
                     let lit = dummy_spanned(ast::LitInt(*self as i64, ast::$tag));
-                    pprust::lit_to_str(&lit)
+                    pprust::lit_to_string(&lit)
                 }
             }
         );
@@ -179,7 +179,7 @@ fn to_source(&self) -> String {
             impl ToSource for $t {
                 fn to_source(&self) -> String {
                     let lit = dummy_spanned(ast::LitUint(*self as u64, ast::$tag));
-                    pprust::lit_to_str(&lit)
+                    pprust::lit_to_string(&lit)
                 }
             }
         );
@@ -363,6 +363,15 @@ fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> {
                         vec!(e_str))
 }
 
+// Lift a name to the expr that evaluates to that name
+fn mk_name(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> {
+    let e_str = cx.expr_str(sp, token::get_ident(ident));
+    cx.expr_method_call(sp,
+                        cx.expr_ident(sp, id_ext("ext_cx")),
+                        id_ext("name_of"),
+                        vec!(e_str))
+}
+
 fn mk_ast_path(cx: &ExtCtxt, sp: Span, name: &str) -> Gc<ast::Expr> {
     let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name));
     cx.expr_path(cx.path_global(sp, idents))
@@ -401,68 +410,37 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Gc<ast::Expr> {
         }
 
         LIT_BYTE(i) => {
-            let e_byte = cx.expr_lit(sp, ast::LitByte(i));
+            let e_byte = mk_name(cx, sp, i.ident());
 
             return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_BYTE"), vec!(e_byte));
         }
 
         LIT_CHAR(i) => {
-            let e_char = cx.expr_lit(sp, ast::LitChar(i));
+            let e_char = mk_name(cx, sp, i.ident());
 
             return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_CHAR"), vec!(e_char));
         }
 
-        LIT_INT(i, ity) => {
-            let s_ity = match ity {
-                ast::TyI => "TyI",
-                ast::TyI8 => "TyI8",
-                ast::TyI16 => "TyI16",
-                ast::TyI32 => "TyI32",
-                ast::TyI64 => "TyI64"
-            };
-            let e_ity = mk_ast_path(cx, sp, s_ity);
-            let e_i64 = cx.expr_lit(sp, ast::LitInt(i, ast::TyI64));
-            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_INT"), vec!(e_i64, e_ity));
+        LIT_INTEGER(i) => {
+            let e_int = mk_name(cx, sp, i.ident());
+            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_INTEGER"), vec!(e_int));
         }
 
-        LIT_UINT(u, uty) => {
-            let s_uty = match uty {
-                ast::TyU => "TyU",
-                ast::TyU8 => "TyU8",
-                ast::TyU16 => "TyU16",
-                ast::TyU32 => "TyU32",
-                ast::TyU64 => "TyU64"
-            };
-            let e_uty = mk_ast_path(cx, sp, s_uty);
-            let e_u64 = cx.expr_lit(sp, ast::LitUint(u, ast::TyU64));
-            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_UINT"), vec!(e_u64, e_uty));
-        }
-
-        LIT_INT_UNSUFFIXED(i) => {
-            let e_i64 = cx.expr_lit(sp, ast::LitInt(i, ast::TyI64));
-            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_INT_UNSUFFIXED"), vec!(e_i64));
-        }
-
-        LIT_FLOAT(fident, fty) => {
-            let s_fty = match fty {
-                ast::TyF32 => "TyF32",
-                ast::TyF64 => "TyF64",
-            };
-            let e_fty = mk_ast_path(cx, sp, s_fty);
-            let e_fident = mk_ident(cx, sp, fident);
-            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_FLOAT"), vec!(e_fident, e_fty));
+        LIT_FLOAT(fident) => {
+            let e_fident = mk_name(cx, sp, fident.ident());
+            return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_FLOAT"), vec!(e_fident));
         }
 
         LIT_STR(ident) => {
             return cx.expr_call(sp,
                                 mk_token_path(cx, sp, "LIT_STR"),
-                                vec!(mk_ident(cx, sp, ident)));
+                                vec!(mk_name(cx, sp, ident.ident())));
         }
 
         LIT_STR_RAW(ident, n) => {
             return cx.expr_call(sp,
                                 mk_token_path(cx, sp, "LIT_STR_RAW"),
-                                vec!(mk_ident(cx, sp, ident), cx.expr_uint(sp, n)));
+                                vec!(mk_name(cx, sp, ident.ident()), cx.expr_uint(sp, n)));
         }
 
         IDENT(ident, b) => {
@@ -480,7 +458,7 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Gc<ast::Expr> {
         DOC_COMMENT(ident) => {
             return cx.expr_call(sp,
                                 mk_token_path(cx, sp, "DOC_COMMENT"),
-                                vec!(mk_ident(cx, sp, ident)));
+                                vec!(mk_name(cx, sp, ident.ident())));
         }
 
         INTERPOLATED(_) => fail!("quote! with interpolated token"),
index 915fc16c15660a05368690c7e770dc05a0bcb81c..5ac9dc86fcec2017e648743ff443165f581667bb 100644 (file)
@@ -28,7 +28,7 @@
 // the column/row/filename of the expression, or they include
 // a given file into the current one.
 
-/* line!(): expands to the current line number */
+/// line!(): expands to the current line number
 pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    -> Box<base::MacResult> {
     base::check_zero_tts(cx, sp, tts, "line!");
@@ -49,9 +49,9 @@ pub fn expand_col(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.col.to_uint()))
 }
 
-/* file!(): expands to the current filename */
-/* The filemap (`loc.file`) contains a bunch more information we could spit
- * out if we wanted. */
+/// file!(): expands to the current filename */
+/// The filemap (`loc.file`) contains a bunch more information we could spit
+/// out if we wanted.
 pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    -> Box<base::MacResult> {
     base::check_zero_tts(cx, sp, tts, "file!");
@@ -64,7 +64,7 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 
 pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult> {
-    let s = pprust::tts_to_str(tts);
+    let s = pprust::tts_to_string(tts);
     base::MacExpr::new(cx.expr_str(sp,
                                    token::intern_and_get_ident(s.as_slice())))
 }
@@ -82,9 +82,9 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             token::intern_and_get_ident(string.as_slice())))
 }
 
-// include! : parse the given file as an expr
-// This is generally a bad idea because it's going to behave
-// unhygienically.
+/// include! : parse the given file as an expr
+/// This is generally a bad idea because it's going to behave
+/// unhygienically.
 pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                       -> Box<base::MacResult> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
@@ -126,7 +126,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Some(src) => {
             // Add this input file to the code map to make it available as
             // dependency information
-            let filename = file.display().to_str();
+            let filename = file.display().to_string();
             let interned = token::intern_and_get_ident(src);
             cx.codemap().new_filemap(filename, src.to_string());
 
index 86fbc8cec2a347f9f4108196fab5a4b3a5201d40..bdf1f6eb6007e3bc2454069b26b905ad2a11b846 100644 (file)
@@ -8,7 +8,72 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Earley-like parser for macros.
+//! This is an Earley-like parser, without support for in-grammar nonterminals,
+//! only by calling out to the main rust parser for named nonterminals (which it
+//! commits to fully when it hits one in a grammar). This means that there are no
+//! completer or predictor rules, and therefore no need to store one column per
+//! token: instead, there's a set of current Earley items and a set of next
+//! ones. Instead of NTs, we have a special case for Kleene star. The big-O, in
+//! pathological cases, is worse than traditional Earley parsing, but it's an
+//! easier fit for Macro-by-Example-style rules, and I think the overhead is
+//! lower. (In order to prevent the pathological case, we'd need to lazily
+//! construct the resulting `NamedMatch`es at the very end. It'd be a pain,
+//! and require more memory to keep around old items, but it would also save
+//! overhead)
+//!
+//! Quick intro to how the parser works:
+//!
+//! A 'position' is a dot in the middle of a matcher, usually represented as a
+//! dot. For example `· a $( a )* a b` is a position, as is `a $( · a )* a b`.
+//!
+//! The parser walks through the input a character at a time, maintaining a list
+//! of items consistent with the current position in the input string: `cur_eis`.
+//!
+//! As it processes them, it fills up `eof_eis` with items that would be valid if
+//! the macro invocation is now over, `bb_eis` with items that are waiting on
+//! a Rust nonterminal like `$e:expr`, and `next_eis` with items that are waiting
+//! on the a particular token. Most of the logic concerns moving the · through the
+//! repetitions indicated by Kleene stars. It only advances or calls out to the
+//! real Rust parser when no `cur_eis` items remain
+//!
+//! Example: Start parsing `a a a a b` against [· a $( a )* a b].
+//!
+//! Remaining input: `a a a a b`
+//! next_eis: [· a $( a )* a b]
+//!
+//! - - - Advance over an `a`. - - -
+//!
+//! Remaining input: `a a a b`
+//! cur: [a · $( a )* a b]
+//! Descend/Skip (first item).
+//! next: [a $( · a )* a b]  [a $( a )* · a b].
+//!
+//! - - - Advance over an `a`. - - -
+//!
+//! Remaining input: `a a b`
+//! cur: [a $( a · )* a b]  next: [a $( a )* a · b]
+//! Finish/Repeat (first item)
+//! next: [a $( a )* · a b]  [a $( · a )* a b]  [a $( a )* a · b]
+//!
+//! - - - Advance over an `a`. - - - (this looks exactly like the last step)
+//!
+//! Remaining input: `a b`
+//! cur: [a $( a · )* a b]  next: [a $( a )* a · b]
+//! Finish/Repeat (first item)
+//! next: [a $( a )* · a b]  [a $( · a )* a b]  [a $( a )* a · b]
+//!
+//! - - - Advance over an `a`. - - - (this looks exactly like the last step)
+//!
+//! Remaining input: `b`
+//! cur: [a $( a · )* a b]  next: [a $( a )* a · b]
+//! Finish/Repeat (first item)
+//! next: [a $( a )* · a b]  [a $( · a )* a b]
+//!
+//! - - - Advance over a `b`. - - -
+//!
+//! Remaining input: ``
+//! eof: [a $( a )* a b ·]
+
 
 use ast;
 use ast::{Matcher, MatchTok, MatchSeq, MatchNonterminal, Ident};
 use std::gc::GC;
 use std::collections::HashMap;
 
-/* This is an Earley-like parser, without support for in-grammar nonterminals,
-only by calling out to the main rust parser for named nonterminals (which it
-commits to fully when it hits one in a grammar). This means that there are no
-completer or predictor rules, and therefore no need to store one column per
-token: instead, there's a set of current Earley items and a set of next
-ones. Instead of NTs, we have a special case for Kleene star. The big-O, in
-pathological cases, is worse than traditional Earley parsing, but it's an
-easier fit for Macro-by-Example-style rules, and I think the overhead is
-lower. (In order to prevent the pathological case, we'd need to lazily
-construct the resulting `NamedMatch`es at the very end. It'd be a pain,
-and require more memory to keep around old items, but it would also save
-overhead)*/
-
-/* Quick intro to how the parser works:
-
-A 'position' is a dot in the middle of a matcher, usually represented as a
-dot. For example `· a $( a )* a b` is a position, as is `a $( · a )* a b`.
-
-The parser walks through the input a character at a time, maintaining a list
-of items consistent with the current position in the input string: `cur_eis`.
-
-As it processes them, it fills up `eof_eis` with items that would be valid if
-the macro invocation is now over, `bb_eis` with items that are waiting on
-a Rust nonterminal like `$e:expr`, and `next_eis` with items that are waiting
-on the a particular token. Most of the logic concerns moving the · through the
-repetitions indicated by Kleene stars. It only advances or calls out to the
-real Rust parser when no `cur_eis` items remain
-
-Example: Start parsing `a a a a b` against [· a $( a )* a b].
-
-Remaining input: `a a a a b`
-next_eis: [· a $( a )* a b]
-
-- - - Advance over an `a`. - - -
-
-Remaining input: `a a a b`
-cur: [a · $( a )* a b]
-Descend/Skip (first item).
-next: [a $( · a )* a b]  [a $( a )* · a b].
-
-- - - Advance over an `a`. - - -
-
-Remaining input: `a a b`
-cur: [a $( a · )* a b]  next: [a $( a )* a · b]
-Finish/Repeat (first item)
-next: [a $( a )* · a b]  [a $( · a )* a b]  [a $( a )* a · b]
-
-- - - Advance over an `a`. - - - (this looks exactly like the last step)
-
-Remaining input: `a b`
-cur: [a $( a · )* a b]  next: [a $( a )* a · b]
-Finish/Repeat (first item)
-next: [a $( a )* · a b]  [a $( · a )* a b]  [a $( a )* a · b]
-
-- - - Advance over an `a`. - - - (this looks exactly like the last step)
-
-Remaining input: `b`
-cur: [a $( a · )* a b]  next: [a $( a )* a · b]
-Finish/Repeat (first item)
-next: [a $( a )* · a b]  [a $( · a )* a b]
-
-- - - Advance over a `b`. - - -
-
-Remaining input: ``
-eof: [a $( a )* a b ·]
-
- */
-
-
 /* to avoid costly uniqueness checks, we require that `MatchSeq` always has a
 nonempty body. */
 
@@ -147,24 +143,24 @@ pub fn initial_matcher_pos(ms: Vec<Matcher> , sep: Option<Token>, lo: BytePos)
     }
 }
 
-// NamedMatch is a pattern-match result for a single ast::MatchNonterminal:
-// so it is associated with a single ident in a parse, and all
-// MatchedNonterminal's in the NamedMatch have the same nonterminal type
-// (expr, item, etc). All the leaves in a single NamedMatch correspond to a
-// single matcher_nonterminal in the ast::Matcher that produced it.
-//
-// It should probably be renamed, it has more or less exact correspondence to
-// ast::match nodes, and the in-memory structure of a particular NamedMatch
-// represents the match that occurred when a particular subset of an
-// ast::match -- those ast::Matcher nodes leading to a single
-// MatchNonterminal -- was applied to a particular token tree.
-//
-// The width of each MatchedSeq in the NamedMatch, and the identity of the
-// MatchedNonterminal's, will depend on the token tree it was applied to: each
-// MatchedSeq corresponds to a single MatchSeq in the originating
-// ast::Matcher. The depth of the NamedMatch structure will therefore depend
-// only on the nesting depth of ast::MatchSeq's in the originating
-// ast::Matcher it was derived from.
+/// NamedMatch is a pattern-match result for a single ast::MatchNonterminal:
+/// so it is associated with a single ident in a parse, and all
+/// MatchedNonterminal's in the NamedMatch have the same nonterminal type
+/// (expr, item, etc). All the leaves in a single NamedMatch correspond to a
+/// single matcher_nonterminal in the ast::Matcher that produced it.
+///
+/// It should probably be renamed, it has more or less exact correspondence to
+/// ast::match nodes, and the in-memory structure of a particular NamedMatch
+/// represents the match that occurred when a particular subset of an
+/// ast::match -- those ast::Matcher nodes leading to a single
+/// MatchNonterminal -- was applied to a particular token tree.
+///
+/// The width of each MatchedSeq in the NamedMatch, and the identity of the
+/// MatchedNonterminal's, will depend on the token tree it was applied to: each
+/// MatchedSeq corresponds to a single MatchSeq in the originating
+/// ast::Matcher. The depth of the NamedMatch structure will therefore depend
+/// only on the nesting depth of ast::MatchSeq's in the originating
+/// ast::Matcher it was derived from.
 
 pub enum NamedMatch {
     MatchedSeq(Vec<Rc<NamedMatch>>, codemap::Span),
@@ -224,7 +220,8 @@ pub fn parse_or_else(sess: &ParseSess,
     }
 }
 
-// perform a token equality check, ignoring syntax context (that is, an unhygienic comparison)
+/// Perform a token equality check, ignoring syntax context (that is, an
+/// unhygienic comparison)
 pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
     match (t1,t2) {
         (&token::IDENT(id1,_),&token::IDENT(id2,_))
@@ -354,8 +351,7 @@ pub fn parse(sess: &ParseSess,
                   MatchNonterminal(_,_,_) => { bb_eis.push(ei) }
                   MatchTok(ref t) => {
                     let mut ei_t = ei.clone();
-                    //if (token_name_eq(t,&tok)) {
-                    if token::mtwt_token_eq(t,&tok) {
+                    if token_name_eq(t,&tok) {
                         ei_t.idx += 1;
                         next_eis.push(ei_t);
                     }
@@ -395,7 +391,7 @@ pub fn parse(sess: &ParseSess,
                     nts, next_eis.len()).to_string());
             } else if bb_eis.len() == 0u && next_eis.len() == 0u {
                 return Failure(sp, format!("no rules expected the token `{}`",
-                            token::to_str(&tok)).to_string());
+                            token::to_string(&tok)).to_string());
             } else if next_eis.len() > 0u {
                 /* Now process the next token */
                 while next_eis.len() > 0u {
@@ -442,7 +438,7 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
       "ident" => match p.token {
         token::IDENT(sn,b) => { p.bump(); token::NtIdent(box sn,b) }
         _ => {
-            let token_str = token::to_str(&p.token);
+            let token_str = token::to_string(&p.token);
             p.fatal((format!("expected ident, found {}",
                              token_str.as_slice())).as_slice())
         }
index 72c578b87699c5b0f335ee3bad3395cc6e4fd818..1eb37abb781a3d73e2f111fe4ebe734b707feed7 100644 (file)
@@ -13,7 +13,7 @@
 use ast;
 use codemap::{Span, Spanned, DUMMY_SP};
 use ext::base::{ExtCtxt, MacResult, MacroDef};
-use ext::base::{NormalTT, MacroExpander};
+use ext::base::{NormalTT, TTMacroExpander};
 use ext::base;
 use ext::tt::macro_parser::{Success, Error, Failure};
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
@@ -38,7 +38,7 @@ struct ParserAnyMacro<'a> {
 impl<'a> ParserAnyMacro<'a> {
     /// Make sure we don't have any tokens left to parse, so we don't
     /// silently drop anything. `allow_semi` is so that "optional"
-    /// semilons at the end of normal expressions aren't complained
+    /// semicolons at the end of normal expressions aren't complained
     /// about e.g. the semicolon in `macro_rules! kapow( () => {
     /// fail!(); } )` doesn't get picked up by .parse_expr(), but it's
     /// allowed to be there.
@@ -48,7 +48,7 @@ fn ensure_complete_parse(&self, allow_semi: bool) {
             parser.bump()
         }
         if parser.token != EOF {
-            let token_str = parser.this_token_to_str();
+            let token_str = parser.this_token_to_string();
             let msg = format!("macro expansion ignores token `{}` and any \
                                following",
                               token_str);
@@ -73,6 +73,9 @@ fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
         let mut ret = SmallVector::zero();
         loop {
             let mut parser = self.parser.borrow_mut();
+            // so... do outer attributes attached to the macro invocation
+            // just disappear? This question applies to make_methods, as
+            // well.
             match parser.parse_item_with_outer_attributes() {
                 Some(item) => ret.push(item),
                 None => break
@@ -81,6 +84,20 @@ fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
         self.ensure_complete_parse(false);
         Some(ret)
     }
+
+    fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> {
+        let mut ret = SmallVector::zero();
+        loop {
+            let mut parser = self.parser.borrow_mut();
+            match parser.token {
+                EOF => break,
+                _ => ret.push(parser.parse_method(None))
+            }
+        }
+        self.ensure_complete_parse(false);
+        Some(ret)
+    }
+
     fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
         let attrs = self.parser.borrow_mut().parse_outer_attributes();
         let ret = self.parser.borrow_mut().parse_stmt(attrs);
@@ -95,7 +112,7 @@ struct MacroRulesMacroExpander {
     rhses: Vec<Rc<NamedMatch>>,
 }
 
-impl MacroExpander for MacroRulesMacroExpander {
+impl TTMacroExpander for MacroRulesMacroExpander {
     fn expand(&self,
               cx: &mut ExtCtxt,
               sp: Span,
@@ -119,7 +136,7 @@ fn make_def(&self) -> Option<MacroDef> {
     }
 }
 
-// Given `lhses` and `rhses`, this is the new macro we create
+/// Given `lhses` and `rhses`, this is the new macro we create
 fn generic_extension(cx: &ExtCtxt,
                      sp: Span,
                      name: Ident,
@@ -131,7 +148,7 @@ fn generic_extension(cx: &ExtCtxt,
         println!("{}! {} {} {}",
                  token::get_ident(name),
                  "{",
-                 print::pprust::tt_to_str(&TTDelim(Rc::new(arg.iter()
+                 print::pprust::tt_to_string(&TTDelim(Rc::new(arg.iter()
                                                               .map(|x| (*x).clone())
                                                               .collect()))),
                  "}");
@@ -193,9 +210,9 @@ fn generic_extension(cx: &ExtCtxt,
     cx.span_fatal(best_fail_spot, best_fail_msg.as_slice());
 }
 
-// this procedure performs the expansion of the
-// macro_rules! macro. It parses the RHS and adds
-// an extension to the current context.
+/// This procedure performs the expansion of the
+/// macro_rules! macro. It parses the RHS and adds
+/// an extension to the current context.
 pub fn add_new_extension(cx: &mut ExtCtxt,
                          sp: Span,
                          name: Ident,
@@ -254,7 +271,7 @@ fn ms(m: Matcher_) -> Matcher {
 
     box MacroRulesDefiner {
         def: RefCell::new(Some(MacroDef {
-            name: token::get_ident(name).to_str(),
+            name: token::get_ident(name).to_string(),
             ext: NormalTT(exp, Some(sp))
         }))
     } as Box<MacResult>
index c0c066fe4668b030fc8d36220cd4ba137211cf53..726a7315f69913c387b89c814edac51c863fa4ba 100644 (file)
@@ -32,7 +32,7 @@ struct TtFrame {
 #[deriving(Clone)]
 pub struct TtReader<'a> {
     pub sp_diag: &'a SpanHandler,
-    // the unzipped tree:
+    /// the unzipped tree:
     stack: Vec<TtFrame>,
     /* for MBE-style macro transcription */
     interpolations: HashMap<Ident, Rc<NamedMatch>>,
@@ -43,9 +43,9 @@ pub struct TtReader<'a> {
     pub cur_span: Span,
 }
 
-/** This can do Macro-By-Example transcription. On the other hand, if
- *  `src` contains no `TTSeq`s and `TTNonterminal`s, `interp` can (and
- *  should) be none. */
+/// This can do Macro-By-Example transcription. On the other hand, if
+/// `src` contains no `TTSeq`s and `TTNonterminal`s, `interp` can (and
+/// should) be none.
 pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
                          interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
                          src: Vec<ast::TokenTree> )
@@ -138,8 +138,8 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize {
     }
 }
 
-// return the next token from the TtReader.
-// EFFECT: advances the reader's token field
+/// Return the next token from the TtReader.
+/// EFFECT: advances the reader's token field
 pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
     // FIXME(pcwalton): Bad copy?
     let ret_val = TokenAndSpan {
index f9d7078da3dcbe4377132259c3c5699ae66fca36..fd786192cb48c181745bf1ed0a7b7022ec9b2440 100644 (file)
@@ -8,6 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! A Folder represents an AST->AST fold; it accepts an AST piece,
+//! and returns a piece of the same type. So, for instance, macro
+//! expansion is a Folder that walks over an AST and produces another
+//! AST.
+//!
+//! Note: using a Folder (other than the MacroExpander Folder) on
+//! an AST before macro expansion is probably a bad idea. For instance,
+//! a folder renaming item names in a module will miss all of those
+//! that are created by the expansion of a macro.
+
 use ast::*;
 use ast;
 use ast_util;
@@ -104,7 +114,7 @@ fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod {
         noop_fold_type_method(m, self)
     }
 
-    fn fold_method(&mut self, m: Gc<Method>) -> Gc<Method>  {
+    fn fold_method(&mut self, m: Gc<Method>) -> SmallVector<Gc<Method>>  {
         noop_fold_method(&*m, self)
     }
 
@@ -299,17 +309,13 @@ fn fold_local(&mut self, l: Gc<Local>) -> Gc<Local> {
         }
     }
 
-    fn fold_mac(&mut self, macro: &Mac) -> Mac {
-        Spanned {
-            node: match macro.node {
-                MacInvocTT(ref p, ref tts, ctxt) => {
-                    MacInvocTT(self.fold_path(p),
-                               fold_tts(tts.as_slice(), self),
-                               ctxt)
-                }
-            },
-            span: self.new_span(macro.span)
-        }
+    fn fold_mac(&mut self, _macro: &Mac) -> Mac {
+        fail!("fold_mac disabled by default");
+        // NB: see note about macros above.
+        // if you really want a folder that
+        // works on macros, use this
+        // definition in your trait impl:
+        // fold::fold_mac(_macro, self)
     }
 
     fn map_exprs(&self, f: |Gc<Expr>| -> Gc<Expr>,
@@ -334,9 +340,9 @@ fn fold_explicit_self(&mut self, es: &ExplicitSelf) -> ExplicitSelf {
 
     fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ {
         match *es {
-            SelfStatic | SelfValue | SelfUniq => *es,
-            SelfRegion(ref lifetime, m) => {
-                SelfRegion(fold_opt_lifetime(lifetime, self), m)
+            SelfStatic | SelfValue(_) | SelfUniq(_) => *es,
+            SelfRegion(ref lifetime, m, id) => {
+                SelfRegion(fold_opt_lifetime(lifetime, self), m, id)
             }
         }
     }
@@ -361,6 +367,20 @@ fn fold_attribute(&mut self, at: Attribute) -> Attribute {
 
 }
 
+
+pub fn fold_mac<T: Folder>(macro: &Mac, fld: &mut T) -> Mac {
+    Spanned {
+        node: match macro.node {
+            MacInvocTT(ref p, ref tts, ctxt) => {
+                MacInvocTT(fld.fold_path(p),
+                           fold_tts(tts.as_slice(), fld),
+                           ctxt)
+            }
+        },
+        span: fld.new_span(macro.span)
+    }
+}
+
 /* some little folds that probably aren't useful to have in Folder itself*/
 
 //used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive
@@ -445,10 +465,16 @@ fn fold_interpolated<T: Folder>(nt : &token::Nonterminal, fld: &mut T) -> token:
     match *nt {
         token::NtItem(item) =>
             token::NtItem(fld.fold_item(item)
+                          // this is probably okay, because the only folds likely
+                          // to peek inside interpolated nodes will be renamings/markings,
+                          // which map single items to single items
                           .expect_one("expected fold to produce exactly one item")),
         token::NtBlock(block) => token::NtBlock(fld.fold_block(block)),
         token::NtStmt(stmt) =>
             token::NtStmt(fld.fold_stmt(stmt)
+                          // this is probably okay, because the only folds likely
+                          // to peek inside interpolated nodes will be renamings/markings,
+                          // which map single items to single items
                           .expect_one("expected fold to produce exactly one statement")),
         token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)),
         token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)),
@@ -491,8 +517,8 @@ pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam {
     TyParam {
         ident: tp.ident,
         id: id,
-        sized: tp.sized,
         bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
+        unbound: tp.unbound.as_ref().map(|x| fold_ty_param_bound(x, fld)),
         default: tp.default.map(|x| fld.fold_ty(x)),
         span: tp.span
     }
@@ -663,18 +689,29 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
             ItemImpl(fold_generics(generics, folder),
                      ifce.as_ref().map(|p| fold_trait_ref(p, folder)),
                      folder.fold_ty(ty),
-                     methods.iter().map(|x| folder.fold_method(*x)).collect()
+                     methods.iter().flat_map(|x| folder.fold_method(*x).move_iter()).collect()
             )
         }
-        ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
-            let methods = methods.iter().map(|method| {
-                match *method {
-                    Required(ref m) => Required(folder.fold_type_method(m)),
-                    Provided(method) => Provided(folder.fold_method(method))
-                }
+        ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
+            let methods = methods.iter().flat_map(|method| {
+                let r = match *method {
+                    Required(ref m) =>
+                            SmallVector::one(Required(folder.fold_type_method(m))).move_iter(),
+                    Provided(method) => {
+                            // the awkward collect/iter idiom here is because
+                            // even though an iter and a map satisfy the same trait bound,
+                            // they're not actually the same type, so the method arms
+                            // don't unify.
+                            let methods : SmallVector<ast::TraitMethod> =
+                                folder.fold_method(method).move_iter()
+                                .map(|m| Provided(m)).collect();
+                            methods.move_iter()
+                        }
+                };
+                r
             }).collect();
             ItemTrait(fold_generics(generics, folder),
-                      *sized,
+                      unbound.clone(),
                       traits.iter().map(|p| fold_trait_ref(p, folder)).collect(),
                       methods)
         }
@@ -713,6 +750,7 @@ pub fn noop_fold_crate<T: Folder>(c: Crate, folder: &mut T) -> Crate {
         attrs: c.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(),
         config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(),
         span: folder.new_span(c.span),
+        exported_macros: c.exported_macros.iter().map(|sp| folder.new_span(*sp)).collect(),
     }
 }
 
@@ -770,20 +808,27 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem,
     }
 }
 
-pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> Gc<Method> {
+// Default fold over a method.
+// Invariant: produces exactly one method.
+pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> SmallVector<Gc<Method>> {
     let id = folder.new_id(m.id); // Needs to be first, for ast_map.
-    box(GC) Method {
-        id: id,
-        ident: folder.fold_ident(m.ident),
+    SmallVector::one(box(GC) Method {
         attrs: m.attrs.iter().map(|a| folder.fold_attribute(*a)).collect(),
-        generics: fold_generics(&m.generics, folder),
-        explicit_self: folder.fold_explicit_self(&m.explicit_self),
-        fn_style: m.fn_style,
-        decl: folder.fold_fn_decl(&*m.decl),
-        body: folder.fold_block(m.body),
+        id: id,
         span: folder.new_span(m.span),
-        vis: m.vis
-    }
+        node: match m.node {
+            MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
+                MethDecl(folder.fold_ident(ident),
+                         fold_generics(generics, folder),
+                         folder.fold_explicit_self(explicit_self),
+                         fn_style,
+                         folder.fold_fn_decl(&*decl),
+                         folder.fold_block(body),
+                         vis)
+            },
+            MethMac(ref mac) => MethMac(folder.fold_mac(mac)),
+        }
+    })
 }
 
 pub fn noop_fold_pat<T: Folder>(p: Gc<Pat>, folder: &mut T) -> Gc<Pat> {
@@ -794,7 +839,7 @@ pub fn noop_fold_pat<T: Folder>(p: Gc<Pat>, folder: &mut T) -> Gc<Pat> {
         PatIdent(binding_mode, ref pth1, ref sub) => {
             PatIdent(binding_mode,
                      Spanned{span: folder.new_span(pth1.span),
-                                       node: folder.fold_ident(pth1.node)},
+                             node: folder.fold_ident(pth1.node)},
                      sub.map(|x| folder.fold_pat(x)))
         }
         PatLit(e) => PatLit(folder.fold_expr(e)),
@@ -985,6 +1030,7 @@ mod test {
     use util::parser_testing::{string_to_crate, matches_codepattern};
     use parse::token;
     use print::pprust;
+    use fold;
     use super::*;
 
     // this version doesn't care about getting comments or docstrings in.
@@ -1000,6 +1046,9 @@ impl Folder for ToZzIdentFolder {
         fn fold_ident(&mut self, _: ast::Ident) -> ast::Ident {
             token::str_to_ident("zz")
         }
+        fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac {
+            fold::fold_mac(macro, self)
+        }
     }
 
     // maybe add to expand.rs...
@@ -1026,7 +1075,7 @@ macro_rules! assert_pred (
         assert_pred!(
             matches_codepattern,
             "matches_codepattern",
-            pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
+            pprust::to_string(|s| fake_print_crate(s, &folded_crate)),
             "#[a]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string());
     }
 
@@ -1040,7 +1089,7 @@ macro_rules! assert_pred (
         assert_pred!(
             matches_codepattern,
             "matches_codepattern",
-            pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
+            pprust::to_string(|s| fake_print_crate(s, &folded_crate)),
             "zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)))".to_string());
     }
 }
index ce63d2bb7311acfece0c700fc8a478208822edbf..8b9cb086949725001bdfeeefc9d27ea4510c802e 100644 (file)
@@ -8,35 +8,30 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
+//! The Rust parser and macro expander.
+//!
+//! # Note
+//!
+//! This API is completely unstable and subject to change.
 
-The Rust parser and macro expander.
-
-# Note
-
-This API is completely unstable and subject to change.
-
-*/
-
-#![crate_id = "syntax#0.11.0"]
+#![crate_name = "syntax"]
 #![experimental]
 #![license = "MIT/ASL2"]
 #![crate_type = "dylib"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 
 #![feature(macro_rules, globs, managed_boxes, default_type_params, phase)]
 #![feature(quote, unsafe_destructor)]
 #![allow(deprecated)]
 
-extern crate serialize;
-extern crate term;
-#[phase(plugin, link)] extern crate log;
-
 extern crate fmt_macros;
 extern crate debug;
+#[phase(plugin, link)] extern crate log;
+extern crate serialize;
+extern crate term;
 
 pub mod util {
     pub mod interner;
@@ -45,26 +40,30 @@ pub mod util {
     pub mod small_vector;
 }
 
+pub mod diagnostics {
+    pub mod macros;
+    pub mod plugin;
+    pub mod registry;
+}
+
 pub mod syntax {
     pub use ext;
     pub use parse;
     pub use ast;
 }
 
-pub mod owned_slice;
-pub mod attr;
-pub mod diagnostic;
-pub mod codemap;
 pub mod abi;
 pub mod ast;
-pub mod ast_util;
 pub mod ast_map;
-pub mod visit;
+pub mod ast_util;
+pub mod attr;
+pub mod codemap;
+pub mod crateid;
+pub mod diagnostic;
 pub mod fold;
-
-
+pub mod owned_slice;
 pub mod parse;
-pub mod crateid;
+pub mod visit;
 
 pub mod print {
     pub mod pp;
@@ -74,31 +73,25 @@ pub mod print {
 pub mod ext {
     pub mod asm;
     pub mod base;
+    pub mod build;
+    pub mod bytes;
+    pub mod cfg;
+    pub mod concat;
+    pub mod concat_idents;
+    pub mod deriving;
+    pub mod env;
     pub mod expand;
-
+    pub mod fmt;
+    pub mod format;
+    pub mod log_syntax;
+    pub mod mtwt;
     pub mod quote;
-
-    pub mod deriving;
-
-    pub mod build;
+    pub mod source_util;
+    pub mod trace_macros;
 
     pub mod tt {
         pub mod transcribe;
         pub mod macro_parser;
         pub mod macro_rules;
     }
-
-    pub mod mtwt;
-
-    pub mod cfg;
-    pub mod fmt;
-    pub mod format;
-    pub mod env;
-    pub mod bytes;
-    pub mod concat;
-    pub mod concat_idents;
-    pub mod log_syntax;
-    pub mod source_util;
-
-    pub mod trace_macros;
 }
index e47080dadfd72361dd5eb1cfc94b62e5b5b13736..550dbfdab71f77ee42a171cd1d057a79cbd45ca8 100644 (file)
@@ -18,7 +18,7 @@
 
 use std::gc::{Gc, GC};
 
-// a parser that can parse attributes.
+/// A parser that can parse attributes.
 pub trait ParserAttr {
     fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute>;
     fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
@@ -30,11 +30,11 @@ fn parse_inner_attrs_and_next(&mut self)
 }
 
 impl<'a> ParserAttr for Parser<'a> {
-    // Parse attributes that appear before an item
+    /// Parse attributes that appear before an item
     fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
         let mut attrs: Vec<ast::Attribute> = Vec::new();
         loop {
-            debug!("parse_outer_attributes: self.token={:?}",
+            debug!("parse_outer_attributes: self.token={}",
                    self.token);
             match self.token {
               token::POUND => {
@@ -43,7 +43,7 @@ fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
               token::DOC_COMMENT(s) => {
                 let attr = ::attr::mk_sugared_doc_attr(
                     attr::mk_attr_id(),
-                    self.id_to_interned_str(s),
+                    self.id_to_interned_str(s.ident()),
                     self.span.lo,
                     self.span.hi
                 );
@@ -59,10 +59,10 @@ fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
         return attrs;
     }
 
-    // matches attribute = # ! [ meta_item ]
-    //
-    // if permit_inner is true, then a leading `!` indicates an inner
-    // attribute
+    /// Matches `attribute = # ! [ meta_item ]`
+    ///
+    /// If permit_inner is true, then a leading `!` indicates an inner
+    /// attribute
     fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
         debug!("parse_attributes: permit_inner={:?} self.token={:?}",
                permit_inner, self.token);
@@ -85,13 +85,13 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
 
                 self.expect(&token::LBRACKET);
                 let meta_item = self.parse_meta_item();
+                let hi = self.span.hi;
                 self.expect(&token::RBRACKET);
 
-                let hi = self.span.hi;
                 (mk_sp(lo, hi), meta_item, style)
             }
             _ => {
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 self.fatal(format!("expected `#` but found `{}`",
                                    token_str).as_slice());
             }
@@ -114,17 +114,17 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
         };
     }
 
-    // Parse attributes that appear after the opening of an item. These should
-    // be preceded by an exclamation mark, but we accept and warn about one
-    // terminated by a semicolon. In addition to a vector of inner attributes,
-    // this function also returns a vector that may contain the first outer
-    // attribute of the next item (since we can't know whether the attribute
-    // is an inner attribute of the containing item or an outer attribute of
-    // the first contained item until we see the semi).
-
-    // matches inner_attrs* outer_attr?
-    // you can make the 'next' field an Option, but the result is going to be
-    // more useful as a vector.
+    /// Parse attributes that appear after the opening of an item. These should
+    /// be preceded by an exclamation mark, but we accept and warn about one
+    /// terminated by a semicolon. In addition to a vector of inner attributes,
+    /// this function also returns a vector that may contain the first outer
+    /// attribute of the next item (since we can't know whether the attribute
+    /// is an inner attribute of the containing item or an outer attribute of
+    /// the first contained item until we see the semi).
+
+    /// matches inner_attrs* outer_attr?
+    /// you can make the 'next' field an Option, but the result is going to be
+    /// more useful as a vector.
     fn parse_inner_attrs_and_next(&mut self)
                                   -> (Vec<ast::Attribute> , Vec<ast::Attribute> ) {
         let mut inner_attrs: Vec<ast::Attribute> = Vec::new();
@@ -139,7 +139,7 @@ fn parse_inner_attrs_and_next(&mut self)
                     let Span { lo, hi, .. } = self.span;
                     self.bump();
                     attr::mk_sugared_doc_attr(attr::mk_attr_id(),
-                                              self.id_to_interned_str(s),
+                                              self.id_to_interned_str(s.ident()),
                                               lo,
                                               hi)
                 }
@@ -157,9 +157,9 @@ fn parse_inner_attrs_and_next(&mut self)
         (inner_attrs, next_outer_attrs)
     }
 
-    // matches meta_item = IDENT
-    // | IDENT = lit
-    // | IDENT meta_seq
+    /// matches meta_item = IDENT
+    /// | IDENT = lit
+    /// | IDENT meta_seq
     fn parse_meta_item(&mut self) -> Gc<ast::MetaItem> {
         match self.token {
             token::INTERPOLATED(token::NtMeta(e)) => {
@@ -201,7 +201,7 @@ fn parse_meta_item(&mut self) -> Gc<ast::MetaItem> {
         }
     }
 
-    // matches meta_seq = ( COMMASEP(meta_item) )
+    /// matches meta_seq = ( COMMASEP(meta_item) )
     fn parse_meta_seq(&mut self) -> Vec<Gc<ast::MetaItem>> {
         self.parse_seq(&token::LPAREN,
                        &token::RPAREN,
index 8d9cc305c26e815d8c65393e5af4fa96623707f8..516f22cdf4d606abab30e64661184aa4714a36f1 100644 (file)
 use ast;
 use std::gc::Gc;
 
-// does this expression require a semicolon to be treated
-// as a statement? The negation of this: 'can this expression
-// be used as a statement without a semicolon' -- is used
-// as an early-bail-out in the parser so that, for instance,
-// 'if true {...} else {...}
-//  |x| 5 '
-// isn't parsed as (if true {...} else {...} | x) | 5
+/// Does this expression require a semicolon to be treated
+/// as a statement? The negation of this: 'can this expression
+/// be used as a statement without a semicolon' -- is used
+/// as an early-bail-out in the parser so that, for instance,
+///     if true {...} else {...}
+///      |x| 5
+/// isn't parsed as (if true {...} else {...} | x) | 5
 pub fn expr_requires_semi_to_be_stmt(e: Gc<ast::Expr>) -> bool {
     match e.node {
         ast::ExprIf(..)
@@ -41,9 +41,9 @@ pub fn expr_is_simple_block(e: Gc<ast::Expr>) -> bool {
     }
 }
 
-// this statement requires a semicolon after it.
-// note that in one case (stmt_semi), we've already
-// seen the semicolon, and thus don't need another.
+/// this statement requires a semicolon after it.
+/// note that in one case (stmt_semi), we've already
+/// seen the semicolon, and thus don't need another.
 pub fn stmt_ends_with_semi(stmt: &ast::Stmt) -> bool {
     return match stmt.node {
         ast::StmtDecl(d, _) => {
index 3c3f0c7a820440cff44b71d07fc5d883a863d7f6..3842170d67777ac039b12ca3536ca1888f29cbb9 100644 (file)
@@ -12,8 +12,8 @@
 
 use parse::token;
 
-// SeqSep : a sequence separator (token)
-// and whether a trailing separator is allowed.
+/// SeqSep : a sequence separator (token)
+/// and whether a trailing separator is allowed.
 pub struct SeqSep {
     pub sep: Option<token::Token>,
     pub trailing_sep_allowed: bool
index f00c1ab44551f63010491a027efe80d06ba6e840..3f3a8a723f10c40d13c9ee7ca4112870247fb3dd 100644 (file)
@@ -13,7 +13,7 @@
 use diagnostic;
 use parse::lexer::{is_whitespace, Reader};
 use parse::lexer::{StringReader, TokenAndSpan};
-use parse::lexer::{is_line_non_doc_comment, is_block_non_doc_comment};
+use parse::lexer::is_block_doc_comment;
 use parse::lexer;
 use parse::token;
 
 
 #[deriving(Clone, PartialEq)]
 pub enum CommentStyle {
-    Isolated, // No code on either side of each line of the comment
-    Trailing, // Code exists to the left of the comment
-    Mixed, // Code before /* foo */ and after the comment
-    BlankLine, // Just a manual blank line "\n\n", for layout
+    /// No code on either side of each line of the comment
+    Isolated,
+    /// Code exists to the left of the comment
+    Trailing,
+    /// Code before /* foo */ and after the comment
+    Mixed,
+    /// Just a manual blank line "\n\n", for layout
+    BlankLine,
 }
 
 #[deriving(Clone)]
@@ -38,9 +42,9 @@ pub struct Comment {
 }
 
 pub fn is_doc_comment(s: &str) -> bool {
-    (s.starts_with("///") && !is_line_non_doc_comment(s)) ||
+    (s.starts_with("///") && super::is_doc_comment(s)) ||
     s.starts_with("//!") ||
-    (s.starts_with("/**") && !is_block_non_doc_comment(s)) ||
+    (s.starts_with("/**") && is_block_doc_comment(s)) ||
     s.starts_with("/*!")
 }
 
@@ -198,9 +202,9 @@ fn read_line_comments(rdr: &mut StringReader, code_to_the_left: bool,
     }
 }
 
-// Returns None if the first col chars of s contain a non-whitespace char.
-// Otherwise returns Some(k) where k is first char offset after that leading
-// whitespace.  Note k may be outside bounds of s.
+/// Returns None if the first col chars of s contain a non-whitespace char.
+/// Otherwise returns Some(k) where k is first char offset after that leading
+/// whitespace.  Note k may be outside bounds of s.
 fn all_whitespace(s: &str, col: CharPos) -> Option<uint> {
     let len = s.len();
     let mut col = col.to_uint();
@@ -256,7 +260,7 @@ fn read_block_comment(rdr: &mut StringReader,
             rdr.bump();
             rdr.bump();
         }
-        if !is_block_non_doc_comment(curr_line.as_slice()) {
+        if is_block_doc_comment(curr_line.as_slice()) {
             return
         }
         assert!(!curr_line.as_slice().contains_char('\n'));
@@ -369,7 +373,7 @@ pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler,
                 literals.push(Literal {lit: s.to_string(), pos: sp.lo});
             })
         } else {
-            debug!("tok: {}", token::to_str(&tok));
+            debug!("tok: {}", token::to_string(&tok));
         }
         first_read = false;
     }
index 0f188fdf18a5a80c06ee94126b1ac47e16198674..5c5943f0cd47c10e5fd461800b0ffbae3024a978 100644 (file)
@@ -18,7 +18,6 @@
 
 use std::char;
 use std::mem::replace;
-use std::num::from_str_radix;
 use std::rc::Rc;
 use std::str;
 
@@ -44,13 +43,13 @@ pub struct TokenAndSpan {
 
 pub struct StringReader<'a> {
     pub span_diagnostic: &'a SpanHandler,
-    // The absolute offset within the codemap of the next character to read
+    /// The absolute offset within the codemap of the next character to read
     pub pos: BytePos,
-    // The absolute offset within the codemap of the last character read(curr)
+    /// The absolute offset within the codemap of the last character read(curr)
     pub last_pos: BytePos,
-    // The column of the next character to read
+    /// The column of the next character to read
     pub col: CharPos,
-    // The last character to be read
+    /// The last character to be read
     pub curr: Option<char>,
     pub filemap: Rc<codemap::FileMap>,
     /* cached: */
@@ -60,7 +59,7 @@ pub struct StringReader<'a> {
 
 impl<'a> Reader for StringReader<'a> {
     fn is_eof(&self) -> bool { self.curr.is_none() }
-    // return the next token. EFFECT: advances the string_reader.
+    /// Return the next token. EFFECT: advances the string_reader.
     fn next_token(&mut self) -> TokenAndSpan {
         let ret_val = TokenAndSpan {
             tok: replace(&mut self.peek_tok, token::UNDERSCORE),
@@ -90,7 +89,7 @@ fn is_eof(&self) -> bool {
     }
     fn next_token(&mut self) -> TokenAndSpan {
         let r = tt_next_token(self);
-        debug!("TtReader: r={:?}", r);
+        debug!("TtReader: r={}", r);
         r
     }
     fn fatal(&self, m: &str) -> ! {
@@ -188,7 +187,7 @@ fn fatal_span_verbose(&self, from_pos: BytePos, to_pos: BytePos, mut m: String)
     /// Advance peek_tok and peek_span to refer to the next token, and
     /// possibly update the interner.
     fn advance_token(&mut self) {
-        match self.consume_whitespace_and_comments() {
+        match self.scan_whitespace_or_comment() {
             Some(comment) => {
                 self.peek_span = comment.sp;
                 self.peek_tok = comment.tok;
@@ -217,6 +216,20 @@ pub fn with_str_from<T>(&self, start: BytePos, f: |s: &str| -> T) -> T {
         self.with_str_from_to(start, self.last_pos, f)
     }
 
+    /// Create a Name from a given offset to the current offset, each
+    /// adjusted 1 towards each other (assumes that on either side there is a
+    /// single-byte delimiter).
+    pub fn name_from(&self, start: BytePos) -> ast::Name {
+        debug!("taking an ident from {} to {}", start, self.last_pos);
+        self.with_str_from(start, token::intern)
+    }
+
+    /// As name_from, with an explicit endpoint.
+    pub fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
+        debug!("taking an ident from {} to {}", start, end);
+        self.with_str_from_to(start, end, token::intern)
+    }
+
     /// Calls `f` with a string slice of the source text spanning from `start`
     /// up to but excluding `end`.
     fn with_str_from_to<T>(&self, start: BytePos, end: BytePos, f: |s: &str| -> T) -> T {
@@ -326,8 +339,7 @@ pub fn nextnextch_is(&self, c: char) -> bool {
 
     /// PRECONDITION: self.curr is not whitespace
     /// Eats any kind of comment.
-    /// Returns a Some(sugared-doc-attr) if one exists, None otherwise
-    fn consume_any_line_comment(&mut self) -> Option<TokenAndSpan> {
+    fn scan_comment(&mut self) -> Option<TokenAndSpan> {
         match self.curr {
             Some(c) => {
                 if c.is_whitespace() {
@@ -362,28 +374,32 @@ fn consume_any_line_comment(&mut self) -> Option<TokenAndSpan> {
                             }
                             self.bump();
                         }
-                        let ret = self.with_str_from(start_bpos, |string| {
+                        return self.with_str_from(start_bpos, |string| {
                             // but comments with only more "/"s are not
-                            if !is_line_non_doc_comment(string) {
-                                Some(TokenAndSpan{
-                                    tok: token::DOC_COMMENT(str_to_ident(string)),
-                                    sp: codemap::mk_sp(start_bpos, self.last_pos)
-                                })
+                            let tok = if is_doc_comment(string) {
+                                token::DOC_COMMENT(token::intern(string))
                             } else {
-                                None
-                            }
-                        });
+                                token::COMMENT
+                            };
 
-                        if ret.is_some() {
-                            return ret;
-                        }
+                            return Some(TokenAndSpan{
+                                tok: tok,
+                                sp: codemap::mk_sp(start_bpos, self.last_pos)
+                            });
+                        });
                     } else {
+                        let start_bpos = self.last_pos - BytePos(2);
                         while !self.curr_is('\n') && !self.is_eof() { self.bump(); }
+                        return Some(TokenAndSpan {
+                            tok: token::COMMENT,
+                            sp: codemap::mk_sp(start_bpos, self.last_pos)
+                        });
                     }
-                    // Restart whitespace munch.
-                    self.consume_whitespace_and_comments()
                 }
-                Some('*') => { self.bump(); self.bump(); self.consume_block_comment() }
+                Some('*') => {
+                    self.bump(); self.bump();
+                    self.scan_block_comment()
+                }
                 _ => None
             }
         } else if self.curr_is('#') {
@@ -399,9 +415,15 @@ fn consume_any_line_comment(&mut self) -> Option<TokenAndSpan> {
                 let cmap = CodeMap::new();
                 cmap.files.borrow_mut().push(self.filemap.clone());
                 let loc = cmap.lookup_char_pos_adj(self.last_pos);
+                debug!("Skipping a shebang");
                 if loc.line == 1u && loc.col == CharPos(0u) {
+                    // FIXME: Add shebang "token", return it
+                    let start = self.last_pos;
                     while !self.curr_is('\n') && !self.is_eof() { self.bump(); }
-                    return self.consume_whitespace_and_comments();
+                    return Some(TokenAndSpan {
+                        tok: token::SHEBANG(self.name_from(start)),
+                        sp: codemap::mk_sp(start, self.last_pos)
+                    });
                 }
             }
             None
@@ -410,15 +432,33 @@ fn consume_any_line_comment(&mut self) -> Option<TokenAndSpan> {
         }
     }
 
-    /// EFFECT: eats whitespace and comments.
-    /// Returns a Some(sugared-doc-attr) if one exists, None otherwise.
-    fn consume_whitespace_and_comments(&mut self) -> Option<TokenAndSpan> {
-        while is_whitespace(self.curr) { self.bump(); }
-        return self.consume_any_line_comment();
+    /// If there is whitespace, shebang, or a comment, scan it. Otherwise,
+    /// return None.
+    fn scan_whitespace_or_comment(&mut self) -> Option<TokenAndSpan> {
+        match self.curr.unwrap_or('\0') {
+            // # to handle shebang at start of file -- this is the entry point
+            // for skipping over all "junk"
+            '/' | '#' => {
+                let c = self.scan_comment();
+                debug!("scanning a comment {}", c);
+                c
+            },
+            c if is_whitespace(Some(c)) => {
+                let start_bpos = self.last_pos;
+                while is_whitespace(self.curr) { self.bump(); }
+                let c = Some(TokenAndSpan {
+                    tok: token::WS,
+                    sp: codemap::mk_sp(start_bpos, self.last_pos)
+                });
+                debug!("scanning whitespace: {}", c);
+                c
+            },
+            _ => None
+        }
     }
 
-    // might return a sugared-doc-attr
-    fn consume_block_comment(&mut self) -> Option<TokenAndSpan> {
+    /// Might return a sugared-doc-attr
+    fn scan_block_comment(&mut self) -> Option<TokenAndSpan> {
         // block comments starting with "/**" or "/*!" are doc-comments
         let is_doc_comment = self.curr_is('*') || self.curr_is('!');
         let start_bpos = self.last_pos - BytePos(2);
@@ -453,228 +493,132 @@ fn consume_block_comment(&mut self) -> Option<TokenAndSpan> {
             self.bump();
         }
 
-        let res = if is_doc_comment {
-            self.with_str_from(start_bpos, |string| {
-                // but comments with only "*"s between two "/"s are not
-                if !is_block_non_doc_comment(string) {
-                    let string = if has_cr {
-                        self.translate_crlf(start_bpos, string,
-                                            "bare CR not allowed in block doc-comment")
-                    } else { string.into_maybe_owned() };
-                    Some(TokenAndSpan{
-                            tok: token::DOC_COMMENT(str_to_ident(string.as_slice())),
-                            sp: codemap::mk_sp(start_bpos, self.last_pos)
-                        })
-                } else {
-                    None
-                }
-            })
-        } else {
-            None
-        };
-
-        // restart whitespace munch.
-        if res.is_some() { res } else { self.consume_whitespace_and_comments() }
-    }
-
-    fn scan_exponent(&mut self, start_bpos: BytePos) -> Option<String> {
-        // \x00 hits the `return None` case immediately, so this is fine.
-        let mut c = self.curr.unwrap_or('\x00');
-        let mut rslt = String::new();
-        if c == 'e' || c == 'E' {
-            rslt.push_char(c);
-            self.bump();
-            c = self.curr.unwrap_or('\x00');
-            if c == '-' || c == '+' {
-                rslt.push_char(c);
-                self.bump();
-            }
-            let exponent = self.scan_digits(10u);
-            if exponent.len() > 0u {
-                rslt.push_str(exponent.as_slice());
-                return Some(rslt);
+        self.with_str_from(start_bpos, |string| {
+            // but comments with only "*"s between two "/"s are not
+            let tok = if is_block_doc_comment(string) {
+                let string = if has_cr {
+                    self.translate_crlf(start_bpos, string,
+                                        "bare CR not allowed in block doc-comment")
+                } else { string.into_maybe_owned() };
+                token::DOC_COMMENT(token::intern(string.as_slice()))
             } else {
-                let last_bpos = self.last_pos;
-                self.err_span_(start_bpos, last_bpos, "scan_exponent: bad fp literal");
-                rslt.push_str("1"); // arbitrary placeholder exponent
-                return Some(rslt);
-            }
-        } else {
-            return None::<String>;
-        }
+                token::COMMENT
+            };
+
+            Some(TokenAndSpan{
+                tok: tok,
+                sp: codemap::mk_sp(start_bpos, self.last_pos)
+            })
+        })
     }
 
-    fn scan_digits(&mut self, radix: uint) -> String {
-        let mut rslt = String::new();
+    /// Scan through any digits (base `radix`) or underscores, and return how
+    /// many digits there were.
+    fn scan_digits(&mut self, radix: uint) -> uint {
+        let mut len = 0u;
         loop {
             let c = self.curr;
-            if c == Some('_') { self.bump(); continue; }
+            if c == Some('_') { debug!("skipping a _"); self.bump(); continue; }
             match c.and_then(|cc| char::to_digit(cc, radix)) {
-              Some(_) => {
-                rslt.push_char(c.unwrap());
-                self.bump();
-              }
-              _ => return rslt
+                Some(_) => {
+                    debug!("{} in scan_digits", c);
+                    len += 1;
+                    self.bump();
+                }
+                _ => return len
             }
         };
     }
 
-    fn check_float_base(&mut self, start_bpos: BytePos, last_bpos: BytePos, base: uint) {
-        match base {
-          16u => self.err_span_(start_bpos, last_bpos,
-                                "hexadecimal float literal is not supported"),
-          8u => self.err_span_(start_bpos, last_bpos, "octal float literal is not supported"),
-          2u => self.err_span_(start_bpos, last_bpos, "binary float literal is not supported"),
-          _ => ()
-        }
-    }
-
+    /// Lex a LIT_INTEGER or a LIT_FLOAT
     fn scan_number(&mut self, c: char) -> token::Token {
-        let mut num_str;
-        let mut base = 10u;
-        let mut c = c;
-        let mut n = self.nextch().unwrap_or('\x00');
+        let mut num_digits;
+        let mut base = 10;
         let start_bpos = self.last_pos;
-        if c == '0' && n == 'x' {
-            self.bump();
-            self.bump();
-            base = 16u;
-        } else if c == '0' && n == 'o' {
-            self.bump();
-            self.bump();
-            base = 8u;
-        } else if c == '0' && n == 'b' {
-            self.bump();
-            self.bump();
-            base = 2u;
-        }
-        num_str = self.scan_digits(base);
-        c = self.curr.unwrap_or('\x00');
-        self.nextch();
-        if c == 'u' || c == 'i' {
-            enum Result { Signed(ast::IntTy), Unsigned(ast::UintTy) }
-            let signed = c == 'i';
-            let mut tp = {
-                if signed { Signed(ast::TyI) }
-                else { Unsigned(ast::TyU) }
-            };
-            self.bump();
-            c = self.curr.unwrap_or('\x00');
-            if c == '8' {
-                self.bump();
-                tp = if signed { Signed(ast::TyI8) }
-                          else { Unsigned(ast::TyU8) };
-            }
-            n = self.nextch().unwrap_or('\x00');
-            if c == '1' && n == '6' {
-                self.bump();
-                self.bump();
-                tp = if signed { Signed(ast::TyI16) }
-                          else { Unsigned(ast::TyU16) };
-            } else if c == '3' && n == '2' {
-                self.bump();
-                self.bump();
-                tp = if signed { Signed(ast::TyI32) }
-                          else { Unsigned(ast::TyU32) };
-            } else if c == '6' && n == '4' {
-                self.bump();
-                self.bump();
-                tp = if signed { Signed(ast::TyI64) }
-                          else { Unsigned(ast::TyU64) };
-            }
-            if num_str.len() == 0u {
-                let last_bpos = self.last_pos;
-                self.err_span_(start_bpos, last_bpos, "no valid digits found for number");
-                num_str = "1".to_string();
-            }
-            let parsed = match from_str_radix::<u64>(num_str.as_slice(),
-                                                     base as uint) {
-                Some(p) => p,
-                None => {
-                    let last_bpos = self.last_pos;
-                    self.err_span_(start_bpos, last_bpos, "int literal is too large");
-                    1
-                }
-            };
 
-            match tp {
-              Signed(t) => return token::LIT_INT(parsed as i64, t),
-              Unsigned(t) => return token::LIT_UINT(parsed, t)
+        self.bump();
+
+        if c == '0' {
+            match self.curr.unwrap_or('\0') {
+                'b' => { self.bump(); base = 2; num_digits = self.scan_digits(2); }
+                'o' => { self.bump(); base = 8; num_digits = self.scan_digits(8); }
+                'x' => { self.bump(); base = 16; num_digits = self.scan_digits(16); }
+                '0'..'9' | '_' | '.' => {
+                    num_digits = self.scan_digits(10) + 1;
+                }
+                'u' | 'i' => {
+                    self.scan_int_suffix();
+                    return token::LIT_INTEGER(self.name_from(start_bpos));
+                },
+                'f' => {
+                    let last_pos = self.last_pos;
+                    self.scan_float_suffix();
+                    self.check_float_base(start_bpos, last_pos, base);
+                    return token::LIT_FLOAT(self.name_from(start_bpos));
+                }
+                _ => {
+                    // just a 0
+                    return token::LIT_INTEGER(self.name_from(start_bpos));
+                }
             }
+        } else if c.is_digit_radix(10) {
+            num_digits = self.scan_digits(10) + 1;
+        } else {
+            num_digits = 0;
         }
-        let mut is_float = false;
-        if self.curr_is('.') && !(ident_start(self.nextch()) || self.nextch_is('.')) {
-            is_float = true;
-            self.bump();
-            let dec_part = self.scan_digits(10u);
-            num_str.push_char('.');
-            num_str.push_str(dec_part.as_slice());
-        }
-        match self.scan_exponent(start_bpos) {
-          Some(ref s) => {
-            is_float = true;
-            num_str.push_str(s.as_slice());
-          }
-          None => ()
+
+        if num_digits == 0 {
+            self.err_span_(start_bpos, self.last_pos, "no valid digits found for number");
+            // eat any suffix
+            self.scan_int_suffix();
+            return token::LIT_INTEGER(token::intern("0"));
         }
 
-        if self.curr_is('f') {
+        // might be a float, but don't be greedy if this is actually an
+        // integer literal followed by field/method access or a range pattern
+        // (`0..2` and `12.foo()`)
+        if self.curr_is('.') && !self.nextch_is('.') && !self.nextch().unwrap_or('\0')
+                                                             .is_XID_start() {
+            // might have stuff after the ., and if it does, it needs to start
+            // with a number
             self.bump();
-            c = self.curr.unwrap_or('\x00');
-            n = self.nextch().unwrap_or('\x00');
-            if c == '3' && n == '2' {
-                self.bump();
-                self.bump();
-                let last_bpos = self.last_pos;
-                self.check_float_base(start_bpos, last_bpos, base);
-                return token::LIT_FLOAT(str_to_ident(num_str.as_slice()),
-                                        ast::TyF32);
-            } else if c == '6' && n == '4' {
-                self.bump();
-                self.bump();
-                let last_bpos = self.last_pos;
-                self.check_float_base(start_bpos, last_bpos, base);
-                return token::LIT_FLOAT(str_to_ident(num_str.as_slice()),
-                                        ast::TyF64);
-                /* FIXME (#2252): if this is out of range for either a
-                32-bit or 64-bit float, it won't be noticed till the
-                back-end.  */
+            if self.curr.unwrap_or('\0').is_digit_radix(10) {
+                self.scan_digits(10);
+                self.scan_float_exponent();
+                self.scan_float_suffix();
             }
-            let last_bpos = self.last_pos;
-            self.err_span_(start_bpos, last_bpos, "expected `f32` or `f64` suffix");
-        }
-        if is_float {
-            let last_bpos = self.last_pos;
-            self.check_float_base(start_bpos, last_bpos, base);
-            return token::LIT_FLOAT_UNSUFFIXED(str_to_ident(
-                    num_str.as_slice()));
+            let last_pos = self.last_pos;
+            self.check_float_base(start_bpos, last_pos, base);
+            return token::LIT_FLOAT(self.name_from(start_bpos));
+        } else if self.curr_is('f') {
+            // or it might be an integer literal suffixed as a float
+            self.scan_float_suffix();
+            let last_pos = self.last_pos;
+            self.check_float_base(start_bpos, last_pos, base);
+            return token::LIT_FLOAT(self.name_from(start_bpos));
         } else {
-            if num_str.len() == 0u {
-                let last_bpos = self.last_pos;
-                self.err_span_(start_bpos, last_bpos, "no valid digits found for number");
-                num_str = "1".to_string();
+            // it might be a float if it has an exponent
+            if self.curr_is('e') || self.curr_is('E') {
+                self.scan_float_exponent();
+                self.scan_float_suffix();
+                let last_pos = self.last_pos;
+                self.check_float_base(start_bpos, last_pos, base);
+                return token::LIT_FLOAT(self.name_from(start_bpos));
             }
-            let parsed = match from_str_radix::<u64>(num_str.as_slice(),
-                                                     base as uint) {
-                Some(p) => p,
-                None => {
-                    let last_bpos = self.last_pos;
-                    self.err_span_(start_bpos, last_bpos, "int literal is too large");
-                    1
-                }
-            };
-
-            debug!("lexing {} as an unsuffixed integer literal",
-                   num_str.as_slice());
-            return token::LIT_INT_UNSUFFIXED(parsed as i64);
+            // but we certainly have an integer!
+            self.scan_int_suffix();
+            return token::LIT_INTEGER(self.name_from(start_bpos));
         }
     }
 
-
-    fn scan_numeric_escape(&mut self, n_hex_digits: uint, delim: char) -> char {
-        let mut accum_int = 0u32;
+    /// Scan over `n_digits` hex digits, stopping at `delim`, reporting an
+    /// error if too many or too few digits are encountered.
+    fn scan_hex_digits(&mut self, n_digits: uint, delim: char) -> bool {
+        debug!("scanning {} digits until {}", n_digits, delim);
         let start_bpos = self.last_pos;
-        for _ in range(0, n_hex_digits) {
+        let mut accum_int = 0;
+
+        for _ in range(0, n_digits) {
             if self.is_eof() {
                 let last_bpos = self.last_pos;
                 self.fatal_span_(start_bpos, last_bpos, "unterminated numeric character escape");
@@ -695,11 +639,11 @@ fn scan_numeric_escape(&mut self, n_hex_digits: uint, delim: char) -> char {
         }
 
         match char::from_u32(accum_int) {
-            Some(x) => x,
+            Some(_) => true,
             None => {
                 let last_bpos = self.last_pos;
                 self.err_span_(start_bpos, last_bpos, "illegal numeric character escape");
-                '?'
+                false
             }
         }
     }
@@ -707,8 +651,10 @@ fn scan_numeric_escape(&mut self, n_hex_digits: uint, delim: char) -> char {
     /// Scan for a single (possibly escaped) byte or char
     /// in a byte, (non-raw) byte string, char, or (non-raw) string literal.
     /// `start` is the position of `first_source_char`, which is already consumed.
+    ///
+    /// Returns true if there was a valid char/byte, false otherwise.
     fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
-                         ascii_only: bool, delim: char) -> Option<char> {
+                         ascii_only: bool, delim: char) -> bool {
         match first_source_char {
             '\\' => {
                 // '\X' for some X must be a character constant:
@@ -718,24 +664,18 @@ fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
                 match escaped {
                     None => {},  // EOF here is an error that will be checked later.
                     Some(e) => {
-                        return Some(match e {
-                            'n' => '\n',
-                            'r' => '\r',
-                            't' => '\t',
-                            '\\' => '\\',
-                            '\'' => '\'',
-                            '"' => '"',
-                            '0' => '\x00',
-                            'x' => self.scan_numeric_escape(2u, delim),
-                            'u' if !ascii_only => self.scan_numeric_escape(4u, delim),
-                            'U' if !ascii_only => self.scan_numeric_escape(8u, delim),
+                        return match e {
+                            'n' | 'r' | 't' | '\\' | '\'' | '"' | '0' => true,
+                            'x' => self.scan_hex_digits(2u, delim),
+                            'u' if !ascii_only => self.scan_hex_digits(4u, delim),
+                            'U' if !ascii_only => self.scan_hex_digits(8u, delim),
                             '\n' if delim == '"' => {
                                 self.consume_whitespace();
-                                return None
+                                true
                             },
                             '\r' if delim == '"' && self.curr_is('\n') => {
                                 self.consume_whitespace();
-                                return None
+                                true
                             }
                             c => {
                                 let last_pos = self.last_pos;
@@ -744,9 +684,9 @@ fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
                                     if ascii_only { "unknown byte escape" }
                                     else { "unknown character escape" },
                                     c);
-                                c
+                                false
                             }
-                        })
+                        }
                     }
                 }
             }
@@ -757,14 +697,16 @@ fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
                     if ascii_only { "byte constant must be escaped" }
                     else { "character constant must be escaped" },
                     first_source_char);
+                return false;
             }
             '\r' => {
                 if self.curr_is('\n') {
                     self.bump();
-                    return Some('\n');
+                    return true;
                 } else {
                     self.err_span_(start, self.last_pos,
                                    "bare CR not allowed in string, use \\r instead");
+                    return false;
                 }
             }
             _ => if ascii_only && first_source_char > '\x7F' {
@@ -773,9 +715,84 @@ fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
                     start, last_pos,
                     "byte constant must be ASCII. \
                      Use a \\xHH escape for a non-ASCII byte", first_source_char);
+                return false;
+            }
+        }
+        true
+    }
+
+    /// Scan over an int literal suffix.
+    fn scan_int_suffix(&mut self) {
+        match self.curr {
+            Some('i') | Some('u') => {
+                self.bump();
+
+                if self.curr_is('8') {
+                    self.bump();
+                } else if self.curr_is('1') {
+                    if !self.nextch_is('6') {
+                        self.err_span_(self.last_pos, self.pos,
+                                      "illegal int suffix");
+                    } else {
+                        self.bump(); self.bump();
+                    }
+                } else if self.curr_is('3') {
+                    if !self.nextch_is('2') {
+                        self.err_span_(self.last_pos, self.pos,
+                                      "illegal int suffix");
+                    } else {
+                        self.bump(); self.bump();
+                    }
+                } else if self.curr_is('6') {
+                    if !self.nextch_is('4') {
+                        self.err_span_(self.last_pos, self.pos,
+                                      "illegal int suffix");
+                    } else {
+                        self.bump(); self.bump();
+                    }
+                }
+            },
+            _ => { }
+        }
+    }
+
+    /// Scan over a float literal suffix
+    fn scan_float_suffix(&mut self) {
+        if self.curr_is('f') {
+            if (self.nextch_is('3') && self.nextnextch_is('2'))
+            || (self.nextch_is('6') && self.nextnextch_is('4')) {
+                self.bump();
+                self.bump();
+                self.bump();
+            } else {
+                self.err_span_(self.last_pos, self.pos, "illegal float suffix");
             }
         }
-        Some(first_source_char)
+    }
+
+    /// Scan over a float exponent.
+    fn scan_float_exponent(&mut self) {
+        if self.curr_is('e') || self.curr_is('E') {
+            self.bump();
+            if self.curr_is('-') || self.curr_is('+') {
+                self.bump();
+            }
+            if self.scan_digits(10) == 0 {
+                self.err_span_(self.last_pos, self.pos, "expected at least one digit in exponent")
+            }
+        }
+    }
+
+    /// Check that a base is valid for a floating literal, emitting a nice
+    /// error if it isn't.
+    fn check_float_base(&mut self, start_bpos: BytePos, last_bpos: BytePos, base: uint) {
+        match base {
+            16u => self.err_span_(start_bpos, last_bpos, "hexadecimal float literal is not \
+                                 supported"),
+            8u => self.err_span_(start_bpos, last_bpos, "octal float literal is not supported"),
+            2u => self.err_span_(start_bpos, last_bpos, "binary float literal is not supported"),
+            _ => ()
+        }
     }
 
     fn binop(&mut self, op: token::BinOp) -> token::Token {
@@ -849,6 +866,7 @@ fn next_token_inner(&mut self) -> token::Token {
           '@' => { self.bump(); return token::AT; }
           '#' => { self.bump(); return token::POUND; }
           '~' => { self.bump(); return token::TILDE; }
+          '?' => { self.bump(); return token::QUESTION; }
           ':' => {
             self.bump();
             if self.curr_is(':') {
@@ -909,7 +927,7 @@ fn next_token_inner(&mut self) -> token::Token {
             let start = self.last_pos;
 
             // the eof will be picked up by the final `'` check below
-            let mut c2 = self.curr.unwrap_or('\x00');
+            let c2 = self.curr.unwrap_or('\x00');
             self.bump();
 
             // If the character is an ident start not followed by another single
@@ -952,7 +970,7 @@ fn next_token_inner(&mut self) -> token::Token {
             }
 
             // Otherwise it is a character constant:
-            c2 = self.scan_char_or_byte(start, c2, /* ascii_only = */ false, '\'').unwrap();
+            let valid = self.scan_char_or_byte(start, c2, /* ascii_only = */ false, '\'');
             if !self.curr_is('\'') {
                 let last_bpos = self.last_pos;
                 self.fatal_span_verbose(
@@ -962,118 +980,23 @@ fn next_token_inner(&mut self) -> token::Token {
                                    start - BytePos(1), last_bpos,
                                    "unterminated character constant".to_string());
             }
+            let id = if valid { self.name_from(start) } else { token::intern("0") };
             self.bump(); // advance curr past token
-            return token::LIT_CHAR(c2);
+            return token::LIT_CHAR(id);
           }
           'b' => {
             self.bump();
             return match self.curr {
-                Some('\'') => parse_byte(self),
-                Some('"') => parse_byte_string(self),
-                Some('r') => parse_raw_byte_string(self),
+                Some('\'') => self.scan_byte(),
+                Some('"') => self.scan_byte_string(),
+                Some('r') => self.scan_raw_byte_string(),
                 _ => unreachable!()  // Should have been a token::IDENT above.
             };
 
-            fn parse_byte(self_: &mut StringReader) -> token::Token {
-                self_.bump();
-                let start = self_.last_pos;
-
-                // the eof will be picked up by the final `'` check below
-                let mut c2 = self_.curr.unwrap_or('\x00');
-                self_.bump();
-
-                c2 = self_.scan_char_or_byte(start, c2, /* ascii_only = */ true, '\'').unwrap();
-                if !self_.curr_is('\'') {
-                    // Byte offsetting here is okay because the
-                    // character before position `start` are an
-                    // ascii single quote and ascii 'b'.
-                    let last_pos = self_.last_pos;
-                    self_.fatal_span_verbose(
-                        start - BytePos(2), last_pos,
-                        "unterminated byte constant".to_string());
-                }
-                self_.bump(); // advance curr past token
-                return token::LIT_BYTE(c2 as u8);
-            }
-
-            fn parse_byte_string(self_: &mut StringReader) -> token::Token {
-                self_.bump();
-                let start = self_.last_pos;
-                let mut value = Vec::new();
-                while !self_.curr_is('"') {
-                    if self_.is_eof() {
-                        let last_pos = self_.last_pos;
-                        self_.fatal_span_(start, last_pos,
-                                          "unterminated double quote byte string");
-                    }
-
-                    let ch_start = self_.last_pos;
-                    let ch = self_.curr.unwrap();
-                    self_.bump();
-                    self_.scan_char_or_byte(ch_start, ch, /* ascii_only = */ true, '"')
-                        .map(|ch| value.push(ch as u8));
-                }
-                self_.bump();
-                return token::LIT_BINARY(Rc::new(value));
-            }
-
-            fn parse_raw_byte_string(self_: &mut StringReader) -> token::Token {
-                let start_bpos = self_.last_pos;
-                self_.bump();
-                let mut hash_count = 0u;
-                while self_.curr_is('#') {
-                    self_.bump();
-                    hash_count += 1;
-                }
-
-                if self_.is_eof() {
-                    let last_pos = self_.last_pos;
-                    self_.fatal_span_(start_bpos, last_pos, "unterminated raw string");
-                } else if !self_.curr_is('"') {
-                    let last_pos = self_.last_pos;
-                    let ch = self_.curr.unwrap();
-                    self_.fatal_span_char(start_bpos, last_pos,
-                                    "only `#` is allowed in raw string delimitation; \
-                                     found illegal character",
-                                    ch);
-                }
-                self_.bump();
-                let content_start_bpos = self_.last_pos;
-                let mut content_end_bpos;
-                'outer: loop {
-                    match self_.curr {
-                        None => {
-                            let last_pos = self_.last_pos;
-                            self_.fatal_span_(start_bpos, last_pos, "unterminated raw string")
-                        },
-                        Some('"') => {
-                            content_end_bpos = self_.last_pos;
-                            for _ in range(0, hash_count) {
-                                self_.bump();
-                                if !self_.curr_is('#') {
-                                    continue 'outer;
-                                }
-                            }
-                            break;
-                        },
-                        Some(c) => if c > '\x7F' {
-                            let last_pos = self_.last_pos;
-                            self_.err_span_char(
-                                last_pos, last_pos, "raw byte string must be ASCII", c);
-                        }
-                    }
-                    self_.bump();
-                }
-                self_.bump();
-                let bytes = self_.with_str_from_to(content_start_bpos,
-                                                   content_end_bpos,
-                                                   |s| s.as_bytes().to_owned());
-                return token::LIT_BINARY_RAW(Rc::new(bytes), hash_count);
-            }
           }
           '"' => {
-            let mut accum_str = String::new();
             let start_bpos = self.last_pos;
+            let mut valid = true;
             self.bump();
             while !self.curr_is('"') {
                 if self.is_eof() {
@@ -1084,11 +1007,13 @@ fn parse_raw_byte_string(self_: &mut StringReader) -> token::Token {
                 let ch_start = self.last_pos;
                 let ch = self.curr.unwrap();
                 self.bump();
-                self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ false, '"')
-                    .map(|ch| accum_str.push_char(ch));
+                valid &= self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ false, '"');
             }
+            // adjust for the ACSII " at the start of the literal
+            let id = if valid { self.name_from(start_bpos + BytePos(1)) }
+                     else { token::intern("??") };
             self.bump();
-            return token::LIT_STR(str_to_ident(accum_str.as_slice()));
+            return token::LIT_STR(id);
           }
           'r' => {
             let start_bpos = self.last_pos;
@@ -1113,7 +1038,7 @@ fn parse_raw_byte_string(self_: &mut StringReader) -> token::Token {
             self.bump();
             let content_start_bpos = self.last_pos;
             let mut content_end_bpos;
-            let mut has_cr = false;
+            let mut valid = true;
             'outer: loop {
                 if self.is_eof() {
                     let last_bpos = self.last_pos;
@@ -1136,23 +1061,26 @@ fn parse_raw_byte_string(self_: &mut StringReader) -> token::Token {
                             }
                         }
                         break;
-                    }
+                    },
                     '\r' => {
-                        has_cr = true;
+                        if !self.nextch_is('\n') {
+                            let last_bpos = self.last_pos;
+                            self.err_span_(start_bpos, last_bpos, "bare CR not allowed in raw \
+                                           string, use \\r instead");
+                            valid = false;
+                        }
                     }
                     _ => ()
                 }
                 self.bump();
             }
             self.bump();
-            let str_content = self.with_str_from_to(content_start_bpos, content_end_bpos, |string| {
-                let string = if has_cr {
-                    self.translate_crlf(content_start_bpos, string,
-                                        "bare CR not allowed in raw string")
-                } else { string.into_maybe_owned() };
-                str_to_ident(string.as_slice())
-            });
-            return token::LIT_STR_RAW(str_content, hash_count);
+            let id = if valid {
+                self.name_from_to(content_start_bpos, content_end_bpos)
+            } else {
+                token::intern("??")
+            };
+            return token::LIT_STR_RAW(id, hash_count);
           }
           '-' => {
             if self.nextch_is('>') {
@@ -1220,6 +1148,104 @@ fn peeking_at_comment(&self) -> bool {
      // consider shebangs comments, but not inner attributes
      || (self.curr_is('#') && self.nextch_is('!') && !self.nextnextch_is('['))
     }
+
+    fn scan_byte(&mut self) -> token::Token {
+        self.bump();
+        let start = self.last_pos;
+
+        // the eof will be picked up by the final `'` check below
+        let c2 = self.curr.unwrap_or('\x00');
+        self.bump();
+
+        let valid = self.scan_char_or_byte(start, c2, /* ascii_only = */ true, '\'');
+        if !self.curr_is('\'') {
+            // Byte offsetting here is okay because the
+            // character before position `start` are an
+            // ascii single quote and ascii 'b'.
+            let last_pos = self.last_pos;
+            self.fatal_span_verbose(
+                start - BytePos(2), last_pos,
+                "unterminated byte constant".to_string());
+        }
+
+        let id = if valid { self.name_from(start) } else { token::intern("??") };
+        self.bump(); // advance curr past token
+        return token::LIT_BYTE(id);
+    }
+
+    fn scan_byte_string(&mut self) -> token::Token {
+        self.bump();
+        let start = self.last_pos;
+        let mut valid = true;
+
+        while !self.curr_is('"') {
+            if self.is_eof() {
+                let last_pos = self.last_pos;
+                self.fatal_span_(start, last_pos,
+                                  "unterminated double quote byte string");
+            }
+
+            let ch_start = self.last_pos;
+            let ch = self.curr.unwrap();
+            self.bump();
+            valid &= self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ true, '"');
+        }
+        let id = if valid { self.name_from(start) } else { token::intern("??") };
+        self.bump();
+        return token::LIT_BINARY(id);
+    }
+
+    fn scan_raw_byte_string(&mut self) -> token::Token {
+        let start_bpos = self.last_pos;
+        self.bump();
+        let mut hash_count = 0u;
+        while self.curr_is('#') {
+            self.bump();
+            hash_count += 1;
+        }
+
+        if self.is_eof() {
+            let last_pos = self.last_pos;
+            self.fatal_span_(start_bpos, last_pos, "unterminated raw string");
+        } else if !self.curr_is('"') {
+            let last_pos = self.last_pos;
+            let ch = self.curr.unwrap();
+            self.fatal_span_char(start_bpos, last_pos,
+                            "only `#` is allowed in raw string delimitation; \
+                             found illegal character",
+                            ch);
+        }
+        self.bump();
+        let content_start_bpos = self.last_pos;
+        let mut content_end_bpos;
+        'outer: loop {
+            match self.curr {
+                None => {
+                    let last_pos = self.last_pos;
+                    self.fatal_span_(start_bpos, last_pos, "unterminated raw string")
+                },
+                Some('"') => {
+                    content_end_bpos = self.last_pos;
+                    for _ in range(0, hash_count) {
+                        self.bump();
+                        if !self.curr_is('#') {
+                            continue 'outer;
+                        }
+                    }
+                    break;
+                },
+                Some(c) => if c > '\x7F' {
+                    let last_pos = self.last_pos;
+                    self.err_span_char(
+                        last_pos, last_pos, "raw byte string must be ASCII", c);
+                }
+            }
+            self.bump();
+        }
+        self.bump();
+        return token::LIT_BINARY_RAW(self.name_from_to(content_start_bpos, content_end_bpos),
+                                     hash_count);
+    }
 }
 
 pub fn is_whitespace(c: Option<char>) -> bool {
@@ -1238,12 +1264,18 @@ fn in_range(c: Option<char>, lo: char, hi: char) -> bool {
 
 fn is_dec_digit(c: Option<char>) -> bool { return in_range(c, '0', '9'); }
 
-pub fn is_line_non_doc_comment(s: &str) -> bool {
-    s.starts_with("////")
+pub fn is_doc_comment(s: &str) -> bool {
+    let res = (s.starts_with("///") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'/')
+              || s.starts_with("//!");
+    debug!("is `{}` a doc comment? {}", s, res);
+    res
 }
 
-pub fn is_block_non_doc_comment(s: &str) -> bool {
-    s.starts_with("/***")
+pub fn is_block_doc_comment(s: &str) -> bool {
+    let res = (s.starts_with("/**") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'*')
+              || s.starts_with("/*!");
+    debug!("is `{}` a doc comment? {}", s, res);
+    res
 }
 
 fn ident_start(c: Option<char>) -> bool {
@@ -1276,7 +1308,7 @@ mod test {
     use std::io::util;
 
     fn mk_sh() -> diagnostic::SpanHandler {
-        let emitter = diagnostic::EmitterWriter::new(box util::NullWriter);
+        let emitter = diagnostic::EmitterWriter::new(box util::NullWriter, None);
         let handler = diagnostic::mk_handler(box emitter);
         diagnostic::mk_span_handler(handler, CodeMap::new())
     }
@@ -1294,11 +1326,14 @@ fn setup<'a>(span_handler: &'a diagnostic::SpanHandler,
             "/* my source file */ \
              fn main() { println!(\"zebra\"); }\n".to_string());
         let id = str_to_ident("fn");
+        assert_eq!(string_reader.next_token().tok, token::COMMENT);
+        assert_eq!(string_reader.next_token().tok, token::WS);
         let tok1 = string_reader.next_token();
         let tok2 = TokenAndSpan{
             tok:token::IDENT(id, false),
             sp:Span {lo:BytePos(21),hi:BytePos(23),expn_info: None}};
         assert_eq!(tok1,tok2);
+        assert_eq!(string_reader.next_token().tok, token::WS);
         // the 'main' id is already read:
         assert_eq!(string_reader.last_pos.clone(), BytePos(28));
         // read another token:
@@ -1327,6 +1362,7 @@ fn mk_ident (id: &str, is_mod_name: bool) -> token::Token {
     #[test] fn doublecolonparsing () {
         check_tokenization(setup(&mk_sh(), "a b".to_string()),
                            vec!(mk_ident("a",false),
+                            token::WS,
                              mk_ident("b",false)));
     }
 
@@ -1340,6 +1376,7 @@ fn mk_ident (id: &str, is_mod_name: bool) -> token::Token {
     #[test] fn dcparsing_3 () {
         check_tokenization(setup(&mk_sh(), "a ::b".to_string()),
                            vec!(mk_ident("a",false),
+                             token::WS,
                              token::MOD_SEP,
                              mk_ident("b",false)));
     }
@@ -1348,22 +1385,23 @@ fn mk_ident (id: &str, is_mod_name: bool) -> token::Token {
         check_tokenization(setup(&mk_sh(), "a:: b".to_string()),
                            vec!(mk_ident("a",true),
                              token::MOD_SEP,
+                             token::WS,
                              mk_ident("b",false)));
     }
 
     #[test] fn character_a() {
         assert_eq!(setup(&mk_sh(), "'a'".to_string()).next_token().tok,
-                   token::LIT_CHAR('a'));
+                   token::LIT_CHAR(token::intern("a")));
     }
 
     #[test] fn character_space() {
         assert_eq!(setup(&mk_sh(), "' '".to_string()).next_token().tok,
-                   token::LIT_CHAR(' '));
+                   token::LIT_CHAR(token::intern(" ")));
     }
 
     #[test] fn character_escaped() {
         assert_eq!(setup(&mk_sh(), "'\\n'".to_string()).next_token().tok,
-                   token::LIT_CHAR('\n'));
+                   token::LIT_CHAR(token::intern("\\n")));
     }
 
     #[test] fn lifetime_name() {
@@ -1375,19 +1413,23 @@ fn mk_ident (id: &str, is_mod_name: bool) -> token::Token {
         assert_eq!(setup(&mk_sh(),
                          "r###\"\"#a\\b\x00c\"\"###".to_string()).next_token()
                                                                  .tok,
-                   token::LIT_STR_RAW(token::str_to_ident("\"#a\\b\x00c\""), 3));
+                   token::LIT_STR_RAW(token::intern("\"#a\\b\x00c\""), 3));
     }
 
     #[test] fn line_doc_comments() {
-        assert!(!is_line_non_doc_comment("///"));
-        assert!(!is_line_non_doc_comment("/// blah"));
-        assert!(is_line_non_doc_comment("////"));
+        assert!(is_doc_comment("///"));
+        assert!(is_doc_comment("/// blah"));
+        assert!(!is_doc_comment("////"));
     }
 
     #[test] fn nested_block_comments() {
-        assert_eq!(setup(&mk_sh(),
-                         "/* /* */ */'a'".to_string()).next_token().tok,
-                   token::LIT_CHAR('a'));
+        let sh = mk_sh();
+        let mut lexer = setup(&sh, "/* /* */ */'a'".to_string());
+        match lexer.next_token().tok {
+            token::COMMENT => { },
+            _ => fail!("expected a comment!")
+        }
+        assert_eq!(lexer.next_token().tok, token::LIT_CHAR(token::intern("a")));
     }
 
 }
index 4b5252bfba3118eb081d8a1783d18631a265b9bc..a3e169cd5116d53c0c22834e70ea6c85c8ca33d1 100644 (file)
@@ -10,7 +10,6 @@
 
 //! The main parser interface
 
-
 use ast;
 use codemap::{Span, CodeMap, FileMap};
 use diagnostic::{SpanHandler, mk_span_handler, default_handler, Auto};
@@ -32,7 +31,7 @@
 pub mod classify;
 pub mod obsolete;
 
-// info about a parsing session.
+/// Info about a parsing session.
 pub struct ParseSess {
     pub span_diagnostic: SpanHandler, // better be the same as the one in the reader!
     /// Used to determine and report recursive mod inclusions
@@ -41,7 +40,7 @@ pub struct ParseSess {
 
 pub fn new_parse_sess() -> ParseSess {
     ParseSess {
-        span_diagnostic: mk_span_handler(default_handler(Auto), CodeMap::new()),
+        span_diagnostic: mk_span_handler(default_handler(Auto, None), CodeMap::new()),
         included_mod_stack: RefCell::new(Vec::new()),
     }
 }
@@ -241,14 +240,14 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
     unreachable!()
 }
 
-// given a session and a string, add the string to
-// the session's codemap and return the new filemap
+/// Given a session and a string, add the string to
+/// the session's codemap and return the new filemap
 pub fn string_to_filemap(sess: &ParseSess, source: String, path: String)
                          -> Rc<FileMap> {
     sess.span_diagnostic.cm.new_filemap(path, source)
 }
 
-// given a filemap, produce a sequence of token-trees
+/// Given a filemap, produce a sequence of token-trees
 pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
     -> Vec<ast::TokenTree> {
     // it appears to me that the cfg doesn't matter here... indeed,
@@ -259,7 +258,7 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
     p1.parse_all_token_trees()
 }
 
-// given tts and cfg, produce a parser
+/// Given tts and cfg, produce a parser
 pub fn tts_to_parser<'a>(sess: &'a ParseSess,
                          tts: Vec<ast::TokenTree>,
                          cfg: ast::CrateConfig) -> Parser<'a> {
@@ -267,22 +266,359 @@ pub fn tts_to_parser<'a>(sess: &'a ParseSess,
     Parser::new(sess, cfg, box trdr)
 }
 
-// abort if necessary
+/// Abort if necessary
 pub fn maybe_aborted<T>(result: T, mut p: Parser) -> T {
     p.abort_if_errors();
     result
 }
 
+/// Parse a string representing a character literal into its final form.
+/// Rather than just accepting/rejecting a given literal, unescapes it as
+/// well. Can take any slice prefixed by a character escape. Returns the
+/// character and the number of characters consumed.
+pub fn char_lit(lit: &str) -> (char, int) {
+    use std::{num, char};
+
+    let mut chars = lit.chars();
+    let c = match (chars.next(), chars.next()) {
+        (Some(c), None) if c != '\\' => return (c, 1),
+        (Some('\\'), Some(c)) => match c {
+            '"' => Some('"'),
+            'n' => Some('\n'),
+            'r' => Some('\r'),
+            't' => Some('\t'),
+            '\\' => Some('\\'),
+            '\'' => Some('\''),
+            '0' => Some('\0'),
+            _ => { None }
+        },
+        _ => fail!("lexer accepted invalid char escape `{}`", lit)
+    };
+
+    match c {
+        Some(x) => return (x, 2),
+        None => { }
+    }
+
+    let msg = format!("lexer should have rejected a bad character escape {}", lit);
+    let msg2 = msg.as_slice();
+
+    let esc: |uint| -> Option<(char, int)> = |len|
+        num::from_str_radix(lit.slice(2, len), 16)
+        .and_then(char::from_u32)
+        .map(|x| (x, len as int));
+
+    // Unicode escapes
+    return match lit.as_bytes()[1] as char {
+        'x' | 'X' => esc(4),
+        'u' => esc(6),
+        'U' => esc(10),
+        _ => None,
+    }.expect(msg2);
+}
+
+/// Parse a string representing a string literal into its final form. Does
+/// unescaping.
+pub fn str_lit(lit: &str) -> String {
+    debug!("parse_str_lit: given {}", lit.escape_default());
+    let mut res = String::with_capacity(lit.len());
+
+    // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
+    let error = |i| format!("lexer should have rejected {} at {}", lit, i);
+
+    /// Eat everything up to a non-whitespace
+    fn eat<'a>(it: &mut ::std::iter::Peekable<(uint, char), ::std::str::CharOffsets<'a>>) {
+        loop {
+            match it.peek().map(|x| x.val1()) {
+                Some(' ') | Some('\n') | Some('\r') | Some('\t') => {
+                    it.next();
+                },
+                _ => { break; }
+            }
+        }
+    }
+
+    let mut chars = lit.char_indices().peekable();
+    loop {
+        match chars.next() {
+            Some((i, c)) => {
+                let em = error(i);
+                match c {
+                    '\\' => {
+                        if chars.peek().expect(em.as_slice()).val1() == '\n' {
+                            eat(&mut chars);
+                        } else if chars.peek().expect(em.as_slice()).val1() == '\r' {
+                            chars.next();
+                            if chars.peek().expect(em.as_slice()).val1() != '\n' {
+                                fail!("lexer accepted bare CR");
+                            }
+                            eat(&mut chars);
+                        } else {
+                            // otherwise, a normal escape
+                            let (c, n) = char_lit(lit.slice_from(i));
+                            for _ in range(0, n - 1) { // we don't need to move past the first \
+                                chars.next();
+                            }
+                            res.push_char(c);
+                        }
+                    },
+                    '\r' => {
+                        if chars.peek().expect(em.as_slice()).val1() != '\n' {
+                            fail!("lexer accepted bare CR");
+                        }
+                        chars.next();
+                        res.push_char('\n');
+                    }
+                    c => res.push_char(c),
+                }
+            },
+            None => break
+        }
+    }
+
+    res.shrink_to_fit(); // probably not going to do anything, unless there was an escape.
+    debug!("parse_str_lit: returning {}", res);
+    res
+}
+
+/// Parse a string representing a raw string literal into its final form. The
+/// only operation this does is convert embedded CRLF into a single LF.
+pub fn raw_str_lit(lit: &str) -> String {
+    debug!("raw_str_lit: given {}", lit.escape_default());
+    let mut res = String::with_capacity(lit.len());
+
+    // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
+    let mut chars = lit.chars().peekable();
+    loop {
+        match chars.next() {
+            Some(c) => {
+                if c == '\r' {
+                    if *chars.peek().unwrap() != '\n' {
+                        fail!("lexer accepted bare CR");
+                    }
+                    chars.next();
+                    res.push_char('\n');
+                } else {
+                    res.push_char(c);
+                }
+            },
+            None => break
+        }
+    }
+
+    res.shrink_to_fit();
+    res
+}
+
+pub fn float_lit(s: &str) -> ast::Lit_ {
+    debug!("float_lit: {}", s);
+    // FIXME #2252: bounds checking float literals is defered until trans
+    let s2 = s.chars().filter(|&c| c != '_').collect::<String>();
+    let s = s2.as_slice();
+
+    let mut ty = None;
+
+    if s.ends_with("f32") {
+        ty = Some(ast::TyF32);
+    } else if s.ends_with("f64") {
+        ty = Some(ast::TyF64);
+    }
+
+
+    match ty {
+        Some(t) => {
+            ast::LitFloat(token::intern_and_get_ident(s.slice_to(s.len() - t.suffix_len())), t)
+        },
+        None => ast::LitFloatUnsuffixed(token::intern_and_get_ident(s))
+    }
+}
+
+/// Parse a string representing a byte literal into its final form. Similar to `char_lit`
+pub fn byte_lit(lit: &str) -> (u8, uint) {
+    let err = |i| format!("lexer accepted invalid byte literal {} step {}", lit, i);
+
+    if lit.len() == 1 {
+        (lit.as_bytes()[0], 1)
+    } else {
+        assert!(lit.as_bytes()[0] == b'\\', err(0i));
+        let b = match lit.as_bytes()[1] {
+            b'"' => b'"',
+            b'n' => b'\n',
+            b'r' => b'\r',
+            b't' => b'\t',
+            b'\\' => b'\\',
+            b'\'' => b'\'',
+            b'0' => b'\0',
+            _ => {
+                match ::std::num::from_str_radix::<u64>(lit.slice(2, 4), 16) {
+                    Some(c) =>
+                        if c > 0xFF {
+                            fail!(err(2))
+                        } else {
+                            return (c as u8, 4)
+                        },
+                    None => fail!(err(3))
+                }
+            }
+        };
+        return (b, 2);
+    }
+}
+
+pub fn binary_lit(lit: &str) -> Rc<Vec<u8>> {
+    let mut res = Vec::with_capacity(lit.len());
 
+    // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
+    let error = |i| format!("lexer should have rejected {} at {}", lit, i);
+
+    // binary literals *must* be ASCII, but the escapes don't have to be
+    let mut chars = lit.as_bytes().iter().enumerate().peekable();
+    loop {
+        match chars.next() {
+            Some((i, &c)) => {
+                if c == b'\\' {
+                    if *chars.peek().expect(error(i).as_slice()).val1() == b'\n' {
+                        loop {
+                            // eat everything up to a non-whitespace
+                            match chars.peek().map(|x| *x.val1()) {
+                                Some(b' ') | Some(b'\n') | Some(b'\r') | Some(b'\t') => {
+                                    chars.next();
+                                },
+                                _ => { break; }
+                            }
+                        }
+                    } else {
+                        // otherwise, a normal escape
+                        let (c, n) = byte_lit(lit.slice_from(i));
+                        for _ in range(0, n - 1) { // we don't need to move past the first \
+                            chars.next();
+                        }
+                        res.push(c);
+                    }
+                } else {
+                    res.push(c);
+                }
+            },
+            None => { break; }
+        }
+    }
+
+    Rc::new(res)
+}
+
+pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
+    // s can only be ascii, byte indexing is fine
+
+    let s2 = s.chars().filter(|&c| c != '_').collect::<String>();
+    let mut s = s2.as_slice();
+
+    debug!("parse_integer_lit: {}", s);
+
+    if s.len() == 1 {
+        return ast::LitIntUnsuffixed((s.char_at(0)).to_digit(10).unwrap() as i64);
+    }
+
+    let mut base = 10;
+    let orig = s;
+
+    #[deriving(Show)]
+    enum Result {
+        Nothing,
+        Signed(ast::IntTy),
+        Unsigned(ast::UintTy)
+    }
+
+    impl Result {
+        fn suffix_len(&self) -> uint {
+            match *self {
+                Nothing => 0,
+                Signed(s) => s.suffix_len(),
+                Unsigned(u) => u.suffix_len()
+            }
+        }
+    }
+
+    let mut ty = Nothing;
+
+
+    if s.char_at(0) == '0' {
+        match s.char_at(1) {
+            'x' => base = 16,
+            'o' => base = 8,
+            'b' => base = 2,
+            _ => { }
+        }
+    }
+
+    if base != 10 {
+        s = s.slice_from(2);
+    }
+
+    let last = s.len() - 1;
+    match s.char_at(last) {
+        'i' => ty = Signed(ast::TyI),
+        'u' => ty = Unsigned(ast::TyU),
+        '8' => {
+            if s.len() > 2 {
+                match s.char_at(last - 1) {
+                    'i' => ty = Signed(ast::TyI8),
+                    'u' => ty = Unsigned(ast::TyU8),
+                    _ => { }
+                }
+            }
+        },
+        '6' => {
+            if s.len() > 3 && s.char_at(last - 1) == '1' {
+                match s.char_at(last - 2) {
+                    'i' => ty = Signed(ast::TyI16),
+                    'u' => ty = Unsigned(ast::TyU16),
+                    _ => { }
+                }
+            }
+        },
+        '2' => {
+            if s.len() > 3 && s.char_at(last - 1) == '3' {
+                match s.char_at(last - 2) {
+                    'i' => ty = Signed(ast::TyI32),
+                    'u' => ty = Unsigned(ast::TyU32),
+                    _ => { }
+                }
+            }
+        },
+        '4' => {
+            if s.len() > 3 && s.char_at(last - 1) == '6' {
+                match s.char_at(last - 2) {
+                    'i' => ty = Signed(ast::TyI64),
+                    'u' => ty = Unsigned(ast::TyU64),
+                    _ => { }
+                }
+            }
+        },
+        _ => { }
+    }
+
+
+    s = s.slice_to(s.len() - ty.suffix_len());
+
+    debug!("The suffix is {}, base {}, the new string is {}, the original \
+           string was {}", ty, base, s, orig);
+
+    let res: u64 = match ::std::num::from_str_radix(s, base) {
+        Some(r) => r,
+        None => { sd.span_err(sp, "int literal is too large"); 0 }
+    };
+
+    match ty {
+        Nothing => ast::LitIntUnsuffixed(res as i64),
+        Signed(t) => ast::LitInt(res as i64, t),
+        Unsigned(t) => ast::LitUint(res, t)
+    }
+}
 
 #[cfg(test)]
 mod test {
     use super::*;
-    use serialize::{json, Encodable};
-    use std::io;
-    use std::io::MemWriter;
-    use std::mem::transmute;
-    use std::str;
+    use serialize::json;
     use std::gc::GC;
     use codemap::{Span, BytePos, Spanned};
     use owned_slice::OwnedSlice;
@@ -296,16 +632,6 @@ mod test {
     use util::parser_testing::{string_to_expr, string_to_item};
     use util::parser_testing::string_to_stmt;
 
-    fn to_json_str<'a, E: Encodable<json::Encoder<'a>, io::IoError>>(val: &E) -> String {
-        let mut writer = MemWriter::new();
-        // FIXME(14302) remove the transmute and unsafe block.
-        unsafe {
-            let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
-            let _ = val.encode(transmute(&mut encoder));
-        }
-        str::from_utf8(writer.unwrap().as_slice()).unwrap().to_string()
-    }
-
     // produce a codemap::span
     fn sp(a: u32, b: u32) -> Span {
         Span{lo:BytePos(a),hi:BytePos(b),expn_info:None}
@@ -415,7 +741,7 @@ fn sp(a: u32, b: u32) -> Span {
 
     #[test] fn string_to_tts_1 () {
         let tts = string_to_tts("fn a (b : int) { b; }".to_string());
-        assert_eq!(to_json_str(&tts),
+        assert_eq!(json::encode(&tts),
         "[\
     {\
         \"variant\":\"TTTok\",\
index 025684ae71e8c41155869058a838225d62ed676f..cadae7ef12f8078b38dfc67a6dde7aed99d7000f 100644 (file)
@@ -38,8 +38,8 @@ pub enum ObsoleteSyntax {
 pub trait ParserObsoleteMethods {
     /// Reports an obsolete syntax non-fatal error.
     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
-    // Reports an obsolete syntax non-fatal error, and returns
-    // a placeholder expression
+    /// Reports an obsolete syntax non-fatal error, and returns
+    /// a placeholder expression
     fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc<Expr>;
     fn report(&mut self,
               sp: Span,
@@ -83,8 +83,8 @@ fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
         self.report(sp, kind, kind_str, desc);
     }
 
-    // Reports an obsolete syntax non-fatal error, and returns
-    // a placeholder expression
+    /// Reports an obsolete syntax non-fatal error, and returns
+    /// a placeholder expression
     fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc<Expr> {
         self.obsolete(sp, kind);
         self.mk_expr(sp.lo, sp.hi, ExprLit(box(GC) respan(sp, LitNil)))
index f3789e25bc8a7e5e39bc1e1ded000561e43c4578..e0c94dffb5cae342603ddb9cf1fcdc6e9e9dc777 100644 (file)
@@ -33,8 +33,8 @@
 use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_};
-use ast::{LitBool, LitFloat, LitFloatUnsuffixed, LitInt, LitChar, LitByte, LitBinary};
-use ast::{LitIntUnsuffixed, LitNil, LitStr, LitUint, Local, LocalLet};
+use ast::{LitBool, LitChar, LitByte, LitBinary};
+use ast::{LitNil, LitStr, LitUint, Local, LocalLet};
 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
 use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
 use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum};
@@ -42,7 +42,6 @@
 use ast::{PatTup, PatBox, PatWild, PatWildMulti};
 use ast::{BiRem, Required};
 use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
-use ast::{Sized, DynSize, StaticSize};
 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
 use ast::{StructVariantKind, BiSub};
 use ast::StrStyle;
@@ -62,6 +61,7 @@
 use ast_util;
 use codemap::{Span, BytePos, Spanned, spanned, mk_sp};
 use codemap;
+use parse;
 use parse::attr::ParserAttr;
 use parse::classify;
 use parse::common::{SeqSep, seq_sep_none};
@@ -118,8 +118,8 @@ pub struct PathAndBounds {
 }
 
 enum ItemOrViewItem {
-    // Indicates a failure to parse any kind of item. The attributes are
-    // returned.
+    /// Indicates a failure to parse any kind of item. The attributes are
+    /// returned.
     IoviNone(Vec<Attribute>),
     IoviItem(Gc<Item>),
     IoviForeignItem(Gc<ForeignItem>),
@@ -127,12 +127,12 @@ enum ItemOrViewItem {
 }
 
 
-// Possibly accept an `INTERPOLATED` expression (a pre-parsed expression
-// dropped into the token stream, which happens while parsing the
-// result of macro expansion)
-/* Placement of these is not as complex as I feared it would be.
-The important thing is to make sure that lookahead doesn't balk
-at INTERPOLATED tokens */
+/// Possibly accept an `INTERPOLATED` expression (a pre-parsed expression
+/// dropped into the token stream, which happens while parsing the
+/// result of macro expansion)
+/// Placement of these is not as complex as I feared it would be.
+/// The important thing is to make sure that lookahead doesn't balk
+/// at INTERPOLATED tokens
 macro_rules! maybe_whole_expr (
     ($p:expr) => (
         {
@@ -167,7 +167,7 @@ macro_rules! maybe_whole_expr (
     )
 )
 
-// As above, but for things other than expressions
+/// As maybe_whole_expr, but for things other than expressions
 macro_rules! maybe_whole (
     ($p:expr, $constructor:ident) => (
         {
@@ -288,14 +288,14 @@ struct ParsedItemsAndViewItems {
 
 pub struct Parser<'a> {
     pub sess: &'a ParseSess,
-    // the current token:
+    /// the current token:
     pub token: token::Token,
-    // the span of the current token:
+    /// the span of the current token:
     pub span: Span,
-    // the span of the prior token:
+    /// the span of the prior token:
     pub last_span: Span,
     pub cfg: CrateConfig,
-    // the previous token or None (only stashed sometimes).
+    /// the previous token or None (only stashed sometimes).
     pub last_token: Option<Box<token::Token>>,
     pub buffer: [TokenAndSpan, ..4],
     pub buffer_start: int,
@@ -325,10 +325,24 @@ fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
     is_plain_ident(t) || *t == token::UNDERSCORE
 }
 
+/// Get a token the parser cares about
+fn real_token(rdr: &mut Reader) -> TokenAndSpan {
+    let mut t = rdr.next_token();
+    loop {
+        match t.tok {
+            token::WS | token::COMMENT | token::SHEBANG(_) => {
+                t = rdr.next_token();
+            },
+            _ => break
+        }
+    }
+    t
+}
+
 impl<'a> Parser<'a> {
     pub fn new(sess: &'a ParseSess, cfg: ast::CrateConfig,
                mut rdr: Box<Reader>) -> Parser<'a> {
-        let tok0 = rdr.next_token();
+        let tok0 = real_token(rdr);
         let span = tok0.sp;
         let placeholder = TokenAndSpan {
             tok: token::UNDERSCORE,
@@ -362,57 +376,58 @@ pub fn new(sess: &'a ParseSess, cfg: ast::CrateConfig,
             root_module_name: None,
         }
     }
-    // convert a token to a string using self's reader
-    pub fn token_to_str(token: &token::Token) -> String {
-        token::to_str(token)
+
+    /// Convert a token to a string using self's reader
+    pub fn token_to_string(token: &token::Token) -> String {
+        token::to_string(token)
     }
 
-    // convert the current token to a string using self's reader
-    pub fn this_token_to_str(&mut self) -> String {
-        Parser::token_to_str(&self.token)
+    /// Convert the current token to a string using self's reader
+    pub fn this_token_to_string(&mut self) -> String {
+        Parser::token_to_string(&self.token)
     }
 
     pub fn unexpected_last(&mut self, t: &token::Token) -> ! {
-        let token_str = Parser::token_to_str(t);
+        let token_str = Parser::token_to_string(t);
         let last_span = self.last_span;
         self.span_fatal(last_span, format!("unexpected token: `{}`",
                                                 token_str).as_slice());
     }
 
     pub fn unexpected(&mut self) -> ! {
-        let this_token = self.this_token_to_str();
+        let this_token = self.this_token_to_string();
         self.fatal(format!("unexpected token: `{}`", this_token).as_slice());
     }
 
-    // expect and consume the token t. Signal an error if
-    // the next token is not t.
+    /// Expect and consume the token t. Signal an error if
+    /// the next token is not t.
     pub fn expect(&mut self, t: &token::Token) {
         if self.token == *t {
             self.bump();
         } else {
-            let token_str = Parser::token_to_str(t);
-            let this_token_str = self.this_token_to_str();
+            let token_str = Parser::token_to_string(t);
+            let this_token_str = self.this_token_to_string();
             self.fatal(format!("expected `{}` but found `{}`",
                                token_str,
                                this_token_str).as_slice())
         }
     }
 
-    // Expect next token to be edible or inedible token.  If edible,
-    // then consume it; if inedible, then return without consuming
-    // anything.  Signal a fatal error if next token is unexpected.
+    /// Expect next token to be edible or inedible token.  If edible,
+    /// then consume it; if inedible, then return without consuming
+    /// anything.  Signal a fatal error if next token is unexpected.
     pub fn expect_one_of(&mut self,
                          edible: &[token::Token],
                          inedible: &[token::Token]) {
-        fn tokens_to_str(tokens: &[token::Token]) -> String {
+        fn tokens_to_string(tokens: &[token::Token]) -> String {
             let mut i = tokens.iter();
             // This might be a sign we need a connect method on Iterator.
             let b = i.next()
-                     .map_or("".to_string(), |t| Parser::token_to_str(t));
+                     .map_or("".to_string(), |t| Parser::token_to_string(t));
             i.fold(b, |b,a| {
                 let mut b = b;
                 b.push_str("`, `");
-                b.push_str(Parser::token_to_str(a).as_slice());
+                b.push_str(Parser::token_to_string(a).as_slice());
                 b
             })
         }
@@ -422,8 +437,8 @@ fn tokens_to_str(tokens: &[token::Token]) -> String {
             // leave it in the input
         } else {
             let expected = edible.iter().map(|x| (*x).clone()).collect::<Vec<_>>().append(inedible);
-            let expect = tokens_to_str(expected.as_slice());
-            let actual = self.this_token_to_str();
+            let expect = tokens_to_string(expected.as_slice());
+            let actual = self.this_token_to_string();
             self.fatal(
                 (if expected.len() != 1 {
                     (format!("expected one of `{}` but found `{}`",
@@ -438,9 +453,9 @@ fn tokens_to_str(tokens: &[token::Token]) -> String {
         }
     }
 
-    // Check for erroneous `ident { }`; if matches, signal error and
-    // recover (without consuming any expected input token).  Returns
-    // true if and only if input was consumed for recovery.
+    /// Check for erroneous `ident { }`; if matches, signal error and
+    /// recover (without consuming any expected input token).  Returns
+    /// true if and only if input was consumed for recovery.
     pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::Token]) -> bool {
         if self.token == token::LBRACE
             && expected.iter().all(|t| *t != token::LBRACE)
@@ -457,9 +472,9 @@ pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::T
         }
     }
 
-    // Commit to parsing a complete expression `e` expected to be
-    // followed by some token from the set edible + inedible.  Recover
-    // from anticipated input errors, discarding erroneous characters.
+    /// Commit to parsing a complete expression `e` expected to be
+    /// followed by some token from the set edible + inedible.  Recover
+    /// from anticipated input errors, discarding erroneous characters.
     pub fn commit_expr(&mut self, e: Gc<Expr>, edible: &[token::Token],
                        inedible: &[token::Token]) {
         debug!("commit_expr {:?}", e);
@@ -480,9 +495,9 @@ pub fn commit_expr_expecting(&mut self, e: Gc<Expr>, edible: token::Token) {
         self.commit_expr(e, &[edible], &[])
     }
 
-    // Commit to parsing a complete statement `s`, which expects to be
-    // followed by some token from the set edible + inedible.  Check
-    // for recoverable input errors, discarding erroneous characters.
+    /// Commit to parsing a complete statement `s`, which expects to be
+    /// followed by some token from the set edible + inedible.  Check
+    /// for recoverable input errors, discarding erroneous characters.
     pub fn commit_stmt(&mut self, s: Gc<Stmt>, edible: &[token::Token],
                        inedible: &[token::Token]) {
         debug!("commit_stmt {:?}", s);
@@ -512,7 +527,7 @@ pub fn parse_ident(&mut self) -> ast::Ident {
                 self.bug("ident interpolation not converted to real token");
             }
             _ => {
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 self.fatal((format!("expected ident, found `{}`",
                                     token_str)).as_slice())
             }
@@ -527,8 +542,8 @@ pub fn parse_path_list_ident(&mut self) -> ast::PathListIdent {
                                               id: ast::DUMMY_NODE_ID })
     }
 
-    // consume token 'tok' if it exists. Returns true if the given
-    // token was present, false otherwise.
+    /// Consume token 'tok' if it exists. Returns true if the given
+    /// token was present, false otherwise.
     pub fn eat(&mut self, tok: &token::Token) -> bool {
         let is_present = self.token == *tok;
         if is_present { self.bump() }
@@ -539,33 +554,34 @@ pub fn is_keyword(&mut self, kw: keywords::Keyword) -> bool {
         token::is_keyword(kw, &self.token)
     }
 
-    // if the next token is the given keyword, eat it and return
-    // true. Otherwise, return false.
+    /// If the next token is the given keyword, eat it and return
+    /// true. Otherwise, return false.
     pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
-        let is_kw = match self.token {
-            token::IDENT(sid, false) => kw.to_ident().name == sid.name,
+        match self.token {
+            token::IDENT(sid, false) if kw.to_name() == sid.name => {
+                self.bump();
+                true
+            }
             _ => false
-        };
-        if is_kw { self.bump() }
-        is_kw
+        }
     }
 
-    // if the given word is not a keyword, signal an error.
-    // if the next token is not the given word, signal an error.
-    // otherwise, eat it.
+    /// If the given word is not a keyword, signal an error.
+    /// If the next token is not the given word, signal an error.
+    /// Otherwise, eat it.
     pub fn expect_keyword(&mut self, kw: keywords::Keyword) {
         if !self.eat_keyword(kw) {
-            let id_interned_str = token::get_ident(kw.to_ident());
-            let token_str = self.this_token_to_str();
+            let id_interned_str = token::get_name(kw.to_name());
+            let token_str = self.this_token_to_string();
             self.fatal(format!("expected `{}`, found `{}`",
                                id_interned_str, token_str).as_slice())
         }
     }
 
-    // signal an error if the given string is a strict keyword
+    /// Signal an error if the given string is a strict keyword
     pub fn check_strict_keywords(&mut self) {
         if token::is_strict_keyword(&self.token) {
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             let span = self.span;
             self.span_err(span,
                           format!("found `{}` in ident position",
@@ -573,17 +589,17 @@ pub fn check_strict_keywords(&mut self) {
         }
     }
 
-    // signal an error if the current token is a reserved keyword
+    /// Signal an error if the current token is a reserved keyword
     pub fn check_reserved_keywords(&mut self) {
         if token::is_reserved_keyword(&self.token) {
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             self.fatal(format!("`{}` is a reserved keyword",
                                token_str).as_slice())
         }
     }
 
-    // Expect and consume an `&`. If `&&` is seen, replace it with a single
-    // `&` and continue. If an `&` is not seen, signal an error.
+    /// Expect and consume an `&`. If `&&` is seen, replace it with a single
+    /// `&` and continue. If an `&` is not seen, signal an error.
     fn expect_and(&mut self) {
         match self.token {
             token::BINOP(token::AND) => self.bump(),
@@ -593,9 +609,9 @@ fn expect_and(&mut self) {
                 self.replace_token(token::BINOP(token::AND), lo, span.hi)
             }
             _ => {
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 let found_token =
-                    Parser::token_to_str(&token::BINOP(token::AND));
+                    Parser::token_to_string(&token::BINOP(token::AND));
                 self.fatal(format!("expected `{}`, found `{}`",
                                    found_token,
                                    token_str).as_slice())
@@ -603,8 +619,8 @@ fn expect_and(&mut self) {
         }
     }
 
-    // Expect and consume a `|`. If `||` is seen, replace it with a single
-    // `|` and continue. If a `|` is not seen, signal an error.
+    /// Expect and consume a `|`. If `||` is seen, replace it with a single
+    /// `|` and continue. If a `|` is not seen, signal an error.
     fn expect_or(&mut self) {
         match self.token {
             token::BINOP(token::OR) => self.bump(),
@@ -614,9 +630,9 @@ fn expect_or(&mut self) {
                 self.replace_token(token::BINOP(token::OR), lo, span.hi)
             }
             _ => {
-                let found_token = self.this_token_to_str();
+                let found_token = self.this_token_to_string();
                 let token_str =
-                    Parser::token_to_str(&token::BINOP(token::OR));
+                    Parser::token_to_string(&token::BINOP(token::OR));
                 self.fatal(format!("expected `{}`, found `{}`",
                                    token_str,
                                    found_token).as_slice())
@@ -624,26 +640,26 @@ fn expect_or(&mut self) {
         }
     }
 
-    // Attempt to consume a `<`. If `<<` is seen, replace it with a single
-    // `<` and continue. If a `<` is not seen, return false.
-    //
-    // This is meant to be used when parsing generics on a path to get the
-    // starting token. The `force` parameter is used to forcefully break up a
-    // `<<` token. If `force` is false, then `<<` is only broken when a lifetime
-    // shows up next. For example, consider the expression:
-    //
-    //      foo as bar << test
-    //
-    // The parser needs to know if `bar <<` is the start of a generic path or if
-    // it's a left-shift token. If `test` were a lifetime, then it's impossible
-    // for the token to be a left-shift, but if it's not a lifetime, then it's
-    // considered a left-shift.
-    //
-    // The reason for this is that the only current ambiguity with `<<` is when
-    // parsing closure types:
-    //
-    //      foo::<<'a> ||>();
-    //      impl Foo<<'a> ||>() { ... }
+    /// Attempt to consume a `<`. If `<<` is seen, replace it with a single
+    /// `<` and continue. If a `<` is not seen, return false.
+    ///
+    /// This is meant to be used when parsing generics on a path to get the
+    /// starting token. The `force` parameter is used to forcefully break up a
+    /// `<<` token. If `force` is false, then `<<` is only broken when a lifetime
+    /// shows up next. For example, consider the expression:
+    ///
+    ///      foo as bar << test
+    ///
+    /// The parser needs to know if `bar <<` is the start of a generic path or if
+    /// it's a left-shift token. If `test` were a lifetime, then it's impossible
+    /// for the token to be a left-shift, but if it's not a lifetime, then it's
+    /// considered a left-shift.
+    ///
+    /// The reason for this is that the only current ambiguity with `<<` is when
+    /// parsing closure types:
+    ///
+    ///      foo::<<'a> ||>();
+    ///      impl Foo<<'a> ||>() { ... }
     fn eat_lt(&mut self, force: bool) -> bool {
         match self.token {
             token::LT => { self.bump(); true }
@@ -667,15 +683,15 @@ fn eat_lt(&mut self, force: bool) -> bool {
 
     fn expect_lt(&mut self) {
         if !self.eat_lt(true) {
-            let found_token = self.this_token_to_str();
-            let token_str = Parser::token_to_str(&token::LT);
+            let found_token = self.this_token_to_string();
+            let token_str = Parser::token_to_string(&token::LT);
             self.fatal(format!("expected `{}`, found `{}`",
                                token_str,
                                found_token).as_slice())
         }
     }
 
-    // Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
+    /// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
     fn parse_seq_to_before_or<T>(
                               &mut self,
                               sep: &token::Token,
@@ -696,9 +712,9 @@ fn parse_seq_to_before_or<T>(
         vector
     }
 
-    // expect and consume a GT. if a >> is seen, replace it
-    // with a single > and continue. If a GT is not seen,
-    // signal an error.
+    /// Expect and consume a GT. if a >> is seen, replace it
+    /// with a single > and continue. If a GT is not seen,
+    /// signal an error.
     pub fn expect_gt(&mut self) {
         match self.token {
             token::GT => self.bump(),
@@ -718,8 +734,8 @@ pub fn expect_gt(&mut self) {
                 self.replace_token(token::EQ, lo, span.hi)
             }
             _ => {
-                let gt_str = Parser::token_to_str(&token::GT);
-                let this_token_str = self.this_token_to_str();
+                let gt_str = Parser::token_to_string(&token::GT);
+                let this_token_str = self.this_token_to_string();
                 self.fatal(format!("expected `{}`, found `{}`",
                                    gt_str,
                                    this_token_str).as_slice())
@@ -727,8 +743,8 @@ pub fn expect_gt(&mut self) {
         }
     }
 
-    // parse a sequence bracketed by '<' and '>', stopping
-    // before the '>'.
+    /// Parse a sequence bracketed by '<' and '>', stopping
+    /// before the '>'.
     pub fn parse_seq_to_before_gt<T>(
                                   &mut self,
                                   sep: Option<token::Token>,
@@ -762,9 +778,9 @@ pub fn parse_seq_to_gt<T>(
         return v;
     }
 
-    // parse a sequence, including the closing delimiter. The function
-    // f must consume tokens until reaching the next separator or
-    // closing bracket.
+    /// Parse a sequence, including the closing delimiter. The function
+    /// f must consume tokens until reaching the next separator or
+    /// closing bracket.
     pub fn parse_seq_to_end<T>(
                             &mut self,
                             ket: &token::Token,
@@ -776,9 +792,9 @@ pub fn parse_seq_to_end<T>(
         val
     }
 
-    // parse a sequence, not including the closing delimiter. The function
-    // f must consume tokens until reaching the next separator or
-    // closing bracket.
+    /// Parse a sequence, not including the closing delimiter. The function
+    /// f must consume tokens until reaching the next separator or
+    /// closing bracket.
     pub fn parse_seq_to_before_end<T>(
                                    &mut self,
                                    ket: &token::Token,
@@ -801,9 +817,9 @@ pub fn parse_seq_to_before_end<T>(
         return v;
     }
 
-    // parse a sequence, including the closing delimiter. The function
-    // f must consume tokens until reaching the next separator or
-    // closing bracket.
+    /// Parse a sequence, including the closing delimiter. The function
+    /// f must consume tokens until reaching the next separator or
+    /// closing bracket.
     pub fn parse_unspanned_seq<T>(
                                &mut self,
                                bra: &token::Token,
@@ -817,8 +833,8 @@ pub fn parse_unspanned_seq<T>(
         result
     }
 
-    // parse a sequence parameter of enum variant. For consistency purposes,
-    // these should not be empty.
+    /// Parse a sequence parameter of enum variant. For consistency purposes,
+    /// these should not be empty.
     pub fn parse_enum_variant_seq<T>(
                                &mut self,
                                bra: &token::Token,
@@ -852,7 +868,7 @@ pub fn parse_seq<T>(
         spanned(lo, hi, result)
     }
 
-    // advance the parser by one token
+    /// Advance the parser by one token
     pub fn bump(&mut self) {
         self.last_span = self.span;
         // Stash token for error recovery (sometimes; clone is not necessarily cheap).
@@ -862,7 +878,7 @@ pub fn bump(&mut self) {
             None
         };
         let next = if self.buffer_start == self.buffer_end {
-            self.reader.next_token()
+            real_token(self.reader)
         } else {
             // Avoid token copies with `replace`.
             let buffer_start = self.buffer_start as uint;
@@ -880,14 +896,14 @@ pub fn bump(&mut self) {
         self.tokens_consumed += 1u;
     }
 
-    // Advance the parser by one token and return the bumped token.
+    /// Advance the parser by one token and return the bumped token.
     pub fn bump_and_get(&mut self) -> token::Token {
         let old_token = replace(&mut self.token, token::UNDERSCORE);
         self.bump();
         old_token
     }
 
-    // EFFECT: replace the current token and span with the given one
+    /// EFFECT: replace the current token and span with the given one
     pub fn replace_token(&mut self,
                          next: token::Token,
                          lo: BytePos,
@@ -906,7 +922,7 @@ pub fn look_ahead<R>(&mut self, distance: uint, f: |&token::Token| -> R)
                       -> R {
         let dist = distance as int;
         while self.buffer_length() < dist {
-            self.buffer[self.buffer_end as uint] = self.reader.next_token();
+            self.buffer[self.buffer_end as uint] = real_token(self.reader);
             self.buffer_end = (self.buffer_end + 1) & 3;
         }
         f(&self.buffer[((self.buffer_start + dist - 1) & 3) as uint].tok)
@@ -940,8 +956,8 @@ pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString {
         token::get_ident(id)
     }
 
-    // Is the current token one of the keywords that signals a bare function
-    // type?
+    /// Is the current token one of the keywords that signals a bare function
+    /// type?
     pub fn token_is_bare_fn_keyword(&mut self) -> bool {
         if token::is_keyword(keywords::Fn, &self.token) {
             return true
@@ -955,14 +971,14 @@ pub fn token_is_bare_fn_keyword(&mut self) -> bool {
         false
     }
 
-    // Is the current token one of the keywords that signals a closure type?
+    /// Is the current token one of the keywords that signals a closure type?
     pub fn token_is_closure_keyword(&mut self) -> bool {
         token::is_keyword(keywords::Unsafe, &self.token) ||
             token::is_keyword(keywords::Once, &self.token)
     }
 
-    // Is the current token one of the keywords that signals an old-style
-    // closure type (with explicit sigil)?
+    /// Is the current token one of the keywords that signals an old-style
+    /// closure type (with explicit sigil)?
     pub fn token_is_old_style_closure_keyword(&mut self) -> bool {
         token::is_keyword(keywords::Unsafe, &self.token) ||
             token::is_keyword(keywords::Once, &self.token) ||
@@ -983,7 +999,7 @@ pub fn get_lifetime(&mut self) -> ast::Ident {
         }
     }
 
-    // parse a TyBareFn type:
+    /// parse a TyBareFn type:
     pub fn parse_ty_bare_fn(&mut self) -> Ty_ {
         /*
 
@@ -1014,8 +1030,8 @@ pub fn parse_ty_bare_fn(&mut self) -> Ty_ {
         });
     }
 
-    // Parses a procedure type (`proc`). The initial `proc` keyword must
-    // already have been parsed.
+    /// Parses a procedure type (`proc`). The initial `proc` keyword must
+    /// already have been parsed.
     pub fn parse_proc_type(&mut self) -> Ty_ {
         /*
 
@@ -1063,7 +1079,7 @@ pub fn parse_proc_type(&mut self) -> Ty_ {
         })
     }
 
-    // parse a TyClosure type
+    /// Parse a TyClosure type
     pub fn parse_ty_closure(&mut self) -> Ty_ {
         /*
 
@@ -1154,7 +1170,7 @@ pub fn parse_unsafety(&mut self) -> FnStyle {
         }
     }
 
-    // parse a function type (following the 'fn')
+    /// Parse a function type (following the 'fn')
     pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
                             -> (P<FnDecl>, Vec<ast::Lifetime>) {
         /*
@@ -1186,7 +1202,7 @@ pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
         (decl, lifetimes)
     }
 
-    // parse the methods in a trait declaration
+    /// Parse the methods in a trait declaration
     pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
         self.parse_unspanned_seq(
             &token::LBRACE,
@@ -1233,21 +1249,15 @@ pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
                     p.parse_inner_attrs_and_block();
                 let attrs = attrs.append(inner_attrs.as_slice());
                 Provided(box(GC) ast::Method {
-                    ident: ident,
                     attrs: attrs,
-                    generics: generics,
-                    explicit_self: explicit_self,
-                    fn_style: style,
-                    decl: d,
-                    body: body,
                     id: ast::DUMMY_NODE_ID,
                     span: mk_sp(lo, hi),
-                    vis: vis,
+                    node: ast::MethDecl(ident, generics, explicit_self, style, d, body, vis)
                 })
               }
 
               _ => {
-                  let token_str = p.this_token_to_str();
+                  let token_str = p.this_token_to_string();
                   p.fatal((format!("expected `;` or `{{` but found `{}`",
                                    token_str)).as_slice())
               }
@@ -1255,15 +1265,15 @@ pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
         })
     }
 
-    // parse a possibly mutable type
+    /// Parse a possibly mutable type
     pub fn parse_mt(&mut self) -> MutTy {
         let mutbl = self.parse_mutability();
         let t = self.parse_ty(true);
         MutTy { ty: t, mutbl: mutbl }
     }
 
-    // parse [mut/const/imm] ID : TY
-    // now used only by obsolete record syntax parser...
+    /// Parse [mut/const/imm] ID : TY
+    /// now used only by obsolete record syntax parser...
     pub fn parse_ty_field(&mut self) -> TypeField {
         let lo = self.span.lo;
         let mutbl = self.parse_mutability();
@@ -1278,7 +1288,7 @@ pub fn parse_ty_field(&mut self) -> TypeField {
         }
     }
 
-    // parse optional return type [ -> TY ] in function decl
+    /// Parse optional return type [ -> TY ] in function decl
     pub fn parse_ret_ty(&mut self) -> (RetStyle, P<Ty>) {
         return if self.eat(&token::RARROW) {
             let lo = self.span.lo;
@@ -1478,8 +1488,8 @@ pub fn is_named_argument(&mut self) -> bool {
         }
     }
 
-    // This version of parse arg doesn't necessarily require
-    // identifier names.
+    /// This version of parse arg doesn't necessarily require
+    /// identifier names.
     pub fn parse_arg_general(&mut self, require_name: bool) -> Arg {
         let pat = if require_name || self.is_named_argument() {
             debug!("parse_arg_general parse_pat (require_name:{:?})",
@@ -1504,12 +1514,12 @@ pub fn parse_arg_general(&mut self, require_name: bool) -> Arg {
         }
     }
 
-    // parse a single function argument
+    /// Parse a single function argument
     pub fn parse_arg(&mut self) -> Arg {
         self.parse_arg_general(true)
     }
 
-    // parse an argument in a lambda header e.g. |arg, arg|
+    /// Parse an argument in a lambda header e.g. |arg, arg|
     pub fn parse_fn_block_arg(&mut self) -> Arg {
         let pat = self.parse_pat();
         let t = if self.eat(&token::COLON) {
@@ -1539,34 +1549,32 @@ pub fn maybe_parse_fixed_vstore(&mut self) -> Option<Gc<ast::Expr>> {
         }
     }
 
-    // matches token_lit = LIT_INT | ...
+    /// Matches token_lit = LIT_INTEGER | ...
     pub fn lit_from_token(&mut self, tok: &token::Token) -> Lit_ {
         match *tok {
-            token::LIT_BYTE(i) => LitByte(i),
-            token::LIT_CHAR(i) => LitChar(i),
-            token::LIT_INT(i, it) => LitInt(i, it),
-            token::LIT_UINT(u, ut) => LitUint(u, ut),
-            token::LIT_INT_UNSUFFIXED(i) => LitIntUnsuffixed(i),
-            token::LIT_FLOAT(s, ft) => {
-                LitFloat(self.id_to_interned_str(s), ft)
-            }
-            token::LIT_FLOAT_UNSUFFIXED(s) => {
-                LitFloatUnsuffixed(self.id_to_interned_str(s))
-            }
+            token::LIT_BYTE(i) => LitByte(parse::byte_lit(i.as_str()).val0()),
+            token::LIT_CHAR(i) => LitChar(parse::char_lit(i.as_str()).val0()),
+            token::LIT_INTEGER(s) => parse::integer_lit(s.as_str(),
+                                                        &self.sess.span_diagnostic, self.span),
+            token::LIT_FLOAT(s) => parse::float_lit(s.as_str()),
             token::LIT_STR(s) => {
-                LitStr(self.id_to_interned_str(s), ast::CookedStr)
+                LitStr(token::intern_and_get_ident(parse::str_lit(s.as_str()).as_slice()),
+                       ast::CookedStr)
             }
             token::LIT_STR_RAW(s, n) => {
-                LitStr(self.id_to_interned_str(s), ast::RawStr(n))
+                LitStr(token::intern_and_get_ident(parse::raw_str_lit(s.as_str()).as_slice()),
+                       ast::RawStr(n))
             }
-            token::LIT_BINARY_RAW(ref v, _) |
-            token::LIT_BINARY(ref v) => LitBinary(v.clone()),
+            token::LIT_BINARY(i) =>
+                LitBinary(parse::binary_lit(i.as_str())),
+            token::LIT_BINARY_RAW(i, _) =>
+                LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())),
             token::LPAREN => { self.expect(&token::RPAREN); LitNil },
             _ => { self.unexpected_last(tok); }
         }
     }
 
-    // matches lit = true | false | token_lit
+    /// Matches lit = true | false | token_lit
     pub fn parse_lit(&mut self) -> Lit {
         let lo = self.span.lo;
         let lit = if self.eat_keyword(keywords::True) {
@@ -1581,7 +1589,7 @@ pub fn parse_lit(&mut self) -> Lit {
         codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
     }
 
-    // matches '-' lit | lit
+    /// matches '-' lit | lit
     pub fn parse_literal_maybe_minus(&mut self) -> Gc<Expr> {
         let minus_lo = self.span.lo;
         let minus_present = self.eat(&token::BINOP(token::MINUS));
@@ -1719,7 +1727,7 @@ pub fn parse_opt_lifetime(&mut self) -> Option<ast::Lifetime> {
     }
 
     /// Parses a single lifetime
-    // matches lifetime = LIFETIME
+    /// Matches lifetime = LIFETIME
     pub fn parse_lifetime(&mut self) -> ast::Lifetime {
         match self.token {
             token::LIFETIME(i) => {
@@ -1779,7 +1787,7 @@ pub fn token_is_mutability(tok: &token::Token) -> bool {
         token::is_keyword(keywords::Const, tok)
     }
 
-    // parse mutability declaration (mut/const/imm)
+    /// Parse mutability declaration (mut/const/imm)
     pub fn parse_mutability(&mut self) -> Mutability {
         if self.eat_keyword(keywords::Mut) {
             MutMutable
@@ -1788,7 +1796,7 @@ pub fn parse_mutability(&mut self) -> Mutability {
         }
     }
 
-    // parse ident COLON expr
+    /// Parse ident COLON expr
     pub fn parse_field(&mut self) -> Field {
         let lo = self.span.lo;
         let i = self.parse_ident();
@@ -1867,9 +1875,9 @@ pub fn mk_lit_u32(&mut self, i: u32) -> Gc<Expr> {
         }
     }
 
-    // at the bottom (top?) of the precedence hierarchy,
-    // parse things like parenthesized exprs,
-    // macros, return, etc.
+    /// At the bottom (top?) of the precedence hierarchy,
+    /// parse things like parenthesized exprs,
+    /// macros, return, etc.
     pub fn parse_bottom_expr(&mut self) -> Gc<Expr> {
         maybe_whole_expr!(self);
 
@@ -1878,217 +1886,241 @@ pub fn parse_bottom_expr(&mut self) -> Gc<Expr> {
 
         let ex: Expr_;
 
-        if self.token == token::LPAREN {
-            self.bump();
-            // (e) is parenthesized e
-            // (e,) is a tuple with only one field, e
-            let mut trailing_comma = false;
-            if self.token == token::RPAREN {
-                hi = self.span.hi;
-                self.bump();
-                let lit = box(GC) spanned(lo, hi, LitNil);
-                return self.mk_expr(lo, hi, ExprLit(lit));
-            }
-            let mut es = vec!(self.parse_expr());
-            self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
-            while self.token == token::COMMA {
+        match self.token {
+            token::LPAREN => {
                 self.bump();
-                if self.token != token::RPAREN {
-                    es.push(self.parse_expr());
-                    self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
+                // (e) is parenthesized e
+                // (e,) is a tuple with only one field, e
+                let mut trailing_comma = false;
+                if self.token == token::RPAREN {
+                    hi = self.span.hi;
+                    self.bump();
+                    let lit = box(GC) spanned(lo, hi, LitNil);
+                    return self.mk_expr(lo, hi, ExprLit(lit));
                 }
-                else {
-                    trailing_comma = true;
+                let mut es = vec!(self.parse_expr());
+                self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
+                while self.token == token::COMMA {
+                    self.bump();
+                    if self.token != token::RPAREN {
+                        es.push(self.parse_expr());
+                        self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
+                    }
+                        else {
+                        trailing_comma = true;
+                    }
                 }
-            }
-            hi = self.span.hi;
-            self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN);
-
-            return if es.len() == 1 && !trailing_comma {
-                self.mk_expr(lo, hi, ExprParen(*es.get(0)))
-            }
-            else {
-                self.mk_expr(lo, hi, ExprTup(es))
-            }
-        } else if self.token == token::LBRACE {
-            self.bump();
-            let blk = self.parse_block_tail(lo, DefaultBlock);
-            return self.mk_expr(blk.span.lo, blk.span.hi,
-                                 ExprBlock(blk));
-        } else if token::is_bar(&self.token) {
-            return self.parse_lambda_expr();
-        } else if self.eat_keyword(keywords::Proc) {
-            let decl = self.parse_proc_decl();
-            let body = self.parse_expr();
-            let fakeblock = P(ast::Block {
-                view_items: Vec::new(),
-                stmts: Vec::new(),
-                expr: Some(body),
-                id: ast::DUMMY_NODE_ID,
-                rules: DefaultBlock,
-                span: body.span,
-            });
+                hi = self.span.hi;
+                self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN);
 
-            return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
-        } else if self.eat_keyword(keywords::Self) {
-            let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_);
-            ex = ExprPath(path);
-            hi = self.last_span.hi;
-        } else if self.eat_keyword(keywords::If) {
-            return self.parse_if_expr();
-        } else if self.eat_keyword(keywords::For) {
-            return self.parse_for_expr(None);
-        } else if self.eat_keyword(keywords::While) {
-            return self.parse_while_expr();
-        } else if Parser::token_is_lifetime(&self.token) {
-            let lifetime = self.get_lifetime();
-            self.bump();
-            self.expect(&token::COLON);
-            if self.eat_keyword(keywords::For) {
-                return self.parse_for_expr(Some(lifetime))
-            } else if self.eat_keyword(keywords::Loop) {
-                return self.parse_loop_expr(Some(lifetime))
-            } else {
-                self.fatal("expected `for` or `loop` after a label")
+                return if es.len() == 1 && !trailing_comma {
+                    self.mk_expr(lo, hi, ExprParen(*es.get(0)))
+                }
+                    else {
+                    self.mk_expr(lo, hi, ExprTup(es))
+                }
+            },
+            token::LBRACE => {
+                self.bump();
+                let blk = self.parse_block_tail(lo, DefaultBlock);
+                return self.mk_expr(blk.span.lo, blk.span.hi,
+                                    ExprBlock(blk));
+            },
+            token::BINOP(token::OR) |  token::OROR => {
+                return self.parse_lambda_expr();
+            },
+            _ if self.eat_keyword(keywords::Proc) => {
+                let decl = self.parse_proc_decl();
+                let body = self.parse_expr();
+                let fakeblock = P(ast::Block {
+                        view_items: Vec::new(),
+                        stmts: Vec::new(),
+                        expr: Some(body),
+                        id: ast::DUMMY_NODE_ID,
+                        rules: DefaultBlock,
+                        span: body.span,
+                    });
+                return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
+            },
+            // FIXME #13626: Should be able to stick in
+            // token::SELF_KEYWORD_NAME
+            token::IDENT(id @ ast::Ident{
+                        name: ast::Name(token::SELF_KEYWORD_NAME_NUM),
+                        ctxt: _
+                    } ,false) => {
+                self.bump();
+                let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
+                ex = ExprPath(path);
+                hi = self.last_span.hi;
             }
-        } else if self.eat_keyword(keywords::Loop) {
-            return self.parse_loop_expr(None);
-        } else if self.eat_keyword(keywords::Continue) {
-            let lo = self.span.lo;
-            let ex = if Parser::token_is_lifetime(&self.token) {
+            _ if self.eat_keyword(keywords::If) => {
+                return self.parse_if_expr();
+            },
+            _ if self.eat_keyword(keywords::For) => {
+                return self.parse_for_expr(None);
+            },
+            _ if self.eat_keyword(keywords::While) => {
+                return self.parse_while_expr();
+            },
+            _ if Parser::token_is_lifetime(&self.token) => {
                 let lifetime = self.get_lifetime();
                 self.bump();
-                ExprAgain(Some(lifetime))
-            } else {
-                ExprAgain(None)
-            };
-            let hi = self.span.hi;
-            return self.mk_expr(lo, hi, ex);
-        } else if self.eat_keyword(keywords::Match) {
-            return self.parse_match_expr();
-        } else if self.eat_keyword(keywords::Unsafe) {
-            return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
-        } else if self.token == token::LBRACKET {
-            self.bump();
-
-            if self.token == token::RBRACKET {
-                // Empty vector.
-                self.bump();
-                ex = ExprVec(Vec::new());
-            } else {
-                // Nonempty vector.
-                let first_expr = self.parse_expr();
-                if self.token == token::COMMA &&
-                        self.look_ahead(1, |t| *t == token::DOTDOT) {
-                    // Repeating vector syntax: [ 0, ..512 ]
+                self.expect(&token::COLON);
+                if self.eat_keyword(keywords::For) {
+                    return self.parse_for_expr(Some(lifetime))
+                } else if self.eat_keyword(keywords::Loop) {
+                    return self.parse_loop_expr(Some(lifetime))
+                } else {
+                    self.fatal("expected `for` or `loop` after a label")
+                }
+            },
+            _ if self.eat_keyword(keywords::Loop) => {
+                return self.parse_loop_expr(None);
+            },
+            _ if self.eat_keyword(keywords::Continue) => {
+                let lo = self.span.lo;
+                let ex = if Parser::token_is_lifetime(&self.token) {
+                    let lifetime = self.get_lifetime();
                     self.bump();
+                    ExprAgain(Some(lifetime))
+                } else {
+                    ExprAgain(None)
+                };
+                let hi = self.span.hi;
+                return self.mk_expr(lo, hi, ex);
+            },
+            _ if self.eat_keyword(keywords::Match) => {
+                return self.parse_match_expr();
+            },
+            _ if self.eat_keyword(keywords::Unsafe) => {
+                return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
+            },
+            token::LBRACKET => {
+                self.bump();
+
+                if self.token == token::RBRACKET {
+                    // Empty vector.
                     self.bump();
-                    let count = self.parse_expr();
-                    self.expect(&token::RBRACKET);
-                    ex = ExprRepeat(first_expr, count);
-                } else if self.token == token::COMMA {
-                    // Vector with two or more elements.
+                    ex = ExprVec(Vec::new());
+                } else {
+                    // Nonempty vector.
+                    let first_expr = self.parse_expr();
+                    if self.token == token::COMMA &&
+                        self.look_ahead(1, |t| *t == token::DOTDOT) {
+                        // Repeating vector syntax: [ 0, ..512 ]
+                        self.bump();
+                        self.bump();
+                        let count = self.parse_expr();
+                        self.expect(&token::RBRACKET);
+                        ex = ExprRepeat(first_expr, count);
+                    } else if self.token == token::COMMA {
+                        // Vector with two or more elements.
+                        self.bump();
+                        let remaining_exprs = self.parse_seq_to_end(
+                            &token::RBRACKET,
+                            seq_sep_trailing_allowed(token::COMMA),
+                            |p| p.parse_expr()
+                                );
+                        let mut exprs = vec!(first_expr);
+                        exprs.push_all_move(remaining_exprs);
+                        ex = ExprVec(exprs);
+                    } else {
+                        // Vector with one element.
+                        self.expect(&token::RBRACKET);
+                        ex = ExprVec(vec!(first_expr));
+                    }
+                }
+                hi = self.last_span.hi;
+            },
+            _ if self.eat_keyword(keywords::Return) => {
+                // RETURN expression
+                if can_begin_expr(&self.token) {
+                    let e = self.parse_expr();
+                    hi = e.span.hi;
+                    ex = ExprRet(Some(e));
+                } else { ex = ExprRet(None); }
+            },
+            _ if self.eat_keyword(keywords::Break) => {
+                // BREAK expression
+                if Parser::token_is_lifetime(&self.token) {
+                    let lifetime = self.get_lifetime();
                     self.bump();
-                    let remaining_exprs = self.parse_seq_to_end(
-                        &token::RBRACKET,
-                        seq_sep_trailing_allowed(token::COMMA),
-                        |p| p.parse_expr()
-                    );
-                    let mut exprs = vec!(first_expr);
-                    exprs.push_all_move(remaining_exprs);
-                    ex = ExprVec(exprs);
+                    ex = ExprBreak(Some(lifetime));
                 } else {
-                    // Vector with one element.
-                    self.expect(&token::RBRACKET);
-                    ex = ExprVec(vec!(first_expr));
+                    ex = ExprBreak(None);
                 }
-            }
-            hi = self.last_span.hi;
-        } else if self.eat_keyword(keywords::Return) {
-            // RETURN expression
-            if can_begin_expr(&self.token) {
-                let e = self.parse_expr();
-                hi = e.span.hi;
-                ex = ExprRet(Some(e));
-            } else { ex = ExprRet(None); }
-        } else if self.eat_keyword(keywords::Break) {
-            // BREAK expression
-            if Parser::token_is_lifetime(&self.token) {
-                let lifetime = self.get_lifetime();
-                self.bump();
-                ex = ExprBreak(Some(lifetime));
-            } else {
-                ex = ExprBreak(None);
-            }
-            hi = self.span.hi;
-        } else if self.token == token::MOD_SEP ||
+                hi = self.span.hi;
+            },
+            _ if self.token == token::MOD_SEP ||
                 is_ident(&self.token) && !self.is_keyword(keywords::True) &&
-                !self.is_keyword(keywords::False) {
-            let pth = self.parse_path(LifetimeAndTypesWithColons).path;
+                !self.is_keyword(keywords::False) => {
+                let pth = self.parse_path(LifetimeAndTypesWithColons).path;
 
-            // `!`, as an operator, is prefix, so we know this isn't that
-            if self.token == token::NOT {
-                // MACRO INVOCATION expression
-                self.bump();
+                // `!`, as an operator, is prefix, so we know this isn't that
+                if self.token == token::NOT {
+                    // MACRO INVOCATION expression
+                    self.bump();
 
-                let ket = token::close_delimiter_for(&self.token)
-                                .unwrap_or_else(|| self.fatal("expected open delimiter"));
-                self.bump();
+                    let ket = token::close_delimiter_for(&self.token)
+                        .unwrap_or_else(|| self.fatal("expected open delimiter"));
+                    self.bump();
 
-                let tts = self.parse_seq_to_end(&ket,
-                                                seq_sep_none(),
-                                                |p| p.parse_token_tree());
-                let hi = self.span.hi;
+                    let tts = self.parse_seq_to_end(&ket,
+                                                    seq_sep_none(),
+                                                    |p| p.parse_token_tree());
+                    let hi = self.span.hi;
 
-                return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
-            } else if self.token == token::LBRACE {
-                // This is a struct literal, unless we're prohibited from
-                // parsing struct literals here.
-                if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
-                    // It's a struct literal.
-                    self.bump();
-                    let mut fields = Vec::new();
-                    let mut base = None;
+                    return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
+                } else if self.token == token::LBRACE {
+                    // This is a struct literal, unless we're prohibited from
+                    // parsing struct literals here.
+                    if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
+                        // It's a struct literal.
+                        self.bump();
+                        let mut fields = Vec::new();
+                        let mut base = None;
+
+                        while self.token != token::RBRACE {
+                            if self.eat(&token::DOTDOT) {
+                                base = Some(self.parse_expr());
+                                break;
+                            }
 
-                    while self.token != token::RBRACE {
-                        if self.eat(&token::DOTDOT) {
-                            base = Some(self.parse_expr());
-                            break;
+                            fields.push(self.parse_field());
+                            self.commit_expr(fields.last().unwrap().expr,
+                                             &[token::COMMA], &[token::RBRACE]);
                         }
 
-                        fields.push(self.parse_field());
-                        self.commit_expr(fields.last().unwrap().expr,
-                                         &[token::COMMA], &[token::RBRACE]);
-                    }
+                        if fields.len() == 0 && base.is_none() {
+                            let last_span = self.last_span;
+                            self.span_err(last_span,
+                                          "structure literal must either have at \
+                                          least one field or use functional \
+                                          structure update syntax");
+                        }
 
-                    if fields.len() == 0 && base.is_none() {
-                        let last_span = self.last_span;
-                        self.span_err(last_span,
-                                      "structure literal must either have at \
-                                       least one field or use functional \
-                                       structure update syntax");
+                        hi = self.span.hi;
+                        self.expect(&token::RBRACE);
+                        ex = ExprStruct(pth, fields, base);
+                        return self.mk_expr(lo, hi, ex);
                     }
-
-                    hi = self.span.hi;
-                    self.expect(&token::RBRACE);
-                    ex = ExprStruct(pth, fields, base);
-                    return self.mk_expr(lo, hi, ex);
                 }
-            }
 
             hi = pth.span.hi;
             ex = ExprPath(pth);
-        } else {
-            // other literal expression
-            let lit = self.parse_lit();
-            hi = lit.span.hi;
-            ex = ExprLit(box(GC) lit);
+            },
+            _ => {
+                // other literal expression
+                let lit = self.parse_lit();
+                hi = lit.span.hi;
+                ex = ExprLit(box(GC) lit);
+            }
         }
 
         return self.mk_expr(lo, hi, ex);
     }
 
-    // parse a block or unsafe block
+    /// Parse a block or unsafe block
     pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode)
                             -> Gc<Expr> {
         self.expect(&token::LBRACE);
@@ -2096,7 +2128,7 @@ pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode)
         return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
     }
 
-    // parse a.b or a(13) or a[4] or just a
+    /// parse a.b or a(13) or a[4] or just a
     pub fn parse_dot_or_call_expr(&mut self) -> Gc<Expr> {
         let b = self.parse_bottom_expr();
         self.parse_dot_or_call_expr_with(b)
@@ -2180,8 +2212,8 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: Gc<Expr>) -> Gc<Expr> {
         return e;
     }
 
-    // parse an optional separator followed by a kleene-style
-    // repetition token (+ or *).
+    /// Parse an optional separator followed by a kleene-style
+    /// repetition token (+ or *).
     pub fn parse_sep_and_zerok(&mut self) -> (Option<token::Token>, bool) {
         fn parse_zerok(parser: &mut Parser) -> Option<bool> {
             match parser.token {
@@ -2206,7 +2238,7 @@ fn parse_zerok(parser: &mut Parser) -> Option<bool> {
         }
     }
 
-    // parse a single token tree from the input.
+    /// parse a single token tree from the input.
     pub fn parse_token_tree(&mut self) -> TokenTree {
         // FIXME #6994: currently, this is too eager. It
         // parses token trees but also identifies TTSeq's
@@ -2231,7 +2263,7 @@ fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
                       None => {}
                       Some(&sp) => p.span_note(sp, "unclosed delimiter"),
                   };
-                  let token_str = p.this_token_to_str();
+                  let token_str = p.this_token_to_string();
                   p.fatal(format!("incorrect close delimiter: `{}`",
                                   token_str).as_slice())
               },
@@ -2322,9 +2354,9 @@ pub fn parse_matchers(&mut self) -> Vec<Matcher> {
         }
     }
 
-    // This goofy function is necessary to correctly match parens in Matcher's.
-    // Otherwise, `$( ( )` would be a valid Matcher, and `$( () )` would be
-    // invalid. It's similar to common::parse_seq.
+    /// This goofy function is necessary to correctly match parens in Matcher's.
+    /// Otherwise, `$( ( )` would be a valid Matcher, and `$( () )` would be
+    /// invalid. It's similar to common::parse_seq.
     pub fn parse_matcher_subseq_upto(&mut self,
                                      name_idx: &mut uint,
                                      ket: &token::Token)
@@ -2373,7 +2405,7 @@ pub fn parse_matcher(&mut self, name_idx: &mut uint) -> Matcher {
         return spanned(lo, self.span.hi, m);
     }
 
-    // parse a prefix-operator expr
+    /// Parse a prefix-operator expr
     pub fn parse_prefix_expr(&mut self) -> Gc<Expr> {
         let lo = self.span.lo;
         let hi;
@@ -2400,7 +2432,6 @@ pub fn parse_prefix_expr(&mut self) -> Gc<Expr> {
           }
           token::BINOP(token::AND) | token::ANDAND => {
             self.expect_and();
-            let _lt = self.parse_opt_lifetime();
             let m = self.parse_mutability();
             let e = self.parse_prefix_expr();
             hi = e.span.hi;
@@ -2482,13 +2513,13 @@ pub fn parse_prefix_expr(&mut self) -> Gc<Expr> {
         return self.mk_expr(lo, hi, ex);
     }
 
-    // parse an expression of binops
+    /// Parse an expression of binops
     pub fn parse_binops(&mut self) -> Gc<Expr> {
         let prefix_expr = self.parse_prefix_expr();
         self.parse_more_binops(prefix_expr, 0)
     }
 
-    // parse an expression of binops of at least min_prec precedence
+    /// Parse an expression of binops of at least min_prec precedence
     pub fn parse_more_binops(&mut self, lhs: Gc<Expr>,
                              min_prec: uint) -> Gc<Expr> {
         if self.expr_is_complete(lhs) { return lhs; }
@@ -2536,9 +2567,9 @@ pub fn parse_more_binops(&mut self, lhs: Gc<Expr>,
         }
     }
 
-    // parse an assignment expression....
-    // actually, this seems to be the main entry point for
-    // parsing an arbitrary expression.
+    /// Parse an assignment expression....
+    /// actually, this seems to be the main entry point for
+    /// parsing an arbitrary expression.
     pub fn parse_assign_expr(&mut self) -> Gc<Expr> {
         let lo = self.span.lo;
         let lhs = self.parse_binops();
@@ -2572,7 +2603,7 @@ pub fn parse_assign_expr(&mut self) -> Gc<Expr> {
         }
     }
 
-    // parse an 'if' expression ('if' token already eaten)
+    /// Parse an 'if' expression ('if' token already eaten)
     pub fn parse_if_expr(&mut self) -> Gc<Expr> {
         let lo = self.last_span.lo;
         let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
@@ -2587,7 +2618,7 @@ pub fn parse_if_expr(&mut self) -> Gc<Expr> {
         self.mk_expr(lo, hi, ExprIf(cond, thn, els))
     }
 
-    // `|args| { ... }` or `{ ...}` like in `do` expressions
+    /// `|args| { ... }` or `{ ...}` like in `do` expressions
     pub fn parse_lambda_block_expr(&mut self) -> Gc<Expr> {
         self.parse_lambda_expr_(
             |p| {
@@ -2616,15 +2647,15 @@ pub fn parse_lambda_block_expr(&mut self) -> Gc<Expr> {
             })
     }
 
-    // `|args| expr`
+    /// `|args| expr`
     pub fn parse_lambda_expr(&mut self) -> Gc<Expr> {
         self.parse_lambda_expr_(|p| p.parse_fn_block_decl(),
                                 |p| p.parse_expr())
     }
 
-    // parse something of the form |args| expr
-    // this is used both in parsing a lambda expr
-    // and in parsing a block expr as e.g. in for...
+    /// parse something of the form |args| expr
+    /// this is used both in parsing a lambda expr
+    /// and in parsing a block expr as e.g. in for...
     pub fn parse_lambda_expr_(&mut self,
                               parse_decl: |&mut Parser| -> P<FnDecl>,
                               parse_body: |&mut Parser| -> Gc<Expr>)
@@ -2653,7 +2684,7 @@ pub fn parse_else_expr(&mut self) -> Gc<Expr> {
         }
     }
 
-    // parse a 'for' .. 'in' expression ('for' token already eaten)
+    /// Parse a 'for' .. 'in' expression ('for' token already eaten)
     pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> {
         // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
 
@@ -2719,12 +2750,12 @@ fn parse_match_expr(&mut self) -> Gc<Expr> {
         return self.mk_expr(lo, hi, ExprMatch(discriminant, arms));
     }
 
-    // parse an expression
+    /// Parse an expression
     pub fn parse_expr(&mut self) -> Gc<Expr> {
         return self.parse_expr_res(UNRESTRICTED);
     }
 
-    // parse an expression, subject to the given restriction
+    /// Parse an expression, subject to the given restriction
     pub fn parse_expr_res(&mut self, r: restriction) -> Gc<Expr> {
         let old = self.restriction;
         self.restriction = r;
@@ -2733,7 +2764,7 @@ pub fn parse_expr_res(&mut self, r: restriction) -> Gc<Expr> {
         return e;
     }
 
-    // parse the RHS of a local variable declaration (e.g. '= 14;')
+    /// Parse the RHS of a local variable declaration (e.g. '= 14;')
     fn parse_initializer(&mut self) -> Option<Gc<Expr>> {
         if self.token == token::EQ {
             self.bump();
@@ -2743,7 +2774,7 @@ fn parse_initializer(&mut self) -> Option<Gc<Expr>> {
         }
     }
 
-    // parse patterns, separated by '|' s
+    /// Parse patterns, separated by '|' s
     fn parse_pats(&mut self) -> Vec<Gc<Pat>> {
         let mut pats = Vec::new();
         loop {
@@ -2806,7 +2837,7 @@ fn parse_pat_vec_elements(
         (before, slice, after)
     }
 
-    // parse the fields of a struct-like pattern
+    /// Parse the fields of a struct-like pattern
     fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
         let mut fields = Vec::new();
         let mut etc = false;
@@ -2823,7 +2854,7 @@ fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
             if self.token == token::DOTDOT {
                 self.bump();
                 if self.token != token::RBRACE {
-                    let token_str = self.this_token_to_str();
+                    let token_str = self.this_token_to_string();
                     self.fatal(format!("expected `{}`, found `{}`", "}",
                                        token_str).as_slice())
                 }
@@ -2844,7 +2875,7 @@ fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
             let subpat = if self.token == token::COLON {
                 match bind_type {
                     BindByRef(..) | BindByValue(MutMutable) => {
-                        let token_str = self.this_token_to_str();
+                        let token_str = self.this_token_to_string();
                         self.fatal(format!("unexpected `{}`",
                                            token_str).as_slice())
                     }
@@ -2866,7 +2897,7 @@ fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
         return (fields, etc);
     }
 
-    // parse a pattern.
+    /// Parse a pattern.
     pub fn parse_pat(&mut self) -> Gc<Pat> {
         maybe_whole!(self, NtPat);
 
@@ -3108,9 +3139,9 @@ pub fn parse_pat(&mut self) -> Gc<Pat> {
         }
     }
 
-    // parse ident or ident @ pat
-    // used by the copy foo and ref foo patterns to give a good
-    // error message when parsing mistakes like ref foo(a,b)
+    /// Parse ident or ident @ pat
+    /// used by the copy foo and ref foo patterns to give a good
+    /// error message when parsing mistakes like ref foo(a,b)
     fn parse_pat_ident(&mut self,
                        binding_mode: ast::BindingMode)
                        -> ast::Pat_ {
@@ -3119,8 +3150,9 @@ fn parse_pat_ident(&mut self,
             self.span_fatal(last_span,
                             "expected identifier, found path");
         }
-        // why a path here, and not just an identifier?
-        let name = codemap::Spanned{span: self.last_span, node: self.parse_ident()};
+        let ident = self.parse_ident();
+        let last_span = self.last_span;
+        let name = codemap::Spanned{span: last_span, node: ident};
         let sub = if self.eat(&token::AT) {
             Some(self.parse_pat())
         } else {
@@ -3143,7 +3175,7 @@ fn parse_pat_ident(&mut self,
         PatIdent(binding_mode, name, sub)
     }
 
-    // parse a local variable declaration
+    /// Parse a local variable declaration
     fn parse_local(&mut self) -> Gc<Local> {
         let lo = self.span.lo;
         let pat = self.parse_pat();
@@ -3167,14 +3199,14 @@ fn parse_local(&mut self) -> Gc<Local> {
         }
     }
 
-    // parse a "let" stmt
+    /// Parse a "let" stmt
     fn parse_let(&mut self) -> Gc<Decl> {
         let lo = self.span.lo;
         let local = self.parse_local();
         box(GC) spanned(lo, self.last_span.hi, DeclLocal(local))
     }
 
-    // parse a structure field
+    /// Parse a structure field
     fn parse_name_and_ty(&mut self, pr: Visibility,
                          attrs: Vec<Attribute> ) -> StructField {
         let lo = self.span.lo;
@@ -3192,8 +3224,8 @@ fn parse_name_and_ty(&mut self, pr: Visibility,
         })
     }
 
-    // parse a statement. may include decl.
-    // precondition: any attributes are parsed already
+    /// Parse a statement. may include decl.
+    /// Precondition: any attributes are parsed already
     pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> Gc<Stmt> {
         maybe_whole!(self, NtStmt);
 
@@ -3214,18 +3246,7 @@ fn check_expected_item(p: &mut Parser, found_attrs: bool) {
         } else if is_ident(&self.token)
             && !token::is_any_keyword(&self.token)
             && self.look_ahead(1, |t| *t == token::NOT) {
-            // parse a macro invocation. Looks like there's serious
-            // overlap here; if this clause doesn't catch it (and it
-            // won't, for brace-delimited macros) it will fall through
-            // to the macro clause of parse_item_or_view_item. This
-            // could use some cleanup, it appears to me.
-
-            // whoops! I now have a guess: I'm guessing the "parens-only"
-            // rule here is deliberate, to allow macro users to use parens
-            // for things that should be parsed as stmt_mac, and braces
-            // for things that should expand into items. Tricky, and
-            // somewhat awkward... and probably undocumented. Of course,
-            // I could just be wrong.
+            // it's a macro invocation:
 
             check_expected_item(self, !item_attrs.is_empty());
 
@@ -3253,7 +3274,7 @@ fn check_expected_item(p: &mut Parser, found_attrs: bool) {
                     } else {
                         ""
                     };
-                    let tok_str = self.this_token_to_str();
+                    let tok_str = self.this_token_to_string();
                     self.fatal(format!("expected {}`(` or `{{`, but found `{}`",
                                        ident_str,
                                        tok_str).as_slice())
@@ -3308,13 +3329,13 @@ fn check_expected_item(p: &mut Parser, found_attrs: bool) {
         }
     }
 
-    // is this expression a successfully-parsed statement?
+    /// Is this expression a successfully-parsed statement?
     fn expr_is_complete(&mut self, e: Gc<Expr>) -> bool {
         return self.restriction == RESTRICT_STMT_EXPR &&
             !classify::expr_requires_semi_to_be_stmt(e);
     }
 
-    // parse a block. No inner attrs are allowed.
+    /// Parse a block. No inner attrs are allowed.
     pub fn parse_block(&mut self) -> P<Block> {
         maybe_whole!(no_clone self, NtBlock);
 
@@ -3324,7 +3345,7 @@ pub fn parse_block(&mut self) -> P<Block> {
         return self.parse_block_tail_(lo, DefaultBlock, Vec::new());
     }
 
-    // parse a block. Inner attrs are allowed.
+    /// Parse a block. Inner attrs are allowed.
     fn parse_inner_attrs_and_block(&mut self)
         -> (Vec<Attribute> , P<Block>) {
 
@@ -3337,15 +3358,15 @@ fn parse_inner_attrs_and_block(&mut self)
         (inner, self.parse_block_tail_(lo, DefaultBlock, next))
     }
 
-    // Precondition: already parsed the '{' or '#{'
-    // I guess that also means "already parsed the 'impure'" if
-    // necessary, and this should take a qualifier.
-    // some blocks start with "#{"...
+    /// Precondition: already parsed the '{' or '#{'
+    /// I guess that also means "already parsed the 'impure'" if
+    /// necessary, and this should take a qualifier.
+    /// Some blocks start with "#{"...
     fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
         self.parse_block_tail_(lo, s, Vec::new())
     }
 
-    // parse the rest of a block expression or function body
+    /// Parse the rest of a block expression or function body
     fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
                          first_item_attrs: Vec<Attribute> ) -> P<Block> {
         let mut stmts = Vec::new();
@@ -3503,18 +3524,18 @@ fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy {
         }
     }
 
-    // matches bounds    = ( boundseq )?
-    // where   boundseq  = ( bound + boundseq ) | bound
-    // and     bound     = 'static | ty
-    // Returns "None" if there's no colon (e.g. "T");
-    // Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
-    // Returns "Some(stuff)" otherwise (e.g. "T:stuff").
-    // NB: The None/Some distinction is important for issue #7264.
-    //
-    // Note that the `allow_any_lifetime` argument is a hack for now while the
-    // AST doesn't support arbitrary lifetimes in bounds on type parameters. In
-    // the future, this flag should be removed, and the return value of this
-    // function should be Option<~[TyParamBound]>
+    /// matches optbounds = ( ( : ( boundseq )? )? )
+    /// where   boundseq  = ( bound + boundseq ) | bound
+    /// and     bound     = 'static | ty
+    /// Returns "None" if there's no colon (e.g. "T");
+    /// Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
+    /// Returns "Some(stuff)" otherwise (e.g. "T:stuff").
+    /// NB: The None/Some distinction is important for issue #7264.
+    ///
+    /// Note that the `allow_any_lifetime` argument is a hack for now while the
+    /// AST doesn't support arbitrary lifetimes in bounds on type parameters. In
+    /// the future, this flag should be removed, and the return value of this
+    /// function should be Option<~[TyParamBound]>
     fn parse_ty_param_bounds(&mut self, allow_any_lifetime: bool)
                              -> (Option<ast::Lifetime>,
                                  OwnedSlice<TyParamBound>) {
@@ -3564,11 +3585,40 @@ fn parse_ty_param_bounds(&mut self, allow_any_lifetime: bool)
         return (ret_lifetime, OwnedSlice::from_vec(result));
     }
 
-    // matches typaram = type? IDENT optbounds ( EQ ty )?
+    fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef {
+        let segment = ast::PathSegment {
+            identifier: ident,
+            lifetimes: Vec::new(),
+            types: OwnedSlice::empty(),
+        };
+        let path = ast::Path {
+            span: span,
+            global: false,
+            segments: vec![segment],
+        };
+        ast::TraitRef {
+            path: path,
+            ref_id: ast::DUMMY_NODE_ID,
+        }
+    }
+
+    /// Matches typaram = (unbound`?`)? IDENT optbounds ( EQ ty )?
     fn parse_ty_param(&mut self) -> TyParam {
-        let sized = self.parse_sized();
-        let span = self.span;
-        let ident = self.parse_ident();
+        // This is a bit hacky. Currently we are only interested in a single
+        // unbound, and it may only be `Sized`. To avoid backtracking and other
+        // complications, we parse an ident, then check for `?`. If we find it,
+        // we use the ident as the unbound, otherwise, we use it as the name of
+        // type param.
+        let mut span = self.span;
+        let mut ident = self.parse_ident();
+        let mut unbound = None;
+        if self.eat(&token::QUESTION) {
+            let tref = Parser::trait_ref_from_ident(ident, span);
+            unbound = Some(TraitTyParamBound(tref));
+            span = self.span;
+            ident = self.parse_ident();
+        }
+
         let opt_bounds = {
             if self.eat(&token::COLON) {
                 let (_, bounds) = self.parse_ty_param_bounds(false);
@@ -3589,17 +3639,17 @@ fn parse_ty_param(&mut self) -> TyParam {
         TyParam {
             ident: ident,
             id: ast::DUMMY_NODE_ID,
-            sized: sized,
             bounds: bounds,
+            unbound: unbound,
             default: default,
             span: span,
         }
     }
 
-    // parse a set of optional generic type parameter declarations
-    // matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
-    //                  | ( < lifetimes , typaramseq ( , )? > )
-    // where   typaramseq = ( typaram ) | ( typaram , typaramseq )
+    /// Parse a set of optional generic type parameter declarations
+    /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
+    ///                  | ( < lifetimes , typaramseq ( , )? > )
+    /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
     pub fn parse_generics(&mut self) -> ast::Generics {
         if self.eat(&token::LT) {
             let lifetimes = self.parse_lifetimes();
@@ -3691,7 +3741,7 @@ fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
         (args, variadic)
     }
 
-    // parse the argument list and result type of a function declaration
+    /// Parse the argument list and result type of a function declaration
     pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P<FnDecl> {
 
         let (args, variadic) = self.parse_fn_args(true, allow_variadic);
@@ -3712,17 +3762,22 @@ fn is_self_ident(&mut self) -> bool {
         }
     }
 
-    fn expect_self_ident(&mut self) {
-        if !self.is_self_ident() {
-            let token_str = self.this_token_to_str();
-            self.fatal(format!("expected `self` but found `{}`",
-                               token_str).as_slice())
+    fn expect_self_ident(&mut self) -> ast::Ident {
+        match self.token {
+            token::IDENT(id, false) if id.name == special_idents::self_.name => {
+                self.bump();
+                id
+            },
+            _ => {
+                let token_str = self.this_token_to_string();
+                self.fatal(format!("expected `self` but found `{}`",
+                                   token_str).as_slice())
+            }
         }
-        self.bump();
     }
 
-    // parse the argument list and result type of a function
-    // that may have a self type.
+    /// Parse the argument list and result type of a function
+    /// that may have a self type.
     fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> Arg)
                                -> (ExplicitSelf, P<FnDecl>) {
         fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
@@ -3738,24 +3793,21 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
 
             if this.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
                 this.bump();
-                this.expect_self_ident();
-                SelfRegion(None, MutImmutable)
+                SelfRegion(None, MutImmutable, this.expect_self_ident())
             } else if this.look_ahead(1, |t| Parser::token_is_mutability(t)) &&
                     this.look_ahead(2,
                                     |t| token::is_keyword(keywords::Self,
                                                           t)) {
                 this.bump();
                 let mutability = this.parse_mutability();
-                this.expect_self_ident();
-                SelfRegion(None, mutability)
+                SelfRegion(None, mutability, this.expect_self_ident())
             } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
                        this.look_ahead(2,
                                        |t| token::is_keyword(keywords::Self,
                                                              t)) {
                 this.bump();
                 let lifetime = this.parse_lifetime();
-                this.expect_self_ident();
-                SelfRegion(Some(lifetime), MutImmutable)
+                SelfRegion(Some(lifetime), MutImmutable, this.expect_self_ident())
             } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
                       this.look_ahead(2, |t| {
                           Parser::token_is_mutability(t)
@@ -3765,8 +3817,7 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                 this.bump();
                 let lifetime = this.parse_lifetime();
                 let mutability = this.parse_mutability();
-                this.expect_self_ident();
-                SelfRegion(Some(lifetime), mutability)
+                SelfRegion(Some(lifetime), mutability, this.expect_self_ident())
             } else {
                 SelfStatic
             }
@@ -3786,15 +3837,13 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                 // We need to make sure it isn't a type
                 if self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
                     self.bump();
-                    self.expect_self_ident();
-                    SelfUniq
+                    SelfUniq(self.expect_self_ident())
                 } else {
                     SelfStatic
                 }
             }
             token::IDENT(..) if self.is_self_ident() => {
-                self.bump();
-                SelfValue
+                SelfValue(self.expect_self_ident())
             }
             token::BINOP(token::STAR) => {
                 // Possibly "*self" or "*mut self" -- not supported. Try to avoid
@@ -3808,29 +3857,32 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                     self.span_err(span, "cannot pass self by unsafe pointer");
                     self.bump();
                 }
-                SelfValue
+                // error case, making bogus self ident:
+                SelfValue(special_idents::self_)
             }
             _ if Parser::token_is_mutability(&self.token) &&
                     self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
                 mutbl_self = self.parse_mutability();
-                self.expect_self_ident();
-                SelfValue
+                SelfValue(self.expect_self_ident())
             }
             _ if Parser::token_is_mutability(&self.token) &&
                     self.look_ahead(1, |t| *t == token::TILDE) &&
                     self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
                 mutbl_self = self.parse_mutability();
                 self.bump();
-                self.expect_self_ident();
-                SelfUniq
+                SelfUniq(self.expect_self_ident())
             }
             _ => SelfStatic
         };
 
         let explicit_self_sp = mk_sp(lo, self.span.hi);
 
-        // If we parsed a self type, expect a comma before the argument list.
-        let fn_inputs = if explicit_self != SelfStatic {
+        // shared fall-through for the three cases below. borrowing prevents simply
+        // writing this as a closure
+        macro_rules! parse_remaining_arguments {
+            ($self_id:ident) =>
+            {
+            // If we parsed a self type, expect a comma before the argument list.
             match self.token {
                 token::COMMA => {
                     self.bump();
@@ -3840,23 +3892,33 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                         sep,
                         parse_arg_fn
                     );
-                    fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self));
+                    fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self, $self_id));
                     fn_inputs
                 }
                 token::RPAREN => {
-                    vec!(Arg::new_self(explicit_self_sp, mutbl_self))
+                    vec!(Arg::new_self(explicit_self_sp, mutbl_self, $self_id))
                 }
                 _ => {
-                    let token_str = self.this_token_to_str();
+                    let token_str = self.this_token_to_string();
                     self.fatal(format!("expected `,` or `)`, found `{}`",
                                        token_str).as_slice())
                 }
             }
-        } else {
-            let sep = seq_sep_trailing_disallowed(token::COMMA);
-            self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
+            }
+        }
+
+        let fn_inputs = match explicit_self {
+            SelfStatic =>  {
+                let sep = seq_sep_trailing_disallowed(token::COMMA);
+                self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
+            }
+            SelfValue(id) => parse_remaining_arguments!(id),
+            SelfRegion(_,_,id) => parse_remaining_arguments!(id),
+            SelfUniq(id) => parse_remaining_arguments!(id)
+
         };
 
+
         self.expect(&token::RPAREN);
 
         let hi = self.span.hi;
@@ -3873,7 +3935,7 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
         (spanned(lo, hi, explicit_self), fn_decl)
     }
 
-    // parse the |arg, arg| header on a lambda
+    /// Parse the |arg, arg| header on a lambda
     fn parse_fn_block_decl(&mut self) -> P<FnDecl> {
         let inputs_captures = {
             if self.eat(&token::OROR) {
@@ -3905,7 +3967,7 @@ fn parse_fn_block_decl(&mut self) -> P<FnDecl> {
         })
     }
 
-    // Parses the `(arg, arg) -> return_type` header on a procedure.
+    /// Parses the `(arg, arg) -> return_type` header on a procedure.
     fn parse_proc_decl(&mut self) -> P<FnDecl> {
         let inputs =
             self.parse_unspanned_seq(&token::LPAREN,
@@ -3931,7 +3993,7 @@ fn parse_proc_decl(&mut self) -> P<FnDecl> {
         })
     }
 
-    // parse the name and optional generic types of a function header.
+    /// Parse the name and optional generic types of a function header.
     fn parse_fn_header(&mut self) -> (Ident, ast::Generics) {
         let id = self.parse_ident();
         let generics = self.parse_generics();
@@ -3951,7 +4013,7 @@ fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
         }
     }
 
-    // parse an item-position function declaration.
+    /// Parse an item-position function declaration.
     fn parse_item_fn(&mut self, fn_style: FnStyle, abi: abi::Abi) -> ItemInfo {
         let (ident, generics) = self.parse_fn_header();
         let decl = self.parse_fn_decl(false);
@@ -3959,8 +4021,8 @@ fn parse_item_fn(&mut self, fn_style: FnStyle, abi: abi::Abi) -> ItemInfo {
         (ident, ItemFn(decl, fn_style, abi, generics, body), Some(inner_attrs))
     }
 
-    // parse a method in a trait impl, starting with `attrs` attributes.
-    fn parse_method(&mut self,
+    /// Parse a method in a trait impl, starting with `attrs` attributes.
+    pub fn parse_method(&mut self,
                     already_parsed_attrs: Option<Vec<Attribute>>) -> Gc<Method> {
         let next_attrs = self.parse_outer_attributes();
         let attrs = match already_parsed_attrs {
@@ -3970,32 +4032,54 @@ fn parse_method(&mut self,
 
         let lo = self.span.lo;
 
-        let visa = self.parse_visibility();
-        let fn_style = self.parse_fn_style();
-        let ident = self.parse_ident();
-        let generics = self.parse_generics();
-        let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
-            p.parse_arg()
-        });
+        // code copied from parse_macro_use_or_failure... abstraction!
+        let (method_, hi, new_attrs) = {
+            if !token::is_any_keyword(&self.token)
+                && self.look_ahead(1, |t| *t == token::NOT)
+                && (self.look_ahead(2, |t| *t == token::LPAREN)
+                    || self.look_ahead(2, |t| *t == token::LBRACE)) {
+                // method macro.
+                let pth = self.parse_path(NoTypesAllowed).path;
+                self.expect(&token::NOT);
 
-        let (inner_attrs, body) = self.parse_inner_attrs_and_block();
-        let hi = body.span.hi;
-        let attrs = attrs.append(inner_attrs.as_slice());
+                // eat a matched-delimiter token tree:
+                let tts = match token::close_delimiter_for(&self.token) {
+                    Some(ket) => {
+                        self.bump();
+                        self.parse_seq_to_end(&ket,
+                                              seq_sep_none(),
+                                              |p| p.parse_token_tree())
+                    }
+                    None => self.fatal("expected open delimiter")
+                };
+                let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
+                let m: ast::Mac = codemap::Spanned { node: m_,
+                                                 span: mk_sp(self.span.lo,
+                                                             self.span.hi) };
+                (ast::MethMac(m), self.span.hi, attrs)
+            } else {
+                let visa = self.parse_visibility();
+                let fn_style = self.parse_fn_style();
+                let ident = self.parse_ident();
+                let generics = self.parse_generics();
+                let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
+                        p.parse_arg()
+                    });
+                let (inner_attrs, body) = self.parse_inner_attrs_and_block();
+                let new_attrs = attrs.append(inner_attrs.as_slice());
+                (ast::MethDecl(ident, generics, explicit_self, fn_style, decl, body, visa),
+                 body.span.hi, new_attrs)
+            }
+        };
         box(GC) ast::Method {
-            ident: ident,
-            attrs: attrs,
-            generics: generics,
-            explicit_self: explicit_self,
-            fn_style: fn_style,
-            decl: decl,
-            body: body,
+            attrs: new_attrs,
             id: ast::DUMMY_NODE_ID,
             span: mk_sp(lo, hi),
-            vis: visa,
+            node: method_,
         }
     }
 
-    // parse trait Foo { ... }
+    /// Parse trait Foo { ... }
     fn parse_item_trait(&mut self) -> ItemInfo {
         let ident = self.parse_ident();
         let tps = self.parse_generics();
@@ -4014,9 +4098,9 @@ fn parse_item_trait(&mut self) -> ItemInfo {
         (ident, ItemTrait(tps, sized, traits, meths), None)
     }
 
-    // Parses two variants (with the region/type params always optional):
-    //    impl<T> Foo { ... }
-    //    impl<T> ToStr for ~[T] { ... }
+    /// Parses two variants (with the region/type params always optional):
+    ///    impl<T> Foo { ... }
+    ///    impl<T> ToString for ~[T] { ... }
     fn parse_item_impl(&mut self) -> ItemInfo {
         // First, parse type parameters if necessary.
         let generics = self.parse_generics();
@@ -4069,7 +4153,7 @@ fn parse_item_impl(&mut self) -> ItemInfo {
         (ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs))
     }
 
-    // parse a::B<String,int>
+    /// Parse a::B<String,int>
     fn parse_trait_ref(&mut self) -> TraitRef {
         ast::TraitRef {
             path: self.parse_path(LifetimeAndTypesWithoutColons).path,
@@ -4077,7 +4161,7 @@ fn parse_trait_ref(&mut self) -> TraitRef {
         }
     }
 
-    // parse B + C<String,int> + D
+    /// Parse B + C<String,int> + D
     fn parse_trait_ref_list(&mut self, ket: &token::Token) -> Vec<TraitRef> {
         self.parse_seq_to_before_end(
             ket,
@@ -4086,7 +4170,7 @@ fn parse_trait_ref_list(&mut self, ket: &token::Token) -> Vec<TraitRef> {
         )
     }
 
-    // parse struct Foo { ... }
+    /// Parse struct Foo { ... }
     fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
         let class_name = self.parse_ident();
         let generics = self.parse_generics();
@@ -4151,7 +4235,7 @@ fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
             is_tuple_like = true;
             fields = Vec::new();
         } else {
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             self.fatal(format!("expected `{}`, `(`, or `;` after struct \
                                 name but found `{}`", "{",
                                token_str).as_slice())
@@ -4169,7 +4253,7 @@ fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
          None)
     }
 
-    // parse a structure field declaration
+    /// Parse a structure field declaration
     pub fn parse_single_struct_field(&mut self,
                                      vis: Visibility,
                                      attrs: Vec<Attribute> )
@@ -4182,7 +4266,7 @@ pub fn parse_single_struct_field(&mut self,
             token::RBRACE => {}
             _ => {
                 let span = self.span;
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 self.span_fatal(span,
                                 format!("expected `,`, or `}}` but found `{}`",
                                         token_str).as_slice())
@@ -4191,7 +4275,7 @@ pub fn parse_single_struct_field(&mut self,
         a_var
     }
 
-    // parse an element of a struct definition
+    /// Parse an element of a struct definition
     fn parse_struct_decl_field(&mut self) -> StructField {
 
         let attrs = self.parse_outer_attributes();
@@ -4203,32 +4287,30 @@ fn parse_struct_decl_field(&mut self) -> StructField {
         return self.parse_single_struct_field(Inherited, attrs);
     }
 
-    // parse visiility: PUB, PRIV, or nothing
+    /// Parse visiility: PUB, PRIV, or nothing
     fn parse_visibility(&mut self) -> Visibility {
         if self.eat_keyword(keywords::Pub) { Public }
         else { Inherited }
     }
 
-    fn parse_sized(&mut self) -> Sized {
-        if self.eat_keyword(keywords::Type) { DynSize }
-        else { StaticSize }
-    }
-
-    fn parse_for_sized(&mut self) -> Sized {
+    fn parse_for_sized(&mut self) -> Option<ast::TyParamBound> {
         if self.eat_keyword(keywords::For) {
-            if !self.eat_keyword(keywords::Type) {
-                let last_span = self.last_span;
-                self.span_err(last_span,
-                    "expected 'type' after for in trait item");
+            let span = self.span;
+            let ident = self.parse_ident();
+            if !self.eat(&token::QUESTION) {
+                self.span_err(span,
+                    "expected 'Sized?' after `for` in trait item");
+                return None;
             }
-            DynSize
+            let tref = Parser::trait_ref_from_ident(ident, span);
+            Some(TraitTyParamBound(tref))
         } else {
-            StaticSize
+            None
         }
     }
 
-    // given a termination token and a vector of already-parsed
-    // attributes (of length 0 or 1), parse all of the items in a module
+    /// Given a termination token and a vector of already-parsed
+    /// attributes (of length 0 or 1), parse all of the items in a module
     fn parse_mod_items(&mut self,
                        term: token::Token,
                        first_item_attrs: Vec<Attribute>,
@@ -4265,7 +4347,7 @@ fn parse_mod_items(&mut self,
                                  the module");
               }
               _ => {
-                  let token_str = self.this_token_to_str();
+                  let token_str = self.this_token_to_string();
                   self.fatal(format!("expected item but found `{}`",
                                      token_str).as_slice())
               }
@@ -4296,7 +4378,7 @@ fn parse_item_const(&mut self) -> ItemInfo {
         (id, ItemStatic(ty, m, e), None)
     }
 
-    // parse a `mod <foo> { ... }` or `mod <foo>;` item
+    /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
     fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> ItemInfo {
         let id_span = self.span;
         let id = self.parse_ident();
@@ -4334,7 +4416,7 @@ fn pop_mod_path(&mut self) {
         self.mod_path_stack.pop().unwrap();
     }
 
-    // read a module from a source file.
+    /// Read a module from a source file.
     fn eval_src_mod(&mut self,
                     id: ast::Ident,
                     outer_attrs: &[ast::Attribute],
@@ -4442,7 +4524,7 @@ fn eval_src_mod_from_path(&mut self,
         return (ast::ItemMod(m0), mod_attrs);
     }
 
-    // parse a function declaration from a foreign module
+    /// Parse a function declaration from a foreign module
     fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
                              attrs: Vec<Attribute>) -> Gc<ForeignItem> {
         let lo = self.span.lo;
@@ -4460,7 +4542,7 @@ fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
                                    vis: vis }
     }
 
-    // parse a static item from a foreign module
+    /// Parse a static item from a foreign module
     fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
                                  attrs: Vec<Attribute> ) -> Gc<ForeignItem> {
         let lo = self.span.lo;
@@ -4483,7 +4565,7 @@ fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
         }
     }
 
-    // parse safe/unsafe and fn
+    /// Parse safe/unsafe and fn
     fn parse_fn_style(&mut self) -> FnStyle {
         if self.eat_keyword(keywords::Fn) { NormalFn }
         else if self.eat_keyword(keywords::Unsafe) {
@@ -4494,8 +4576,8 @@ fn parse_fn_style(&mut self) -> FnStyle {
     }
 
 
-    // at this point, this is essentially a wrapper for
-    // parse_foreign_items.
+    /// At this point, this is essentially a wrapper for
+    /// parse_foreign_items.
     fn parse_foreign_mod_items(&mut self,
                                abi: abi::Abi,
                                first_item_attrs: Vec<Attribute> )
@@ -4545,7 +4627,7 @@ fn parse_item_extern_crate(&mut self,
             }
             _ => {
                 let span = self.span;
-                let token_str = self.this_token_to_str();
+                let token_str = self.this_token_to_string();
                 self.span_fatal(span,
                                 format!("expected extern crate name but \
                                          found `{}`",
@@ -4596,7 +4678,7 @@ fn parse_item_foreign_mod(&mut self,
         return IoviItem(item);
     }
 
-    // parse type Foo = Bar;
+    /// Parse type Foo = Bar;
     fn parse_item_type(&mut self) -> ItemInfo {
         let ident = self.parse_ident();
         let tps = self.parse_generics();
@@ -4606,8 +4688,8 @@ fn parse_item_type(&mut self) -> ItemInfo {
         (ident, ItemTy(ty, tps), None)
     }
 
-    // parse a structure-like enum variant definition
-    // this should probably be renamed or refactored...
+    /// Parse a structure-like enum variant definition
+    /// this should probably be renamed or refactored...
     fn parse_struct_def(&mut self) -> Gc<StructDef> {
         let mut fields: Vec<StructField> = Vec::new();
         while self.token != token::RBRACE {
@@ -4623,7 +4705,7 @@ fn parse_struct_def(&mut self) -> Gc<StructDef> {
         };
     }
 
-    // parse the part of an "enum" decl following the '{'
+    /// Parse the part of an "enum" decl following the '{'
     fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
         let mut variants = Vec::new();
         let mut all_nullary = true;
@@ -4687,7 +4769,7 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
         ast::EnumDef { variants: variants }
     }
 
-    // parse an "enum" declaration
+    /// Parse an "enum" declaration
     fn parse_item_enum(&mut self) -> ItemInfo {
         let id = self.parse_ident();
         let generics = self.parse_generics();
@@ -4704,14 +4786,13 @@ fn fn_expr_lookahead(tok: &token::Token) -> bool {
         }
     }
 
-    // Parses a string as an ABI spec on an extern type or module. Consumes
-    // the `extern` keyword, if one is found.
+    /// Parses a string as an ABI spec on an extern type or module. Consumes
+    /// the `extern` keyword, if one is found.
     fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
         match self.token {
             token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => {
                 self.bump();
-                let identifier_string = token::get_ident(s);
-                let the_string = identifier_string.get();
+                let the_string = s.as_str();
                 match abi::lookup(the_string) {
                     Some(abi) => Some(abi),
                     None => {
@@ -4731,10 +4812,10 @@ fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
         }
     }
 
-    // parse one of the items or view items allowed by the
-    // flags; on failure, return IoviNone.
-    // NB: this function no longer parses the items inside an
-    // extern crate.
+    /// Parse one of the items or view items allowed by the
+    /// flags; on failure, return IoviNone.
+    /// NB: this function no longer parses the items inside an
+    /// extern crate.
     fn parse_item_or_view_item(&mut self,
                                attrs: Vec<Attribute> ,
                                macros_allowed: bool)
@@ -4803,7 +4884,7 @@ fn parse_item_or_view_item(&mut self,
             }
 
             let span = self.span;
-            let token_str = self.this_token_to_str();
+            let token_str = self.this_token_to_string();
             self.span_fatal(span,
                             format!("expected `{}` or `fn` but found `{}`", "{",
                                     token_str).as_slice());
@@ -4942,7 +5023,7 @@ fn parse_item_or_view_item(&mut self,
         self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
     }
 
-    // parse a foreign item; on failure, return IoviNone.
+    /// Parse a foreign item; on failure, return IoviNone.
     fn parse_foreign_item(&mut self,
                           attrs: Vec<Attribute> ,
                           macros_allowed: bool)
@@ -4965,7 +5046,7 @@ fn parse_foreign_item(&mut self,
         self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
     }
 
-    // this is the fall-through for parsing items.
+    /// This is the fall-through for parsing items.
     fn parse_macro_use_or_failure(
         &mut self,
         attrs: Vec<Attribute> ,
@@ -5049,17 +5130,17 @@ pub fn parse_item(&mut self, attrs: Vec<Attribute> ) -> Option<Gc<Item>> {
         }
     }
 
-    // parse, e.g., "use a::b::{z,y}"
+    /// Parse, e.g., "use a::b::{z,y}"
     fn parse_use(&mut self) -> ViewItem_ {
         return ViewItemUse(self.parse_view_path());
     }
 
 
-    // matches view_path : MOD? IDENT EQ non_global_path
-    // | MOD? non_global_path MOD_SEP LBRACE RBRACE
-    // | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
-    // | MOD? non_global_path MOD_SEP STAR
-    // | MOD? non_global_path
+    /// Matches view_path : MOD? IDENT EQ non_global_path
+    /// | MOD? non_global_path MOD_SEP LBRACE RBRACE
+    /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
+    /// | MOD? non_global_path MOD_SEP STAR
+    /// | MOD? non_global_path
     fn parse_view_path(&mut self) -> Gc<ViewPath> {
         let lo = self.span.lo;
 
@@ -5182,10 +5263,10 @@ fn parse_view_path(&mut self) -> Gc<ViewPath> {
                         ViewPathSimple(last, path, ast::DUMMY_NODE_ID));
     }
 
-    // Parses a sequence of items. Stops when it finds program
-    // text that can't be parsed as an item
-    // - mod_items uses extern_mod_allowed = true
-    // - block_tail_ uses extern_mod_allowed = false
+    /// Parses a sequence of items. Stops when it finds program
+    /// text that can't be parsed as an item
+    /// - mod_items uses extern_mod_allowed = true
+    /// - block_tail_ uses extern_mod_allowed = false
     fn parse_items_and_view_items(&mut self,
                                   first_item_attrs: Vec<Attribute> ,
                                   mut extern_mod_allowed: bool,
@@ -5267,8 +5348,8 @@ fn parse_items_and_view_items(&mut self,
         }
     }
 
-    // Parses a sequence of foreign items. Stops when it finds program
-    // text that can't be parsed as an item
+    /// Parses a sequence of foreign items. Stops when it finds program
+    /// text that can't be parsed as an item
     fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
                            macros_allowed: bool)
         -> ParsedItemsAndViewItems {
@@ -5307,8 +5388,8 @@ fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
         }
     }
 
-    // Parses a source module as a crate. This is the main
-    // entry point for the parser.
+    /// Parses a source module as a crate. This is the main
+    /// entry point for the parser.
     pub fn parse_crate_mod(&mut self) -> Crate {
         let lo = self.span.lo;
         // parse the crate's inner attrs, maybe (oops) one
@@ -5322,16 +5403,17 @@ pub fn parse_crate_mod(&mut self) -> Crate {
             module: m,
             attrs: inner,
             config: self.cfg.clone(),
-            span: mk_sp(lo, self.span.lo)
+            span: mk_sp(lo, self.span.lo),
+            exported_macros: Vec::new(),
         }
     }
 
     pub fn parse_optional_str(&mut self)
                               -> Option<(InternedString, ast::StrStyle)> {
         let (s, style) = match self.token {
-            token::LIT_STR(s) => (self.id_to_interned_str(s), ast::CookedStr),
+            token::LIT_STR(s) => (self.id_to_interned_str(s.ident()), ast::CookedStr),
             token::LIT_STR_RAW(s, n) => {
-                (self.id_to_interned_str(s), ast::RawStr(n))
+                (self.id_to_interned_str(s.ident()), ast::RawStr(n))
             }
             _ => return None
         };
@@ -5346,3 +5428,4 @@ pub fn parse_str(&mut self) -> (InternedString, StrStyle) {
         }
     }
 }
+
index a93e8270d9866c0b12fe791ab2127411b3a43ffb..5839df6702245d0a8a89e241b45a435262ae5b07 100644 (file)
@@ -10,7 +10,6 @@
 
 use ast;
 use ast::{P, Ident, Name, Mrk};
-use ast_util;
 use ext::mtwt;
 use parse::token;
 use util::interner::{RcStr, StrInterner};
@@ -76,32 +75,40 @@ pub enum Token {
     RBRACE,
     POUND,
     DOLLAR,
+    QUESTION,
 
     /* Literals */
-    LIT_BYTE(u8),
-    LIT_CHAR(char),
-    LIT_INT(i64, ast::IntTy),
-    LIT_UINT(u64, ast::UintTy),
-    LIT_INT_UNSUFFIXED(i64),
-    LIT_FLOAT(ast::Ident, ast::FloatTy),
-    LIT_FLOAT_UNSUFFIXED(ast::Ident),
-    LIT_STR(ast::Ident),
-    LIT_STR_RAW(ast::Ident, uint), /* raw str delimited by n hash symbols */
-    LIT_BINARY(Rc<Vec<u8>>),
-    LIT_BINARY_RAW(Rc<Vec<u8>>, uint), /* raw binary str delimited by n hash symbols */
+    LIT_BYTE(Name),
+    LIT_CHAR(Name),
+    LIT_INTEGER(Name),
+    LIT_FLOAT(Name),
+    LIT_STR(Name),
+    LIT_STR_RAW(Name, uint), /* raw str delimited by n hash symbols */
+    LIT_BINARY(Name),
+    LIT_BINARY_RAW(Name, uint), /* raw binary str delimited by n hash symbols */
 
     /* Name components */
-    // an identifier contains an "is_mod_name" boolean,
-    // indicating whether :: follows this token with no
-    // whitespace in between.
-    IDENT(ast::Ident, bool),
+    /// An identifier contains an "is_mod_name" boolean,
+    /// indicating whether :: follows this token with no
+    /// whitespace in between.
+    IDENT(Ident, bool),
     UNDERSCORE,
-    LIFETIME(ast::Ident),
+    LIFETIME(Ident),
 
     /* For interpolation */
     INTERPOLATED(Nonterminal),
+    DOC_COMMENT(Name),
+
+    // Junk. These carry no data because we don't really care about the data
+    // they *would* carry, and don't really want to allocate a new ident for
+    // them. Instead, users could extract that from the associated span.
+
+    /// Whitespace
+    WS,
+    /// Comment
+    COMMENT,
+    SHEBANG(Name),
 
-    DOC_COMMENT(ast::Ident),
     EOF,
 }
 
@@ -114,11 +121,12 @@ pub enum Nonterminal {
     NtPat( Gc<ast::Pat>),
     NtExpr(Gc<ast::Expr>),
     NtTy(  P<ast::Ty>),
-    // see IDENT, above, for meaning of bool in NtIdent:
-    NtIdent(Box<ast::Ident>, bool),
-    NtMeta(Gc<ast::MetaItem>), // stuff inside brackets for attributes
+    /// See IDENT, above, for meaning of bool in NtIdent:
+    NtIdent(Box<Ident>, bool),
+    /// Stuff inside brackets for attributes
+    NtMeta(Gc<ast::MetaItem>),
     NtPath(Box<ast::Path>),
-    NtTT(  Gc<ast::TokenTree>), // needs @ed to break a circularity
+    NtTT(  Gc<ast::TokenTree>), // needs Gc'd to break a circularity
     NtMatchers(Vec<ast::Matcher> )
 }
 
@@ -140,7 +148,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-pub fn binop_to_str(o: BinOp) -> &'static str {
+pub fn binop_to_string(o: BinOp) -> &'static str {
     match o {
       PLUS => "+",
       MINUS => "-",
@@ -155,7 +163,7 @@ pub fn binop_to_str(o: BinOp) -> &'static str {
     }
 }
 
-pub fn to_str(t: &Token) -> String {
+pub fn to_string(t: &Token) -> String {
     match *t {
       EQ => "=".to_string(),
       LT => "<".to_string(),
@@ -168,9 +176,9 @@ pub fn to_str(t: &Token) -> String {
       TILDE => "~".to_string(),
       OROR => "||".to_string(),
       ANDAND => "&&".to_string(),
-      BINOP(op) => binop_to_str(op).to_string(),
+      BINOP(op) => binop_to_string(op).to_string(),
       BINOPEQ(op) => {
-          let mut s = binop_to_str(op).to_string();
+          let mut s = binop_to_string(op).to_string();
           s.push_str("=");
           s
       }
@@ -195,57 +203,32 @@ pub fn to_str(t: &Token) -> String {
       RBRACE => "}".to_string(),
       POUND => "#".to_string(),
       DOLLAR => "$".to_string(),
+      QUESTION => "?".to_string(),
 
       /* Literals */
       LIT_BYTE(b) => {
-          let mut res = String::from_str("b'");
-          (b as char).escape_default(|c| {
-              res.push_char(c);
-          });
-          res.push_char('\'');
-          res
+          format!("b'{}'", b.as_str())
       }
       LIT_CHAR(c) => {
-          let mut res = String::from_str("'");
-          c.escape_default(|c| {
-              res.push_char(c);
-          });
-          res.push_char('\'');
-          res
-      }
-      LIT_INT(i, t) => ast_util::int_ty_to_str(t, Some(i)),
-      LIT_UINT(u, t) => ast_util::uint_ty_to_str(t, Some(u)),
-      LIT_INT_UNSUFFIXED(i) => { (i as u64).to_str() }
-      LIT_FLOAT(s, t) => {
-        let mut body = String::from_str(get_ident(s).get());
-        if body.as_slice().ends_with(".") {
-            body.push_char('0');  // `10.f` is not a float literal
-        }
-        body.push_str(ast_util::float_ty_to_str(t).as_slice());
-        body
+          format!("'{}'", c.as_str())
       }
-      LIT_FLOAT_UNSUFFIXED(s) => {
-        let mut body = String::from_str(get_ident(s).get());
-        if body.as_slice().ends_with(".") {
-            body.push_char('0');  // `10.f` is not a float literal
-        }
-        body
+      LIT_INTEGER(c) | LIT_FLOAT(c) => {
+          c.as_str().to_string()
       }
+
       LIT_STR(s) => {
-          format!("\"{}\"", get_ident(s).get().escape_default())
+          format!("\"{}\"", s.as_str())
       }
       LIT_STR_RAW(s, n) => {
         format!("r{delim}\"{string}\"{delim}",
-                 delim="#".repeat(n), string=get_ident(s))
+                 delim="#".repeat(n), string=s.as_str())
       }
-      LIT_BINARY(ref v) => {
-          format!(
-            "b\"{}\"",
-            v.iter().map(|&b| b as char).collect::<String>().escape_default())
+      LIT_BINARY(v) => {
+          format!("b\"{}\"", v.as_str())
       }
-      LIT_BINARY_RAW(ref s, n) => {
+      LIT_BINARY_RAW(s, n) => {
         format!("br{delim}\"{string}\"{delim}",
-                 delim="#".repeat(n), string=s.as_slice().to_ascii().as_str_ascii())
+                 delim="#".repeat(n), string=s.as_str())
       }
 
       /* Name components */
@@ -256,12 +239,16 @@ pub fn to_str(t: &Token) -> String {
       UNDERSCORE => "_".to_string(),
 
       /* Other */
-      DOC_COMMENT(s) => get_ident(s).get().to_string(),
+      DOC_COMMENT(s) => s.as_str().to_string(),
       EOF => "<eof>".to_string(),
+      WS => " ".to_string(),
+      COMMENT => "/* */".to_string(),
+      SHEBANG(s) => format!("/* shebang: {}*/", s.as_str()),
+
       INTERPOLATED(ref nt) => {
         match nt {
-            &NtExpr(ref e) => ::print::pprust::expr_to_str(&**e),
-            &NtMeta(ref e) => ::print::pprust::meta_item_to_str(&**e),
+            &NtExpr(ref e) => ::print::pprust::expr_to_string(&**e),
+            &NtMeta(ref e) => ::print::pprust::meta_item_to_string(&**e),
             _ => {
                 let mut s = "an interpolated ".to_string();
                 match *nt {
@@ -294,11 +281,8 @@ pub fn can_begin_expr(t: &Token) -> bool {
       TILDE => true,
       LIT_BYTE(_) => true,
       LIT_CHAR(_) => true,
-      LIT_INT(_, _) => true,
-      LIT_UINT(_, _) => true,
-      LIT_INT_UNSUFFIXED(_) => true,
-      LIT_FLOAT(_, _) => true,
-      LIT_FLOAT_UNSUFFIXED(_) => true,
+      LIT_INTEGER(_) => true,
+      LIT_FLOAT(_) => true,
       LIT_STR(_) => true,
       LIT_STR_RAW(_, _) => true,
       LIT_BINARY(_) => true,
@@ -335,11 +319,8 @@ pub fn is_lit(t: &Token) -> bool {
     match *t {
       LIT_BYTE(_) => true,
       LIT_CHAR(_) => true,
-      LIT_INT(_, _) => true,
-      LIT_UINT(_, _) => true,
-      LIT_INT_UNSUFFIXED(_) => true,
-      LIT_FLOAT(_, _) => true,
-      LIT_FLOAT_UNSUFFIXED(_) => true,
+      LIT_INTEGER(_) => true,
+      LIT_FLOAT(_) => true,
       LIT_STR(_) => true,
       LIT_STR_RAW(_, _) => true,
       LIT_BINARY(_) => true,
@@ -363,10 +344,6 @@ pub fn is_plain_ident(t: &Token) -> bool {
     match *t { IDENT(_, false) => true, _ => false }
 }
 
-pub fn is_bar(t: &Token) -> bool {
-    match *t { BINOP(OR) | OROR => true, _ => false }
-}
-
 // Get the first "argument"
 macro_rules! first {
     ( $first:expr, $( $remainder:expr, )* ) => ( $first )
@@ -397,14 +374,19 @@ pub mod keywords {
         $( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )*
     }
 ) => {
-    static STRICT_KEYWORD_START: Name = first!($( $sk_name, )*);
-    static STRICT_KEYWORD_FINAL: Name = last!($( $sk_name, )*);
-    static RESERVED_KEYWORD_START: Name = first!($( $rk_name, )*);
-    static RESERVED_KEYWORD_FINAL: Name = last!($( $rk_name, )*);
+    static STRICT_KEYWORD_START: Name = first!($( Name($sk_name), )*);
+    static STRICT_KEYWORD_FINAL: Name = last!($( Name($sk_name), )*);
+    static RESERVED_KEYWORD_START: Name = first!($( Name($rk_name), )*);
+    static RESERVED_KEYWORD_FINAL: Name = last!($( Name($rk_name), )*);
 
     pub mod special_idents {
-        use ast::Ident;
-        $( pub static $si_static: Ident = Ident { name: $si_name, ctxt: 0 }; )*
+        use ast::{Ident, Name};
+        $( pub static $si_static: Ident = Ident { name: Name($si_name), ctxt: 0 }; )*
+    }
+
+    pub mod special_names {
+        use ast::Name;
+        $( pub static $si_static: Name =  Name($si_name); )*
     }
 
     /**
@@ -415,7 +397,7 @@ pub mod special_idents {
      * the language and may not appear as identifiers.
      */
     pub mod keywords {
-        use ast::Ident;
+        use ast::Name;
 
         pub enum Keyword {
             $( $sk_variant, )*
@@ -423,10 +405,10 @@ pub enum Keyword {
         }
 
         impl Keyword {
-            pub fn to_ident(&self) -> Ident {
+            pub fn to_name(&self) -> Name {
                 match *self {
-                    $( $sk_variant => Ident { name: $sk_name, ctxt: 0 }, )*
-                    $( $rk_variant => Ident { name: $rk_name, ctxt: 0 }, )*
+                    $( $sk_variant => Name($sk_name), )*
+                    $( $rk_variant => Name($rk_name), )*
                 }
             }
         }
@@ -434,7 +416,7 @@ pub fn to_ident(&self) -> Ident {
 
     fn mk_fresh_ident_interner() -> IdentInterner {
         // The indices here must correspond to the numbers in
-        // special_idents, in Keyword to_ident(), and in static
+        // special_idents, in Keyword to_name(), and in static
         // constants below.
         let mut init_vec = Vec::new();
         $(init_vec.push($si_str);)*
@@ -445,8 +427,11 @@ fn mk_fresh_ident_interner() -> IdentInterner {
 }}
 
 // If the special idents get renumbered, remember to modify these two as appropriate
-static SELF_KEYWORD_NAME: Name = 1;
-static STATIC_KEYWORD_NAME: Name = 2;
+pub static SELF_KEYWORD_NAME: Name = Name(SELF_KEYWORD_NAME_NUM);
+static STATIC_KEYWORD_NAME: Name = Name(STATIC_KEYWORD_NAME_NUM);
+
+pub static SELF_KEYWORD_NAME_NUM: u32 = 1;
+static STATIC_KEYWORD_NAME_NUM: u32 = 2;
 
 // NB: leaving holes in the ident table is bad! a different ident will get
 // interned with the id from the hole, but it will be between the min and max
@@ -456,8 +441,8 @@ fn mk_fresh_ident_interner() -> IdentInterner {
     pub mod special_idents {
         // These ones are statics
         (0,                          invalid,                "");
-        (super::SELF_KEYWORD_NAME,   self_,                  "self");
-        (super::STATIC_KEYWORD_NAME, statik,                 "static");
+        (super::SELF_KEYWORD_NAME_NUM,   self_,                  "self");
+        (super::STATIC_KEYWORD_NAME_NUM, statik,                 "static");
         (3,                          static_lifetime,        "'static");
 
         // for matcher NTs
@@ -497,8 +482,8 @@ pub mod keywords {
         (29,                         Ref,        "ref");
         (30,                         Return,     "return");
         // Static and Self are also special idents (prefill de-dupes)
-        (super::STATIC_KEYWORD_NAME, Static,     "static");
-        (super::SELF_KEYWORD_NAME,   Self,       "self");
+        (super::STATIC_KEYWORD_NAME_NUM, Static,     "static");
+        (super::SELF_KEYWORD_NAME_NUM,   Self,       "self");
         (31,                         Struct,     "struct");
         (32,                         Super,      "super");
         (33,                         True,       "true");
@@ -680,49 +665,52 @@ pub fn gensym(s: &str) -> Name {
 
 /// Maps a string to an identifier with an empty syntax context.
 #[inline]
-pub fn str_to_ident(s: &str) -> ast::Ident {
-    ast::Ident::new(intern(s))
+pub fn str_to_ident(s: &str) -> Ident {
+    Ident::new(intern(s))
 }
 
 /// Maps a string to a gensym'ed identifier.
 #[inline]
-pub fn gensym_ident(s: &str) -> ast::Ident {
-    ast::Ident::new(gensym(s))
+pub fn gensym_ident(s: &str) -> Ident {
+    Ident::new(gensym(s))
 }
 
 // create a fresh name that maps to the same string as the old one.
-// note that this guarantees that str_ptr_eq(ident_to_str(src),interner_get(fresh_name(src)));
+// note that this guarantees that str_ptr_eq(ident_to_string(src),interner_get(fresh_name(src)));
 // that is, that the new name and the old one are connected to ptr_eq strings.
-pub fn fresh_name(src: &ast::Ident) -> Name {
+pub fn fresh_name(src: &Ident) -> Name {
     let interner = get_ident_interner();
     interner.gensym_copy(src.name)
     // following: debug version. Could work in final except that it's incompatible with
     // good error messages and uses of struct names in ambiguous could-be-binding
     // locations. Also definitely destroys the guarantee given above about ptr_eq.
     /*let num = rand::task_rng().gen_uint_range(0,0xffff);
-    gensym(format!("{}_{}",ident_to_str(src),num))*/
+    gensym(format!("{}_{}",ident_to_string(src),num))*/
 }
 
 // create a fresh mark.
 pub fn fresh_mark() -> Mrk {
-    gensym("mark")
+    gensym("mark").uint() as u32
 }
 
 // See the macro above about the types of keywords
 
 pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool {
     match *tok {
-        token::IDENT(sid, false) => { kw.to_ident().name == sid.name }
+        token::IDENT(sid, false) => { kw.to_name() == sid.name }
         _ => { false }
     }
 }
 
 pub fn is_any_keyword(tok: &Token) -> bool {
     match *tok {
-        token::IDENT(sid, false) => match sid.name {
-            SELF_KEYWORD_NAME | STATIC_KEYWORD_NAME |
-            STRICT_KEYWORD_START .. RESERVED_KEYWORD_FINAL => true,
-            _ => false,
+        token::IDENT(sid, false) => {
+            let n = sid.name;
+
+               n == SELF_KEYWORD_NAME
+            || n == STATIC_KEYWORD_NAME
+            || STRICT_KEYWORD_START <= n
+            && n <= RESERVED_KEYWORD_FINAL
         },
         _ => false
     }
@@ -730,10 +718,13 @@ pub fn is_any_keyword(tok: &Token) -> bool {
 
 pub fn is_strict_keyword(tok: &Token) -> bool {
     match *tok {
-        token::IDENT(sid, false) => match sid.name {
-            SELF_KEYWORD_NAME | STATIC_KEYWORD_NAME |
-            STRICT_KEYWORD_START .. STRICT_KEYWORD_FINAL => true,
-            _ => false,
+        token::IDENT(sid, false) => {
+            let n = sid.name;
+
+               n == SELF_KEYWORD_NAME
+            || n == STATIC_KEYWORD_NAME
+            || STRICT_KEYWORD_START <= n
+            && n <= STRICT_KEYWORD_FINAL
         },
         _ => false,
     }
@@ -741,9 +732,11 @@ pub fn is_strict_keyword(tok: &Token) -> bool {
 
 pub fn is_reserved_keyword(tok: &Token) -> bool {
     match *tok {
-        token::IDENT(sid, false) => match sid.name {
-            RESERVED_KEYWORD_START .. RESERVED_KEYWORD_FINAL => true,
-            _ => false,
+        token::IDENT(sid, false) => {
+            let n = sid.name;
+
+               RESERVED_KEYWORD_START <= n
+            && n <= RESERVED_KEYWORD_FINAL
         },
         _ => false,
     }
@@ -765,7 +758,7 @@ mod test {
     use ext::mtwt;
 
     fn mark_ident(id : ast::Ident, m : ast::Mrk) -> ast::Ident {
-        ast::Ident{name:id.name,ctxt:mtwt::new_mark(m,id.ctxt)}
+        ast::Ident { name: id.name, ctxt:mtwt::apply_mark(m, id.ctxt) }
     }
 
     #[test] fn mtwt_token_eq_test() {
index 24ab4b38e54b88c585b871c7f3b868ebe398a6c5..fe84eeff4f87faa4b1248903a9eb26583a1e52db 100644 (file)
@@ -8,58 +8,56 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*
- * This pretty-printer is a direct reimplementation of Philip Karlton's
- * Mesa pretty-printer, as described in appendix A of
- *
- *     STAN-CS-79-770: "Pretty Printing", by Derek C. Oppen.
- *     Stanford Department of Computer Science, 1979.
- *
- * The algorithm's aim is to break a stream into as few lines as possible
- * while respecting the indentation-consistency requirements of the enclosing
- * block, and avoiding breaking at silly places on block boundaries, for
- * example, between "x" and ")" in "x)".
- *
- * I am implementing this algorithm because it comes with 20 pages of
- * documentation explaining its theory, and because it addresses the set of
- * concerns I've seen other pretty-printers fall down on. Weirdly. Even though
- * it's 32 years old. What can I say?
- *
- * Despite some redundancies and quirks in the way it's implemented in that
- * paper, I've opted to keep the implementation here as similar as I can,
- * changing only what was blatantly wrong, a typo, or sufficiently
- * non-idiomatic rust that it really stuck out.
- *
- * In particular you'll see a certain amount of churn related to INTEGER vs.
- * CARDINAL in the Mesa implementation. Mesa apparently interconverts the two
- * somewhat readily? In any case, I've used uint for indices-in-buffers and
- * ints for character-sizes-and-indentation-offsets. This respects the need
- * for ints to "go negative" while carrying a pending-calculation balance, and
- * helps differentiate all the numbers flying around internally (slightly).
- *
- * I also inverted the indentation arithmetic used in the print stack, since
- * the Mesa implementation (somewhat randomly) stores the offset on the print
- * stack in terms of margin-col rather than col itself. I store col.
- *
- * I also implemented a small change in the String token, in that I store an
- * explicit length for the string. For most tokens this is just the length of
- * the accompanying string. But it's necessary to permit it to differ, for
- * encoding things that are supposed to "go on their own line" -- certain
- * classes of comment and blank-line -- where relying on adjacent
- * hardbreak-like Break tokens with long blankness indication doesn't actually
- * work. To see why, consider when there is a "thing that should be on its own
- * line" between two long blocks, say functions. If you put a hardbreak after
- * each function (or before each) and the breaking algorithm decides to break
- * there anyways (because the functions themselves are long) you wind up with
- * extra blank lines. If you don't put hardbreaks you can wind up with the
- * "thing which should be on its own line" not getting its own line in the
- * rare case of "really small functions" or such. This re-occurs with comments
- * and explicit blank lines. So in those cases we use a string with a payload
- * we want isolated to a line and an explicit length that's huge, surrounded
- * by two zero-length breaks. The algorithm will try its best to fit it on a
- * line (which it can't) and so naturally place the content on its own line to
- * avoid combining it with other lines and making matters even worse.
- */
+//! This pretty-printer is a direct reimplementation of Philip Karlton's
+//! Mesa pretty-printer, as described in appendix A of
+//!
+//!     STAN-CS-79-770: "Pretty Printing", by Derek C. Oppen.
+//!     Stanford Department of Computer Science, 1979.
+//!
+//! The algorithm's aim is to break a stream into as few lines as possible
+//! while respecting the indentation-consistency requirements of the enclosing
+//! block, and avoiding breaking at silly places on block boundaries, for
+//! example, between "x" and ")" in "x)".
+//!
+//! I am implementing this algorithm because it comes with 20 pages of
+//! documentation explaining its theory, and because it addresses the set of
+//! concerns I've seen other pretty-printers fall down on. Weirdly. Even though
+//! it's 32 years old. What can I say?
+//!
+//! Despite some redundancies and quirks in the way it's implemented in that
+//! paper, I've opted to keep the implementation here as similar as I can,
+//! changing only what was blatantly wrong, a typo, or sufficiently
+//! non-idiomatic rust that it really stuck out.
+//!
+//! In particular you'll see a certain amount of churn related to INTEGER vs.
+//! CARDINAL in the Mesa implementation. Mesa apparently interconverts the two
+//! somewhat readily? In any case, I've used uint for indices-in-buffers and
+//! ints for character-sizes-and-indentation-offsets. This respects the need
+//! for ints to "go negative" while carrying a pending-calculation balance, and
+//! helps differentiate all the numbers flying around internally (slightly).
+//!
+//! I also inverted the indentation arithmetic used in the print stack, since
+//! the Mesa implementation (somewhat randomly) stores the offset on the print
+//! stack in terms of margin-col rather than col itself. I store col.
+//!
+//! I also implemented a small change in the String token, in that I store an
+//! explicit length for the string. For most tokens this is just the length of
+//! the accompanying string. But it's necessary to permit it to differ, for
+//! encoding things that are supposed to "go on their own line" -- certain
+//! classes of comment and blank-line -- where relying on adjacent
+//! hardbreak-like Break tokens with long blankness indication doesn't actually
+//! work. To see why, consider when there is a "thing that should be on its own
+//! line" between two long blocks, say functions. If you put a hardbreak after
+//! each function (or before each) and the breaking algorithm decides to break
+//! there anyways (because the functions themselves are long) you wind up with
+//! extra blank lines. If you don't put hardbreaks you can wind up with the
+//! "thing which should be on its own line" not getting its own line in the
+//! rare case of "really small functions" or such. This re-occurs with comments
+//! and explicit blank lines. So in those cases we use a string with a payload
+//! we want isolated to a line and an explicit length that's huge, surrounded
+//! by two zero-length breaks. The algorithm will try its best to fit it on a
+//! line (which it can't) and so naturally place the content on its own line to
+//! avoid combining it with other lines and making matters even worse.
 
 use std::io;
 use std::string::String;
@@ -186,107 +184,116 @@ pub fn mk_printer(out: Box<io::Writer>, linewidth: uint) -> Printer {
 }
 
 
-/*
- * In case you do not have the paper, here is an explanation of what's going
- * on.
- *
- * There is a stream of input tokens flowing through this printer.
- *
- * The printer buffers up to 3N tokens inside itself, where N is linewidth.
- * Yes, linewidth is chars and tokens are multi-char, but in the worst
- * case every token worth buffering is 1 char long, so it's ok.
- *
- * Tokens are String, Break, and Begin/End to delimit blocks.
- *
- * Begin tokens can carry an offset, saying "how far to indent when you break
- * inside here", as well as a flag indicating "consistent" or "inconsistent"
- * breaking. Consistent breaking means that after the first break, no attempt
- * will be made to flow subsequent breaks together onto lines. Inconsistent
- * is the opposite. Inconsistent breaking example would be, say:
- *
- *  foo(hello, there, good, friends)
- *
- * breaking inconsistently to become
- *
- *  foo(hello, there
- *      good, friends);
- *
- * whereas a consistent breaking would yield:
- *
- *  foo(hello,
- *      there
- *      good,
- *      friends);
- *
- * That is, in the consistent-break blocks we value vertical alignment
- * more than the ability to cram stuff onto a line. But in all cases if it
- * can make a block a one-liner, it'll do so.
- *
- * Carrying on with high-level logic:
- *
- * The buffered tokens go through a ring-buffer, 'tokens'. The 'left' and
- * 'right' indices denote the active portion of the ring buffer as well as
- * describing hypothetical points-in-the-infinite-stream at most 3N tokens
- * apart (i.e. "not wrapped to ring-buffer boundaries"). The paper will switch
- * between using 'left' and 'right' terms to denote the wrapepd-to-ring-buffer
- * and point-in-infinite-stream senses freely.
- *
- * There is a parallel ring buffer, 'size', that holds the calculated size of
- * each token. Why calculated? Because for Begin/End pairs, the "size"
- * includes everything between the pair. That is, the "size" of Begin is
- * actually the sum of the sizes of everything between Begin and the paired
- * End that follows. Since that is arbitrarily far in the future, 'size' is
- * being rewritten regularly while the printer runs; in fact most of the
- * machinery is here to work out 'size' entries on the fly (and give up when
- * they're so obviously over-long that "infinity" is a good enough
- * approximation for purposes of line breaking).
- *
- * The "input side" of the printer is managed as an abstract process called
- * SCAN, which uses 'scan_stack', 'scan_stack_empty', 'top' and 'bottom', to
- * manage calculating 'size'. SCAN is, in other words, the process of
- * calculating 'size' entries.
- *
- * The "output side" of the printer is managed by an abstract process called
- * PRINT, which uses 'print_stack', 'margin' and 'space' to figure out what to
- * do with each token/size pair it consumes as it goes. It's trying to consume
- * the entire buffered window, but can't output anything until the size is >=
- * 0 (sizes are set to negative while they're pending calculation).
- *
- * So SCAN takes input and buffers tokens and pending calculations, while
- * PRINT gobbles up completed calculations and tokens from the buffer. The
- * theory is that the two can never get more than 3N tokens apart, because
- * once there's "obviously" too much data to fit on a line, in a size
- * calculation, SCAN will write "infinity" to the size and let PRINT consume
- * it.
- *
- * In this implementation (following the paper, again) the SCAN process is
- * the method called 'pretty_print', and the 'PRINT' process is the method
- * called 'print'.
- */
+/// In case you do not have the paper, here is an explanation of what's going
+/// on.
+///
+/// There is a stream of input tokens flowing through this printer.
+///
+/// The printer buffers up to 3N tokens inside itself, where N is linewidth.
+/// Yes, linewidth is chars and tokens are multi-char, but in the worst
+/// case every token worth buffering is 1 char long, so it's ok.
+///
+/// Tokens are String, Break, and Begin/End to delimit blocks.
+///
+/// Begin tokens can carry an offset, saying "how far to indent when you break
+/// inside here", as well as a flag indicating "consistent" or "inconsistent"
+/// breaking. Consistent breaking means that after the first break, no attempt
+/// will be made to flow subsequent breaks together onto lines. Inconsistent
+/// is the opposite. Inconsistent breaking example would be, say:
+///
+///  foo(hello, there, good, friends)
+///
+/// breaking inconsistently to become
+///
+///  foo(hello, there
+///      good, friends);
+///
+/// whereas a consistent breaking would yield:
+///
+///  foo(hello,
+///      there
+///      good,
+///      friends);
+///
+/// That is, in the consistent-break blocks we value vertical alignment
+/// more than the ability to cram stuff onto a line. But in all cases if it
+/// can make a block a one-liner, it'll do so.
+///
+/// Carrying on with high-level logic:
+///
+/// The buffered tokens go through a ring-buffer, 'tokens'. The 'left' and
+/// 'right' indices denote the active portion of the ring buffer as well as
+/// describing hypothetical points-in-the-infinite-stream at most 3N tokens
+/// apart (i.e. "not wrapped to ring-buffer boundaries"). The paper will switch
+/// between using 'left' and 'right' terms to denote the wrapepd-to-ring-buffer
+/// and point-in-infinite-stream senses freely.
+///
+/// There is a parallel ring buffer, 'size', that holds the calculated size of
+/// each token. Why calculated? Because for Begin/End pairs, the "size"
+/// includes everything betwen the pair. That is, the "size" of Begin is
+/// actually the sum of the sizes of everything between Begin and the paired
+/// End that follows. Since that is arbitrarily far in the future, 'size' is
+/// being rewritten regularly while the printer runs; in fact most of the
+/// machinery is here to work out 'size' entries on the fly (and give up when
+/// they're so obviously over-long that "infinity" is a good enough
+/// approximation for purposes of line breaking).
+///
+/// The "input side" of the printer is managed as an abstract process called
+/// SCAN, which uses 'scan_stack', 'scan_stack_empty', 'top' and 'bottom', to
+/// manage calculating 'size'. SCAN is, in other words, the process of
+/// calculating 'size' entries.
+///
+/// The "output side" of the printer is managed by an abstract process called
+/// PRINT, which uses 'print_stack', 'margin' and 'space' to figure out what to
+/// do with each token/size pair it consumes as it goes. It's trying to consume
+/// the entire buffered window, but can't output anything until the size is >=
+/// 0 (sizes are set to negative while they're pending calculation).
+///
+/// So SCAN takes input and buffers tokens and pending calculations, while
+/// PRINT gobbles up completed calculations and tokens from the buffer. The
+/// theory is that the two can never get more than 3N tokens apart, because
+/// once there's "obviously" too much data to fit on a line, in a size
+/// calculation, SCAN will write "infinity" to the size and let PRINT consume
+/// it.
+///
+/// In this implementation (following the paper, again) the SCAN process is
+/// the method called 'pretty_print', and the 'PRINT' process is the method
+/// called 'print'.
 pub struct Printer {
     pub out: Box<io::Writer>,
     buf_len: uint,
-    margin: int, // width of lines we're constrained to
-    space: int, // number of spaces left on line
-    left: uint, // index of left side of input stream
-    right: uint, // index of right side of input stream
-    token: Vec<Token> , // ring-buffr stream goes through
-    size: Vec<int> , // ring-buffer of calculated sizes
-    left_total: int, // running size of stream "...left"
-    right_total: int, // running size of stream "...right"
-    // pseudo-stack, really a ring too. Holds the
-    // primary-ring-buffers index of the Begin that started the
-    // current block, possibly with the most recent Break after that
-    // Begin (if there is any) on top of it. Stuff is flushed off the
-    // bottom as it becomes irrelevant due to the primary ring-buffer
-    // advancing.
+    /// Width of lines we're constrained to
+    margin: int,
+    /// Number of spaces left on line
+    space: int,
+    /// Index of left side of input stream
+    left: uint,
+    /// Index of right side of input stream
+    right: uint,
+    /// Ring-buffr stream goes through
+    token: Vec<Token> ,
+    /// Ring-buffer of calculated sizes
+    size: Vec<int> ,
+    /// Running size of stream "...left"
+    left_total: int,
+    /// Running size of stream "...right"
+    right_total: int,
+    /// Pseudo-stack, really a ring too. Holds the
+    /// primary-ring-buffers index of the Begin that started the
+    /// current block, possibly with the most recent Break after that
+    /// Begin (if there is any) on top of it. Stuff is flushed off the
+    /// bottom as it becomes irrelevant due to the primary ring-buffer
+    /// advancing.
     scan_stack: Vec<uint> ,
-    scan_stack_empty: bool, // top==bottom disambiguator
-    top: uint, // index of top of scan_stack
-    bottom: uint, // index of bottom of scan_stack
-    // stack of blocks-in-progress being flushed by print
+    /// Top==bottom disambiguator
+    scan_stack_empty: bool,
+    /// Index of top of scan_stack
+    top: uint,
+    /// Index of bottom of scan_stack
+    bottom: uint,
+    /// Stack of blocks-in-progress being flushed by print
     print_stack: Vec<PrintStackElem> ,
-    // buffered indentation to avoid writing trailing whitespace
+    /// Buffered indentation to avoid writing trailing whitespace
     pending_indentation: int,
 }
 
index 4660bb337ab23e1d46c4d8ad2fb608a214d5804c..615a4489a73de46041e29694a90db51b2776e962 100644 (file)
@@ -88,9 +88,9 @@ pub fn rust_printer_annotated<'a>(writer: Box<io::Writer>,
 
 pub static default_columns: uint = 78u;
 
-// Requires you to pass an input filename and reader so that
-// it can scan the input text for comments and literals to
-// copy forward.
+/// Requires you to pass an input filename and reader so that
+/// it can scan the input text for comments and literals to
+/// copy forward.
 pub fn print_crate<'a>(cm: &'a CodeMap,
                        span_diagnostic: &diagnostic::SpanHandler,
                        krate: &ast::Crate,
@@ -128,7 +128,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
     eof(&mut s.s)
 }
 
-pub fn to_str(f: |&mut State| -> IoResult<()>) -> String {
+pub fn to_string(f: |&mut State| -> IoResult<()>) -> String {
     let mut s = rust_printer(box MemWriter::new());
     f(&mut s).unwrap();
     eof(&mut s.s).unwrap();
@@ -144,66 +144,66 @@ pub fn to_str(f: |&mut State| -> IoResult<()>) -> String {
     }
 }
 
-pub fn ty_to_str(ty: &ast::Ty) -> String {
-    to_str(|s| s.print_type(ty))
+pub fn ty_to_string(ty: &ast::Ty) -> String {
+    to_string(|s| s.print_type(ty))
 }
 
-pub fn pat_to_str(pat: &ast::Pat) -> String {
-    to_str(|s| s.print_pat(pat))
+pub fn pat_to_string(pat: &ast::Pat) -> String {
+    to_string(|s| s.print_pat(pat))
 }
 
-pub fn expr_to_str(e: &ast::Expr) -> String {
-    to_str(|s| s.print_expr(e))
+pub fn expr_to_string(e: &ast::Expr) -> String {
+    to_string(|s| s.print_expr(e))
 }
 
-pub fn lifetime_to_str(e: &ast::Lifetime) -> String {
-    to_str(|s| s.print_lifetime(e))
+pub fn lifetime_to_string(e: &ast::Lifetime) -> String {
+    to_string(|s| s.print_lifetime(e))
 }
 
-pub fn tt_to_str(tt: &ast::TokenTree) -> String {
-    to_str(|s| s.print_tt(tt))
+pub fn tt_to_string(tt: &ast::TokenTree) -> String {
+    to_string(|s| s.print_tt(tt))
 }
 
-pub fn tts_to_str(tts: &[ast::TokenTree]) -> String {
-    to_str(|s| s.print_tts(tts))
+pub fn tts_to_string(tts: &[ast::TokenTree]) -> String {
+    to_string(|s| s.print_tts(tts))
 }
 
-pub fn stmt_to_str(stmt: &ast::Stmt) -> String {
-    to_str(|s| s.print_stmt(stmt))
+pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
+    to_string(|s| s.print_stmt(stmt))
 }
 
-pub fn item_to_str(i: &ast::Item) -> String {
-    to_str(|s| s.print_item(i))
+pub fn item_to_string(i: &ast::Item) -> String {
+    to_string(|s| s.print_item(i))
 }
 
-pub fn generics_to_str(generics: &ast::Generics) -> String {
-    to_str(|s| s.print_generics(generics))
+pub fn generics_to_string(generics: &ast::Generics) -> String {
+    to_string(|s| s.print_generics(generics))
 }
 
-pub fn ty_method_to_str(p: &ast::TypeMethod) -> String {
-    to_str(|s| s.print_ty_method(p))
+pub fn ty_method_to_string(p: &ast::TypeMethod) -> String {
+    to_string(|s| s.print_ty_method(p))
 }
 
-pub fn method_to_str(p: &ast::Method) -> String {
-    to_str(|s| s.print_method(p))
+pub fn method_to_string(p: &ast::Method) -> String {
+    to_string(|s| s.print_method(p))
 }
 
-pub fn fn_block_to_str(p: &ast::FnDecl) -> String {
-    to_str(|s| s.print_fn_block_args(p))
+pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
+    to_string(|s| s.print_fn_block_args(p))
 }
 
-pub fn path_to_str(p: &ast::Path) -> String {
-    to_str(|s| s.print_path(p, false))
+pub fn path_to_string(p: &ast::Path) -> String {
+    to_string(|s| s.print_path(p, false))
 }
 
-pub fn ident_to_str(id: &ast::Ident) -> String {
-    to_str(|s| s.print_ident(*id))
+pub fn ident_to_string(id: &ast::Ident) -> String {
+    to_string(|s| s.print_ident(*id))
 }
 
-pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
+pub fn fun_to_string(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
                   opt_explicit_self: Option<ast::ExplicitSelf_>,
                   generics: &ast::Generics) -> String {
-    to_str(|s| {
+    to_string(|s| {
         try!(s.print_fn(decl, Some(fn_style), abi::Rust,
                         name, generics, opt_explicit_self, ast::Inherited));
         try!(s.end()); // Close the head box
@@ -211,8 +211,8 @@ pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
     })
 }
 
-pub fn block_to_str(blk: &ast::Block) -> String {
-    to_str(|s| {
+pub fn block_to_string(blk: &ast::Block) -> String {
+    to_string(|s| {
         // containing cbox, will be closed by print-block at }
         try!(s.cbox(indent_unit));
         // head-ibox, will be closed by print-block after {
@@ -221,28 +221,32 @@ pub fn block_to_str(blk: &ast::Block) -> String {
     })
 }
 
-pub fn meta_item_to_str(mi: &ast::MetaItem) -> String {
-    to_str(|s| s.print_meta_item(mi))
+pub fn meta_item_to_string(mi: &ast::MetaItem) -> String {
+    to_string(|s| s.print_meta_item(mi))
 }
 
-pub fn attribute_to_str(attr: &ast::Attribute) -> String {
-    to_str(|s| s.print_attribute(attr))
+pub fn attribute_to_string(attr: &ast::Attribute) -> String {
+    to_string(|s| s.print_attribute(attr))
 }
 
-pub fn lit_to_str(l: &ast::Lit) -> String {
-    to_str(|s| s.print_literal(l))
+pub fn lit_to_string(l: &ast::Lit) -> String {
+    to_string(|s| s.print_literal(l))
 }
 
-pub fn explicit_self_to_str(explicit_self: ast::ExplicitSelf_) -> String {
-    to_str(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
+pub fn explicit_self_to_string(explicit_self: ast::ExplicitSelf_) -> String {
+    to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
 }
 
-pub fn variant_to_str(var: &ast::Variant) -> String {
-    to_str(|s| s.print_variant(var))
+pub fn variant_to_string(var: &ast::Variant) -> String {
+    to_string(|s| s.print_variant(var))
 }
 
-pub fn arg_to_str(arg: &ast::Arg) -> String {
-    to_str(|s| s.print_arg(arg))
+pub fn arg_to_string(arg: &ast::Arg) -> String {
+    to_string(|s| s.print_arg(arg))
+}
+
+pub fn mac_to_string(arg: &ast::Mac) -> String {
+    to_string(|s| s.print_mac(arg))
 }
 
 pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String {
@@ -342,6 +346,7 @@ pub fn is_end(&mut self) -> bool {
         match self.s.last_token() { pp::End => true, _ => false }
     }
 
+    // is this the beginning of a line?
     pub fn is_bol(&mut self) -> bool {
         self.s.last_token().is_eof() || self.s.last_token().is_hardbreak_tok()
     }
@@ -627,6 +632,7 @@ pub fn print_foreign_item(&mut self,
         }
     }
 
+    /// Pretty-print an item
     pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(item.span.lo));
@@ -674,7 +680,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
             }
             ast::ItemForeignMod(ref nmod) => {
                 try!(self.head("extern"));
-                try!(self.word_nbsp(nmod.abi.to_str().as_slice()));
+                try!(self.word_nbsp(nmod.abi.to_string().as_slice()));
                 try!(self.bopen());
                 try!(self.print_foreign_mod(nmod, item.attrs.as_slice()));
                 try!(self.bclose(item.span));
@@ -740,14 +746,19 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 }
                 try!(self.bclose(item.span));
             }
-            ast::ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
+            ast::ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
                 try!(self.head(visibility_qualified(item.vis,
                                                     "trait").as_slice()));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(generics));
-                if *sized == ast::DynSize {
-                    try!(space(&mut self.s));
-                    try!(word(&mut self.s, "for type"));
+                match unbound {
+                    &Some(TraitTyParamBound(ref tref)) => {
+                        try!(space(&mut self.s));
+                        try!(self.word_space("for"));
+                        try!(self.print_trait_ref(tref));
+                        try!(word(&mut self.s, "?"));
+                    }
+                    _ => {}
                 }
                 if traits.len() != 0u {
                     try!(word(&mut self.s, ":"));
@@ -893,7 +904,7 @@ pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
         match *tt {
             ast::TTDelim(ref tts) => self.print_tts(tts.as_slice()),
             ast::TTTok(_, ref tk) => {
-                try!(word(&mut self.s, parse::token::to_str(tk).as_slice()));
+                try!(word(&mut self.s, parse::token::to_string(tk).as_slice()));
                 match *tk {
                     parse::token::DOC_COMMENT(..) => {
                         hardbreak(&mut self.s)
@@ -910,7 +921,7 @@ pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
                 match *sep {
                     Some(ref tk) => {
                         try!(word(&mut self.s,
-                                  parse::token::to_str(tk).as_slice()));
+                                  parse::token::to_string(tk).as_slice()));
                     }
                     None => ()
                 }
@@ -993,11 +1004,26 @@ pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(meth.span.lo));
         try!(self.print_outer_attributes(meth.attrs.as_slice()));
-        try!(self.print_fn(&*meth.decl, Some(meth.fn_style), abi::Rust,
-                        meth.ident, &meth.generics, Some(meth.explicit_self.node),
-                        meth.vis));
-        try!(word(&mut self.s, " "));
-        self.print_block_with_attrs(&*meth.body, meth.attrs.as_slice())
+        match meth.node {
+            ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
+                try!(self.print_fn(&*decl, Some(fn_style), abi::Rust,
+                                   ident, generics, Some(explicit_self.node),
+                                   vis));
+                try!(word(&mut self.s, " "));
+                self.print_block_with_attrs(&*body, meth.attrs.as_slice())
+            },
+            ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
+                                            ..}) => {
+                // code copied from ItemMac:
+                try!(self.print_path(pth, false));
+                try!(word(&mut self.s, "! "));
+                try!(self.cbox(indent_unit));
+                try!(self.popen());
+                try!(self.print_tts(tts.as_slice()));
+                try!(self.pclose());
+                self.end()
+            }
+        }
     }
 
     pub fn print_outer_attributes(&mut self,
@@ -1308,11 +1334,11 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
             ast::ExprBinary(op, ref lhs, ref rhs) => {
                 try!(self.print_expr(&**lhs));
                 try!(space(&mut self.s));
-                try!(self.word_space(ast_util::binop_to_str(op)));
+                try!(self.word_space(ast_util::binop_to_string(op)));
                 try!(self.print_expr(&**rhs));
             }
             ast::ExprUnary(op, ref expr) => {
-                try!(word(&mut self.s, ast_util::unop_to_str(op)));
+                try!(word(&mut self.s, ast_util::unop_to_string(op)));
                 try!(self.print_expr_maybe_paren(&**expr));
             }
             ast::ExprAddrOf(m, ref expr) => {
@@ -1488,7 +1514,7 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
             ast::ExprAssignOp(op, ref lhs, ref rhs) => {
                 try!(self.print_expr(&**lhs));
                 try!(space(&mut self.s));
-                try!(word(&mut self.s, ast_util::binop_to_str(op)));
+                try!(word(&mut self.s, ast_util::binop_to_string(op)));
                 try!(self.word_space("="));
                 try!(self.print_expr(&**rhs));
             }
@@ -1745,13 +1771,14 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
             }
             ast::PatStruct(ref path, ref fields, etc) => {
                 try!(self.print_path(path, true));
-                try!(word(&mut self.s, "{"));
+                try!(self.nbsp());
+                try!(self.word_space("{"));
                 try!(self.commasep_cmnt(
                     Consistent, fields.as_slice(),
                     |s, f| {
                         try!(s.cbox(indent_unit));
                         try!(s.print_ident(f.ident));
-                        try!(s.word_space(":"));
+                        try!(s.word_nbsp(":"));
                         try!(s.print_pat(&*f.pat));
                         s.end()
                     },
@@ -1760,6 +1787,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
                     if fields.len() != 0u { try!(self.word_space(",")); }
                     try!(word(&mut self.s, ".."));
                 }
+                try!(space(&mut self.s));
                 try!(word(&mut self.s, "}"));
             }
             ast::PatTup(ref elts) => {
@@ -1820,13 +1848,13 @@ fn print_explicit_self(&mut self,
         try!(self.print_mutability(mutbl));
         match explicit_self {
             ast::SelfStatic => { return Ok(false); }
-            ast::SelfValue => {
+            ast::SelfValue(_) => {
                 try!(word(&mut self.s, "self"));
             }
-            ast::SelfUniq => {
+            ast::SelfUniq(_) => {
                 try!(word(&mut self.s, "~self"));
             }
-            ast::SelfRegion(ref lt, m) => {
+            ast::SelfRegion(ref lt, m, _) => {
                 try!(word(&mut self.s, "&"));
                 try!(self.print_opt_lifetime(lt));
                 try!(self.print_mutability(m));
@@ -2027,8 +2055,12 @@ pub fn print_generics(&mut self,
                     } else {
                         let idx = idx - generics.lifetimes.len();
                         let param = generics.ty_params.get(idx);
-                        if param.sized == ast::DynSize {
-                            try!(s.word_space("type"));
+                        match param.unbound {
+                            Some(TraitTyParamBound(ref tref)) => {
+                                try!(s.print_trait_ref(tref));
+                                try!(s.word_space("?"));
+                            }
+                            _ => {}
                         }
                         try!(s.print_ident(param.ident));
                         try!(s.print_bounds(&None,
@@ -2326,11 +2358,11 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
             }
             ast::LitInt(i, t) => {
                 word(&mut self.s,
-                     ast_util::int_ty_to_str(t, Some(i)).as_slice())
+                     ast_util::int_ty_to_string(t, Some(i)).as_slice())
             }
             ast::LitUint(u, t) => {
                 word(&mut self.s,
-                     ast_util::uint_ty_to_str(t, Some(u)).as_slice())
+                     ast_util::uint_ty_to_string(t, Some(u)).as_slice())
             }
             ast::LitIntUnsuffixed(i) => {
                 word(&mut self.s, format!("{}", i).as_slice())
@@ -2340,7 +2372,7 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
                      format!(
                          "{}{}",
                          f.get(),
-                         ast_util::float_ty_to_str(t).as_slice()).as_slice())
+                         ast_util::float_ty_to_string(t).as_slice()).as_slice())
             }
             ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, f.get()),
             ast::LitNil => word(&mut self.s, "()"),
@@ -2478,7 +2510,7 @@ pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
             Some(abi::Rust) => Ok(()),
             Some(abi) => {
                 try!(self.word_nbsp("extern"));
-                self.word_nbsp(abi.to_str().as_slice())
+                self.word_nbsp(abi.to_string().as_slice())
             }
             None => Ok(())
         }
@@ -2489,7 +2521,7 @@ pub fn print_extern_opt_abi(&mut self,
         match opt_abi {
             Some(abi) => {
                 try!(self.word_nbsp("extern"));
-                self.word_nbsp(abi.to_str().as_slice())
+                self.word_nbsp(abi.to_string().as_slice())
             }
             None => Ok(())
         }
@@ -2505,7 +2537,7 @@ pub fn print_fn_header_info(&mut self,
 
         if abi != abi::Rust {
             try!(self.word_nbsp("extern"));
-            try!(self.word_nbsp(abi.to_str().as_slice()));
+            try!(self.word_nbsp(abi.to_string().as_slice()));
         }
 
         word(&mut self.s, "fn")
@@ -2536,7 +2568,7 @@ mod test {
     use parse::token;
 
     #[test]
-    fn test_fun_to_str() {
+    fn test_fun_to_string() {
         let abba_ident = token::str_to_ident("abba");
 
         let decl = ast::FnDecl {
@@ -2548,13 +2580,13 @@ fn test_fun_to_str() {
             variadic: false
         };
         let generics = ast_util::empty_generics();
-        assert_eq!(&fun_to_str(&decl, ast::NormalFn, abba_ident,
+        assert_eq!(&fun_to_string(&decl, ast::NormalFn, abba_ident,
                                None, &generics),
                    &"fn abba()".to_string());
     }
 
     #[test]
-    fn test_variant_to_str() {
+    fn test_variant_to_string() {
         let ident = token::str_to_ident("principal_skinner");
 
         let var = codemap::respan(codemap::DUMMY_SP, ast::Variant_ {
@@ -2567,7 +2599,7 @@ fn test_variant_to_str() {
             vis: ast::Public,
         });
 
-        let varstr = variant_to_str(&var);
+        let varstr = variant_to_string(&var);
         assert_eq!(&varstr,&"pub principal_skinner".to_string());
     }
 }
index 4d88aaca7486be7994efdb6938fe0e130dfedd08..452b5a5251222ca1a22b1c092c0c52848094e0f9 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// An "interner" is a data structure that associates values with uint tags and
-// allows bidirectional lookup; i.e. given a value, one can easily find the
-// type, and vice versa.
+//! An "interner" is a data structure that associates values with uint tags and
+//! allows bidirectional lookup; i.e. given a value, one can easily find the
+//! type, and vice versa.
 
 use ast::Name;
 
@@ -52,7 +52,7 @@ pub fn intern(&self, val: T) -> Name {
         }
 
         let mut vect = self.vect.borrow_mut();
-        let new_idx = (*vect).len() as Name;
+        let new_idx = Name((*vect).len() as u32);
         (*map).insert(val.clone(), new_idx);
         (*vect).push(val);
         new_idx
@@ -60,7 +60,7 @@ pub fn intern(&self, val: T) -> Name {
 
     pub fn gensym(&self, val: T) -> Name {
         let mut vect = self.vect.borrow_mut();
-        let new_idx = (*vect).len() as Name;
+        let new_idx = Name((*vect).len() as u32);
         // leave out of .map to avoid colliding
         (*vect).push(val);
         new_idx
@@ -68,7 +68,7 @@ pub fn gensym(&self, val: T) -> Name {
 
     pub fn get(&self, idx: Name) -> T {
         let vect = self.vect.borrow();
-        (*(*vect).get(idx as uint)).clone()
+        (*(*vect).get(idx.uint())).clone()
     }
 
     pub fn len(&self) -> uint {
@@ -155,7 +155,7 @@ pub fn intern(&self, val: &str) -> Name {
             None => (),
         }
 
-        let new_idx = self.len() as Name;
+        let new_idx = Name(self.len() as u32);
         let val = RcStr::new(val);
         map.insert(val.clone(), new_idx);
         self.vect.borrow_mut().push(val);
@@ -163,7 +163,7 @@ pub fn intern(&self, val: &str) -> Name {
     }
 
     pub fn gensym(&self, val: &str) -> Name {
-        let new_idx = self.len() as Name;
+        let new_idx = Name(self.len() as u32);
         // leave out of .map to avoid colliding
         self.vect.borrow_mut().push(RcStr::new(val));
         new_idx
@@ -180,23 +180,23 @@ pub fn gensym(&self, val: &str) -> Name {
     /// Create a gensym with the same name as an existing
     /// entry.
     pub fn gensym_copy(&self, idx : Name) -> Name {
-        let new_idx = self.len() as Name;
+        let new_idx = Name(self.len() as u32);
         // leave out of map to avoid colliding
         let mut vect = self.vect.borrow_mut();
-        let existing = (*vect.get(idx as uint)).clone();
+        let existing = (*vect.get(idx.uint())).clone();
         vect.push(existing);
         new_idx
     }
 
     pub fn get(&self, idx: Name) -> RcStr {
-        (*self.vect.borrow().get(idx as uint)).clone()
+        (*self.vect.borrow().get(idx.uint())).clone()
     }
 
     /// Returns this string with lifetime tied to the interner. Since
     /// strings may never be removed from the interner, this is safe.
     pub fn get_ref<'a>(&'a self, idx: Name) -> &'a str {
         let vect = self.vect.borrow();
-        let s: &str = vect.get(idx as uint).as_slice();
+        let s: &str = vect.get(idx.uint()).as_slice();
         unsafe {
             mem::transmute(s)
         }
@@ -222,36 +222,38 @@ pub fn clear(&self) {
 #[cfg(test)]
 mod tests {
     use super::*;
+    use ast::Name;
+
     #[test]
     #[should_fail]
     fn i1 () {
         let i : Interner<RcStr> = Interner::new();
-        i.get(13);
+        i.get(Name(13));
     }
 
     #[test]
     fn interner_tests () {
         let i : Interner<RcStr> = Interner::new();
         // first one is zero:
-        assert_eq!(i.intern(RcStr::new("dog")), 0);
+        assert_eq!(i.intern(RcStr::new("dog")), Name(0));
         // re-use gets the same entry:
-        assert_eq!(i.intern(RcStr::new("dog")), 0);
+        assert_eq!(i.intern(RcStr::new("dog")), Name(0));
         // different string gets a different #:
-        assert_eq!(i.intern(RcStr::new("cat")), 1);
-        assert_eq!(i.intern(RcStr::new("cat")), 1);
+        assert_eq!(i.intern(RcStr::new("cat")), Name(1));
+        assert_eq!(i.intern(RcStr::new("cat")), Name(1));
         // dog is still at zero
-        assert_eq!(i.intern(RcStr::new("dog")), 0);
+        assert_eq!(i.intern(RcStr::new("dog")), Name(0));
         // gensym gets 3
-        assert_eq!(i.gensym(RcStr::new("zebra") ), 2);
+        assert_eq!(i.gensym(RcStr::new("zebra") ), Name(2));
         // gensym of same string gets new number :
-        assert_eq!(i.gensym (RcStr::new("zebra") ), 3);
+        assert_eq!(i.gensym (RcStr::new("zebra") ), Name(3));
         // gensym of *existing* string gets new number:
-        assert_eq!(i.gensym(RcStr::new("dog")), 4);
-        assert_eq!(i.get(0), RcStr::new("dog"));
-        assert_eq!(i.get(1), RcStr::new("cat"));
-        assert_eq!(i.get(2), RcStr::new("zebra"));
-        assert_eq!(i.get(3), RcStr::new("zebra"));
-        assert_eq!(i.get(4), RcStr::new("dog"));
+        assert_eq!(i.gensym(RcStr::new("dog")), Name(4));
+        assert_eq!(i.get(Name(0)), RcStr::new("dog"));
+        assert_eq!(i.get(Name(1)), RcStr::new("cat"));
+        assert_eq!(i.get(Name(2)), RcStr::new("zebra"));
+        assert_eq!(i.get(Name(3)), RcStr::new("zebra"));
+        assert_eq!(i.get(Name(4)), RcStr::new("dog"));
     }
 
     #[test]
@@ -261,39 +263,39 @@ fn i3 () {
             RcStr::new("Bob"),
             RcStr::new("Carol")
         ]);
-        assert_eq!(i.get(0), RcStr::new("Alan"));
-        assert_eq!(i.get(1), RcStr::new("Bob"));
-        assert_eq!(i.get(2), RcStr::new("Carol"));
-        assert_eq!(i.intern(RcStr::new("Bob")), 1);
+        assert_eq!(i.get(Name(0)), RcStr::new("Alan"));
+        assert_eq!(i.get(Name(1)), RcStr::new("Bob"));
+        assert_eq!(i.get(Name(2)), RcStr::new("Carol"));
+        assert_eq!(i.intern(RcStr::new("Bob")), Name(1));
     }
 
     #[test]
     fn string_interner_tests() {
         let i : StrInterner = StrInterner::new();
         // first one is zero:
-        assert_eq!(i.intern("dog"), 0);
+        assert_eq!(i.intern("dog"), Name(0));
         // re-use gets the same entry:
-        assert_eq!(i.intern ("dog"), 0);
+        assert_eq!(i.intern ("dog"), Name(0));
         // different string gets a different #:
-        assert_eq!(i.intern("cat"), 1);
-        assert_eq!(i.intern("cat"), 1);
+        assert_eq!(i.intern("cat"), Name(1));
+        assert_eq!(i.intern("cat"), Name(1));
         // dog is still at zero
-        assert_eq!(i.intern("dog"), 0);
+        assert_eq!(i.intern("dog"), Name(0));
         // gensym gets 3
-        assert_eq!(i.gensym("zebra"), 2);
+        assert_eq!(i.gensym("zebra"), Name(2));
         // gensym of same string gets new number :
-        assert_eq!(i.gensym("zebra"), 3);
+        assert_eq!(i.gensym("zebra"), Name(3));
         // gensym of *existing* string gets new number:
-        assert_eq!(i.gensym("dog"), 4);
+        assert_eq!(i.gensym("dog"), Name(4));
         // gensym tests again with gensym_copy:
-        assert_eq!(i.gensym_copy(2), 5);
-        assert_eq!(i.get(5), RcStr::new("zebra"));
-        assert_eq!(i.gensym_copy(2), 6);
-        assert_eq!(i.get(6), RcStr::new("zebra"));
-        assert_eq!(i.get(0), RcStr::new("dog"));
-        assert_eq!(i.get(1), RcStr::new("cat"));
-        assert_eq!(i.get(2), RcStr::new("zebra"));
-        assert_eq!(i.get(3), RcStr::new("zebra"));
-        assert_eq!(i.get(4), RcStr::new("dog"));
+        assert_eq!(i.gensym_copy(Name(2)), Name(5));
+        assert_eq!(i.get(Name(5)), RcStr::new("zebra"));
+        assert_eq!(i.gensym_copy(Name(2)), Name(6));
+        assert_eq!(i.get(Name(6)), RcStr::new("zebra"));
+        assert_eq!(i.get(Name(0)), RcStr::new("dog"));
+        assert_eq!(i.get(Name(1)), RcStr::new("cat"));
+        assert_eq!(i.get(Name(2)), RcStr::new("zebra"));
+        assert_eq!(i.get(Name(3)), RcStr::new("zebra"));
+        assert_eq!(i.get(Name(4)), RcStr::new("dog"));
     }
 }
index 04116dec60e3113fb1e6b31e5e94da601158f7fd..f50739a7069e05a61d18496e35027ea242a77ef0 100644 (file)
 
 use std::gc::Gc;
 
-// map a string to tts, using a made-up filename:
+/// Map a string to tts, using a made-up filename:
 pub fn string_to_tts(source_str: String) -> Vec<ast::TokenTree> {
     let ps = new_parse_sess();
     filemap_to_tts(&ps,
                    string_to_filemap(&ps, source_str, "bogofile".to_string()))
 }
 
-// map string to parser (via tts)
+/// Map string to parser (via tts)
 pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> {
     new_parser_from_source_str(ps,
                                Vec::new(),
@@ -40,51 +40,51 @@ fn with_error_checking_parse<T>(s: String, f: |&mut Parser| -> T) -> T {
     x
 }
 
-// parse a string, return a crate.
+/// Parse a string, return a crate.
 pub fn string_to_crate (source_str : String) -> ast::Crate {
     with_error_checking_parse(source_str, |p| {
         p.parse_crate_mod()
     })
 }
 
-// parse a string, return an expr
+/// Parse a string, return an expr
 pub fn string_to_expr (source_str : String) -> Gc<ast::Expr> {
     with_error_checking_parse(source_str, |p| {
         p.parse_expr()
     })
 }
 
-// parse a string, return an item
+/// Parse a string, return an item
 pub fn string_to_item (source_str : String) -> Option<Gc<ast::Item>> {
     with_error_checking_parse(source_str, |p| {
         p.parse_item(Vec::new())
     })
 }
 
-// parse a string, return a stmt
+/// Parse a string, return a stmt
 pub fn string_to_stmt(source_str : String) -> Gc<ast::Stmt> {
     with_error_checking_parse(source_str, |p| {
         p.parse_stmt(Vec::new())
     })
 }
 
-// parse a string, return a pat. Uses "irrefutable"... which doesn't
-// (currently) affect parsing.
+/// Parse a string, return a pat. Uses "irrefutable"... which doesn't
+/// (currently) affect parsing.
 pub fn string_to_pat(source_str: String) -> Gc<ast::Pat> {
     string_to_parser(&new_parse_sess(), source_str).parse_pat()
 }
 
-// convert a vector of strings to a vector of ast::Ident's
+/// Convert a vector of strings to a vector of ast::Ident's
 pub fn strs_to_idents(ids: Vec<&str> ) -> Vec<ast::Ident> {
     ids.iter().map(|u| token::str_to_ident(*u)).collect()
 }
 
-// does the given string match the pattern? whitespace in the first string
-// may be deleted or replaced with other whitespace to match the pattern.
-// this function is unicode-ignorant; fortunately, the careful design of
-// UTF-8 mitigates this ignorance.  In particular, this function only collapses
-// sequences of \n, \r, ' ', and \t, but it should otherwise tolerate unicode
-// chars. Unsurprisingly, it doesn't do NKF-normalization(?).
+/// Does the given string match the pattern? whitespace in the first string
+/// may be deleted or replaced with other whitespace to match the pattern.
+/// this function is unicode-ignorant; fortunately, the careful design of
+/// UTF-8 mitigates this ignorance.  In particular, this function only collapses
+/// sequences of \n, \r, ' ', and \t, but it should otherwise tolerate unicode
+/// chars. Unsurprisingly, it doesn't do NKF-normalization(?).
 pub fn matches_codepattern(a : &str, b : &str) -> bool {
     let mut idx_a = 0;
     let mut idx_b = 0;
@@ -122,9 +122,9 @@ pub fn matches_codepattern(a : &str, b : &str) -> bool {
     }
 }
 
-// given a string and an index, return the first uint >= idx
-// that is a non-ws-char or is outside of the legal range of
-// the string.
+/// Given a string and an index, return the first uint >= idx
+/// that is a non-ws-char or is outside of the legal range of
+/// the string.
 fn scan_for_non_ws_or_end(a : &str, idx: uint) -> uint {
     let mut i = idx;
     let len = a.len();
@@ -134,7 +134,7 @@ fn scan_for_non_ws_or_end(a : &str, idx: uint) -> uint {
     i
 }
 
-// copied from lexer.
+/// Copied from lexer.
 pub fn is_whitespace(c: char) -> bool {
     return c == ' ' || c == '\t' || c == '\r' || c == '\n';
 }
index 4ab064a88b7950d3ede7d4ab57d8c05591666205..795f19d0cfb06170050fea6da1206a8e09390189 100644 (file)
@@ -8,6 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Context-passing AST walker. Each overridden visit method has full control
+//! over what happens with its node, it can do its own traversal of the node's
+//! children (potentially passing in different contexts to each), call
+//! `visit::visit_*` to apply the default traversal algorithm (again, it can
+//! override the context), or prevent deeper traversal by doing nothing.
+//!
+//! Note: it is an important invariant that the default visitor walks the body
+//! of a function in "execution order" (more concretely, reverse post-order
+//! with respect to the CFG implied by the AST), meaning that if AST node A may
+//! execute before AST node B, then A is visited first.  The borrow checker in
+//! particular relies on this property.
+//!
+//! Note: walking an AST before macro expansion is probably a bad idea. For
+//! instance, a walker looking for item names in a module will miss all of
+//! those that are created by the expansion of a macro.
+
 use abi::Abi;
 use ast::*;
 use ast;
 
 use std::gc::Gc;
 
-// Context-passing AST walker. Each overridden visit method has full control
-// over what happens with its node, it can do its own traversal of the node's
-// children (potentially passing in different contexts to each), call
-// visit::visit_* to apply the default traversal algorithm (again, it can
-// override the context), or prevent deeper traversal by doing nothing.
-//
-// Note: it is an important invariant that the default visitor walks the body
-// of a function in "execution order" (more concretely, reverse post-order
-// with respect to the CFG implied by the AST), meaning that if AST node A may
-// execute before AST node B, then A is visited first.  The borrow checker in
-// particular relies on this property.
-
 pub enum FnKind<'a> {
-    // fn foo() or extern "Abi" fn foo()
+    /// fn foo() or extern "Abi" fn foo()
     FkItemFn(Ident, &'a Generics, FnStyle, Abi),
 
-    // fn foo(&self)
+    /// fn foo(&self)
     FkMethod(Ident, &'a Generics, &'a Method),
 
-    // |x, y| ...
-    // proc(x, y) ...
+    /// |x, y| ...
+    /// proc(x, y) ...
     FkFnBlock,
 }
 
@@ -124,8 +128,13 @@ fn visit_lifetime_decl(&mut self, _lifetime: &Lifetime, _e: E) {
     fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) {
         walk_explicit_self(self, es, e)
     }
-    fn visit_mac(&mut self, macro: &Mac, e: E) {
-        walk_mac(self, macro, e)
+    fn visit_mac(&mut self, _macro: &Mac, _e: E) {
+        fail!("visit_mac disabled by default");
+        // NB: see note about macros above.
+        // if you really want a visitor that
+        // works on macros, use this
+        // definition in your trait impl:
+        // visit::walk_mac(self, _macro, _e)
     }
     fn visit_path(&mut self, path: &Path, _id: ast::NodeId, e: E) {
         walk_path(self, path, e)
@@ -202,8 +211,8 @@ pub fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V,
                                                    explicit_self: &ExplicitSelf,
                                                    env: E) {
     match explicit_self.node {
-        SelfStatic | SelfValue | SelfUniq => {}
-        SelfRegion(ref lifetime, _) => {
+        SelfStatic | SelfValue(_) | SelfUniq(_) => {},
+        SelfRegion(ref lifetime, _, _) => {
             visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
         }
     }
@@ -551,15 +560,21 @@ pub fn walk_fn_decl<E: Clone, V: Visitor<E>>(visitor: &mut V,
 pub fn walk_method_helper<E: Clone, V: Visitor<E>>(visitor: &mut V,
                                                    method: &Method,
                                                    env: E) {
-    visitor.visit_ident(method.span, method.ident, env.clone());
-    visitor.visit_fn(&FkMethod(method.ident, &method.generics, method),
-                     &*method.decl,
-                     &*method.body,
-                     method.span,
-                     method.id,
-                     env.clone());
-    for attr in method.attrs.iter() {
-        visitor.visit_attribute(attr, env.clone());
+    match method.node {
+        MethDecl(ident, ref generics, _, _, decl, body, _) => {
+            visitor.visit_ident(method.span, ident, env.clone());
+            visitor.visit_fn(&FkMethod(ident, generics, method),
+                             decl,
+                             body,
+                             method.span,
+                             method.id,
+                             env.clone());
+            for attr in method.attrs.iter() {
+                visitor.visit_attribute(attr, env.clone());
+            }
+
+        },
+        MethMac(ref mac) => visitor.visit_mac(mac, env.clone())
     }
 }
 
@@ -577,8 +592,12 @@ pub fn walk_fn<E: Clone, V: Visitor<E>>(visitor: &mut V,
         }
         FkMethod(_, generics, method) => {
             visitor.visit_generics(generics, env.clone());
-
-            visitor.visit_explicit_self(&method.explicit_self, env.clone());
+            match method.node {
+                MethDecl(_, _, ref explicit_self, _, _, _, _) =>
+                    visitor.visit_explicit_self(explicit_self, env.clone()),
+                MethMac(ref mac) =>
+                    visitor.visit_mac(mac, env.clone())
+            }
         }
         FkFnBlock(..) => {}
     }
index 56694e28b666227e1a87c513d83c40c119e3c99e..3fc631422d5f3a3e78cba2a5400ca0119f83c635 100644 (file)
@@ -38,7 +38,7 @@
 //! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
 //! [ti]: https://en.wikipedia.org/wiki/Terminfo
 
-#![crate_id = "term#0.11.0"]
+#![crate_name = "term"]
 #![experimental]
 #![comment = "Simple ANSI color library"]
 #![license = "MIT/ASL2"]
@@ -46,7 +46,7 @@
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, phase)]
index 71fdea9b9ec8e80f3aaec65dbaa4dda624b10c95..9467eb699217074217d016d55405352385b8b43a 100644 (file)
@@ -19,7 +19,7 @@
 
 // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
 
-pub static boolfnames: &'static[&'static str] = &'static["auto_left_margin", "auto_right_margin",
+pub static boolfnames: &'static[&'static str] = &["auto_left_margin", "auto_right_margin",
     "no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
     "hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
     "memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
     "no_correctly_working_cr", "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs",
     "return_does_clr_eol"];
 
-pub static boolnames: &'static[&'static str] = &'static["bw", "am", "xsb", "xhp", "xenl", "eo",
+pub static boolnames: &'static[&'static str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
     "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
     "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
     "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
 
-pub static numfnames: &'static[&'static str] = &'static[ "columns", "init_tabs", "lines",
+pub static numfnames: &'static[&'static str] = &[ "columns", "init_tabs", "lines",
     "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
     "width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
     "maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
     "bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", "carriage_return_delay",
     "new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
 
-pub static numnames: &'static[&'static str] = &'static[ "cols", "it", "lines", "lm", "xmc", "pb",
+pub static numnames: &'static[&'static str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
     "vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
     "spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
     "btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
 
-pub static stringfnames: &'static[&'static str] = &'static[ "back_tab", "bell", "carriage_return",
+pub static stringfnames: &'static[&'static str] = &[ "back_tab", "bell", "carriage_return",
     "change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
     "column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
     "cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
     "acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", "acs_hline", "acs_vline",
     "acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
 
-pub static stringnames: &'static[&'static str] = &'static[ "cbt", "_", "cr", "csr", "tbc", "clear",
+pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
     "_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
     "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
     "dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
index 02f7ebc6d21c816d007b4a4f3c1cabb7e8c67172..8fbb821d0b96e484b2762af5cc4e0757f41b5588 100644 (file)
@@ -23,7 +23,7 @@
 // running tests while providing a base that other test frameworks may
 // build off of.
 
-#![crate_id = "test#0.11.0"]
+#![crate_name = "test"]
 #![experimental]
 #![comment = "Rust internal test library only used by rustc"]
 #![license = "MIT/ASL2"]
@@ -31,7 +31,7 @@
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+       html_root_url = "http://doc.rust-lang.org/master/")]
 
 #![feature(asm, macro_rules, phase)]
 
@@ -368,7 +368,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
     let matches =
         match getopts::getopts(args_.as_slice(), optgroups().as_slice()) {
           Ok(m) => m,
-          Err(f) => return Some(Err(f.to_str()))
+          Err(f) => return Some(Err(f.to_string()))
         };
 
     if matches.opt_present("h") { usage(args[0].as_slice()); return None; }
@@ -632,7 +632,7 @@ pub fn write_failures(&mut self) -> io::IoResult<()> {
         let mut failures = Vec::new();
         let mut fail_out = String::new();
         for &(ref f, ref stdout) in self.failures.iter() {
-            failures.push(f.name.to_str());
+            failures.push(f.name.to_string());
             if stdout.len() > 0 {
                 fail_out.push_str(format!("---- {} stdout ----\n\t",
                                           f.name.as_slice()).as_slice());
@@ -1520,7 +1520,7 @@ pub fn filter_for_ignored_option() {
         let filtered = filter_tests(&opts, tests);
 
         assert_eq!(filtered.len(), 1);
-        assert_eq!(filtered.get(0).desc.name.to_str(),
+        assert_eq!(filtered.get(0).desc.name.to_string(),
                    "1".to_string());
         assert!(filtered.get(0).desc.ignore == false);
     }
@@ -1571,7 +1571,7 @@ fn testfn() { }
                  "test::sort_tests".to_string());
 
         for (a, b) in expected.iter().zip(filtered.iter()) {
-            assert!(*a == b.desc.name.to_str());
+            assert!(*a == b.desc.name.to_string());
         }
     }
 
index 8db9a4f53aa9bc8a8dab871729aa6839c46d2c20..325582ff99c98a6370effc3bf2ede983b6579e10 100644 (file)
@@ -385,8 +385,8 @@ pub fn write_boxplot<T: Float + Show + FromPrimitive>(
 
     let range = hi - lo;
 
-    let lostr = lo.to_str();
-    let histr = hi.to_str();
+    let lostr = lo.to_string();
+    let histr = hi.to_string();
 
     let overhead_width = lostr.len() + histr.len() + 4;
     let range_width = width_hint - overhead_width;
index 0e4de41959a33de9717bb41f8d73cdefac62a9a0..7655ace0ecb08c78699fcdbb19ad86076e9a183a 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Simple time handling.
 
-#![crate_id = "time#0.11.0"]
+#![crate_name = "time"]
 #![experimental]
 
 #![crate_type = "rlib"]
@@ -18,7 +18,7 @@
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(phase)]
 
@@ -1037,7 +1037,7 @@ fn parse_type(ch: char, tm: &Tm) -> String {
           'U' => format!("{:02d}", (tm.tm_yday - tm.tm_wday + 7) / 7),
           'u' => {
             let i = tm.tm_wday as int;
-            (if i == 0 { 7 } else { i }).to_str()
+            (if i == 0 { 7 } else { i }).to_string()
           }
           'V' => iso_week('V', tm),
           'v' => {
@@ -1050,8 +1050,8 @@ fn parse_type(ch: char, tm: &Tm) -> String {
               format!("{:02d}",
                              (tm.tm_yday - (tm.tm_wday - 1 + 7) % 7 + 7) / 7)
           }
-          'w' => (tm.tm_wday as int).to_str(),
-          'Y' => (tm.tm_year as int + 1900).to_str(),
+          'w' => (tm.tm_wday as int).to_string(),
+          'Y' => (tm.tm_year as int + 1900).to_string(),
           'y' => format!("{:02d}", (tm.tm_year as int + 1900) % 100),
           'Z' => "".to_string(),    // FIXME(pcwalton): Implement this.
           'z' => {
diff --git a/src/libunicode/decompose.rs b/src/libunicode/decompose.rs
new file mode 100644 (file)
index 0000000..832b65d
--- /dev/null
@@ -0,0 +1,111 @@
+// Copyright 2012-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.
+
+/*!
+  Functions for computing canonical and compatible decompositions
+  for Unicode characters.
+  */
+
+use core::option::{Option, Some, None};
+use core::slice::ImmutableVector;
+use tables::normalization::{canonical_table, compatibility_table};
+
+fn bsearch_table(c: char, r: &'static [(char, &'static [char])]) -> Option<&'static [char]> {
+    use core::cmp::{Equal, Less, Greater};
+    match r.bsearch(|&(val, _)| {
+        if c == val { Equal }
+        else if val < c { Less }
+        else { Greater }
+    }) {
+        Some(idx) => {
+            let (_, result) = r[idx];
+            Some(result)
+        }
+        None => None
+    }
+}
+
+/// Compute canonical Unicode decomposition for character
+pub fn decompose_canonical(c: char, i: |char|) { d(c, i, false); }
+
+/// Compute canonical or compatible Unicode decomposition for character
+pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
+
+fn d(c: char, i: |char|, k: bool) {
+    use core::iter::Iterator;
+
+    // 7-bit ASCII never decomposes
+    if c <= '\x7f' { i(c); return; }
+
+    // Perform decomposition for Hangul
+    if (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) {
+        decompose_hangul(c, i);
+        return;
+    }
+
+    // First check the canonical decompositions
+    match bsearch_table(c, canonical_table) {
+        Some(canon) => {
+            for x in canon.iter() {
+                d(*x, |b| i(b), k);
+            }
+            return;
+        }
+        None => ()
+    }
+
+    // Bottom out if we're not doing compat.
+    if !k { i(c); return; }
+
+    // Then check the compatibility decompositions
+    match bsearch_table(c, compatibility_table) {
+        Some(compat) => {
+            for x in compat.iter() {
+                d(*x, |b| i(b), k);
+            }
+            return;
+        }
+        None => ()
+    }
+
+    // Finally bottom out.
+    i(c);
+}
+
+// Constants from Unicode 6.3.0 Section 3.12 Conjoining Jamo Behavior
+static S_BASE: u32 = 0xAC00;
+static L_BASE: u32 = 0x1100;
+static V_BASE: u32 = 0x1161;
+static T_BASE: u32 = 0x11A7;
+static L_COUNT: u32 = 19;
+static V_COUNT: u32 = 21;
+static T_COUNT: u32 = 28;
+static N_COUNT: u32 = (V_COUNT * T_COUNT);
+static S_COUNT: u32 = (L_COUNT * N_COUNT);
+
+// Decompose a precomposed Hangul syllable
+fn decompose_hangul(s: char, f: |char|) {
+    use core::mem::transmute;
+
+    let si = s as u32 - S_BASE;
+
+    let li = si / N_COUNT;
+    unsafe {
+        f(transmute(L_BASE + li));
+
+        let vi = (si % N_COUNT) / T_COUNT;
+        f(transmute(V_BASE + vi));
+
+        let ti = si % T_COUNT;
+        if ti > 0 {
+            f(transmute(T_BASE + ti));
+        }
+    }
+}
diff --git a/src/libunicode/lib.rs b/src/libunicode/lib.rs
new file mode 100644 (file)
index 0000000..608bdbf
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2012-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.
+
+//! # The Unicode Library
+//!
+//! Unicode-intensive functions for `char` and `str` types.
+//!
+//! This crate provides a collection of Unicode-related functionality,
+//! including decompositions, conversions, etc., and provides traits
+//! implementing these functions for the `char` and `str` types.
+//!
+//! The functionality included here is only that which is necessary to
+//! provide for basic string-related manipulations. This crate does not
+//! (yet) aim to provide a full set of Unicode tables.
+
+#![crate_name = "unicode"]
+#![experimental]
+#![license = "MIT/ASL2"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
+#![no_std]
+#![allow(unused_attribute)] // NOTE: remove after stage0
+
+extern crate core;
+
+pub use tables::normalization::canonical_combining_class;
+pub use tables::regex;
+
+pub use u_char::UnicodeChar;
+pub use u_str::UnicodeStrSlice;
+pub use u_str::Words;
+
+mod decompose;
+mod tables;
+mod u_char;
+mod u_str;
+
+// re-export char so that std et al see it correctly
+/// Character manipulation (`char` type, Unicode Scalar Value)
+///
+/// This module  provides the `Char` and `UnicodeChar` traits, as well as their
+/// implementation for the primitive `char` type, in order to allow basic character
+/// manipulation.
+///
+/// A `char` actually represents a
+/// *[Unicode Scalar Value](http://www.unicode.org/glossary/#unicode_scalar_value)*,
+/// as it can contain any Unicode code point except high-surrogate and
+/// low-surrogate code points.
+///
+/// As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
+/// (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
+/// however the converse is not always true due to the above range limits
+/// and, as such, should be performed via the `from_u32` function..
+pub mod char {
+    pub use core::char::{MAX, from_u32, is_digit_radix, to_digit};
+    pub use core::char::{from_digit, escape_unicode, escape_default};
+    pub use core::char::{len_utf8_bytes, Char};
+
+    pub use decompose::decompose_canonical;
+    pub use decompose::decompose_compatible;
+
+    pub use u_char::{is_alphabetic, is_XID_start, is_XID_continue};
+    pub use u_char::{is_lowercase, is_uppercase, is_whitespace};
+    pub use u_char::{is_alphanumeric, is_control, is_digit};
+    pub use u_char::{to_uppercase, to_lowercase, width, UnicodeChar};
+}
diff --git a/src/libunicode/tables.rs b/src/libunicode/tables.rs
new file mode 100644 (file)
index 0000000..7f59656
--- /dev/null
@@ -0,0 +1,6445 @@
+// Copyright 2012-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.
+
+// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
+
+#![allow(missing_doc, non_uppercase_statics, non_snake_case_functions)]
+
+fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
+    use core::cmp::{Equal, Less, Greater};
+    use core::slice::ImmutableVector;
+    use core::option::None;
+    r.bsearch(|&(lo,hi)| {
+        if lo <= c && c <= hi { Equal }
+        else if hi < c { Less }
+        else { Greater }
+    }) != None
+}
+
+pub mod general_category {
+    pub static C_table: &'static [(char, char)] = &[
+        ('\x00', '\x1f'), ('\x7f', '\x9f'), ('\xad', '\xad'), ('\u0600', '\u0605'), ('\u061c',
+        '\u061c'), ('\u06dd', '\u06dd'), ('\u070f', '\u070f'), ('\u180e', '\u180e'), ('\u200b',
+        '\u200f'), ('\u202a', '\u202e'), ('\u2060', '\u2064'), ('\u2066', '\u206f'), ('\ue000',
+        '\ue000'), ('\uf8ff', '\uf8ff'), ('\ufeff', '\ufeff'), ('\ufff9', '\ufffb'), ('\U000110bd',
+        '\U000110bd'), ('\U0001bca0', '\U0001bca3'), ('\U0001d173', '\U0001d17a'), ('\U000e0001',
+        '\U000e0001'), ('\U000e0020', '\U000e007f'), ('\U000f0000', '\U000f0000'), ('\U000ffffd',
+        '\U000ffffd'), ('\U00100000', '\U00100000'), ('\U0010fffd', '\U0010fffd')
+    ];
+
+    pub static Cc_table: &'static [(char, char)] = &[
+        ('\x00', '\x1f'), ('\x7f', '\x9f')
+    ];
+
+    pub fn Cc(c: char) -> bool {
+        super::bsearch_range_table(c, Cc_table)
+    }
+
+    pub static Cf_table: &'static [(char, char)] = &[
+        ('\xad', '\xad'), ('\u0600', '\u0605'), ('\u061c', '\u061c'), ('\u06dd', '\u06dd'),
+        ('\u070f', '\u070f'), ('\u180e', '\u180e'), ('\u200b', '\u200f'), ('\u202a', '\u202e'),
+        ('\u2060', '\u2064'), ('\u2066', '\u206f'), ('\ufeff', '\ufeff'), ('\ufff9', '\ufffb'),
+        ('\U000110bd', '\U000110bd'), ('\U0001bca0', '\U0001bca3'), ('\U0001d173', '\U0001d17a'),
+        ('\U000e0001', '\U000e0001'), ('\U000e0020', '\U000e007f')
+    ];
+
+    pub static Co_table: &'static [(char, char)] = &[
+        ('\ue000', '\ue000'), ('\uf8ff', '\uf8ff'), ('\U000f0000', '\U000f0000'), ('\U000ffffd',
+        '\U000ffffd'), ('\U00100000', '\U00100000'), ('\U0010fffd', '\U0010fffd')
+    ];
+
+    pub static L_table: &'static [(char, char)] = &[
+        ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xb5', '\xb5'), ('\xba', '\xba'),
+        ('\xc0', '\xd6'), ('\xd8', '\xf6'), ('\xf8', '\u02c1'), ('\u02c6', '\u02d1'), ('\u02e0',
+        '\u02e4'), ('\u02ec', '\u02ec'), ('\u02ee', '\u02ee'), ('\u0370', '\u0374'), ('\u0376',
+        '\u0377'), ('\u037a', '\u037d'), ('\u037f', '\u037f'), ('\u0386', '\u0386'), ('\u0388',
+        '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'), ('\u03f7',
+        '\u0481'), ('\u048a', '\u052f'), ('\u0531', '\u0556'), ('\u0559', '\u0559'), ('\u0561',
+        '\u0587'), ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'), ('\u0620', '\u064a'), ('\u066e',
+        '\u066f'), ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'), ('\u06e5', '\u06e6'), ('\u06ee',
+        '\u06ef'), ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'), ('\u0710', '\u0710'), ('\u0712',
+        '\u072f'), ('\u074d', '\u07a5'), ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'), ('\u07f4',
+        '\u07f5'), ('\u07fa', '\u07fa'), ('\u0800', '\u0815'), ('\u081a', '\u081a'), ('\u0824',
+        '\u0824'), ('\u0828', '\u0828'), ('\u0840', '\u0858'), ('\u08a0', '\u08b2'), ('\u0904',
+        '\u0939'), ('\u093d', '\u093d'), ('\u0950', '\u0950'), ('\u0958', '\u0961'), ('\u0971',
+        '\u0980'), ('\u0985', '\u098c'), ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa',
+        '\u09b0'), ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'), ('\u09bd', '\u09bd'), ('\u09ce',
+        '\u09ce'), ('\u09dc', '\u09dd'), ('\u09df', '\u09e1'), ('\u09f0', '\u09f1'), ('\u0a05',
+        '\u0a0a'), ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32',
+        '\u0a33'), ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'), ('\u0a59', '\u0a5c'), ('\u0a5e',
+        '\u0a5e'), ('\u0a72', '\u0a74'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93',
+        '\u0aa8'), ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abd',
+        '\u0abd'), ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0b05', '\u0b0c'), ('\u0b0f',
+        '\u0b10'), ('\u0b13', '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35',
+        '\u0b39'), ('\u0b3d', '\u0b3d'), ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b71',
+        '\u0b71'), ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'), ('\u0b92',
+        '\u0b95'), ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'), ('\u0ba3',
+        '\u0ba4'), ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bd0', '\u0bd0'), ('\u0c05',
+        '\u0c0c'), ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d',
+        '\u0c3d'), ('\u0c58', '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c85', '\u0c8c'), ('\u0c8e',
+        '\u0c90'), ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'), ('\u0cbd',
+        '\u0cbd'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0cf1', '\u0cf2'), ('\u0d05',
+        '\u0d0c'), ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d4e',
+        '\u0d4e'), ('\u0d60', '\u0d61'), ('\u0d7a', '\u0d7f'), ('\u0d85', '\u0d96'), ('\u0d9a',
+        '\u0db1'), ('\u0db3', '\u0dbb'), ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0e01',
+        '\u0e30'), ('\u0e32', '\u0e33'), ('\u0e40', '\u0e46'), ('\u0e81', '\u0e82'), ('\u0e84',
+        '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94',
+        '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7',
+        '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'), ('\u0eb2', '\u0eb3'), ('\u0ebd',
+        '\u0ebd'), ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0edc', '\u0edf'), ('\u0f00',
+        '\u0f00'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'), ('\u0f88', '\u0f8c'), ('\u1000',
+        '\u102a'), ('\u103f', '\u103f'), ('\u1050', '\u1055'), ('\u105a', '\u105d'), ('\u1061',
+        '\u1061'), ('\u1065', '\u1066'), ('\u106e', '\u1070'), ('\u1075', '\u1081'), ('\u108e',
+        '\u108e'), ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0',
+        '\u10fa'), ('\u10fc', '\u1248'), ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258',
+        '\u1258'), ('\u125a', '\u125d'), ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290',
+        '\u12b0'), ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2',
+        '\u12c5'), ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318',
+        '\u135a'), ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401', '\u166c'), ('\u166f',
+        '\u167f'), ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16f1', '\u16f8'), ('\u1700',
+        '\u170c'), ('\u170e', '\u1711'), ('\u1720', '\u1731'), ('\u1740', '\u1751'), ('\u1760',
+        '\u176c'), ('\u176e', '\u1770'), ('\u1780', '\u17b3'), ('\u17d7', '\u17d7'), ('\u17dc',
+        '\u17dc'), ('\u1820', '\u1877'), ('\u1880', '\u18a8'), ('\u18aa', '\u18aa'), ('\u18b0',
+        '\u18f5'), ('\u1900', '\u191e'), ('\u1950', '\u196d'), ('\u1970', '\u1974'), ('\u1980',
+        '\u19ab'), ('\u19c1', '\u19c7'), ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'), ('\u1aa7',
+        '\u1aa7'), ('\u1b05', '\u1b33'), ('\u1b45', '\u1b4b'), ('\u1b83', '\u1ba0'), ('\u1bae',
+        '\u1baf'), ('\u1bba', '\u1be5'), ('\u1c00', '\u1c23'), ('\u1c4d', '\u1c4f'), ('\u1c5a',
+        '\u1c7d'), ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'), ('\u1cf5', '\u1cf6'), ('\u1d00',
+        '\u1dbf'), ('\u1e00', '\u1f15'), ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'), ('\u1f48',
+        '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d',
+        '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'), ('\u1fbe',
+        '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'), ('\u1fd6',
+        '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'), ('\u2071',
+        '\u2071'), ('\u207f', '\u207f'), ('\u2090', '\u209c'), ('\u2102', '\u2102'), ('\u2107',
+        '\u2107'), ('\u210a', '\u2113'), ('\u2115', '\u2115'), ('\u2119', '\u211d'), ('\u2124',
+        '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u212f',
+        '\u2139'), ('\u213c', '\u213f'), ('\u2145', '\u2149'), ('\u214e', '\u214e'), ('\u2183',
+        '\u2184'), ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'), ('\u2c60', '\u2ce4'), ('\u2ceb',
+        '\u2cee'), ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d',
+        '\u2d2d'), ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'), ('\u2d80', '\u2d96'), ('\u2da0',
+        '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0',
+        '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'), ('\u2e2f',
+        '\u2e2f'), ('\u3005', '\u3006'), ('\u3031', '\u3035'), ('\u303b', '\u303c'), ('\u3041',
+        '\u3096'), ('\u309d', '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30ff'), ('\u3105',
+        '\u312d'), ('\u3131', '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400',
+        '\u3400'), ('\u4db5', '\u4db5'), ('\u4e00', '\u4e00'), ('\u9fcc', '\u9fcc'), ('\ua000',
+        '\ua48c'), ('\ua4d0', '\ua4fd'), ('\ua500', '\ua60c'), ('\ua610', '\ua61f'), ('\ua62a',
+        '\ua62b'), ('\ua640', '\ua66e'), ('\ua67f', '\ua69d'), ('\ua6a0', '\ua6e5'), ('\ua717',
+        '\ua71f'), ('\ua722', '\ua788'), ('\ua78b', '\ua78e'), ('\ua790', '\ua7ad'), ('\ua7b0',
+        '\ua7b1'), ('\ua7f7', '\ua801'), ('\ua803', '\ua805'), ('\ua807', '\ua80a'), ('\ua80c',
+        '\ua822'), ('\ua840', '\ua873'), ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'), ('\ua8fb',
+        '\ua8fb'), ('\ua90a', '\ua925'), ('\ua930', '\ua946'), ('\ua960', '\ua97c'), ('\ua984',
+        '\ua9b2'), ('\ua9cf', '\ua9cf'), ('\ua9e0', '\ua9e4'), ('\ua9e6', '\ua9ef'), ('\ua9fa',
+        '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa40', '\uaa42'), ('\uaa44', '\uaa4b'), ('\uaa60',
+        '\uaa76'), ('\uaa7a', '\uaa7a'), ('\uaa7e', '\uaaaf'), ('\uaab1', '\uaab1'), ('\uaab5',
+        '\uaab6'), ('\uaab9', '\uaabd'), ('\uaac0', '\uaac0'), ('\uaac2', '\uaac2'), ('\uaadb',
+        '\uaadd'), ('\uaae0', '\uaaea'), ('\uaaf2', '\uaaf4'), ('\uab01', '\uab06'), ('\uab09',
+        '\uab0e'), ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e'), ('\uab30',
+        '\uab5a'), ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\uabc0', '\uabe2'), ('\uac00',
+        '\uac00'), ('\ud7a3', '\ud7a3'), ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900',
+        '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'), ('\ufb1d',
+        '\ufb1d'), ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e',
+        '\ufb3e'), ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3',
+        '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdfb'), ('\ufe70',
+        '\ufe74'), ('\ufe76', '\ufefc'), ('\uff21', '\uff3a'), ('\uff41', '\uff5a'), ('\uff66',
+        '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'), ('\uffd2', '\uffd7'), ('\uffda',
+        '\uffdc'), ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'), ('\U00010028',
+        '\U0001003a'), ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'), ('\U00010050',
+        '\U0001005d'), ('\U00010080', '\U000100fa'), ('\U00010280', '\U0001029c'), ('\U000102a0',
+        '\U000102d0'), ('\U00010300', '\U0001031f'), ('\U00010330', '\U00010340'), ('\U00010342',
+        '\U00010349'), ('\U00010350', '\U00010375'), ('\U00010380', '\U0001039d'), ('\U000103a0',
+        '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U00010400', '\U0001049d'), ('\U00010500',
+        '\U00010527'), ('\U00010530', '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740',
+        '\U00010755'), ('\U00010760', '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808',
+        '\U00010808'), ('\U0001080a', '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c',
+        '\U0001083c'), ('\U0001083f', '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880',
+        '\U0001089e'), ('\U00010900', '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980',
+        '\U000109b7'), ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'), ('\U00010a10',
+        '\U00010a13'), ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a60',
+        '\U00010a7c'), ('\U00010a80', '\U00010a9c'), ('\U00010ac0', '\U00010ac7'), ('\U00010ac9',
+        '\U00010ae4'), ('\U00010b00', '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60',
+        '\U00010b72'), ('\U00010b80', '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011003',
+        '\U00011037'), ('\U00011083', '\U000110af'), ('\U000110d0', '\U000110e8'), ('\U00011103',
+        '\U00011126'), ('\U00011150', '\U00011172'), ('\U00011176', '\U00011176'), ('\U00011183',
+        '\U000111b2'), ('\U000111c1', '\U000111c4'), ('\U000111da', '\U000111da'), ('\U00011200',
+        '\U00011211'), ('\U00011213', '\U0001122b'), ('\U000112b0', '\U000112de'), ('\U00011305',
+        '\U0001130c'), ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a',
+        '\U00011330'), ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133d',
+        '\U0001133d'), ('\U0001135d', '\U00011361'), ('\U00011480', '\U000114af'), ('\U000114c4',
+        '\U000114c5'), ('\U000114c7', '\U000114c7'), ('\U00011580', '\U000115ae'), ('\U00011600',
+        '\U0001162f'), ('\U00011644', '\U00011644'), ('\U00011680', '\U000116aa'), ('\U000118a0',
+        '\U000118df'), ('\U000118ff', '\U000118ff'), ('\U00011ac0', '\U00011af8'), ('\U00012000',
+        '\U00012398'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'), ('\U00016a40',
+        '\U00016a5e'), ('\U00016ad0', '\U00016aed'), ('\U00016b00', '\U00016b2f'), ('\U00016b40',
+        '\U00016b43'), ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'), ('\U00016f00',
+        '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f93', '\U00016f9f'), ('\U0001b000',
+        '\U0001b001'), ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80',
+        '\U0001bc88'), ('\U0001bc90', '\U0001bc99'), ('\U0001d400', '\U0001d454'), ('\U0001d456',
+        '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5',
+        '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb',
+        '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'), ('\U0001d507',
+        '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'), ('\U0001d51e',
+        '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'), ('\U0001d546',
+        '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8',
+        '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fc',
+        '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'), ('\U0001d750',
+        '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'), ('\U0001d7aa',
+        '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001e800', '\U0001e8c4'), ('\U0001ee00',
+        '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'), ('\U0001ee24',
+        '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'), ('\U0001ee34',
+        '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42',
+        '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b',
+        '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'), ('\U0001ee54',
+        '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b',
+        '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61',
+        '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c',
+        '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e',
+        '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1',
+        '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'), ('\U00020000',
+        '\U00020000'), ('\U0002a6d6', '\U0002a6d6'), ('\U0002a700', '\U0002a700'), ('\U0002b734',
+        '\U0002b734'), ('\U0002b740', '\U0002b740'), ('\U0002b81d', '\U0002b81d'), ('\U0002f800',
+        '\U0002fa1d')
+    ];
+
+    pub static LC_table: &'static [(char, char)] = &[
+        ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xb5', '\xb5'), ('\xc0', '\xd6'), ('\xd8', '\xf6'),
+        ('\xf8', '\u01ba'), ('\u01bc', '\u01bf'), ('\u01c4', '\u0293'), ('\u0295', '\u02af'),
+        ('\u0370', '\u0373'), ('\u0376', '\u0377'), ('\u037b', '\u037d'), ('\u037f', '\u037f'),
+        ('\u0386', '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'),
+        ('\u03a3', '\u03f5'), ('\u03f7', '\u0481'), ('\u048a', '\u052f'), ('\u0531', '\u0556'),
+        ('\u0561', '\u0587'), ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
+        ('\u1d00', '\u1d2b'), ('\u1d6b', '\u1d77'), ('\u1d79', '\u1d9a'), ('\u1e00', '\u1f15'),
+        ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'), ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
+        ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
+        ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
+        ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'),
+        ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'), ('\u2102', '\u2102'), ('\u2107', '\u2107'),
+        ('\u210a', '\u2113'), ('\u2115', '\u2115'), ('\u2119', '\u211d'), ('\u2124', '\u2124'),
+        ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u212f', '\u2134'),
+        ('\u2139', '\u2139'), ('\u213c', '\u213f'), ('\u2145', '\u2149'), ('\u214e', '\u214e'),
+        ('\u2183', '\u2184'), ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'),
+        ('\u2c7e', '\u2ce4'), ('\u2ceb', '\u2cee'), ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'),
+        ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\ua640', '\ua66d'), ('\ua680', '\ua69b'),
+        ('\ua722', '\ua76f'), ('\ua771', '\ua787'), ('\ua78b', '\ua78e'), ('\ua790', '\ua7ad'),
+        ('\ua7b0', '\ua7b1'), ('\ua7fa', '\ua7fa'), ('\uab30', '\uab5a'), ('\uab64', '\uab65'),
+        ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'), ('\uff21', '\uff3a'), ('\uff41', '\uff5a'),
+        ('\U00010400', '\U0001044f'), ('\U000118a0', '\U000118df'), ('\U0001d400', '\U0001d454'),
+        ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
+        ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'),
+        ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
+        ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'),
+        ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
+        ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'),
+        ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
+        ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'),
+        ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
+        ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb')
+    ];
+
+    pub static Ll_table: &'static [(char, char)] = &[
+        ('\x61', '\x7a'), ('\xb5', '\xb5'), ('\xdf', '\xf6'), ('\xf8', '\xff'), ('\u0101',
+        '\u0101'), ('\u0103', '\u0103'), ('\u0105', '\u0105'), ('\u0107', '\u0107'), ('\u0109',
+        '\u0109'), ('\u010b', '\u010b'), ('\u010d', '\u010d'), ('\u010f', '\u010f'), ('\u0111',
+        '\u0111'), ('\u0113', '\u0113'), ('\u0115', '\u0115'), ('\u0117', '\u0117'), ('\u0119',
+        '\u0119'), ('\u011b', '\u011b'), ('\u011d', '\u011d'), ('\u011f', '\u011f'), ('\u0121',
+        '\u0121'), ('\u0123', '\u0123'), ('\u0125', '\u0125'), ('\u0127', '\u0127'), ('\u0129',
+        '\u0129'), ('\u012b', '\u012b'), ('\u012d', '\u012d'), ('\u012f', '\u012f'), ('\u0131',
+        '\u0131'), ('\u0133', '\u0133'), ('\u0135', '\u0135'), ('\u0137', '\u0138'), ('\u013a',
+        '\u013a'), ('\u013c', '\u013c'), ('\u013e', '\u013e'), ('\u0140', '\u0140'), ('\u0142',
+        '\u0142'), ('\u0144', '\u0144'), ('\u0146', '\u0146'), ('\u0148', '\u0149'), ('\u014b',
+        '\u014b'), ('\u014d', '\u014d'), ('\u014f', '\u014f'), ('\u0151', '\u0151'), ('\u0153',
+        '\u0153'), ('\u0155', '\u0155'), ('\u0157', '\u0157'), ('\u0159', '\u0159'), ('\u015b',
+        '\u015b'), ('\u015d', '\u015d'), ('\u015f', '\u015f'), ('\u0161', '\u0161'), ('\u0163',
+        '\u0163'), ('\u0165', '\u0165'), ('\u0167', '\u0167'), ('\u0169', '\u0169'), ('\u016b',
+        '\u016b'), ('\u016d', '\u016d'), ('\u016f', '\u016f'), ('\u0171', '\u0171'), ('\u0173',
+        '\u0173'), ('\u0175', '\u0175'), ('\u0177', '\u0177'), ('\u017a', '\u017a'), ('\u017c',
+        '\u017c'), ('\u017e', '\u0180'), ('\u0183', '\u0183'), ('\u0185', '\u0185'), ('\u0188',
+        '\u0188'), ('\u018c', '\u018d'), ('\u0192', '\u0192'), ('\u0195', '\u0195'), ('\u0199',
+        '\u019b'), ('\u019e', '\u019e'), ('\u01a1', '\u01a1'), ('\u01a3', '\u01a3'), ('\u01a5',
+        '\u01a5'), ('\u01a8', '\u01a8'), ('\u01aa', '\u01ab'), ('\u01ad', '\u01ad'), ('\u01b0',
+        '\u01b0'), ('\u01b4', '\u01b4'), ('\u01b6', '\u01b6'), ('\u01b9', '\u01ba'), ('\u01bd',
+        '\u01bf'), ('\u01c6', '\u01c6'), ('\u01c9', '\u01c9'), ('\u01cc', '\u01cc'), ('\u01ce',
+        '\u01ce'), ('\u01d0', '\u01d0'), ('\u01d2', '\u01d2'), ('\u01d4', '\u01d4'), ('\u01d6',
+        '\u01d6'), ('\u01d8', '\u01d8'), ('\u01da', '\u01da'), ('\u01dc', '\u01dd'), ('\u01df',
+        '\u01df'), ('\u01e1', '\u01e1'), ('\u01e3', '\u01e3'), ('\u01e5', '\u01e5'), ('\u01e7',
+        '\u01e7'), ('\u01e9', '\u01e9'), ('\u01eb', '\u01eb'), ('\u01ed', '\u01ed'), ('\u01ef',
+        '\u01f0'), ('\u01f3', '\u01f3'), ('\u01f5', '\u01f5'), ('\u01f9', '\u01f9'), ('\u01fb',
+        '\u01fb'), ('\u01fd', '\u01fd'), ('\u01ff', '\u01ff'), ('\u0201', '\u0201'), ('\u0203',
+        '\u0203'), ('\u0205', '\u0205'), ('\u0207', '\u0207'), ('\u0209', '\u0209'), ('\u020b',
+        '\u020b'), ('\u020d', '\u020d'), ('\u020f', '\u020f'), ('\u0211', '\u0211'), ('\u0213',
+        '\u0213'), ('\u0215', '\u0215'), ('\u0217', '\u0217'), ('\u0219', '\u0219'), ('\u021b',
+        '\u021b'), ('\u021d', '\u021d'), ('\u021f', '\u021f'), ('\u0221', '\u0221'), ('\u0223',
+        '\u0223'), ('\u0225', '\u0225'), ('\u0227', '\u0227'), ('\u0229', '\u0229'), ('\u022b',
+        '\u022b'), ('\u022d', '\u022d'), ('\u022f', '\u022f'), ('\u0231', '\u0231'), ('\u0233',
+        '\u0239'), ('\u023c', '\u023c'), ('\u023f', '\u0240'), ('\u0242', '\u0242'), ('\u0247',
+        '\u0247'), ('\u0249', '\u0249'), ('\u024b', '\u024b'), ('\u024d', '\u024d'), ('\u024f',
+        '\u0293'), ('\u0295', '\u02af'), ('\u0371', '\u0371'), ('\u0373', '\u0373'), ('\u0377',
+        '\u0377'), ('\u037b', '\u037d'), ('\u0390', '\u0390'), ('\u03ac', '\u03ce'), ('\u03d0',
+        '\u03d1'), ('\u03d5', '\u03d7'), ('\u03d9', '\u03d9'), ('\u03db', '\u03db'), ('\u03dd',
+        '\u03dd'), ('\u03df', '\u03df'), ('\u03e1', '\u03e1'), ('\u03e3', '\u03e3'), ('\u03e5',
+        '\u03e5'), ('\u03e7', '\u03e7'), ('\u03e9', '\u03e9'), ('\u03eb', '\u03eb'), ('\u03ed',
+        '\u03ed'), ('\u03ef', '\u03f3'), ('\u03f5', '\u03f5'), ('\u03f8', '\u03f8'), ('\u03fb',
+        '\u03fc'), ('\u0430', '\u045f'), ('\u0461', '\u0461'), ('\u0463', '\u0463'), ('\u0465',
+        '\u0465'), ('\u0467', '\u0467'), ('\u0469', '\u0469'), ('\u046b', '\u046b'), ('\u046d',
+        '\u046d'), ('\u046f', '\u046f'), ('\u0471', '\u0471'), ('\u0473', '\u0473'), ('\u0475',
+        '\u0475'), ('\u0477', '\u0477'), ('\u0479', '\u0479'), ('\u047b', '\u047b'), ('\u047d',
+        '\u047d'), ('\u047f', '\u047f'), ('\u0481', '\u0481'), ('\u048b', '\u048b'), ('\u048d',
+        '\u048d'), ('\u048f', '\u048f'), ('\u0491', '\u0491'), ('\u0493', '\u0493'), ('\u0495',
+        '\u0495'), ('\u0497', '\u0497'), ('\u0499', '\u0499'), ('\u049b', '\u049b'), ('\u049d',
+        '\u049d'), ('\u049f', '\u049f'), ('\u04a1', '\u04a1'), ('\u04a3', '\u04a3'), ('\u04a5',
+        '\u04a5'), ('\u04a7', '\u04a7'), ('\u04a9', '\u04a9'), ('\u04ab', '\u04ab'), ('\u04ad',
+        '\u04ad'), ('\u04af', '\u04af'), ('\u04b1', '\u04b1'), ('\u04b3', '\u04b3'), ('\u04b5',
+        '\u04b5'), ('\u04b7', '\u04b7'), ('\u04b9', '\u04b9'), ('\u04bb', '\u04bb'), ('\u04bd',
+        '\u04bd'), ('\u04bf', '\u04bf'), ('\u04c2', '\u04c2'), ('\u04c4', '\u04c4'), ('\u04c6',
+        '\u04c6'), ('\u04c8', '\u04c8'), ('\u04ca', '\u04ca'), ('\u04cc', '\u04cc'), ('\u04ce',
+        '\u04cf'), ('\u04d1', '\u04d1'), ('\u04d3', '\u04d3'), ('\u04d5', '\u04d5'), ('\u04d7',
+        '\u04d7'), ('\u04d9', '\u04d9'), ('\u04db', '\u04db'), ('\u04dd', '\u04dd'), ('\u04df',
+        '\u04df'), ('\u04e1', '\u04e1'), ('\u04e3', '\u04e3'), ('\u04e5', '\u04e5'), ('\u04e7',
+        '\u04e7'), ('\u04e9', '\u04e9'), ('\u04eb', '\u04eb'), ('\u04ed', '\u04ed'), ('\u04ef',
+        '\u04ef'), ('\u04f1', '\u04f1'), ('\u04f3', '\u04f3'), ('\u04f5', '\u04f5'), ('\u04f7',
+        '\u04f7'), ('\u04f9', '\u04f9'), ('\u04fb', '\u04fb'), ('\u04fd', '\u04fd'), ('\u04ff',
+        '\u04ff'), ('\u0501', '\u0501'), ('\u0503', '\u0503'), ('\u0505', '\u0505'), ('\u0507',
+        '\u0507'), ('\u0509', '\u0509'), ('\u050b', '\u050b'), ('\u050d', '\u050d'), ('\u050f',
+        '\u050f'), ('\u0511', '\u0511'), ('\u0513', '\u0513'), ('\u0515', '\u0515'), ('\u0517',
+        '\u0517'), ('\u0519', '\u0519'), ('\u051b', '\u051b'), ('\u051d', '\u051d'), ('\u051f',
+        '\u051f'), ('\u0521', '\u0521'), ('\u0523', '\u0523'), ('\u0525', '\u0525'), ('\u0527',
+        '\u0527'), ('\u0529', '\u0529'), ('\u052b', '\u052b'), ('\u052d', '\u052d'), ('\u052f',
+        '\u052f'), ('\u0561', '\u0587'), ('\u1d00', '\u1d2b'), ('\u1d6b', '\u1d77'), ('\u1d79',
+        '\u1d9a'), ('\u1e01', '\u1e01'), ('\u1e03', '\u1e03'), ('\u1e05', '\u1e05'), ('\u1e07',
+        '\u1e07'), ('\u1e09', '\u1e09'), ('\u1e0b', '\u1e0b'), ('\u1e0d', '\u1e0d'), ('\u1e0f',
+        '\u1e0f'), ('\u1e11', '\u1e11'), ('\u1e13', '\u1e13'), ('\u1e15', '\u1e15'), ('\u1e17',
+        '\u1e17'), ('\u1e19', '\u1e19'), ('\u1e1b', '\u1e1b'), ('\u1e1d', '\u1e1d'), ('\u1e1f',
+        '\u1e1f'), ('\u1e21', '\u1e21'), ('\u1e23', '\u1e23'), ('\u1e25', '\u1e25'), ('\u1e27',
+        '\u1e27'), ('\u1e29', '\u1e29'), ('\u1e2b', '\u1e2b'), ('\u1e2d', '\u1e2d'), ('\u1e2f',
+        '\u1e2f'), ('\u1e31', '\u1e31'), ('\u1e33', '\u1e33'), ('\u1e35', '\u1e35'), ('\u1e37',
+        '\u1e37'), ('\u1e39', '\u1e39'), ('\u1e3b', '\u1e3b'), ('\u1e3d', '\u1e3d'), ('\u1e3f',
+        '\u1e3f'), ('\u1e41', '\u1e41'), ('\u1e43', '\u1e43'), ('\u1e45', '\u1e45'), ('\u1e47',
+        '\u1e47'), ('\u1e49', '\u1e49'), ('\u1e4b', '\u1e4b'), ('\u1e4d', '\u1e4d'), ('\u1e4f',
+        '\u1e4f'), ('\u1e51', '\u1e51'), ('\u1e53', '\u1e53'), ('\u1e55', '\u1e55'), ('\u1e57',
+        '\u1e57'), ('\u1e59', '\u1e59'), ('\u1e5b', '\u1e5b'), ('\u1e5d', '\u1e5d'), ('\u1e5f',
+        '\u1e5f'), ('\u1e61', '\u1e61'), ('\u1e63', '\u1e63'), ('\u1e65', '\u1e65'), ('\u1e67',
+        '\u1e67'), ('\u1e69', '\u1e69'), ('\u1e6b', '\u1e6b'), ('\u1e6d', '\u1e6d'), ('\u1e6f',
+        '\u1e6f'), ('\u1e71', '\u1e71'), ('\u1e73', '\u1e73'), ('\u1e75', '\u1e75'), ('\u1e77',
+        '\u1e77'), ('\u1e79', '\u1e79'), ('\u1e7b', '\u1e7b'), ('\u1e7d', '\u1e7d'), ('\u1e7f',
+        '\u1e7f'), ('\u1e81', '\u1e81'), ('\u1e83', '\u1e83'), ('\u1e85', '\u1e85'), ('\u1e87',
+        '\u1e87'), ('\u1e89', '\u1e89'), ('\u1e8b', '\u1e8b'), ('\u1e8d', '\u1e8d'), ('\u1e8f',
+        '\u1e8f'), ('\u1e91', '\u1e91'), ('\u1e93', '\u1e93'), ('\u1e95', '\u1e9d'), ('\u1e9f',
+        '\u1e9f'), ('\u1ea1', '\u1ea1'), ('\u1ea3', '\u1ea3'), ('\u1ea5', '\u1ea5'), ('\u1ea7',
+        '\u1ea7'), ('\u1ea9', '\u1ea9'), ('\u1eab', '\u1eab'), ('\u1ead', '\u1ead'), ('\u1eaf',
+        '\u1eaf'), ('\u1eb1', '\u1eb1'), ('\u1eb3', '\u1eb3'), ('\u1eb5', '\u1eb5'), ('\u1eb7',
+        '\u1eb7'), ('\u1eb9', '\u1eb9'), ('\u1ebb', '\u1ebb'), ('\u1ebd', '\u1ebd'), ('\u1ebf',
+        '\u1ebf'), ('\u1ec1', '\u1ec1'), ('\u1ec3', '\u1ec3'), ('\u1ec5', '\u1ec5'), ('\u1ec7',
+        '\u1ec7'), ('\u1ec9', '\u1ec9'), ('\u1ecb', '\u1ecb'), ('\u1ecd', '\u1ecd'), ('\u1ecf',
+        '\u1ecf'), ('\u1ed1', '\u1ed1'), ('\u1ed3', '\u1ed3'), ('\u1ed5', '\u1ed5'), ('\u1ed7',
+        '\u1ed7'), ('\u1ed9', '\u1ed9'), ('\u1edb', '\u1edb'), ('\u1edd', '\u1edd'), ('\u1edf',
+        '\u1edf'), ('\u1ee1', '\u1ee1'), ('\u1ee3', '\u1ee3'), ('\u1ee5', '\u1ee5'), ('\u1ee7',
+        '\u1ee7'), ('\u1ee9', '\u1ee9'), ('\u1eeb', '\u1eeb'), ('\u1eed', '\u1eed'), ('\u1eef',
+        '\u1eef'), ('\u1ef1', '\u1ef1'), ('\u1ef3', '\u1ef3'), ('\u1ef5', '\u1ef5'), ('\u1ef7',
+        '\u1ef7'), ('\u1ef9', '\u1ef9'), ('\u1efb', '\u1efb'), ('\u1efd', '\u1efd'), ('\u1eff',
+        '\u1f07'), ('\u1f10', '\u1f15'), ('\u1f20', '\u1f27'), ('\u1f30', '\u1f37'), ('\u1f40',
+        '\u1f45'), ('\u1f50', '\u1f57'), ('\u1f60', '\u1f67'), ('\u1f70', '\u1f7d'), ('\u1f80',
+        '\u1f87'), ('\u1f90', '\u1f97'), ('\u1fa0', '\u1fa7'), ('\u1fb0', '\u1fb4'), ('\u1fb6',
+        '\u1fb7'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fc7'), ('\u1fd0',
+        '\u1fd3'), ('\u1fd6', '\u1fd7'), ('\u1fe0', '\u1fe7'), ('\u1ff2', '\u1ff4'), ('\u1ff6',
+        '\u1ff7'), ('\u210a', '\u210a'), ('\u210e', '\u210f'), ('\u2113', '\u2113'), ('\u212f',
+        '\u212f'), ('\u2134', '\u2134'), ('\u2139', '\u2139'), ('\u213c', '\u213d'), ('\u2146',
+        '\u2149'), ('\u214e', '\u214e'), ('\u2184', '\u2184'), ('\u2c30', '\u2c5e'), ('\u2c61',
+        '\u2c61'), ('\u2c65', '\u2c66'), ('\u2c68', '\u2c68'), ('\u2c6a', '\u2c6a'), ('\u2c6c',
+        '\u2c6c'), ('\u2c71', '\u2c71'), ('\u2c73', '\u2c74'), ('\u2c76', '\u2c7b'), ('\u2c81',
+        '\u2c81'), ('\u2c83', '\u2c83'), ('\u2c85', '\u2c85'), ('\u2c87', '\u2c87'), ('\u2c89',
+        '\u2c89'), ('\u2c8b', '\u2c8b'), ('\u2c8d', '\u2c8d'), ('\u2c8f', '\u2c8f'), ('\u2c91',
+        '\u2c91'), ('\u2c93', '\u2c93'), ('\u2c95', '\u2c95'), ('\u2c97', '\u2c97'), ('\u2c99',
+        '\u2c99'), ('\u2c9b', '\u2c9b'), ('\u2c9d', '\u2c9d'), ('\u2c9f', '\u2c9f'), ('\u2ca1',
+        '\u2ca1'), ('\u2ca3', '\u2ca3'), ('\u2ca5', '\u2ca5'), ('\u2ca7', '\u2ca7'), ('\u2ca9',
+        '\u2ca9'), ('\u2cab', '\u2cab'), ('\u2cad', '\u2cad'), ('\u2caf', '\u2caf'), ('\u2cb1',
+        '\u2cb1'), ('\u2cb3', '\u2cb3'), ('\u2cb5', '\u2cb5'), ('\u2cb7', '\u2cb7'), ('\u2cb9',
+        '\u2cb9'), ('\u2cbb', '\u2cbb'), ('\u2cbd', '\u2cbd'), ('\u2cbf', '\u2cbf'), ('\u2cc1',
+        '\u2cc1'), ('\u2cc3', '\u2cc3'), ('\u2cc5', '\u2cc5'), ('\u2cc7', '\u2cc7'), ('\u2cc9',
+        '\u2cc9'), ('\u2ccb', '\u2ccb'), ('\u2ccd', '\u2ccd'), ('\u2ccf', '\u2ccf'), ('\u2cd1',
+        '\u2cd1'), ('\u2cd3', '\u2cd3'), ('\u2cd5', '\u2cd5'), ('\u2cd7', '\u2cd7'), ('\u2cd9',
+        '\u2cd9'), ('\u2cdb', '\u2cdb'), ('\u2cdd', '\u2cdd'), ('\u2cdf', '\u2cdf'), ('\u2ce1',
+        '\u2ce1'), ('\u2ce3', '\u2ce4'), ('\u2cec', '\u2cec'), ('\u2cee', '\u2cee'), ('\u2cf3',
+        '\u2cf3'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\ua641',
+        '\ua641'), ('\ua643', '\ua643'), ('\ua645', '\ua645'), ('\ua647', '\ua647'), ('\ua649',
+        '\ua649'), ('\ua64b', '\ua64b'), ('\ua64d', '\ua64d'), ('\ua64f', '\ua64f'), ('\ua651',
+        '\ua651'), ('\ua653', '\ua653'), ('\ua655', '\ua655'), ('\ua657', '\ua657'), ('\ua659',
+        '\ua659'), ('\ua65b', '\ua65b'), ('\ua65d', '\ua65d'), ('\ua65f', '\ua65f'), ('\ua661',
+        '\ua661'), ('\ua663', '\ua663'), ('\ua665', '\ua665'), ('\ua667', '\ua667'), ('\ua669',
+        '\ua669'), ('\ua66b', '\ua66b'), ('\ua66d', '\ua66d'), ('\ua681', '\ua681'), ('\ua683',
+        '\ua683'), ('\ua685', '\ua685'), ('\ua687', '\ua687'), ('\ua689', '\ua689'), ('\ua68b',
+        '\ua68b'), ('\ua68d', '\ua68d'), ('\ua68f', '\ua68f'), ('\ua691', '\ua691'), ('\ua693',
+        '\ua693'), ('\ua695', '\ua695'), ('\ua697', '\ua697'), ('\ua699', '\ua699'), ('\ua69b',
+        '\ua69b'), ('\ua723', '\ua723'), ('\ua725', '\ua725'), ('\ua727', '\ua727'), ('\ua729',
+        '\ua729'), ('\ua72b', '\ua72b'), ('\ua72d', '\ua72d'), ('\ua72f', '\ua731'), ('\ua733',
+        '\ua733'), ('\ua735', '\ua735'), ('\ua737', '\ua737'), ('\ua739', '\ua739'), ('\ua73b',
+        '\ua73b'), ('\ua73d', '\ua73d'), ('\ua73f', '\ua73f'), ('\ua741', '\ua741'), ('\ua743',
+        '\ua743'), ('\ua745', '\ua745'), ('\ua747', '\ua747'), ('\ua749', '\ua749'), ('\ua74b',
+        '\ua74b'), ('\ua74d', '\ua74d'), ('\ua74f', '\ua74f'), ('\ua751', '\ua751'), ('\ua753',
+        '\ua753'), ('\ua755', '\ua755'), ('\ua757', '\ua757'), ('\ua759', '\ua759'), ('\ua75b',
+        '\ua75b'), ('\ua75d', '\ua75d'), ('\ua75f', '\ua75f'), ('\ua761', '\ua761'), ('\ua763',
+        '\ua763'), ('\ua765', '\ua765'), ('\ua767', '\ua767'), ('\ua769', '\ua769'), ('\ua76b',
+        '\ua76b'), ('\ua76d', '\ua76d'), ('\ua76f', '\ua76f'), ('\ua771', '\ua778'), ('\ua77a',
+        '\ua77a'), ('\ua77c', '\ua77c'), ('\ua77f', '\ua77f'), ('\ua781', '\ua781'), ('\ua783',
+        '\ua783'), ('\ua785', '\ua785'), ('\ua787', '\ua787'), ('\ua78c', '\ua78c'), ('\ua78e',
+        '\ua78e'), ('\ua791', '\ua791'), ('\ua793', '\ua795'), ('\ua797', '\ua797'), ('\ua799',
+        '\ua799'), ('\ua79b', '\ua79b'), ('\ua79d', '\ua79d'), ('\ua79f', '\ua79f'), ('\ua7a1',
+        '\ua7a1'), ('\ua7a3', '\ua7a3'), ('\ua7a5', '\ua7a5'), ('\ua7a7', '\ua7a7'), ('\ua7a9',
+        '\ua7a9'), ('\ua7fa', '\ua7fa'), ('\uab30', '\uab5a'), ('\uab64', '\uab65'), ('\ufb00',
+        '\ufb06'), ('\ufb13', '\ufb17'), ('\uff41', '\uff5a'), ('\U00010428', '\U0001044f'),
+        ('\U000118c0', '\U000118df'), ('\U0001d41a', '\U0001d433'), ('\U0001d44e', '\U0001d454'),
+        ('\U0001d456', '\U0001d467'), ('\U0001d482', '\U0001d49b'), ('\U0001d4b6', '\U0001d4b9'),
+        ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d4cf'),
+        ('\U0001d4ea', '\U0001d503'), ('\U0001d51e', '\U0001d537'), ('\U0001d552', '\U0001d56b'),
+        ('\U0001d586', '\U0001d59f'), ('\U0001d5ba', '\U0001d5d3'), ('\U0001d5ee', '\U0001d607'),
+        ('\U0001d622', '\U0001d63b'), ('\U0001d656', '\U0001d66f'), ('\U0001d68a', '\U0001d6a5'),
+        ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6e1'), ('\U0001d6fc', '\U0001d714'),
+        ('\U0001d716', '\U0001d71b'), ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d755'),
+        ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d78f'), ('\U0001d7aa', '\U0001d7c2'),
+        ('\U0001d7c4', '\U0001d7c9'), ('\U0001d7cb', '\U0001d7cb')
+    ];
+
+    pub static Lm_table: &'static [(char, char)] = &[
+        ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'),
+        ('\u02ee', '\u02ee'), ('\u0374', '\u0374'), ('\u037a', '\u037a'), ('\u0559', '\u0559'),
+        ('\u0640', '\u0640'), ('\u06e5', '\u06e6'), ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
+        ('\u081a', '\u081a'), ('\u0824', '\u0824'), ('\u0828', '\u0828'), ('\u0971', '\u0971'),
+        ('\u0e46', '\u0e46'), ('\u0ec6', '\u0ec6'), ('\u10fc', '\u10fc'), ('\u17d7', '\u17d7'),
+        ('\u1843', '\u1843'), ('\u1aa7', '\u1aa7'), ('\u1c78', '\u1c7d'), ('\u1d2c', '\u1d6a'),
+        ('\u1d78', '\u1d78'), ('\u1d9b', '\u1dbf'), ('\u2071', '\u2071'), ('\u207f', '\u207f'),
+        ('\u2090', '\u209c'), ('\u2c7c', '\u2c7d'), ('\u2d6f', '\u2d6f'), ('\u2e2f', '\u2e2f'),
+        ('\u3005', '\u3005'), ('\u3031', '\u3035'), ('\u303b', '\u303b'), ('\u309d', '\u309e'),
+        ('\u30fc', '\u30fe'), ('\ua015', '\ua015'), ('\ua4f8', '\ua4fd'), ('\ua60c', '\ua60c'),
+        ('\ua67f', '\ua67f'), ('\ua69c', '\ua69d'), ('\ua717', '\ua71f'), ('\ua770', '\ua770'),
+        ('\ua788', '\ua788'), ('\ua7f8', '\ua7f9'), ('\ua9cf', '\ua9cf'), ('\ua9e6', '\ua9e6'),
+        ('\uaa70', '\uaa70'), ('\uaadd', '\uaadd'), ('\uaaf3', '\uaaf4'), ('\uab5c', '\uab5f'),
+        ('\uff70', '\uff70'), ('\uff9e', '\uff9f'), ('\U00016b40', '\U00016b43'), ('\U00016f93',
+        '\U00016f9f')
+    ];
+
+    pub static Lo_table: &'static [(char, char)] = &[
+        ('\xaa', '\xaa'), ('\xba', '\xba'), ('\u01bb', '\u01bb'), ('\u01c0', '\u01c3'), ('\u0294',
+        '\u0294'), ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'), ('\u0620', '\u063f'), ('\u0641',
+        '\u064a'), ('\u066e', '\u066f'), ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'), ('\u06ee',
+        '\u06ef'), ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'), ('\u0710', '\u0710'), ('\u0712',
+        '\u072f'), ('\u074d', '\u07a5'), ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'), ('\u0800',
+        '\u0815'), ('\u0840', '\u0858'), ('\u08a0', '\u08b2'), ('\u0904', '\u0939'), ('\u093d',
+        '\u093d'), ('\u0950', '\u0950'), ('\u0958', '\u0961'), ('\u0972', '\u0980'), ('\u0985',
+        '\u098c'), ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2',
+        '\u09b2'), ('\u09b6', '\u09b9'), ('\u09bd', '\u09bd'), ('\u09ce', '\u09ce'), ('\u09dc',
+        '\u09dd'), ('\u09df', '\u09e1'), ('\u09f0', '\u09f1'), ('\u0a05', '\u0a0a'), ('\u0a0f',
+        '\u0a10'), ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35',
+        '\u0a36'), ('\u0a38', '\u0a39'), ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'), ('\u0a72',
+        '\u0a74'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa',
+        '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abd', '\u0abd'), ('\u0ad0',
+        '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'), ('\u0b13',
+        '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'), ('\u0b3d',
+        '\u0b3d'), ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b71', '\u0b71'), ('\u0b83',
+        '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99',
+        '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8',
+        '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bd0', '\u0bd0'), ('\u0c05', '\u0c0c'), ('\u0c0e',
+        '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d', '\u0c3d'), ('\u0c58',
+        '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'), ('\u0c92',
+        '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'), ('\u0cbd', '\u0cbd'), ('\u0cde',
+        '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0cf1', '\u0cf2'), ('\u0d05', '\u0d0c'), ('\u0d0e',
+        '\u0d10'), ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d4e', '\u0d4e'), ('\u0d60',
+        '\u0d61'), ('\u0d7a', '\u0d7f'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3',
+        '\u0dbb'), ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0e01', '\u0e30'), ('\u0e32',
+        '\u0e33'), ('\u0e40', '\u0e45'), ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'), ('\u0e87',
+        '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'), ('\u0e99',
+        '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'), ('\u0eaa',
+        '\u0eab'), ('\u0ead', '\u0eb0'), ('\u0eb2', '\u0eb3'), ('\u0ebd', '\u0ebd'), ('\u0ec0',
+        '\u0ec4'), ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'), ('\u0f40', '\u0f47'), ('\u0f49',
+        '\u0f6c'), ('\u0f88', '\u0f8c'), ('\u1000', '\u102a'), ('\u103f', '\u103f'), ('\u1050',
+        '\u1055'), ('\u105a', '\u105d'), ('\u1061', '\u1061'), ('\u1065', '\u1066'), ('\u106e',
+        '\u1070'), ('\u1075', '\u1081'), ('\u108e', '\u108e'), ('\u10d0', '\u10fa'), ('\u10fd',
+        '\u1248'), ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258', '\u1258'), ('\u125a',
+        '\u125d'), ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290', '\u12b0'), ('\u12b2',
+        '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'), ('\u12c8',
+        '\u12d6'), ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318', '\u135a'), ('\u1380',
+        '\u138f'), ('\u13a0', '\u13f4'), ('\u1401', '\u166c'), ('\u166f', '\u167f'), ('\u1681',
+        '\u169a'), ('\u16a0', '\u16ea'), ('\u16f1', '\u16f8'), ('\u1700', '\u170c'), ('\u170e',
+        '\u1711'), ('\u1720', '\u1731'), ('\u1740', '\u1751'), ('\u1760', '\u176c'), ('\u176e',
+        '\u1770'), ('\u1780', '\u17b3'), ('\u17dc', '\u17dc'), ('\u1820', '\u1842'), ('\u1844',
+        '\u1877'), ('\u1880', '\u18a8'), ('\u18aa', '\u18aa'), ('\u18b0', '\u18f5'), ('\u1900',
+        '\u191e'), ('\u1950', '\u196d'), ('\u1970', '\u1974'), ('\u1980', '\u19ab'), ('\u19c1',
+        '\u19c7'), ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'), ('\u1b05', '\u1b33'), ('\u1b45',
+        '\u1b4b'), ('\u1b83', '\u1ba0'), ('\u1bae', '\u1baf'), ('\u1bba', '\u1be5'), ('\u1c00',
+        '\u1c23'), ('\u1c4d', '\u1c4f'), ('\u1c5a', '\u1c77'), ('\u1ce9', '\u1cec'), ('\u1cee',
+        '\u1cf1'), ('\u1cf5', '\u1cf6'), ('\u2135', '\u2138'), ('\u2d30', '\u2d67'), ('\u2d80',
+        '\u2d96'), ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8',
+        '\u2dbe'), ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8',
+        '\u2dde'), ('\u3006', '\u3006'), ('\u303c', '\u303c'), ('\u3041', '\u3096'), ('\u309f',
+        '\u309f'), ('\u30a1', '\u30fa'), ('\u30ff', '\u30ff'), ('\u3105', '\u312d'), ('\u3131',
+        '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400', '\u3400'), ('\u4db5',
+        '\u4db5'), ('\u4e00', '\u4e00'), ('\u9fcc', '\u9fcc'), ('\ua000', '\ua014'), ('\ua016',
+        '\ua48c'), ('\ua4d0', '\ua4f7'), ('\ua500', '\ua60b'), ('\ua610', '\ua61f'), ('\ua62a',
+        '\ua62b'), ('\ua66e', '\ua66e'), ('\ua6a0', '\ua6e5'), ('\ua7f7', '\ua7f7'), ('\ua7fb',
+        '\ua801'), ('\ua803', '\ua805'), ('\ua807', '\ua80a'), ('\ua80c', '\ua822'), ('\ua840',
+        '\ua873'), ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'), ('\ua8fb', '\ua8fb'), ('\ua90a',
+        '\ua925'), ('\ua930', '\ua946'), ('\ua960', '\ua97c'), ('\ua984', '\ua9b2'), ('\ua9e0',
+        '\ua9e4'), ('\ua9e7', '\ua9ef'), ('\ua9fa', '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa40',
+        '\uaa42'), ('\uaa44', '\uaa4b'), ('\uaa60', '\uaa6f'), ('\uaa71', '\uaa76'), ('\uaa7a',
+        '\uaa7a'), ('\uaa7e', '\uaaaf'), ('\uaab1', '\uaab1'), ('\uaab5', '\uaab6'), ('\uaab9',
+        '\uaabd'), ('\uaac0', '\uaac0'), ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'), ('\uaae0',
+        '\uaaea'), ('\uaaf2', '\uaaf2'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'), ('\uab11',
+        '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e'), ('\uabc0', '\uabe2'), ('\uac00',
+        '\uac00'), ('\ud7a3', '\ud7a3'), ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900',
+        '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb1d', '\ufb1d'), ('\ufb1f', '\ufb28'), ('\ufb2a',
+        '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'), ('\ufb40', '\ufb41'), ('\ufb43',
+        '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92',
+        '\ufdc7'), ('\ufdf0', '\ufdfb'), ('\ufe70', '\ufe74'), ('\ufe76', '\ufefc'), ('\uff66',
+        '\uff6f'), ('\uff71', '\uff9d'), ('\uffa0', '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca',
+        '\uffcf'), ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'), ('\U00010000', '\U0001000b'),
+        ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'),
+        ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'), ('\U00010080', '\U000100fa'),
+        ('\U00010280', '\U0001029c'), ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031f'),
+        ('\U00010330', '\U00010340'), ('\U00010342', '\U00010349'), ('\U00010350', '\U00010375'),
+        ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'), ('\U000103c8', '\U000103cf'),
+        ('\U00010450', '\U0001049d'), ('\U00010500', '\U00010527'), ('\U00010530', '\U00010563'),
+        ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'), ('\U00010760', '\U00010767'),
+        ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
+        ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'), ('\U0001083f', '\U00010855'),
+        ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'), ('\U00010900', '\U00010915'),
+        ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'), ('\U000109be', '\U000109bf'),
+        ('\U00010a00', '\U00010a00'), ('\U00010a10', '\U00010a13'), ('\U00010a15', '\U00010a17'),
+        ('\U00010a19', '\U00010a33'), ('\U00010a60', '\U00010a7c'), ('\U00010a80', '\U00010a9c'),
+        ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae4'), ('\U00010b00', '\U00010b35'),
+        ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'), ('\U00010b80', '\U00010b91'),
+        ('\U00010c00', '\U00010c48'), ('\U00011003', '\U00011037'), ('\U00011083', '\U000110af'),
+        ('\U000110d0', '\U000110e8'), ('\U00011103', '\U00011126'), ('\U00011150', '\U00011172'),
+        ('\U00011176', '\U00011176'), ('\U00011183', '\U000111b2'), ('\U000111c1', '\U000111c4'),
+        ('\U000111da', '\U000111da'), ('\U00011200', '\U00011211'), ('\U00011213', '\U0001122b'),
+        ('\U000112b0', '\U000112de'), ('\U00011305', '\U0001130c'), ('\U0001130f', '\U00011310'),
+        ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'), ('\U00011332', '\U00011333'),
+        ('\U00011335', '\U00011339'), ('\U0001133d', '\U0001133d'), ('\U0001135d', '\U00011361'),
+        ('\U00011480', '\U000114af'), ('\U000114c4', '\U000114c5'), ('\U000114c7', '\U000114c7'),
+        ('\U00011580', '\U000115ae'), ('\U00011600', '\U0001162f'), ('\U00011644', '\U00011644'),
+        ('\U00011680', '\U000116aa'), ('\U000118ff', '\U000118ff'), ('\U00011ac0', '\U00011af8'),
+        ('\U00012000', '\U00012398'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
+        ('\U00016a40', '\U00016a5e'), ('\U00016ad0', '\U00016aed'), ('\U00016b00', '\U00016b2f'),
+        ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'), ('\U00016f00', '\U00016f44'),
+        ('\U00016f50', '\U00016f50'), ('\U0001b000', '\U0001b001'), ('\U0001bc00', '\U0001bc6a'),
+        ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80', '\U0001bc88'), ('\U0001bc90', '\U0001bc99'),
+        ('\U0001e800', '\U0001e8c4'), ('\U0001ee00', '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'),
+        ('\U0001ee21', '\U0001ee22'), ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'),
+        ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'), ('\U0001ee39', '\U0001ee39'),
+        ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'),
+        ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'),
+        ('\U0001ee51', '\U0001ee52'), ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'),
+        ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'),
+        ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'),
+        ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'), ('\U0001ee74', '\U0001ee77'),
+        ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'),
+        ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'), ('\U0001eea5', '\U0001eea9'),
+        ('\U0001eeab', '\U0001eebb'), ('\U00020000', '\U00020000'), ('\U0002a6d6', '\U0002a6d6'),
+        ('\U0002a700', '\U0002a700'), ('\U0002b734', '\U0002b734'), ('\U0002b740', '\U0002b740'),
+        ('\U0002b81d', '\U0002b81d'), ('\U0002f800', '\U0002fa1d')
+    ];
+
+    pub static Lt_table: &'static [(char, char)] = &[
+        ('\u01c5', '\u01c5'), ('\u01c8', '\u01c8'), ('\u01cb', '\u01cb'), ('\u01f2', '\u01f2'),
+        ('\u1f88', '\u1f8f'), ('\u1f98', '\u1f9f'), ('\u1fa8', '\u1faf'), ('\u1fbc', '\u1fbc'),
+        ('\u1fcc', '\u1fcc'), ('\u1ffc', '\u1ffc')
+    ];
+
+    pub static Lu_table: &'static [(char, char)] = &[
+        ('\x41', '\x5a'), ('\xc0', '\xd6'), ('\xd8', '\xde'), ('\u0100', '\u0100'), ('\u0102',
+        '\u0102'), ('\u0104', '\u0104'), ('\u0106', '\u0106'), ('\u0108', '\u0108'), ('\u010a',
+        '\u010a'), ('\u010c', '\u010c'), ('\u010e', '\u010e'), ('\u0110', '\u0110'), ('\u0112',
+        '\u0112'), ('\u0114', '\u0114'), ('\u0116', '\u0116'), ('\u0118', '\u0118'), ('\u011a',
+        '\u011a'), ('\u011c', '\u011c'), ('\u011e', '\u011e'), ('\u0120', '\u0120'), ('\u0122',
+        '\u0122'), ('\u0124', '\u0124'), ('\u0126', '\u0126'), ('\u0128', '\u0128'), ('\u012a',
+        '\u012a'), ('\u012c', '\u012c'), ('\u012e', '\u012e'), ('\u0130', '\u0130'), ('\u0132',
+        '\u0132'), ('\u0134', '\u0134'), ('\u0136', '\u0136'), ('\u0139', '\u0139'), ('\u013b',
+        '\u013b'), ('\u013d', '\u013d'), ('\u013f', '\u013f'), ('\u0141', '\u0141'), ('\u0143',
+        '\u0143'), ('\u0145', '\u0145'), ('\u0147', '\u0147'), ('\u014a', '\u014a'), ('\u014c',
+        '\u014c'), ('\u014e', '\u014e'), ('\u0150', '\u0150'), ('\u0152', '\u0152'), ('\u0154',
+        '\u0154'), ('\u0156', '\u0156'), ('\u0158', '\u0158'), ('\u015a', '\u015a'), ('\u015c',
+        '\u015c'), ('\u015e', '\u015e'), ('\u0160', '\u0160'), ('\u0162', '\u0162'), ('\u0164',
+        '\u0164'), ('\u0166', '\u0166'), ('\u0168', '\u0168'), ('\u016a', '\u016a'), ('\u016c',
+        '\u016c'), ('\u016e', '\u016e'), ('\u0170', '\u0170'), ('\u0172', '\u0172'), ('\u0174',
+        '\u0174'), ('\u0176', '\u0176'), ('\u0178', '\u0179'), ('\u017b', '\u017b'), ('\u017d',
+        '\u017d'), ('\u0181', '\u0182'), ('\u0184', '\u0184'), ('\u0186', '\u0187'), ('\u0189',
+        '\u018b'), ('\u018e', '\u0191'), ('\u0193', '\u0194'), ('\u0196', '\u0198'), ('\u019c',
+        '\u019d'), ('\u019f', '\u01a0'), ('\u01a2', '\u01a2'), ('\u01a4', '\u01a4'), ('\u01a6',
+        '\u01a7'), ('\u01a9', '\u01a9'), ('\u01ac', '\u01ac'), ('\u01ae', '\u01af'), ('\u01b1',
+        '\u01b3'), ('\u01b5', '\u01b5'), ('\u01b7', '\u01b8'), ('\u01bc', '\u01bc'), ('\u01c4',
+        '\u01c4'), ('\u01c7', '\u01c7'), ('\u01ca', '\u01ca'), ('\u01cd', '\u01cd'), ('\u01cf',
+        '\u01cf'), ('\u01d1', '\u01d1'), ('\u01d3', '\u01d3'), ('\u01d5', '\u01d5'), ('\u01d7',
+        '\u01d7'), ('\u01d9', '\u01d9'), ('\u01db', '\u01db'), ('\u01de', '\u01de'), ('\u01e0',
+        '\u01e0'), ('\u01e2', '\u01e2'), ('\u01e4', '\u01e4'), ('\u01e6', '\u01e6'), ('\u01e8',
+        '\u01e8'), ('\u01ea', '\u01ea'), ('\u01ec', '\u01ec'), ('\u01ee', '\u01ee'), ('\u01f1',
+        '\u01f1'), ('\u01f4', '\u01f4'), ('\u01f6', '\u01f8'), ('\u01fa', '\u01fa'), ('\u01fc',
+        '\u01fc'), ('\u01fe', '\u01fe'), ('\u0200', '\u0200'), ('\u0202', '\u0202'), ('\u0204',
+        '\u0204'), ('\u0206', '\u0206'), ('\u0208', '\u0208'), ('\u020a', '\u020a'), ('\u020c',
+        '\u020c'), ('\u020e', '\u020e'), ('\u0210', '\u0210'), ('\u0212', '\u0212'), ('\u0214',
+        '\u0214'), ('\u0216', '\u0216'), ('\u0218', '\u0218'), ('\u021a', '\u021a'), ('\u021c',
+        '\u021c'), ('\u021e', '\u021e'), ('\u0220', '\u0220'), ('\u0222', '\u0222'), ('\u0224',
+        '\u0224'), ('\u0226', '\u0226'), ('\u0228', '\u0228'), ('\u022a', '\u022a'), ('\u022c',
+        '\u022c'), ('\u022e', '\u022e'), ('\u0230', '\u0230'), ('\u0232', '\u0232'), ('\u023a',
+        '\u023b'), ('\u023d', '\u023e'), ('\u0241', '\u0241'), ('\u0243', '\u0246'), ('\u0248',
+        '\u0248'), ('\u024a', '\u024a'), ('\u024c', '\u024c'), ('\u024e', '\u024e'), ('\u0370',
+        '\u0370'), ('\u0372', '\u0372'), ('\u0376', '\u0376'), ('\u037f', '\u037f'), ('\u0386',
+        '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u038f'), ('\u0391',
+        '\u03a1'), ('\u03a3', '\u03ab'), ('\u03cf', '\u03cf'), ('\u03d2', '\u03d4'), ('\u03d8',
+        '\u03d8'), ('\u03da', '\u03da'), ('\u03dc', '\u03dc'), ('\u03de', '\u03de'), ('\u03e0',
+        '\u03e0'), ('\u03e2', '\u03e2'), ('\u03e4', '\u03e4'), ('\u03e6', '\u03e6'), ('\u03e8',
+        '\u03e8'), ('\u03ea', '\u03ea'), ('\u03ec', '\u03ec'), ('\u03ee', '\u03ee'), ('\u03f4',
+        '\u03f4'), ('\u03f7', '\u03f7'), ('\u03f9', '\u03fa'), ('\u03fd', '\u042f'), ('\u0460',
+        '\u0460'), ('\u0462', '\u0462'), ('\u0464', '\u0464'), ('\u0466', '\u0466'), ('\u0468',
+        '\u0468'), ('\u046a', '\u046a'), ('\u046c', '\u046c'), ('\u046e', '\u046e'), ('\u0470',
+        '\u0470'), ('\u0472', '\u0472'), ('\u0474', '\u0474'), ('\u0476', '\u0476'), ('\u0478',
+        '\u0478'), ('\u047a', '\u047a'), ('\u047c', '\u047c'), ('\u047e', '\u047e'), ('\u0480',
+        '\u0480'), ('\u048a', '\u048a'), ('\u048c', '\u048c'), ('\u048e', '\u048e'), ('\u0490',
+        '\u0490'), ('\u0492', '\u0492'), ('\u0494', '\u0494'), ('\u0496', '\u0496'), ('\u0498',
+        '\u0498'), ('\u049a', '\u049a'), ('\u049c', '\u049c'), ('\u049e', '\u049e'), ('\u04a0',
+        '\u04a0'), ('\u04a2', '\u04a2'), ('\u04a4', '\u04a4'), ('\u04a6', '\u04a6'), ('\u04a8',
+        '\u04a8'), ('\u04aa', '\u04aa'), ('\u04ac', '\u04ac'), ('\u04ae', '\u04ae'), ('\u04b0',
+        '\u04b0'), ('\u04b2', '\u04b2'), ('\u04b4', '\u04b4'), ('\u04b6', '\u04b6'), ('\u04b8',
+        '\u04b8'), ('\u04ba', '\u04ba'), ('\u04bc', '\u04bc'), ('\u04be', '\u04be'), ('\u04c0',
+        '\u04c1'), ('\u04c3', '\u04c3'), ('\u04c5', '\u04c5'), ('\u04c7', '\u04c7'), ('\u04c9',
+        '\u04c9'), ('\u04cb', '\u04cb'), ('\u04cd', '\u04cd'), ('\u04d0', '\u04d0'), ('\u04d2',
+        '\u04d2'), ('\u04d4', '\u04d4'), ('\u04d6', '\u04d6'), ('\u04d8', '\u04d8'), ('\u04da',
+        '\u04da'), ('\u04dc', '\u04dc'), ('\u04de', '\u04de'), ('\u04e0', '\u04e0'), ('\u04e2',
+        '\u04e2'), ('\u04e4', '\u04e4'), ('\u04e6', '\u04e6'), ('\u04e8', '\u04e8'), ('\u04ea',
+        '\u04ea'), ('\u04ec', '\u04ec'), ('\u04ee', '\u04ee'), ('\u04f0', '\u04f0'), ('\u04f2',
+        '\u04f2'), ('\u04f4', '\u04f4'), ('\u04f6', '\u04f6'), ('\u04f8', '\u04f8'), ('\u04fa',
+        '\u04fa'), ('\u04fc', '\u04fc'), ('\u04fe', '\u04fe'), ('\u0500', '\u0500'), ('\u0502',
+        '\u0502'), ('\u0504', '\u0504'), ('\u0506', '\u0506'), ('\u0508', '\u0508'), ('\u050a',
+        '\u050a'), ('\u050c', '\u050c'), ('\u050e', '\u050e'), ('\u0510', '\u0510'), ('\u0512',
+        '\u0512'), ('\u0514', '\u0514'), ('\u0516', '\u0516'), ('\u0518', '\u0518'), ('\u051a',
+        '\u051a'), ('\u051c', '\u051c'), ('\u051e', '\u051e'), ('\u0520', '\u0520'), ('\u0522',
+        '\u0522'), ('\u0524', '\u0524'), ('\u0526', '\u0526'), ('\u0528', '\u0528'), ('\u052a',
+        '\u052a'), ('\u052c', '\u052c'), ('\u052e', '\u052e'), ('\u0531', '\u0556'), ('\u10a0',
+        '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u1e00', '\u1e00'), ('\u1e02',
+        '\u1e02'), ('\u1e04', '\u1e04'), ('\u1e06', '\u1e06'), ('\u1e08', '\u1e08'), ('\u1e0a',
+        '\u1e0a'), ('\u1e0c', '\u1e0c'), ('\u1e0e', '\u1e0e'), ('\u1e10', '\u1e10'), ('\u1e12',
+        '\u1e12'), ('\u1e14', '\u1e14'), ('\u1e16', '\u1e16'), ('\u1e18', '\u1e18'), ('\u1e1a',
+        '\u1e1a'), ('\u1e1c', '\u1e1c'), ('\u1e1e', '\u1e1e'), ('\u1e20', '\u1e20'), ('\u1e22',
+        '\u1e22'), ('\u1e24', '\u1e24'), ('\u1e26', '\u1e26'), ('\u1e28', '\u1e28'), ('\u1e2a',
+        '\u1e2a'), ('\u1e2c', '\u1e2c'), ('\u1e2e', '\u1e2e'), ('\u1e30', '\u1e30'), ('\u1e32',
+        '\u1e32'), ('\u1e34', '\u1e34'), ('\u1e36', '\u1e36'), ('\u1e38', '\u1e38'), ('\u1e3a',
+        '\u1e3a'), ('\u1e3c', '\u1e3c'), ('\u1e3e', '\u1e3e'), ('\u1e40', '\u1e40'), ('\u1e42',
+        '\u1e42'), ('\u1e44', '\u1e44'), ('\u1e46', '\u1e46'), ('\u1e48', '\u1e48'), ('\u1e4a',
+        '\u1e4a'), ('\u1e4c', '\u1e4c'), ('\u1e4e', '\u1e4e'), ('\u1e50', '\u1e50'), ('\u1e52',
+        '\u1e52'), ('\u1e54', '\u1e54'), ('\u1e56', '\u1e56'), ('\u1e58', '\u1e58'), ('\u1e5a',
+        '\u1e5a'), ('\u1e5c', '\u1e5c'), ('\u1e5e', '\u1e5e'), ('\u1e60', '\u1e60'), ('\u1e62',
+        '\u1e62'), ('\u1e64', '\u1e64'), ('\u1e66', '\u1e66'), ('\u1e68', '\u1e68'), ('\u1e6a',
+        '\u1e6a'), ('\u1e6c', '\u1e6c'), ('\u1e6e', '\u1e6e'), ('\u1e70', '\u1e70'), ('\u1e72',
+        '\u1e72'), ('\u1e74', '\u1e74'), ('\u1e76', '\u1e76'), ('\u1e78', '\u1e78'), ('\u1e7a',
+        '\u1e7a'), ('\u1e7c', '\u1e7c'), ('\u1e7e', '\u1e7e'), ('\u1e80', '\u1e80'), ('\u1e82',
+        '\u1e82'), ('\u1e84', '\u1e84'), ('\u1e86', '\u1e86'), ('\u1e88', '\u1e88'), ('\u1e8a',
+        '\u1e8a'), ('\u1e8c', '\u1e8c'), ('\u1e8e', '\u1e8e'), ('\u1e90', '\u1e90'), ('\u1e92',
+        '\u1e92'), ('\u1e94', '\u1e94'), ('\u1e9e', '\u1e9e'), ('\u1ea0', '\u1ea0'), ('\u1ea2',
+        '\u1ea2'), ('\u1ea4', '\u1ea4'), ('\u1ea6', '\u1ea6'), ('\u1ea8', '\u1ea8'), ('\u1eaa',
+        '\u1eaa'), ('\u1eac', '\u1eac'), ('\u1eae', '\u1eae'), ('\u1eb0', '\u1eb0'), ('\u1eb2',
+        '\u1eb2'), ('\u1eb4', '\u1eb4'), ('\u1eb6', '\u1eb6'), ('\u1eb8', '\u1eb8'), ('\u1eba',
+        '\u1eba'), ('\u1ebc', '\u1ebc'), ('\u1ebe', '\u1ebe'), ('\u1ec0', '\u1ec0'), ('\u1ec2',
+        '\u1ec2'), ('\u1ec4', '\u1ec4'), ('\u1ec6', '\u1ec6'), ('\u1ec8', '\u1ec8'), ('\u1eca',
+        '\u1eca'), ('\u1ecc', '\u1ecc'), ('\u1ece', '\u1ece'), ('\u1ed0', '\u1ed0'), ('\u1ed2',
+        '\u1ed2'), ('\u1ed4', '\u1ed4'), ('\u1ed6', '\u1ed6'), ('\u1ed8', '\u1ed8'), ('\u1eda',
+        '\u1eda'), ('\u1edc', '\u1edc'), ('\u1ede', '\u1ede'), ('\u1ee0', '\u1ee0'), ('\u1ee2',
+        '\u1ee2'), ('\u1ee4', '\u1ee4'), ('\u1ee6', '\u1ee6'), ('\u1ee8', '\u1ee8'), ('\u1eea',
+        '\u1eea'), ('\u1eec', '\u1eec'), ('\u1eee', '\u1eee'), ('\u1ef0', '\u1ef0'), ('\u1ef2',
+        '\u1ef2'), ('\u1ef4', '\u1ef4'), ('\u1ef6', '\u1ef6'), ('\u1ef8', '\u1ef8'), ('\u1efa',
+        '\u1efa'), ('\u1efc', '\u1efc'), ('\u1efe', '\u1efe'), ('\u1f08', '\u1f0f'), ('\u1f18',
+        '\u1f1d'), ('\u1f28', '\u1f2f'), ('\u1f38', '\u1f3f'), ('\u1f48', '\u1f4d'), ('\u1f59',
+        '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f5f'), ('\u1f68',
+        '\u1f6f'), ('\u1fb8', '\u1fbb'), ('\u1fc8', '\u1fcb'), ('\u1fd8', '\u1fdb'), ('\u1fe8',
+        '\u1fec'), ('\u1ff8', '\u1ffb'), ('\u2102', '\u2102'), ('\u2107', '\u2107'), ('\u210b',
+        '\u210d'), ('\u2110', '\u2112'), ('\u2115', '\u2115'), ('\u2119', '\u211d'), ('\u2124',
+        '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u2130',
+        '\u2133'), ('\u213e', '\u213f'), ('\u2145', '\u2145'), ('\u2183', '\u2183'), ('\u2c00',
+        '\u2c2e'), ('\u2c60', '\u2c60'), ('\u2c62', '\u2c64'), ('\u2c67', '\u2c67'), ('\u2c69',
+        '\u2c69'), ('\u2c6b', '\u2c6b'), ('\u2c6d', '\u2c70'), ('\u2c72', '\u2c72'), ('\u2c75',
+        '\u2c75'), ('\u2c7e', '\u2c80'), ('\u2c82', '\u2c82'), ('\u2c84', '\u2c84'), ('\u2c86',
+        '\u2c86'), ('\u2c88', '\u2c88'), ('\u2c8a', '\u2c8a'), ('\u2c8c', '\u2c8c'), ('\u2c8e',
+        '\u2c8e'), ('\u2c90', '\u2c90'), ('\u2c92', '\u2c92'), ('\u2c94', '\u2c94'), ('\u2c96',
+        '\u2c96'), ('\u2c98', '\u2c98'), ('\u2c9a', '\u2c9a'), ('\u2c9c', '\u2c9c'), ('\u2c9e',
+        '\u2c9e'), ('\u2ca0', '\u2ca0'), ('\u2ca2', '\u2ca2'), ('\u2ca4', '\u2ca4'), ('\u2ca6',
+        '\u2ca6'), ('\u2ca8', '\u2ca8'), ('\u2caa', '\u2caa'), ('\u2cac', '\u2cac'), ('\u2cae',
+        '\u2cae'), ('\u2cb0', '\u2cb0'), ('\u2cb2', '\u2cb2'), ('\u2cb4', '\u2cb4'), ('\u2cb6',
+        '\u2cb6'), ('\u2cb8', '\u2cb8'), ('\u2cba', '\u2cba'), ('\u2cbc', '\u2cbc'), ('\u2cbe',
+        '\u2cbe'), ('\u2cc0', '\u2cc0'), ('\u2cc2', '\u2cc2'), ('\u2cc4', '\u2cc4'), ('\u2cc6',
+        '\u2cc6'), ('\u2cc8', '\u2cc8'), ('\u2cca', '\u2cca'), ('\u2ccc', '\u2ccc'), ('\u2cce',
+        '\u2cce'), ('\u2cd0', '\u2cd0'), ('\u2cd2', '\u2cd2'), ('\u2cd4', '\u2cd4'), ('\u2cd6',
+        '\u2cd6'), ('\u2cd8', '\u2cd8'), ('\u2cda', '\u2cda'), ('\u2cdc', '\u2cdc'), ('\u2cde',
+        '\u2cde'), ('\u2ce0', '\u2ce0'), ('\u2ce2', '\u2ce2'), ('\u2ceb', '\u2ceb'), ('\u2ced',
+        '\u2ced'), ('\u2cf2', '\u2cf2'), ('\ua640', '\ua640'), ('\ua642', '\ua642'), ('\ua644',
+        '\ua644'), ('\ua646', '\ua646'), ('\ua648', '\ua648'), ('\ua64a', '\ua64a'), ('\ua64c',
+        '\ua64c'), ('\ua64e', '\ua64e'), ('\ua650', '\ua650'), ('\ua652', '\ua652'), ('\ua654',
+        '\ua654'), ('\ua656', '\ua656'), ('\ua658', '\ua658'), ('\ua65a', '\ua65a'), ('\ua65c',
+        '\ua65c'), ('\ua65e', '\ua65e'), ('\ua660', '\ua660'), ('\ua662', '\ua662'), ('\ua664',
+        '\ua664'), ('\ua666', '\ua666'), ('\ua668', '\ua668'), ('\ua66a', '\ua66a'), ('\ua66c',
+        '\ua66c'), ('\ua680', '\ua680'), ('\ua682', '\ua682'), ('\ua684', '\ua684'), ('\ua686',
+        '\ua686'), ('\ua688', '\ua688'), ('\ua68a', '\ua68a'), ('\ua68c', '\ua68c'), ('\ua68e',
+        '\ua68e'), ('\ua690', '\ua690'), ('\ua692', '\ua692'), ('\ua694', '\ua694'), ('\ua696',
+        '\ua696'), ('\ua698', '\ua698'), ('\ua69a', '\ua69a'), ('\ua722', '\ua722'), ('\ua724',
+        '\ua724'), ('\ua726', '\ua726'), ('\ua728', '\ua728'), ('\ua72a', '\ua72a'), ('\ua72c',
+        '\ua72c'), ('\ua72e', '\ua72e'), ('\ua732', '\ua732'), ('\ua734', '\ua734'), ('\ua736',
+        '\ua736'), ('\ua738', '\ua738'), ('\ua73a', '\ua73a'), ('\ua73c', '\ua73c'), ('\ua73e',
+        '\ua73e'), ('\ua740', '\ua740'), ('\ua742', '\ua742'), ('\ua744', '\ua744'), ('\ua746',
+        '\ua746'), ('\ua748', '\ua748'), ('\ua74a', '\ua74a'), ('\ua74c', '\ua74c'), ('\ua74e',
+        '\ua74e'), ('\ua750', '\ua750'), ('\ua752', '\ua752'), ('\ua754', '\ua754'), ('\ua756',
+        '\ua756'), ('\ua758', '\ua758'), ('\ua75a', '\ua75a'), ('\ua75c', '\ua75c'), ('\ua75e',
+        '\ua75e'), ('\ua760', '\ua760'), ('\ua762', '\ua762'), ('\ua764', '\ua764'), ('\ua766',
+        '\ua766'), ('\ua768', '\ua768'), ('\ua76a', '\ua76a'), ('\ua76c', '\ua76c'), ('\ua76e',
+        '\ua76e'), ('\ua779', '\ua779'), ('\ua77b', '\ua77b'), ('\ua77d', '\ua77e'), ('\ua780',
+        '\ua780'), ('\ua782', '\ua782'), ('\ua784', '\ua784'), ('\ua786', '\ua786'), ('\ua78b',
+        '\ua78b'), ('\ua78d', '\ua78d'), ('\ua790', '\ua790'), ('\ua792', '\ua792'), ('\ua796',
+        '\ua796'), ('\ua798', '\ua798'), ('\ua79a', '\ua79a'), ('\ua79c', '\ua79c'), ('\ua79e',
+        '\ua79e'), ('\ua7a0', '\ua7a0'), ('\ua7a2', '\ua7a2'), ('\ua7a4', '\ua7a4'), ('\ua7a6',
+        '\ua7a6'), ('\ua7a8', '\ua7a8'), ('\ua7aa', '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\uff21',
+        '\uff3a'), ('\U00010400', '\U00010427'), ('\U000118a0', '\U000118bf'), ('\U0001d400',
+        '\U0001d419'), ('\U0001d434', '\U0001d44d'), ('\U0001d468', '\U0001d481'), ('\U0001d49c',
+        '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5',
+        '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b5'), ('\U0001d4d0',
+        '\U0001d4e9'), ('\U0001d504', '\U0001d505'), ('\U0001d507', '\U0001d50a'), ('\U0001d50d',
+        '\U0001d514'), ('\U0001d516', '\U0001d51c'), ('\U0001d538', '\U0001d539'), ('\U0001d53b',
+        '\U0001d53e'), ('\U0001d540', '\U0001d544'), ('\U0001d546', '\U0001d546'), ('\U0001d54a',
+        '\U0001d550'), ('\U0001d56c', '\U0001d585'), ('\U0001d5a0', '\U0001d5b9'), ('\U0001d5d4',
+        '\U0001d5ed'), ('\U0001d608', '\U0001d621'), ('\U0001d63c', '\U0001d655'), ('\U0001d670',
+        '\U0001d689'), ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6e2', '\U0001d6fa'), ('\U0001d71c',
+        '\U0001d734'), ('\U0001d756', '\U0001d76e'), ('\U0001d790', '\U0001d7a8'), ('\U0001d7ca',
+        '\U0001d7ca')
+    ];
+
+    pub static M_table: &'static [(char, char)] = &[
+        ('\u0300', '\u036f'), ('\u0483', '\u0489'), ('\u0591', '\u05bd'), ('\u05bf', '\u05bf'),
+        ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u0610', '\u061a'),
+        ('\u064b', '\u065f'), ('\u0670', '\u0670'), ('\u06d6', '\u06dc'), ('\u06df', '\u06e4'),
+        ('\u06e7', '\u06e8'), ('\u06ea', '\u06ed'), ('\u0711', '\u0711'), ('\u0730', '\u074a'),
+        ('\u07a6', '\u07b0'), ('\u07eb', '\u07f3'), ('\u0816', '\u0819'), ('\u081b', '\u0823'),
+        ('\u0825', '\u0827'), ('\u0829', '\u082d'), ('\u0859', '\u085b'), ('\u08e4', '\u0903'),
+        ('\u093a', '\u093c'), ('\u093e', '\u094f'), ('\u0951', '\u0957'), ('\u0962', '\u0963'),
+        ('\u0981', '\u0983'), ('\u09bc', '\u09bc'), ('\u09be', '\u09c4'), ('\u09c7', '\u09c8'),
+        ('\u09cb', '\u09cd'), ('\u09d7', '\u09d7'), ('\u09e2', '\u09e3'), ('\u0a01', '\u0a03'),
+        ('\u0a3c', '\u0a3c'), ('\u0a3e', '\u0a42'), ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'),
+        ('\u0a51', '\u0a51'), ('\u0a70', '\u0a71'), ('\u0a75', '\u0a75'), ('\u0a81', '\u0a83'),
+        ('\u0abc', '\u0abc'), ('\u0abe', '\u0ac5'), ('\u0ac7', '\u0ac9'), ('\u0acb', '\u0acd'),
+        ('\u0ae2', '\u0ae3'), ('\u0b01', '\u0b03'), ('\u0b3c', '\u0b3c'), ('\u0b3e', '\u0b44'),
+        ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4d'), ('\u0b56', '\u0b57'), ('\u0b62', '\u0b63'),
+        ('\u0b82', '\u0b82'), ('\u0bbe', '\u0bc2'), ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcd'),
+        ('\u0bd7', '\u0bd7'), ('\u0c00', '\u0c03'), ('\u0c3e', '\u0c44'), ('\u0c46', '\u0c48'),
+        ('\u0c4a', '\u0c4d'), ('\u0c55', '\u0c56'), ('\u0c62', '\u0c63'), ('\u0c81', '\u0c83'),
+        ('\u0cbc', '\u0cbc'), ('\u0cbe', '\u0cc4'), ('\u0cc6', '\u0cc8'), ('\u0cca', '\u0ccd'),
+        ('\u0cd5', '\u0cd6'), ('\u0ce2', '\u0ce3'), ('\u0d01', '\u0d03'), ('\u0d3e', '\u0d44'),
+        ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4d'), ('\u0d57', '\u0d57'), ('\u0d62', '\u0d63'),
+        ('\u0d82', '\u0d83'), ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd4'), ('\u0dd6', '\u0dd6'),
+        ('\u0dd8', '\u0ddf'), ('\u0df2', '\u0df3'), ('\u0e31', '\u0e31'), ('\u0e34', '\u0e3a'),
+        ('\u0e47', '\u0e4e'), ('\u0eb1', '\u0eb1'), ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
+        ('\u0ec8', '\u0ecd'), ('\u0f18', '\u0f19'), ('\u0f35', '\u0f35'), ('\u0f37', '\u0f37'),
+        ('\u0f39', '\u0f39'), ('\u0f3e', '\u0f3f'), ('\u0f71', '\u0f84'), ('\u0f86', '\u0f87'),
+        ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'), ('\u0fc6', '\u0fc6'), ('\u102b', '\u103e'),
+        ('\u1056', '\u1059'), ('\u105e', '\u1060'), ('\u1062', '\u1064'), ('\u1067', '\u106d'),
+        ('\u1071', '\u1074'), ('\u1082', '\u108d'), ('\u108f', '\u108f'), ('\u109a', '\u109d'),
+        ('\u135d', '\u135f'), ('\u1712', '\u1714'), ('\u1732', '\u1734'), ('\u1752', '\u1753'),
+        ('\u1772', '\u1773'), ('\u17b4', '\u17d3'), ('\u17dd', '\u17dd'), ('\u180b', '\u180d'),
+        ('\u18a9', '\u18a9'), ('\u1920', '\u192b'), ('\u1930', '\u193b'), ('\u19b0', '\u19c0'),
+        ('\u19c8', '\u19c9'), ('\u1a17', '\u1a1b'), ('\u1a55', '\u1a5e'), ('\u1a60', '\u1a7c'),
+        ('\u1a7f', '\u1a7f'), ('\u1ab0', '\u1abe'), ('\u1b00', '\u1b04'), ('\u1b34', '\u1b44'),
+        ('\u1b6b', '\u1b73'), ('\u1b80', '\u1b82'), ('\u1ba1', '\u1bad'), ('\u1be6', '\u1bf3'),
+        ('\u1c24', '\u1c37'), ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1ce8'), ('\u1ced', '\u1ced'),
+        ('\u1cf2', '\u1cf4'), ('\u1cf8', '\u1cf9'), ('\u1dc0', '\u1df5'), ('\u1dfc', '\u1dff'),
+        ('\u20d0', '\u20f0'), ('\u2cef', '\u2cf1'), ('\u2d7f', '\u2d7f'), ('\u2de0', '\u2dff'),
+        ('\u302a', '\u302f'), ('\u3099', '\u309a'), ('\ua66f', '\ua672'), ('\ua674', '\ua67d'),
+        ('\ua69f', '\ua69f'), ('\ua6f0', '\ua6f1'), ('\ua802', '\ua802'), ('\ua806', '\ua806'),
+        ('\ua80b', '\ua80b'), ('\ua823', '\ua827'), ('\ua880', '\ua881'), ('\ua8b4', '\ua8c4'),
+        ('\ua8e0', '\ua8f1'), ('\ua926', '\ua92d'), ('\ua947', '\ua953'), ('\ua980', '\ua983'),
+        ('\ua9b3', '\ua9c0'), ('\ua9e5', '\ua9e5'), ('\uaa29', '\uaa36'), ('\uaa43', '\uaa43'),
+        ('\uaa4c', '\uaa4d'), ('\uaa7b', '\uaa7d'), ('\uaab0', '\uaab0'), ('\uaab2', '\uaab4'),
+        ('\uaab7', '\uaab8'), ('\uaabe', '\uaabf'), ('\uaac1', '\uaac1'), ('\uaaeb', '\uaaef'),
+        ('\uaaf5', '\uaaf6'), ('\uabe3', '\uabea'), ('\uabec', '\uabed'), ('\ufb1e', '\ufb1e'),
+        ('\ufe00', '\ufe0f'), ('\ufe20', '\ufe2d'), ('\U000101fd', '\U000101fd'), ('\U000102e0',
+        '\U000102e0'), ('\U00010376', '\U0001037a'), ('\U00010a01', '\U00010a03'), ('\U00010a05',
+        '\U00010a06'), ('\U00010a0c', '\U00010a0f'), ('\U00010a38', '\U00010a3a'), ('\U00010a3f',
+        '\U00010a3f'), ('\U00010ae5', '\U00010ae6'), ('\U00011000', '\U00011002'), ('\U00011038',
+        '\U00011046'), ('\U0001107f', '\U00011082'), ('\U000110b0', '\U000110ba'), ('\U00011100',
+        '\U00011102'), ('\U00011127', '\U00011134'), ('\U00011173', '\U00011173'), ('\U00011180',
+        '\U00011182'), ('\U000111b3', '\U000111c0'), ('\U0001122c', '\U00011237'), ('\U000112df',
+        '\U000112ea'), ('\U00011301', '\U00011303'), ('\U0001133c', '\U0001133c'), ('\U0001133e',
+        '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'), ('\U00011357',
+        '\U00011357'), ('\U00011362', '\U00011363'), ('\U00011366', '\U0001136c'), ('\U00011370',
+        '\U00011374'), ('\U000114b0', '\U000114c3'), ('\U000115af', '\U000115b5'), ('\U000115b8',
+        '\U000115c0'), ('\U00011630', '\U00011640'), ('\U000116ab', '\U000116b7'), ('\U00016af0',
+        '\U00016af4'), ('\U00016b30', '\U00016b36'), ('\U00016f51', '\U00016f7e'), ('\U00016f8f',
+        '\U00016f92'), ('\U0001bc9d', '\U0001bc9e'), ('\U0001d165', '\U0001d169'), ('\U0001d16d',
+        '\U0001d172'), ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'), ('\U0001d1aa',
+        '\U0001d1ad'), ('\U0001d242', '\U0001d244'), ('\U0001e8d0', '\U0001e8d6'), ('\U000e0100',
+        '\U000e01ef')
+    ];
+
+    pub static Mc_table: &'static [(char, char)] = &[
+        ('\u0903', '\u0903'), ('\u093b', '\u093b'), ('\u093e', '\u0940'), ('\u0949', '\u094c'),
+        ('\u094e', '\u094f'), ('\u0982', '\u0983'), ('\u09be', '\u09c0'), ('\u09c7', '\u09c8'),
+        ('\u09cb', '\u09cc'), ('\u09d7', '\u09d7'), ('\u0a03', '\u0a03'), ('\u0a3e', '\u0a40'),
+        ('\u0a83', '\u0a83'), ('\u0abe', '\u0ac0'), ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
+        ('\u0b02', '\u0b03'), ('\u0b3e', '\u0b3e'), ('\u0b40', '\u0b40'), ('\u0b47', '\u0b48'),
+        ('\u0b4b', '\u0b4c'), ('\u0b57', '\u0b57'), ('\u0bbe', '\u0bbf'), ('\u0bc1', '\u0bc2'),
+        ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcc'), ('\u0bd7', '\u0bd7'), ('\u0c01', '\u0c03'),
+        ('\u0c41', '\u0c44'), ('\u0c82', '\u0c83'), ('\u0cbe', '\u0cbe'), ('\u0cc0', '\u0cc4'),
+        ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'), ('\u0cd5', '\u0cd6'), ('\u0d02', '\u0d03'),
+        ('\u0d3e', '\u0d40'), ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4c'), ('\u0d57', '\u0d57'),
+        ('\u0d82', '\u0d83'), ('\u0dcf', '\u0dd1'), ('\u0dd8', '\u0ddf'), ('\u0df2', '\u0df3'),
+        ('\u0f3e', '\u0f3f'), ('\u0f7f', '\u0f7f'), ('\u102b', '\u102c'), ('\u1031', '\u1031'),
+        ('\u1038', '\u1038'), ('\u103b', '\u103c'), ('\u1056', '\u1057'), ('\u1062', '\u1064'),
+        ('\u1067', '\u106d'), ('\u1083', '\u1084'), ('\u1087', '\u108c'), ('\u108f', '\u108f'),
+        ('\u109a', '\u109c'), ('\u17b6', '\u17b6'), ('\u17be', '\u17c5'), ('\u17c7', '\u17c8'),
+        ('\u1923', '\u1926'), ('\u1929', '\u192b'), ('\u1930', '\u1931'), ('\u1933', '\u1938'),
+        ('\u19b0', '\u19c0'), ('\u19c8', '\u19c9'), ('\u1a19', '\u1a1a'), ('\u1a55', '\u1a55'),
+        ('\u1a57', '\u1a57'), ('\u1a61', '\u1a61'), ('\u1a63', '\u1a64'), ('\u1a6d', '\u1a72'),
+        ('\u1b04', '\u1b04'), ('\u1b35', '\u1b35'), ('\u1b3b', '\u1b3b'), ('\u1b3d', '\u1b41'),
+        ('\u1b43', '\u1b44'), ('\u1b82', '\u1b82'), ('\u1ba1', '\u1ba1'), ('\u1ba6', '\u1ba7'),
+        ('\u1baa', '\u1baa'), ('\u1be7', '\u1be7'), ('\u1bea', '\u1bec'), ('\u1bee', '\u1bee'),
+        ('\u1bf2', '\u1bf3'), ('\u1c24', '\u1c2b'), ('\u1c34', '\u1c35'), ('\u1ce1', '\u1ce1'),
+        ('\u1cf2', '\u1cf3'), ('\u302e', '\u302f'), ('\ua823', '\ua824'), ('\ua827', '\ua827'),
+        ('\ua880', '\ua881'), ('\ua8b4', '\ua8c3'), ('\ua952', '\ua953'), ('\ua983', '\ua983'),
+        ('\ua9b4', '\ua9b5'), ('\ua9ba', '\ua9bb'), ('\ua9bd', '\ua9c0'), ('\uaa2f', '\uaa30'),
+        ('\uaa33', '\uaa34'), ('\uaa4d', '\uaa4d'), ('\uaa7b', '\uaa7b'), ('\uaa7d', '\uaa7d'),
+        ('\uaaeb', '\uaaeb'), ('\uaaee', '\uaaef'), ('\uaaf5', '\uaaf5'), ('\uabe3', '\uabe4'),
+        ('\uabe6', '\uabe7'), ('\uabe9', '\uabea'), ('\uabec', '\uabec'), ('\U00011000',
+        '\U00011000'), ('\U00011002', '\U00011002'), ('\U00011082', '\U00011082'), ('\U000110b0',
+        '\U000110b2'), ('\U000110b7', '\U000110b8'), ('\U0001112c', '\U0001112c'), ('\U00011182',
+        '\U00011182'), ('\U000111b3', '\U000111b5'), ('\U000111bf', '\U000111c0'), ('\U0001122c',
+        '\U0001122e'), ('\U00011232', '\U00011233'), ('\U00011235', '\U00011235'), ('\U000112e0',
+        '\U000112e2'), ('\U00011302', '\U00011303'), ('\U0001133e', '\U0001133f'), ('\U00011341',
+        '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'), ('\U00011357',
+        '\U00011357'), ('\U00011362', '\U00011363'), ('\U000114b0', '\U000114b2'), ('\U000114b9',
+        '\U000114b9'), ('\U000114bb', '\U000114be'), ('\U000114c1', '\U000114c1'), ('\U000115af',
+        '\U000115b1'), ('\U000115b8', '\U000115bb'), ('\U000115be', '\U000115be'), ('\U00011630',
+        '\U00011632'), ('\U0001163b', '\U0001163c'), ('\U0001163e', '\U0001163e'), ('\U000116ac',
+        '\U000116ac'), ('\U000116ae', '\U000116af'), ('\U000116b6', '\U000116b6'), ('\U00016f51',
+        '\U00016f7e'), ('\U0001d165', '\U0001d166'), ('\U0001d16d', '\U0001d172')
+    ];
+
+    pub static Me_table: &'static [(char, char)] = &[
+        ('\u0488', '\u0489'), ('\u1abe', '\u1abe'), ('\u20dd', '\u20e0'), ('\u20e2', '\u20e4'),
+        ('\ua670', '\ua672')
+    ];
+
+    pub static Mn_table: &'static [(char, char)] = &[
+        ('\u0300', '\u036f'), ('\u0483', '\u0487'), ('\u0591', '\u05bd'), ('\u05bf', '\u05bf'),
+        ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u0610', '\u061a'),
+        ('\u064b', '\u065f'), ('\u0670', '\u0670'), ('\u06d6', '\u06dc'), ('\u06df', '\u06e4'),
+        ('\u06e7', '\u06e8'), ('\u06ea', '\u06ed'), ('\u0711', '\u0711'), ('\u0730', '\u074a'),
+        ('\u07a6', '\u07b0'), ('\u07eb', '\u07f3'), ('\u0816', '\u0819'), ('\u081b', '\u0823'),
+        ('\u0825', '\u0827'), ('\u0829', '\u082d'), ('\u0859', '\u085b'), ('\u08e4', '\u0902'),
+        ('\u093a', '\u093a'), ('\u093c', '\u093c'), ('\u0941', '\u0948'), ('\u094d', '\u094d'),
+        ('\u0951', '\u0957'), ('\u0962', '\u0963'), ('\u0981', '\u0981'), ('\u09bc', '\u09bc'),
+        ('\u09c1', '\u09c4'), ('\u09cd', '\u09cd'), ('\u09e2', '\u09e3'), ('\u0a01', '\u0a02'),
+        ('\u0a3c', '\u0a3c'), ('\u0a41', '\u0a42'), ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'),
+        ('\u0a51', '\u0a51'), ('\u0a70', '\u0a71'), ('\u0a75', '\u0a75'), ('\u0a81', '\u0a82'),
+        ('\u0abc', '\u0abc'), ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'), ('\u0acd', '\u0acd'),
+        ('\u0ae2', '\u0ae3'), ('\u0b01', '\u0b01'), ('\u0b3c', '\u0b3c'), ('\u0b3f', '\u0b3f'),
+        ('\u0b41', '\u0b44'), ('\u0b4d', '\u0b4d'), ('\u0b56', '\u0b56'), ('\u0b62', '\u0b63'),
+        ('\u0b82', '\u0b82'), ('\u0bc0', '\u0bc0'), ('\u0bcd', '\u0bcd'), ('\u0c00', '\u0c00'),
+        ('\u0c3e', '\u0c40'), ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'), ('\u0c55', '\u0c56'),
+        ('\u0c62', '\u0c63'), ('\u0c81', '\u0c81'), ('\u0cbc', '\u0cbc'), ('\u0cbf', '\u0cbf'),
+        ('\u0cc6', '\u0cc6'), ('\u0ccc', '\u0ccd'), ('\u0ce2', '\u0ce3'), ('\u0d01', '\u0d01'),
+        ('\u0d41', '\u0d44'), ('\u0d4d', '\u0d4d'), ('\u0d62', '\u0d63'), ('\u0dca', '\u0dca'),
+        ('\u0dd2', '\u0dd4'), ('\u0dd6', '\u0dd6'), ('\u0e31', '\u0e31'), ('\u0e34', '\u0e3a'),
+        ('\u0e47', '\u0e4e'), ('\u0eb1', '\u0eb1'), ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
+        ('\u0ec8', '\u0ecd'), ('\u0f18', '\u0f19'), ('\u0f35', '\u0f35'), ('\u0f37', '\u0f37'),
+        ('\u0f39', '\u0f39'), ('\u0f71', '\u0f7e'), ('\u0f80', '\u0f84'), ('\u0f86', '\u0f87'),
+        ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'), ('\u0fc6', '\u0fc6'), ('\u102d', '\u1030'),
+        ('\u1032', '\u1037'), ('\u1039', '\u103a'), ('\u103d', '\u103e'), ('\u1058', '\u1059'),
+        ('\u105e', '\u1060'), ('\u1071', '\u1074'), ('\u1082', '\u1082'), ('\u1085', '\u1086'),
+        ('\u108d', '\u108d'), ('\u109d', '\u109d'), ('\u135d', '\u135f'), ('\u1712', '\u1714'),
+        ('\u1732', '\u1734'), ('\u1752', '\u1753'), ('\u1772', '\u1773'), ('\u17b4', '\u17b5'),
+        ('\u17b7', '\u17bd'), ('\u17c6', '\u17c6'), ('\u17c9', '\u17d3'), ('\u17dd', '\u17dd'),
+        ('\u180b', '\u180d'), ('\u18a9', '\u18a9'), ('\u1920', '\u1922'), ('\u1927', '\u1928'),
+        ('\u1932', '\u1932'), ('\u1939', '\u193b'), ('\u1a17', '\u1a18'), ('\u1a1b', '\u1a1b'),
+        ('\u1a56', '\u1a56'), ('\u1a58', '\u1a5e'), ('\u1a60', '\u1a60'), ('\u1a62', '\u1a62'),
+        ('\u1a65', '\u1a6c'), ('\u1a73', '\u1a7c'), ('\u1a7f', '\u1a7f'), ('\u1ab0', '\u1abd'),
+        ('\u1b00', '\u1b03'), ('\u1b34', '\u1b34'), ('\u1b36', '\u1b3a'), ('\u1b3c', '\u1b3c'),
+        ('\u1b42', '\u1b42'), ('\u1b6b', '\u1b73'), ('\u1b80', '\u1b81'), ('\u1ba2', '\u1ba5'),
+        ('\u1ba8', '\u1ba9'), ('\u1bab', '\u1bad'), ('\u1be6', '\u1be6'), ('\u1be8', '\u1be9'),
+        ('\u1bed', '\u1bed'), ('\u1bef', '\u1bf1'), ('\u1c2c', '\u1c33'), ('\u1c36', '\u1c37'),
+        ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1ce0'), ('\u1ce2', '\u1ce8'), ('\u1ced', '\u1ced'),
+        ('\u1cf4', '\u1cf4'), ('\u1cf8', '\u1cf9'), ('\u1dc0', '\u1df5'), ('\u1dfc', '\u1dff'),
+        ('\u20d0', '\u20dc'), ('\u20e1', '\u20e1'), ('\u20e5', '\u20f0'), ('\u2cef', '\u2cf1'),
+        ('\u2d7f', '\u2d7f'), ('\u2de0', '\u2dff'), ('\u302a', '\u302d'), ('\u3099', '\u309a'),
+        ('\ua66f', '\ua66f'), ('\ua674', '\ua67d'), ('\ua69f', '\ua69f'), ('\ua6f0', '\ua6f1'),
+        ('\ua802', '\ua802'), ('\ua806', '\ua806'), ('\ua80b', '\ua80b'), ('\ua825', '\ua826'),
+        ('\ua8c4', '\ua8c4'), ('\ua8e0', '\ua8f1'), ('\ua926', '\ua92d'), ('\ua947', '\ua951'),
+        ('\ua980', '\ua982'), ('\ua9b3', '\ua9b3'), ('\ua9b6', '\ua9b9'), ('\ua9bc', '\ua9bc'),
+        ('\ua9e5', '\ua9e5'), ('\uaa29', '\uaa2e'), ('\uaa31', '\uaa32'), ('\uaa35', '\uaa36'),
+        ('\uaa43', '\uaa43'), ('\uaa4c', '\uaa4c'), ('\uaa7c', '\uaa7c'), ('\uaab0', '\uaab0'),
+        ('\uaab2', '\uaab4'), ('\uaab7', '\uaab8'), ('\uaabe', '\uaabf'), ('\uaac1', '\uaac1'),
+        ('\uaaec', '\uaaed'), ('\uaaf6', '\uaaf6'), ('\uabe5', '\uabe5'), ('\uabe8', '\uabe8'),
+        ('\uabed', '\uabed'), ('\ufb1e', '\ufb1e'), ('\ufe00', '\ufe0f'), ('\ufe20', '\ufe2d'),
+        ('\U000101fd', '\U000101fd'), ('\U000102e0', '\U000102e0'), ('\U00010376', '\U0001037a'),
+        ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'), ('\U00010a0c', '\U00010a0f'),
+        ('\U00010a38', '\U00010a3a'), ('\U00010a3f', '\U00010a3f'), ('\U00010ae5', '\U00010ae6'),
+        ('\U00011001', '\U00011001'), ('\U00011038', '\U00011046'), ('\U0001107f', '\U00011081'),
+        ('\U000110b3', '\U000110b6'), ('\U000110b9', '\U000110ba'), ('\U00011100', '\U00011102'),
+        ('\U00011127', '\U0001112b'), ('\U0001112d', '\U00011134'), ('\U00011173', '\U00011173'),
+        ('\U00011180', '\U00011181'), ('\U000111b6', '\U000111be'), ('\U0001122f', '\U00011231'),
+        ('\U00011234', '\U00011234'), ('\U00011236', '\U00011237'), ('\U000112df', '\U000112df'),
+        ('\U000112e3', '\U000112ea'), ('\U00011301', '\U00011301'), ('\U0001133c', '\U0001133c'),
+        ('\U00011340', '\U00011340'), ('\U00011366', '\U0001136c'), ('\U00011370', '\U00011374'),
+        ('\U000114b3', '\U000114b8'), ('\U000114ba', '\U000114ba'), ('\U000114bf', '\U000114c0'),
+        ('\U000114c2', '\U000114c3'), ('\U000115b2', '\U000115b5'), ('\U000115bc', '\U000115bd'),
+        ('\U000115bf', '\U000115c0'), ('\U00011633', '\U0001163a'), ('\U0001163d', '\U0001163d'),
+        ('\U0001163f', '\U00011640'), ('\U000116ab', '\U000116ab'), ('\U000116ad', '\U000116ad'),
+        ('\U000116b0', '\U000116b5'), ('\U000116b7', '\U000116b7'), ('\U00016af0', '\U00016af4'),
+        ('\U00016b30', '\U00016b36'), ('\U00016f8f', '\U00016f92'), ('\U0001bc9d', '\U0001bc9e'),
+        ('\U0001d167', '\U0001d169'), ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'),
+        ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'), ('\U0001e8d0', '\U0001e8d6'),
+        ('\U000e0100', '\U000e01ef')
+    ];
+
+    pub static N_table: &'static [(char, char)] = &[
+        ('\x30', '\x39'), ('\u0660', '\u0669'), ('\u06f0', '\u06f9'), ('\u07c0', '\u07c9'),
+        ('\u0966', '\u096f'), ('\u09e6', '\u09ef'), ('\u0a66', '\u0a6f'), ('\u0ae6', '\u0aef'),
+        ('\u0b66', '\u0b6f'), ('\u0be6', '\u0bef'), ('\u0c66', '\u0c6f'), ('\u0ce6', '\u0cef'),
+        ('\u0d66', '\u0d6f'), ('\u0de6', '\u0def'), ('\u0e50', '\u0e59'), ('\u0ed0', '\u0ed9'),
+        ('\u0f20', '\u0f29'), ('\u1040', '\u1049'), ('\u1090', '\u1099'), ('\u16ee', '\u16f0'),
+        ('\u17e0', '\u17e9'), ('\u1810', '\u1819'), ('\u1946', '\u194f'), ('\u19d0', '\u19d9'),
+        ('\u1a80', '\u1a89'), ('\u1a90', '\u1a99'), ('\u1b50', '\u1b59'), ('\u1bb0', '\u1bb9'),
+        ('\u1c40', '\u1c49'), ('\u1c50', '\u1c59'), ('\u2160', '\u2182'), ('\u2185', '\u2188'),
+        ('\u3007', '\u3007'), ('\u3021', '\u3029'), ('\u3038', '\u303a'), ('\ua620', '\ua629'),
+        ('\ua6e6', '\ua6ef'), ('\ua8d0', '\ua8d9'), ('\ua900', '\ua909'), ('\ua9d0', '\ua9d9'),
+        ('\ua9f0', '\ua9f9'), ('\uaa50', '\uaa59'), ('\uabf0', '\uabf9'), ('\uff10', '\uff19'),
+        ('\U00010140', '\U00010174'), ('\U00010341', '\U00010341'), ('\U0001034a', '\U0001034a'),
+        ('\U000103d1', '\U000103d5'), ('\U000104a0', '\U000104a9'), ('\U00011066', '\U0001106f'),
+        ('\U000110f0', '\U000110f9'), ('\U00011136', '\U0001113f'), ('\U000111d0', '\U000111d9'),
+        ('\U000112f0', '\U000112f9'), ('\U000114d0', '\U000114d9'), ('\U00011650', '\U00011659'),
+        ('\U000116c0', '\U000116c9'), ('\U000118e0', '\U000118e9'), ('\U00012400', '\U0001246e'),
+        ('\U00016a60', '\U00016a69'), ('\U00016b50', '\U00016b59'), ('\U0001d7ce', '\U0001d7ff')
+    ];
+
+    pub fn N(c: char) -> bool {
+        super::bsearch_range_table(c, N_table)
+    }
+
+    pub static Nd_table: &'static [(char, char)] = &[
+        ('\x30', '\x39'), ('\u0660', '\u0669'), ('\u06f0', '\u06f9'), ('\u07c0', '\u07c9'),
+        ('\u0966', '\u096f'), ('\u09e6', '\u09ef'), ('\u0a66', '\u0a6f'), ('\u0ae6', '\u0aef'),
+        ('\u0b66', '\u0b6f'), ('\u0be6', '\u0bef'), ('\u0c66', '\u0c6f'), ('\u0ce6', '\u0cef'),
+        ('\u0d66', '\u0d6f'), ('\u0de6', '\u0def'), ('\u0e50', '\u0e59'), ('\u0ed0', '\u0ed9'),
+        ('\u0f20', '\u0f29'), ('\u1040', '\u1049'), ('\u1090', '\u1099'), ('\u17e0', '\u17e9'),
+        ('\u1810', '\u1819'), ('\u1946', '\u194f'), ('\u19d0', '\u19d9'), ('\u1a80', '\u1a89'),
+        ('\u1a90', '\u1a99'), ('\u1b50', '\u1b59'), ('\u1bb0', '\u1bb9'), ('\u1c40', '\u1c49'),
+        ('\u1c50', '\u1c59'), ('\ua620', '\ua629'), ('\ua8d0', '\ua8d9'), ('\ua900', '\ua909'),
+        ('\ua9d0', '\ua9d9'), ('\ua9f0', '\ua9f9'), ('\uaa50', '\uaa59'), ('\uabf0', '\uabf9'),
+        ('\uff10', '\uff19'), ('\U000104a0', '\U000104a9'), ('\U00011066', '\U0001106f'),
+        ('\U000110f0', '\U000110f9'), ('\U00011136', '\U0001113f'), ('\U000111d0', '\U000111d9'),
+        ('\U000112f0', '\U000112f9'), ('\U000114d0', '\U000114d9'), ('\U00011650', '\U00011659'),
+        ('\U000116c0', '\U000116c9'), ('\U000118e0', '\U000118e9'), ('\U00016a60', '\U00016a69'),
+        ('\U00016b50', '\U00016b59'), ('\U0001d7ce', '\U0001d7ff')
+    ];
+
+    pub static Nl_table: &'static [(char, char)] = &[
+        ('\u16ee', '\u16f0'), ('\u2160', '\u2182'), ('\u2185', '\u2188'), ('\u3007', '\u3007'),
+        ('\u3021', '\u3029'), ('\u3038', '\u303a'), ('\ua6e6', '\ua6ef'), ('\U00010140',
+        '\U00010174'), ('\U00010341', '\U00010341'), ('\U0001034a', '\U0001034a'), ('\U000103d1',
+        '\U000103d5'), ('\U00012400', '\U0001246e')
+    ];
+
+    pub static No_table: &'static [(char, char)] = &[
+        ('\xb2', '\xb3'), ('\xb9', '\xb9'), ('\xbc', '\xbe'), ('\u09f4', '\u09f9'), ('\u0b72',
+        '\u0b77'), ('\u0bf0', '\u0bf2'), ('\u0c78', '\u0c7e'), ('\u0d70', '\u0d75'), ('\u0f2a',
+        '\u0f33'), ('\u1369', '\u137c'), ('\u17f0', '\u17f9'), ('\u19da', '\u19da'), ('\u2070',
+        '\u2070'), ('\u2074', '\u2079'), ('\u2080', '\u2089'), ('\u2150', '\u215f'), ('\u2189',
+        '\u2189'), ('\u2460', '\u249b'), ('\u24ea', '\u24ff'), ('\u2776', '\u2793'), ('\u2cfd',
+        '\u2cfd'), ('\u3192', '\u3195'), ('\u3220', '\u3229'), ('\u3248', '\u324f'), ('\u3251',
+        '\u325f'), ('\u3280', '\u3289'), ('\u32b1', '\u32bf'), ('\ua830', '\ua835'), ('\U00010107',
+        '\U00010133'), ('\U00010175', '\U00010178'), ('\U0001018a', '\U0001018b'), ('\U000102e1',
+        '\U000102fb'), ('\U00010320', '\U00010323'), ('\U00010858', '\U0001085f'), ('\U00010879',
+        '\U0001087f'), ('\U000108a7', '\U000108af'), ('\U00010916', '\U0001091b'), ('\U00010a40',
+        '\U00010a47'), ('\U00010a7d', '\U00010a7e'), ('\U00010a9d', '\U00010a9f'), ('\U00010aeb',
+        '\U00010aef'), ('\U00010b58', '\U00010b5f'), ('\U00010b78', '\U00010b7f'), ('\U00010ba9',
+        '\U00010baf'), ('\U00010e60', '\U00010e7e'), ('\U00011052', '\U00011065'), ('\U000111e1',
+        '\U000111f4'), ('\U000118ea', '\U000118f2'), ('\U00016b5b', '\U00016b61'), ('\U0001d360',
+        '\U0001d371'), ('\U0001e8c7', '\U0001e8cf'), ('\U0001f100', '\U0001f10c')
+    ];
+
+    pub static P_table: &'static [(char, char)] = &[
+        ('\x21', '\x23'), ('\x25', '\x2a'), ('\x2c', '\x2f'), ('\x3a', '\x3b'), ('\x3f', '\x40'),
+        ('\x5b', '\x5d'), ('\x5f', '\x5f'), ('\x7b', '\x7b'), ('\x7d', '\x7d'), ('\xa1', '\xa1'),
+        ('\xa7', '\xa7'), ('\xab', '\xab'), ('\xb6', '\xb7'), ('\xbb', '\xbb'), ('\xbf', '\xbf'),
+        ('\u037e', '\u037e'), ('\u0387', '\u0387'), ('\u055a', '\u055f'), ('\u0589', '\u058a'),
+        ('\u05be', '\u05be'), ('\u05c0', '\u05c0'), ('\u05c3', '\u05c3'), ('\u05c6', '\u05c6'),
+        ('\u05f3', '\u05f4'), ('\u0609', '\u060a'), ('\u060c', '\u060d'), ('\u061b', '\u061b'),
+        ('\u061e', '\u061f'), ('\u066a', '\u066d'), ('\u06d4', '\u06d4'), ('\u0700', '\u070d'),
+        ('\u07f7', '\u07f9'), ('\u0830', '\u083e'), ('\u085e', '\u085e'), ('\u0964', '\u0965'),
+        ('\u0970', '\u0970'), ('\u0af0', '\u0af0'), ('\u0df4', '\u0df4'), ('\u0e4f', '\u0e4f'),
+        ('\u0e5a', '\u0e5b'), ('\u0f04', '\u0f12'), ('\u0f14', '\u0f14'), ('\u0f3a', '\u0f3d'),
+        ('\u0f85', '\u0f85'), ('\u0fd0', '\u0fd4'), ('\u0fd9', '\u0fda'), ('\u104a', '\u104f'),
+        ('\u10fb', '\u10fb'), ('\u1360', '\u1368'), ('\u1400', '\u1400'), ('\u166d', '\u166e'),
+        ('\u169b', '\u169c'), ('\u16eb', '\u16ed'), ('\u1735', '\u1736'), ('\u17d4', '\u17d6'),
+        ('\u17d8', '\u17da'), ('\u1800', '\u180a'), ('\u1944', '\u1945'), ('\u1a1e', '\u1a1f'),
+        ('\u1aa0', '\u1aa6'), ('\u1aa8', '\u1aad'), ('\u1b5a', '\u1b60'), ('\u1bfc', '\u1bff'),
+        ('\u1c3b', '\u1c3f'), ('\u1c7e', '\u1c7f'), ('\u1cc0', '\u1cc7'), ('\u1cd3', '\u1cd3'),
+        ('\u2010', '\u2027'), ('\u2030', '\u2043'), ('\u2045', '\u2051'), ('\u2053', '\u205e'),
+        ('\u207d', '\u207e'), ('\u208d', '\u208e'), ('\u2308', '\u230b'), ('\u2329', '\u232a'),
+        ('\u2768', '\u2775'), ('\u27c5', '\u27c6'), ('\u27e6', '\u27ef'), ('\u2983', '\u2998'),
+        ('\u29d8', '\u29db'), ('\u29fc', '\u29fd'), ('\u2cf9', '\u2cfc'), ('\u2cfe', '\u2cff'),
+        ('\u2d70', '\u2d70'), ('\u2e00', '\u2e2e'), ('\u2e30', '\u2e42'), ('\u3001', '\u3003'),
+        ('\u3008', '\u3011'), ('\u3014', '\u301f'), ('\u3030', '\u3030'), ('\u303d', '\u303d'),
+        ('\u30a0', '\u30a0'), ('\u30fb', '\u30fb'), ('\ua4fe', '\ua4ff'), ('\ua60d', '\ua60f'),
+        ('\ua673', '\ua673'), ('\ua67e', '\ua67e'), ('\ua6f2', '\ua6f7'), ('\ua874', '\ua877'),
+        ('\ua8ce', '\ua8cf'), ('\ua8f8', '\ua8fa'), ('\ua92e', '\ua92f'), ('\ua95f', '\ua95f'),
+        ('\ua9c1', '\ua9cd'), ('\ua9de', '\ua9df'), ('\uaa5c', '\uaa5f'), ('\uaade', '\uaadf'),
+        ('\uaaf0', '\uaaf1'), ('\uabeb', '\uabeb'), ('\ufd3e', '\ufd3f'), ('\ufe10', '\ufe19'),
+        ('\ufe30', '\ufe52'), ('\ufe54', '\ufe61'), ('\ufe63', '\ufe63'), ('\ufe68', '\ufe68'),
+        ('\ufe6a', '\ufe6b'), ('\uff01', '\uff03'), ('\uff05', '\uff0a'), ('\uff0c', '\uff0f'),
+        ('\uff1a', '\uff1b'), ('\uff1f', '\uff20'), ('\uff3b', '\uff3d'), ('\uff3f', '\uff3f'),
+        ('\uff5b', '\uff5b'), ('\uff5d', '\uff5d'), ('\uff5f', '\uff65'), ('\U00010100',
+        '\U00010102'), ('\U0001039f', '\U0001039f'), ('\U000103d0', '\U000103d0'), ('\U0001056f',
+        '\U0001056f'), ('\U00010857', '\U00010857'), ('\U0001091f', '\U0001091f'), ('\U0001093f',
+        '\U0001093f'), ('\U00010a50', '\U00010a58'), ('\U00010a7f', '\U00010a7f'), ('\U00010af0',
+        '\U00010af6'), ('\U00010b39', '\U00010b3f'), ('\U00010b99', '\U00010b9c'), ('\U00011047',
+        '\U0001104d'), ('\U000110bb', '\U000110bc'), ('\U000110be', '\U000110c1'), ('\U00011140',
+        '\U00011143'), ('\U00011174', '\U00011175'), ('\U000111c5', '\U000111c8'), ('\U000111cd',
+        '\U000111cd'), ('\U00011238', '\U0001123d'), ('\U000114c6', '\U000114c6'), ('\U000115c1',
+        '\U000115c9'), ('\U00011641', '\U00011643'), ('\U00012470', '\U00012474'), ('\U00016a6e',
+        '\U00016a6f'), ('\U00016af5', '\U00016af5'), ('\U00016b37', '\U00016b3b'), ('\U00016b44',
+        '\U00016b44'), ('\U0001bc9f', '\U0001bc9f')
+    ];
+
+    pub static Pc_table: &'static [(char, char)] = &[
+        ('\x5f', '\x5f'), ('\u203f', '\u2040'), ('\u2054', '\u2054'), ('\ufe33', '\ufe34'),
+        ('\ufe4d', '\ufe4f'), ('\uff3f', '\uff3f')
+    ];
+
+    pub static Pd_table: &'static [(char, char)] = &[
+        ('\x2d', '\x2d'), ('\u058a', '\u058a'), ('\u05be', '\u05be'), ('\u1400', '\u1400'),
+        ('\u1806', '\u1806'), ('\u2010', '\u2015'), ('\u2e17', '\u2e17'), ('\u2e1a', '\u2e1a'),
+        ('\u2e3a', '\u2e3b'), ('\u2e40', '\u2e40'), ('\u301c', '\u301c'), ('\u3030', '\u3030'),
+        ('\u30a0', '\u30a0'), ('\ufe31', '\ufe32'), ('\ufe58', '\ufe58'), ('\ufe63', '\ufe63'),
+        ('\uff0d', '\uff0d')
+    ];
+
+    pub static Pe_table: &'static [(char, char)] = &[
+        ('\x29', '\x29'), ('\x5d', '\x5d'), ('\x7d', '\x7d'), ('\u0f3b', '\u0f3b'), ('\u0f3d',
+        '\u0f3d'), ('\u169c', '\u169c'), ('\u2046', '\u2046'), ('\u207e', '\u207e'), ('\u208e',
+        '\u208e'), ('\u2309', '\u2309'), ('\u230b', '\u230b'), ('\u232a', '\u232a'), ('\u2769',
+        '\u2769'), ('\u276b', '\u276b'), ('\u276d', '\u276d'), ('\u276f', '\u276f'), ('\u2771',
+        '\u2771'), ('\u2773', '\u2773'), ('\u2775', '\u2775'), ('\u27c6', '\u27c6'), ('\u27e7',
+        '\u27e7'), ('\u27e9', '\u27e9'), ('\u27eb', '\u27eb'), ('\u27ed', '\u27ed'), ('\u27ef',
+        '\u27ef'), ('\u2984', '\u2984'), ('\u2986', '\u2986'), ('\u2988', '\u2988'), ('\u298a',
+        '\u298a'), ('\u298c', '\u298c'), ('\u298e', '\u298e'), ('\u2990', '\u2990'), ('\u2992',
+        '\u2992'), ('\u2994', '\u2994'), ('\u2996', '\u2996'), ('\u2998', '\u2998'), ('\u29d9',
+        '\u29d9'), ('\u29db', '\u29db'), ('\u29fd', '\u29fd'), ('\u2e23', '\u2e23'), ('\u2e25',
+        '\u2e25'), ('\u2e27', '\u2e27'), ('\u2e29', '\u2e29'), ('\u3009', '\u3009'), ('\u300b',
+        '\u300b'), ('\u300d', '\u300d'), ('\u300f', '\u300f'), ('\u3011', '\u3011'), ('\u3015',
+        '\u3015'), ('\u3017', '\u3017'), ('\u3019', '\u3019'), ('\u301b', '\u301b'), ('\u301e',
+        '\u301f'), ('\ufd3e', '\ufd3e'), ('\ufe18', '\ufe18'), ('\ufe36', '\ufe36'), ('\ufe38',
+        '\ufe38'), ('\ufe3a', '\ufe3a'), ('\ufe3c', '\ufe3c'), ('\ufe3e', '\ufe3e'), ('\ufe40',
+        '\ufe40'), ('\ufe42', '\ufe42'), ('\ufe44', '\ufe44'), ('\ufe48', '\ufe48'), ('\ufe5a',
+        '\ufe5a'), ('\ufe5c', '\ufe5c'), ('\ufe5e', '\ufe5e'), ('\uff09', '\uff09'), ('\uff3d',
+        '\uff3d'), ('\uff5d', '\uff5d'), ('\uff60', '\uff60'), ('\uff63', '\uff63')
+    ];
+
+    pub static Pf_table: &'static [(char, char)] = &[
+        ('\xbb', '\xbb'), ('\u2019', '\u2019'), ('\u201d', '\u201d'), ('\u203a', '\u203a'),
+        ('\u2e03', '\u2e03'), ('\u2e05', '\u2e05'), ('\u2e0a', '\u2e0a'), ('\u2e0d', '\u2e0d'),
+        ('\u2e1d', '\u2e1d'), ('\u2e21', '\u2e21')
+    ];
+
+    pub static Pi_table: &'static [(char, char)] = &[
+        ('\xab', '\xab'), ('\u2018', '\u2018'), ('\u201b', '\u201c'), ('\u201f', '\u201f'),
+        ('\u2039', '\u2039'), ('\u2e02', '\u2e02'), ('\u2e04', '\u2e04'), ('\u2e09', '\u2e09'),
+        ('\u2e0c', '\u2e0c'), ('\u2e1c', '\u2e1c'), ('\u2e20', '\u2e20')
+    ];
+
+    pub static Po_table: &'static [(char, char)] = &[
+        ('\x21', '\x23'), ('\x25', '\x27'), ('\x2a', '\x2a'), ('\x2c', '\x2c'), ('\x2e', '\x2f'),
+        ('\x3a', '\x3b'), ('\x3f', '\x40'), ('\x5c', '\x5c'), ('\xa1', '\xa1'), ('\xa7', '\xa7'),
+        ('\xb6', '\xb7'), ('\xbf', '\xbf'), ('\u037e', '\u037e'), ('\u0387', '\u0387'), ('\u055a',
+        '\u055f'), ('\u0589', '\u0589'), ('\u05c0', '\u05c0'), ('\u05c3', '\u05c3'), ('\u05c6',
+        '\u05c6'), ('\u05f3', '\u05f4'), ('\u0609', '\u060a'), ('\u060c', '\u060d'), ('\u061b',
+        '\u061b'), ('\u061e', '\u061f'), ('\u066a', '\u066d'), ('\u06d4', '\u06d4'), ('\u0700',
+        '\u070d'), ('\u07f7', '\u07f9'), ('\u0830', '\u083e'), ('\u085e', '\u085e'), ('\u0964',
+        '\u0965'), ('\u0970', '\u0970'), ('\u0af0', '\u0af0'), ('\u0df4', '\u0df4'), ('\u0e4f',
+        '\u0e4f'), ('\u0e5a', '\u0e5b'), ('\u0f04', '\u0f12'), ('\u0f14', '\u0f14'), ('\u0f85',
+        '\u0f85'), ('\u0fd0', '\u0fd4'), ('\u0fd9', '\u0fda'), ('\u104a', '\u104f'), ('\u10fb',
+        '\u10fb'), ('\u1360', '\u1368'), ('\u166d', '\u166e'), ('\u16eb', '\u16ed'), ('\u1735',
+        '\u1736'), ('\u17d4', '\u17d6'), ('\u17d8', '\u17da'), ('\u1800', '\u1805'), ('\u1807',
+        '\u180a'), ('\u1944', '\u1945'), ('\u1a1e', '\u1a1f'), ('\u1aa0', '\u1aa6'), ('\u1aa8',
+        '\u1aad'), ('\u1b5a', '\u1b60'), ('\u1bfc', '\u1bff'), ('\u1c3b', '\u1c3f'), ('\u1c7e',
+        '\u1c7f'), ('\u1cc0', '\u1cc7'), ('\u1cd3', '\u1cd3'), ('\u2016', '\u2017'), ('\u2020',
+        '\u2027'), ('\u2030', '\u2038'), ('\u203b', '\u203e'), ('\u2041', '\u2043'), ('\u2047',
+        '\u2051'), ('\u2053', '\u2053'), ('\u2055', '\u205e'), ('\u2cf9', '\u2cfc'), ('\u2cfe',
+        '\u2cff'), ('\u2d70', '\u2d70'), ('\u2e00', '\u2e01'), ('\u2e06', '\u2e08'), ('\u2e0b',
+        '\u2e0b'), ('\u2e0e', '\u2e16'), ('\u2e18', '\u2e19'), ('\u2e1b', '\u2e1b'), ('\u2e1e',
+        '\u2e1f'), ('\u2e2a', '\u2e2e'), ('\u2e30', '\u2e39'), ('\u2e3c', '\u2e3f'), ('\u2e41',
+        '\u2e41'), ('\u3001', '\u3003'), ('\u303d', '\u303d'), ('\u30fb', '\u30fb'), ('\ua4fe',
+        '\ua4ff'), ('\ua60d', '\ua60f'), ('\ua673', '\ua673'), ('\ua67e', '\ua67e'), ('\ua6f2',
+        '\ua6f7'), ('\ua874', '\ua877'), ('\ua8ce', '\ua8cf'), ('\ua8f8', '\ua8fa'), ('\ua92e',
+        '\ua92f'), ('\ua95f', '\ua95f'), ('\ua9c1', '\ua9cd'), ('\ua9de', '\ua9df'), ('\uaa5c',
+        '\uaa5f'), ('\uaade', '\uaadf'), ('\uaaf0', '\uaaf1'), ('\uabeb', '\uabeb'), ('\ufe10',
+        '\ufe16'), ('\ufe19', '\ufe19'), ('\ufe30', '\ufe30'), ('\ufe45', '\ufe46'), ('\ufe49',
+        '\ufe4c'), ('\ufe50', '\ufe52'), ('\ufe54', '\ufe57'), ('\ufe5f', '\ufe61'), ('\ufe68',
+        '\ufe68'), ('\ufe6a', '\ufe6b'), ('\uff01', '\uff03'), ('\uff05', '\uff07'), ('\uff0a',
+        '\uff0a'), ('\uff0c', '\uff0c'), ('\uff0e', '\uff0f'), ('\uff1a', '\uff1b'), ('\uff1f',
+        '\uff20'), ('\uff3c', '\uff3c'), ('\uff61', '\uff61'), ('\uff64', '\uff65'), ('\U00010100',
+        '\U00010102'), ('\U0001039f', '\U0001039f'), ('\U000103d0', '\U000103d0'), ('\U0001056f',
+        '\U0001056f'), ('\U00010857', '\U00010857'), ('\U0001091f', '\U0001091f'), ('\U0001093f',
+        '\U0001093f'), ('\U00010a50', '\U00010a58'), ('\U00010a7f', '\U00010a7f'), ('\U00010af0',
+        '\U00010af6'), ('\U00010b39', '\U00010b3f'), ('\U00010b99', '\U00010b9c'), ('\U00011047',
+        '\U0001104d'), ('\U000110bb', '\U000110bc'), ('\U000110be', '\U000110c1'), ('\U00011140',
+        '\U00011143'), ('\U00011174', '\U00011175'), ('\U000111c5', '\U000111c8'), ('\U000111cd',
+        '\U000111cd'), ('\U00011238', '\U0001123d'), ('\U000114c6', '\U000114c6'), ('\U000115c1',
+        '\U000115c9'), ('\U00011641', '\U00011643'), ('\U00012470', '\U00012474'), ('\U00016a6e',
+        '\U00016a6f'), ('\U00016af5', '\U00016af5'), ('\U00016b37', '\U00016b3b'), ('\U00016b44',
+        '\U00016b44'), ('\U0001bc9f', '\U0001bc9f')
+    ];
+
+    pub static Ps_table: &'static [(char, char)] = &[
+        ('\x28', '\x28'), ('\x5b', '\x5b'), ('\x7b', '\x7b'), ('\u0f3a', '\u0f3a'), ('\u0f3c',
+        '\u0f3c'), ('\u169b', '\u169b'), ('\u201a', '\u201a'), ('\u201e', '\u201e'), ('\u2045',
+        '\u2045'), ('\u207d', '\u207d'), ('\u208d', '\u208d'), ('\u2308', '\u2308'), ('\u230a',
+        '\u230a'), ('\u2329', '\u2329'), ('\u2768', '\u2768'), ('\u276a', '\u276a'), ('\u276c',
+        '\u276c'), ('\u276e', '\u276e'), ('\u2770', '\u2770'), ('\u2772', '\u2772'), ('\u2774',
+        '\u2774'), ('\u27c5', '\u27c5'), ('\u27e6', '\u27e6'), ('\u27e8', '\u27e8'), ('\u27ea',
+        '\u27ea'), ('\u27ec', '\u27ec'), ('\u27ee', '\u27ee'), ('\u2983', '\u2983'), ('\u2985',
+        '\u2985'), ('\u2987', '\u2987'), ('\u2989', '\u2989'), ('\u298b', '\u298b'), ('\u298d',
+        '\u298d'), ('\u298f', '\u298f'), ('\u2991', '\u2991'), ('\u2993', '\u2993'), ('\u2995',
+        '\u2995'), ('\u2997', '\u2997'), ('\u29d8', '\u29d8'), ('\u29da', '\u29da'), ('\u29fc',
+        '\u29fc'), ('\u2e22', '\u2e22'), ('\u2e24', '\u2e24'), ('\u2e26', '\u2e26'), ('\u2e28',
+        '\u2e28'), ('\u2e42', '\u2e42'), ('\u3008', '\u3008'), ('\u300a', '\u300a'), ('\u300c',
+        '\u300c'), ('\u300e', '\u300e'), ('\u3010', '\u3010'), ('\u3014', '\u3014'), ('\u3016',
+        '\u3016'), ('\u3018', '\u3018'), ('\u301a', '\u301a'), ('\u301d', '\u301d'), ('\ufd3f',
+        '\ufd3f'), ('\ufe17', '\ufe17'), ('\ufe35', '\ufe35'), ('\ufe37', '\ufe37'), ('\ufe39',
+        '\ufe39'), ('\ufe3b', '\ufe3b'), ('\ufe3d', '\ufe3d'), ('\ufe3f', '\ufe3f'), ('\ufe41',
+        '\ufe41'), ('\ufe43', '\ufe43'), ('\ufe47', '\ufe47'), ('\ufe59', '\ufe59'), ('\ufe5b',
+        '\ufe5b'), ('\ufe5d', '\ufe5d'), ('\uff08', '\uff08'), ('\uff3b', '\uff3b'), ('\uff5b',
+        '\uff5b'), ('\uff5f', '\uff5f'), ('\uff62', '\uff62')
+    ];
+
+    pub static S_table: &'static [(char, char)] = &[
+        ('\x24', '\x24'), ('\x2b', '\x2b'), ('\x3c', '\x3e'), ('\x5e', '\x5e'), ('\x60', '\x60'),
+        ('\x7c', '\x7c'), ('\x7e', '\x7e'), ('\xa2', '\xa6'), ('\xa8', '\xa9'), ('\xac', '\xac'),
+        ('\xae', '\xb1'), ('\xb4', '\xb4'), ('\xb8', '\xb8'), ('\xd7', '\xd7'), ('\xf7', '\xf7'),
+        ('\u02c2', '\u02c5'), ('\u02d2', '\u02df'), ('\u02e5', '\u02eb'), ('\u02ed', '\u02ed'),
+        ('\u02ef', '\u02ff'), ('\u0375', '\u0375'), ('\u0384', '\u0385'), ('\u03f6', '\u03f6'),
+        ('\u0482', '\u0482'), ('\u058d', '\u058f'), ('\u0606', '\u0608'), ('\u060b', '\u060b'),
+        ('\u060e', '\u060f'), ('\u06de', '\u06de'), ('\u06e9', '\u06e9'), ('\u06fd', '\u06fe'),
+        ('\u07f6', '\u07f6'), ('\u09f2', '\u09f3'), ('\u09fa', '\u09fb'), ('\u0af1', '\u0af1'),
+        ('\u0b70', '\u0b70'), ('\u0bf3', '\u0bfa'), ('\u0c7f', '\u0c7f'), ('\u0d79', '\u0d79'),
+        ('\u0e3f', '\u0e3f'), ('\u0f01', '\u0f03'), ('\u0f13', '\u0f13'), ('\u0f15', '\u0f17'),
+        ('\u0f1a', '\u0f1f'), ('\u0f34', '\u0f34'), ('\u0f36', '\u0f36'), ('\u0f38', '\u0f38'),
+        ('\u0fbe', '\u0fc5'), ('\u0fc7', '\u0fcc'), ('\u0fce', '\u0fcf'), ('\u0fd5', '\u0fd8'),
+        ('\u109e', '\u109f'), ('\u1390', '\u1399'), ('\u17db', '\u17db'), ('\u1940', '\u1940'),
+        ('\u19de', '\u19ff'), ('\u1b61', '\u1b6a'), ('\u1b74', '\u1b7c'), ('\u1fbd', '\u1fbd'),
+        ('\u1fbf', '\u1fc1'), ('\u1fcd', '\u1fcf'), ('\u1fdd', '\u1fdf'), ('\u1fed', '\u1fef'),
+        ('\u1ffd', '\u1ffe'), ('\u2044', '\u2044'), ('\u2052', '\u2052'), ('\u207a', '\u207c'),
+        ('\u208a', '\u208c'), ('\u20a0', '\u20bd'), ('\u2100', '\u2101'), ('\u2103', '\u2106'),
+        ('\u2108', '\u2109'), ('\u2114', '\u2114'), ('\u2116', '\u2118'), ('\u211e', '\u2123'),
+        ('\u2125', '\u2125'), ('\u2127', '\u2127'), ('\u2129', '\u2129'), ('\u212e', '\u212e'),
+        ('\u213a', '\u213b'), ('\u2140', '\u2144'), ('\u214a', '\u214d'), ('\u214f', '\u214f'),
+        ('\u2190', '\u2307'), ('\u230c', '\u2328'), ('\u232b', '\u23fa'), ('\u2400', '\u2426'),
+        ('\u2440', '\u244a'), ('\u249c', '\u24e9'), ('\u2500', '\u2767'), ('\u2794', '\u27c4'),
+        ('\u27c7', '\u27e5'), ('\u27f0', '\u2982'), ('\u2999', '\u29d7'), ('\u29dc', '\u29fb'),
+        ('\u29fe', '\u2b73'), ('\u2b76', '\u2b95'), ('\u2b98', '\u2bb9'), ('\u2bbd', '\u2bc8'),
+        ('\u2bca', '\u2bd1'), ('\u2ce5', '\u2cea'), ('\u2e80', '\u2e99'), ('\u2e9b', '\u2ef3'),
+        ('\u2f00', '\u2fd5'), ('\u2ff0', '\u2ffb'), ('\u3004', '\u3004'), ('\u3012', '\u3013'),
+        ('\u3020', '\u3020'), ('\u3036', '\u3037'), ('\u303e', '\u303f'), ('\u309b', '\u309c'),
+        ('\u3190', '\u3191'), ('\u3196', '\u319f'), ('\u31c0', '\u31e3'), ('\u3200', '\u321e'),
+        ('\u322a', '\u3247'), ('\u3250', '\u3250'), ('\u3260', '\u327f'), ('\u328a', '\u32b0'),
+        ('\u32c0', '\u32fe'), ('\u3300', '\u33ff'), ('\u4dc0', '\u4dff'), ('\ua490', '\ua4c6'),
+        ('\ua700', '\ua716'), ('\ua720', '\ua721'), ('\ua789', '\ua78a'), ('\ua828', '\ua82b'),
+        ('\ua836', '\ua839'), ('\uaa77', '\uaa79'), ('\uab5b', '\uab5b'), ('\ufb29', '\ufb29'),
+        ('\ufbb2', '\ufbc1'), ('\ufdfc', '\ufdfd'), ('\ufe62', '\ufe62'), ('\ufe64', '\ufe66'),
+        ('\ufe69', '\ufe69'), ('\uff04', '\uff04'), ('\uff0b', '\uff0b'), ('\uff1c', '\uff1e'),
+        ('\uff3e', '\uff3e'), ('\uff40', '\uff40'), ('\uff5c', '\uff5c'), ('\uff5e', '\uff5e'),
+        ('\uffe0', '\uffe6'), ('\uffe8', '\uffee'), ('\ufffc', '\ufffd'), ('\U00010137',
+        '\U0001013f'), ('\U00010179', '\U00010189'), ('\U0001018c', '\U0001018c'), ('\U00010190',
+        '\U0001019b'), ('\U000101a0', '\U000101a0'), ('\U000101d0', '\U000101fc'), ('\U00010877',
+        '\U00010878'), ('\U00010ac8', '\U00010ac8'), ('\U00016b3c', '\U00016b3f'), ('\U00016b45',
+        '\U00016b45'), ('\U0001bc9c', '\U0001bc9c'), ('\U0001d000', '\U0001d0f5'), ('\U0001d100',
+        '\U0001d126'), ('\U0001d129', '\U0001d164'), ('\U0001d16a', '\U0001d16c'), ('\U0001d183',
+        '\U0001d184'), ('\U0001d18c', '\U0001d1a9'), ('\U0001d1ae', '\U0001d1dd'), ('\U0001d200',
+        '\U0001d241'), ('\U0001d245', '\U0001d245'), ('\U0001d300', '\U0001d356'), ('\U0001d6c1',
+        '\U0001d6c1'), ('\U0001d6db', '\U0001d6db'), ('\U0001d6fb', '\U0001d6fb'), ('\U0001d715',
+        '\U0001d715'), ('\U0001d735', '\U0001d735'), ('\U0001d74f', '\U0001d74f'), ('\U0001d76f',
+        '\U0001d76f'), ('\U0001d789', '\U0001d789'), ('\U0001d7a9', '\U0001d7a9'), ('\U0001d7c3',
+        '\U0001d7c3'), ('\U0001eef0', '\U0001eef1'), ('\U0001f000', '\U0001f02b'), ('\U0001f030',
+        '\U0001f093'), ('\U0001f0a0', '\U0001f0ae'), ('\U0001f0b1', '\U0001f0bf'), ('\U0001f0c1',
+        '\U0001f0cf'), ('\U0001f0d1', '\U0001f0f5'), ('\U0001f110', '\U0001f12e'), ('\U0001f130',
+        '\U0001f16b'), ('\U0001f170', '\U0001f19a'), ('\U0001f1e6', '\U0001f202'), ('\U0001f210',
+        '\U0001f23a'), ('\U0001f240', '\U0001f248'), ('\U0001f250', '\U0001f251'), ('\U0001f300',
+        '\U0001f32c'), ('\U0001f330', '\U0001f37d'), ('\U0001f380', '\U0001f3ce'), ('\U0001f3d4',
+        '\U0001f3f7'), ('\U0001f400', '\U0001f4fe'), ('\U0001f500', '\U0001f54a'), ('\U0001f550',
+        '\U0001f579'), ('\U0001f57b', '\U0001f5a3'), ('\U0001f5a5', '\U0001f642'), ('\U0001f645',
+        '\U0001f6cf'), ('\U0001f6e0', '\U0001f6ec'), ('\U0001f6f0', '\U0001f6f3'), ('\U0001f700',
+        '\U0001f773'), ('\U0001f780', '\U0001f7d4'), ('\U0001f800', '\U0001f80b'), ('\U0001f810',
+        '\U0001f847'), ('\U0001f850', '\U0001f859'), ('\U0001f860', '\U0001f887'), ('\U0001f890',
+        '\U0001f8ad')
+    ];
+
+    pub static Sc_table: &'static [(char, char)] = &[
+        ('\x24', '\x24'), ('\xa2', '\xa5'), ('\u058f', '\u058f'), ('\u060b', '\u060b'), ('\u09f2',
+        '\u09f3'), ('\u09fb', '\u09fb'), ('\u0af1', '\u0af1'), ('\u0bf9', '\u0bf9'), ('\u0e3f',
+        '\u0e3f'), ('\u17db', '\u17db'), ('\u20a0', '\u20bd'), ('\ua838', '\ua838'), ('\ufdfc',
+        '\ufdfc'), ('\ufe69', '\ufe69'), ('\uff04', '\uff04'), ('\uffe0', '\uffe1'), ('\uffe5',
+        '\uffe6')
+    ];
+
+    pub static Sk_table: &'static [(char, char)] = &[
+        ('\x5e', '\x5e'), ('\x60', '\x60'), ('\xa8', '\xa8'), ('\xaf', '\xaf'), ('\xb4', '\xb4'),
+        ('\xb8', '\xb8'), ('\u02c2', '\u02c5'), ('\u02d2', '\u02df'), ('\u02e5', '\u02eb'),
+        ('\u02ed', '\u02ed'), ('\u02ef', '\u02ff'), ('\u0375', '\u0375'), ('\u0384', '\u0385'),
+        ('\u1fbd', '\u1fbd'), ('\u1fbf', '\u1fc1'), ('\u1fcd', '\u1fcf'), ('\u1fdd', '\u1fdf'),
+        ('\u1fed', '\u1fef'), ('\u1ffd', '\u1ffe'), ('\u309b', '\u309c'), ('\ua700', '\ua716'),
+        ('\ua720', '\ua721'), ('\ua789', '\ua78a'), ('\uab5b', '\uab5b'), ('\ufbb2', '\ufbc1'),
+        ('\uff3e', '\uff3e'), ('\uff40', '\uff40'), ('\uffe3', '\uffe3')
+    ];
+
+    pub static Sm_table: &'static [(char, char)] = &[
+        ('\x2b', '\x2b'), ('\x3c', '\x3e'), ('\x7c', '\x7c'), ('\x7e', '\x7e'), ('\xac', '\xac'),
+        ('\xb1', '\xb1'), ('\xd7', '\xd7'), ('\xf7', '\xf7'), ('\u03f6', '\u03f6'), ('\u0606',
+        '\u0608'), ('\u2044', '\u2044'), ('\u2052', '\u2052'), ('\u207a', '\u207c'), ('\u208a',
+        '\u208c'), ('\u2118', '\u2118'), ('\u2140', '\u2144'), ('\u214b', '\u214b'), ('\u2190',
+        '\u2194'), ('\u219a', '\u219b'), ('\u21a0', '\u21a0'), ('\u21a3', '\u21a3'), ('\u21a6',
+        '\u21a6'), ('\u21ae', '\u21ae'), ('\u21ce', '\u21cf'), ('\u21d2', '\u21d2'), ('\u21d4',
+        '\u21d4'), ('\u21f4', '\u22ff'), ('\u2320', '\u2321'), ('\u237c', '\u237c'), ('\u239b',
+        '\u23b3'), ('\u23dc', '\u23e1'), ('\u25b7', '\u25b7'), ('\u25c1', '\u25c1'), ('\u25f8',
+        '\u25ff'), ('\u266f', '\u266f'), ('\u27c0', '\u27c4'), ('\u27c7', '\u27e5'), ('\u27f0',
+        '\u27ff'), ('\u2900', '\u2982'), ('\u2999', '\u29d7'), ('\u29dc', '\u29fb'), ('\u29fe',
+        '\u2aff'), ('\u2b30', '\u2b44'), ('\u2b47', '\u2b4c'), ('\ufb29', '\ufb29'), ('\ufe62',
+        '\ufe62'), ('\ufe64', '\ufe66'), ('\uff0b', '\uff0b'), ('\uff1c', '\uff1e'), ('\uff5c',
+        '\uff5c'), ('\uff5e', '\uff5e'), ('\uffe2', '\uffe2'), ('\uffe9', '\uffec'), ('\U0001d6c1',
+        '\U0001d6c1'), ('\U0001d6db', '\U0001d6db'), ('\U0001d6fb', '\U0001d6fb'), ('\U0001d715',
+        '\U0001d715'), ('\U0001d735', '\U0001d735'), ('\U0001d74f', '\U0001d74f'), ('\U0001d76f',
+        '\U0001d76f'), ('\U0001d789', '\U0001d789'), ('\U0001d7a9', '\U0001d7a9'), ('\U0001d7c3',
+        '\U0001d7c3'), ('\U0001eef0', '\U0001eef1')
+    ];
+
+    pub static So_table: &'static [(char, char)] = &[
+        ('\xa6', '\xa6'), ('\xa9', '\xa9'), ('\xae', '\xae'), ('\xb0', '\xb0'), ('\u0482',
+        '\u0482'), ('\u058d', '\u058e'), ('\u060e', '\u060f'), ('\u06de', '\u06de'), ('\u06e9',
+        '\u06e9'), ('\u06fd', '\u06fe'), ('\u07f6', '\u07f6'), ('\u09fa', '\u09fa'), ('\u0b70',
+        '\u0b70'), ('\u0bf3', '\u0bf8'), ('\u0bfa', '\u0bfa'), ('\u0c7f', '\u0c7f'), ('\u0d79',
+        '\u0d79'), ('\u0f01', '\u0f03'), ('\u0f13', '\u0f13'), ('\u0f15', '\u0f17'), ('\u0f1a',
+        '\u0f1f'), ('\u0f34', '\u0f34'), ('\u0f36', '\u0f36'), ('\u0f38', '\u0f38'), ('\u0fbe',
+        '\u0fc5'), ('\u0fc7', '\u0fcc'), ('\u0fce', '\u0fcf'), ('\u0fd5', '\u0fd8'), ('\u109e',
+        '\u109f'), ('\u1390', '\u1399'), ('\u1940', '\u1940'), ('\u19de', '\u19ff'), ('\u1b61',
+        '\u1b6a'), ('\u1b74', '\u1b7c'), ('\u2100', '\u2101'), ('\u2103', '\u2106'), ('\u2108',
+        '\u2109'), ('\u2114', '\u2114'), ('\u2116', '\u2117'), ('\u211e', '\u2123'), ('\u2125',
+        '\u2125'), ('\u2127', '\u2127'), ('\u2129', '\u2129'), ('\u212e', '\u212e'), ('\u213a',
+        '\u213b'), ('\u214a', '\u214a'), ('\u214c', '\u214d'), ('\u214f', '\u214f'), ('\u2195',
+        '\u2199'), ('\u219c', '\u219f'), ('\u21a1', '\u21a2'), ('\u21a4', '\u21a5'), ('\u21a7',
+        '\u21ad'), ('\u21af', '\u21cd'), ('\u21d0', '\u21d1'), ('\u21d3', '\u21d3'), ('\u21d5',
+        '\u21f3'), ('\u2300', '\u2307'), ('\u230c', '\u231f'), ('\u2322', '\u2328'), ('\u232b',
+        '\u237b'), ('\u237d', '\u239a'), ('\u23b4', '\u23db'), ('\u23e2', '\u23fa'), ('\u2400',
+        '\u2426'), ('\u2440', '\u244a'), ('\u249c', '\u24e9'), ('\u2500', '\u25b6'), ('\u25b8',
+        '\u25c0'), ('\u25c2', '\u25f7'), ('\u2600', '\u266e'), ('\u2670', '\u2767'), ('\u2794',
+        '\u27bf'), ('\u2800', '\u28ff'), ('\u2b00', '\u2b2f'), ('\u2b45', '\u2b46'), ('\u2b4d',
+        '\u2b73'), ('\u2b76', '\u2b95'), ('\u2b98', '\u2bb9'), ('\u2bbd', '\u2bc8'), ('\u2bca',
+        '\u2bd1'), ('\u2ce5', '\u2cea'), ('\u2e80', '\u2e99'), ('\u2e9b', '\u2ef3'), ('\u2f00',
+        '\u2fd5'), ('\u2ff0', '\u2ffb'), ('\u3004', '\u3004'), ('\u3012', '\u3013'), ('\u3020',
+        '\u3020'), ('\u3036', '\u3037'), ('\u303e', '\u303f'), ('\u3190', '\u3191'), ('\u3196',
+        '\u319f'), ('\u31c0', '\u31e3'), ('\u3200', '\u321e'), ('\u322a', '\u3247'), ('\u3250',
+        '\u3250'), ('\u3260', '\u327f'), ('\u328a', '\u32b0'), ('\u32c0', '\u32fe'), ('\u3300',
+        '\u33ff'), ('\u4dc0', '\u4dff'), ('\ua490', '\ua4c6'), ('\ua828', '\ua82b'), ('\ua836',
+        '\ua837'), ('\ua839', '\ua839'), ('\uaa77', '\uaa79'), ('\ufdfd', '\ufdfd'), ('\uffe4',
+        '\uffe4'), ('\uffe8', '\uffe8'), ('\uffed', '\uffee'), ('\ufffc', '\ufffd'), ('\U00010137',
+        '\U0001013f'), ('\U00010179', '\U00010189'), ('\U0001018c', '\U0001018c'), ('\U00010190',
+        '\U0001019b'), ('\U000101a0', '\U000101a0'), ('\U000101d0', '\U000101fc'), ('\U00010877',
+        '\U00010878'), ('\U00010ac8', '\U00010ac8'), ('\U00016b3c', '\U00016b3f'), ('\U00016b45',
+        '\U00016b45'), ('\U0001bc9c', '\U0001bc9c'), ('\U0001d000', '\U0001d0f5'), ('\U0001d100',
+        '\U0001d126'), ('\U0001d129', '\U0001d164'), ('\U0001d16a', '\U0001d16c'), ('\U0001d183',
+        '\U0001d184'), ('\U0001d18c', '\U0001d1a9'), ('\U0001d1ae', '\U0001d1dd'), ('\U0001d200',
+        '\U0001d241'), ('\U0001d245', '\U0001d245'), ('\U0001d300', '\U0001d356'), ('\U0001f000',
+        '\U0001f02b'), ('\U0001f030', '\U0001f093'), ('\U0001f0a0', '\U0001f0ae'), ('\U0001f0b1',
+        '\U0001f0bf'), ('\U0001f0c1', '\U0001f0cf'), ('\U0001f0d1', '\U0001f0f5'), ('\U0001f110',
+        '\U0001f12e'), ('\U0001f130', '\U0001f16b'), ('\U0001f170', '\U0001f19a'), ('\U0001f1e6',
+        '\U0001f202'), ('\U0001f210', '\U0001f23a'), ('\U0001f240', '\U0001f248'), ('\U0001f250',
+        '\U0001f251'), ('\U0001f300', '\U0001f32c'), ('\U0001f330', '\U0001f37d'), ('\U0001f380',
+        '\U0001f3ce'), ('\U0001f3d4', '\U0001f3f7'), ('\U0001f400', '\U0001f4fe'), ('\U0001f500',
+        '\U0001f54a'), ('\U0001f550', '\U0001f579'), ('\U0001f57b', '\U0001f5a3'), ('\U0001f5a5',
+        '\U0001f642'), ('\U0001f645', '\U0001f6cf'), ('\U0001f6e0', '\U0001f6ec'), ('\U0001f6f0',
+        '\U0001f6f3'), ('\U0001f700', '\U0001f773'), ('\U0001f780', '\U0001f7d4'), ('\U0001f800',
+        '\U0001f80b'), ('\U0001f810', '\U0001f847'), ('\U0001f850', '\U0001f859'), ('\U0001f860',
+        '\U0001f887'), ('\U0001f890', '\U0001f8ad')
+    ];
+
+    pub static Z_table: &'static [(char, char)] = &[
+        ('\x20', '\x20'), ('\xa0', '\xa0'), ('\u1680', '\u1680'), ('\u2000', '\u200a'), ('\u2028',
+        '\u2029'), ('\u202f', '\u202f'), ('\u205f', '\u205f'), ('\u3000', '\u3000')
+    ];
+
+    pub static Zl_table: &'static [(char, char)] = &[
+        ('\u2028', '\u2028')
+    ];
+
+    pub static Zp_table: &'static [(char, char)] = &[
+        ('\u2029', '\u2029')
+    ];
+
+    pub static Zs_table: &'static [(char, char)] = &[
+        ('\x20', '\x20'), ('\xa0', '\xa0'), ('\u1680', '\u1680'), ('\u2000', '\u200a'), ('\u202f',
+        '\u202f'), ('\u205f', '\u205f'), ('\u3000', '\u3000')
+    ];
+
+}
+
+pub mod derived_property {
+    pub static Alphabetic_table: &'static [(char, char)] = &[
+        ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xb5', '\xb5'), ('\xba', '\xba'),
+        ('\xc0', '\xd6'), ('\xd8', '\xf6'), ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'), ('\u01bc',
+        '\u01bf'), ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'), ('\u0294', '\u0294'), ('\u0295',
+        '\u02af'), ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec',
+        '\u02ec'), ('\u02ee', '\u02ee'), ('\u0345', '\u0345'), ('\u0370', '\u0373'), ('\u0374',
+        '\u0374'), ('\u0376', '\u0377'), ('\u037a', '\u037a'), ('\u037b', '\u037d'), ('\u037f',
+        '\u037f'), ('\u0386', '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e',
+        '\u03a1'), ('\u03a3', '\u03f5'), ('\u03f7', '\u0481'), ('\u048a', '\u052f'), ('\u0531',
+        '\u0556'), ('\u0559', '\u0559'), ('\u0561', '\u0587'), ('\u05b0', '\u05bd'), ('\u05bf',
+        '\u05bf'), ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u05d0',
+        '\u05ea'), ('\u05f0', '\u05f2'), ('\u0610', '\u061a'), ('\u0620', '\u063f'), ('\u0640',
+        '\u0640'), ('\u0641', '\u064a'), ('\u064b', '\u0657'), ('\u0659', '\u065f'), ('\u066e',
+        '\u066f'), ('\u0670', '\u0670'), ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'), ('\u06d6',
+        '\u06dc'), ('\u06e1', '\u06e4'), ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'), ('\u06ed',
+        '\u06ed'), ('\u06ee', '\u06ef'), ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'), ('\u0710',
+        '\u0710'), ('\u0711', '\u0711'), ('\u0712', '\u072f'), ('\u0730', '\u073f'), ('\u074d',
+        '\u07a5'), ('\u07a6', '\u07b0'), ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'), ('\u07f4',
+        '\u07f5'), ('\u07fa', '\u07fa'), ('\u0800', '\u0815'), ('\u0816', '\u0817'), ('\u081a',
+        '\u081a'), ('\u081b', '\u0823'), ('\u0824', '\u0824'), ('\u0825', '\u0827'), ('\u0828',
+        '\u0828'), ('\u0829', '\u082c'), ('\u0840', '\u0858'), ('\u08a0', '\u08b2'), ('\u08e4',
+        '\u08e9'), ('\u08f0', '\u0902'), ('\u0903', '\u0903'), ('\u0904', '\u0939'), ('\u093a',
+        '\u093a'), ('\u093b', '\u093b'), ('\u093d', '\u093d'), ('\u093e', '\u0940'), ('\u0941',
+        '\u0948'), ('\u0949', '\u094c'), ('\u094e', '\u094f'), ('\u0950', '\u0950'), ('\u0955',
+        '\u0957'), ('\u0958', '\u0961'), ('\u0962', '\u0963'), ('\u0971', '\u0971'), ('\u0972',
+        '\u0980'), ('\u0981', '\u0981'), ('\u0982', '\u0983'), ('\u0985', '\u098c'), ('\u098f',
+        '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2', '\u09b2'), ('\u09b6',
+        '\u09b9'), ('\u09bd', '\u09bd'), ('\u09be', '\u09c0'), ('\u09c1', '\u09c4'), ('\u09c7',
+        '\u09c8'), ('\u09cb', '\u09cc'), ('\u09ce', '\u09ce'), ('\u09d7', '\u09d7'), ('\u09dc',
+        '\u09dd'), ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'), ('\u09f0', '\u09f1'), ('\u0a01',
+        '\u0a02'), ('\u0a03', '\u0a03'), ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'), ('\u0a13',
+        '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'), ('\u0a38',
+        '\u0a39'), ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'), ('\u0a47', '\u0a48'), ('\u0a4b',
+        '\u0a4c'), ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'), ('\u0a70',
+        '\u0a71'), ('\u0a72', '\u0a74'), ('\u0a75', '\u0a75'), ('\u0a81', '\u0a82'), ('\u0a83',
+        '\u0a83'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa',
+        '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abd', '\u0abd'), ('\u0abe',
+        '\u0ac0'), ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'), ('\u0ac9', '\u0ac9'), ('\u0acb',
+        '\u0acc'), ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0ae2', '\u0ae3'), ('\u0b01',
+        '\u0b01'), ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'), ('\u0b13',
+        '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'), ('\u0b3d',
+        '\u0b3d'), ('\u0b3e', '\u0b3e'), ('\u0b3f', '\u0b3f'), ('\u0b40', '\u0b40'), ('\u0b41',
+        '\u0b44'), ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4c'), ('\u0b56', '\u0b56'), ('\u0b57',
+        '\u0b57'), ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b62', '\u0b63'), ('\u0b71',
+        '\u0b71'), ('\u0b82', '\u0b82'), ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e',
+        '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e',
+        '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bbe',
+        '\u0bbf'), ('\u0bc0', '\u0bc0'), ('\u0bc1', '\u0bc2'), ('\u0bc6', '\u0bc8'), ('\u0bca',
+        '\u0bcc'), ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'), ('\u0c00', '\u0c00'), ('\u0c01',
+        '\u0c03'), ('\u0c05', '\u0c0c'), ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a',
+        '\u0c39'), ('\u0c3d', '\u0c3d'), ('\u0c3e', '\u0c40'), ('\u0c41', '\u0c44'), ('\u0c46',
+        '\u0c48'), ('\u0c4a', '\u0c4c'), ('\u0c55', '\u0c56'), ('\u0c58', '\u0c59'), ('\u0c60',
+        '\u0c61'), ('\u0c62', '\u0c63'), ('\u0c81', '\u0c81'), ('\u0c82', '\u0c83'), ('\u0c85',
+        '\u0c8c'), ('\u0c8e', '\u0c90'), ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5',
+        '\u0cb9'), ('\u0cbd', '\u0cbd'), ('\u0cbe', '\u0cbe'), ('\u0cbf', '\u0cbf'), ('\u0cc0',
+        '\u0cc4'), ('\u0cc6', '\u0cc6'), ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'), ('\u0ccc',
+        '\u0ccc'), ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0ce2',
+        '\u0ce3'), ('\u0cf1', '\u0cf2'), ('\u0d01', '\u0d01'), ('\u0d02', '\u0d03'), ('\u0d05',
+        '\u0d0c'), ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d3e',
+        '\u0d40'), ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4c'), ('\u0d4e',
+        '\u0d4e'), ('\u0d57', '\u0d57'), ('\u0d60', '\u0d61'), ('\u0d62', '\u0d63'), ('\u0d7a',
+        '\u0d7f'), ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3',
+        '\u0dbb'), ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0dcf', '\u0dd1'), ('\u0dd2',
+        '\u0dd4'), ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'), ('\u0df2', '\u0df3'), ('\u0e01',
+        '\u0e30'), ('\u0e31', '\u0e31'), ('\u0e32', '\u0e33'), ('\u0e34', '\u0e3a'), ('\u0e40',
+        '\u0e45'), ('\u0e46', '\u0e46'), ('\u0e4d', '\u0e4d'), ('\u0e81', '\u0e82'), ('\u0e84',
+        '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94',
+        '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7',
+        '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'), ('\u0eb1', '\u0eb1'), ('\u0eb2',
+        '\u0eb3'), ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'), ('\u0ebd', '\u0ebd'), ('\u0ec0',
+        '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0ecd', '\u0ecd'), ('\u0edc', '\u0edf'), ('\u0f00',
+        '\u0f00'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'), ('\u0f71', '\u0f7e'), ('\u0f7f',
+        '\u0f7f'), ('\u0f80', '\u0f81'), ('\u0f88', '\u0f8c'), ('\u0f8d', '\u0f97'), ('\u0f99',
+        '\u0fbc'), ('\u1000', '\u102a'), ('\u102b', '\u102c'), ('\u102d', '\u1030'), ('\u1031',
+        '\u1031'), ('\u1032', '\u1036'), ('\u1038', '\u1038'), ('\u103b', '\u103c'), ('\u103d',
+        '\u103e'), ('\u103f', '\u103f'), ('\u1050', '\u1055'), ('\u1056', '\u1057'), ('\u1058',
+        '\u1059'), ('\u105a', '\u105d'), ('\u105e', '\u1060'), ('\u1061', '\u1061'), ('\u1062',
+        '\u1062'), ('\u1065', '\u1066'), ('\u1067', '\u1068'), ('\u106e', '\u1070'), ('\u1071',
+        '\u1074'), ('\u1075', '\u1081'), ('\u1082', '\u1082'), ('\u1083', '\u1084'), ('\u1085',
+        '\u1086'), ('\u108e', '\u108e'), ('\u109c', '\u109c'), ('\u109d', '\u109d'), ('\u10a0',
+        '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'), ('\u10fc',
+        '\u10fc'), ('\u10fd', '\u1248'), ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258',
+        '\u1258'), ('\u125a', '\u125d'), ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290',
+        '\u12b0'), ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2',
+        '\u12c5'), ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318',
+        '\u135a'), ('\u135f', '\u135f'), ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401',
+        '\u166c'), ('\u166f', '\u167f'), ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16ee',
+        '\u16f0'), ('\u16f1', '\u16f8'), ('\u1700', '\u170c'), ('\u170e', '\u1711'), ('\u1712',
+        '\u1713'), ('\u1720', '\u1731'), ('\u1732', '\u1733'), ('\u1740', '\u1751'), ('\u1752',
+        '\u1753'), ('\u1760', '\u176c'), ('\u176e', '\u1770'), ('\u1772', '\u1773'), ('\u1780',
+        '\u17b3'), ('\u17b6', '\u17b6'), ('\u17b7', '\u17bd'), ('\u17be', '\u17c5'), ('\u17c6',
+        '\u17c6'), ('\u17c7', '\u17c8'), ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'), ('\u1820',
+        '\u1842'), ('\u1843', '\u1843'), ('\u1844', '\u1877'), ('\u1880', '\u18a8'), ('\u18a9',
+        '\u18a9'), ('\u18aa', '\u18aa'), ('\u18b0', '\u18f5'), ('\u1900', '\u191e'), ('\u1920',
+        '\u1922'), ('\u1923', '\u1926'), ('\u1927', '\u1928'), ('\u1929', '\u192b'), ('\u1930',
+        '\u1931'), ('\u1932', '\u1932'), ('\u1933', '\u1938'), ('\u1950', '\u196d'), ('\u1970',
+        '\u1974'), ('\u1980', '\u19ab'), ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'), ('\u19c8',
+        '\u19c9'), ('\u1a00', '\u1a16'), ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'), ('\u1a1b',
+        '\u1a1b'), ('\u1a20', '\u1a54'), ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'), ('\u1a57',
+        '\u1a57'), ('\u1a58', '\u1a5e'), ('\u1a61', '\u1a61'), ('\u1a62', '\u1a62'), ('\u1a63',
+        '\u1a64'), ('\u1a65', '\u1a6c'), ('\u1a6d', '\u1a72'), ('\u1a73', '\u1a74'), ('\u1aa7',
+        '\u1aa7'), ('\u1b00', '\u1b03'), ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'), ('\u1b35',
+        '\u1b35'), ('\u1b36', '\u1b3a'), ('\u1b3b', '\u1b3b'), ('\u1b3c', '\u1b3c'), ('\u1b3d',
+        '\u1b41'), ('\u1b42', '\u1b42'), ('\u1b43', '\u1b43'), ('\u1b45', '\u1b4b'), ('\u1b80',
+        '\u1b81'), ('\u1b82', '\u1b82'), ('\u1b83', '\u1ba0'), ('\u1ba1', '\u1ba1'), ('\u1ba2',
+        '\u1ba5'), ('\u1ba6', '\u1ba7'), ('\u1ba8', '\u1ba9'), ('\u1bac', '\u1bad'), ('\u1bae',
+        '\u1baf'), ('\u1bba', '\u1be5'), ('\u1be7', '\u1be7'), ('\u1be8', '\u1be9'), ('\u1bea',
+        '\u1bec'), ('\u1bed', '\u1bed'), ('\u1bee', '\u1bee'), ('\u1bef', '\u1bf1'), ('\u1c00',
+        '\u1c23'), ('\u1c24', '\u1c2b'), ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'), ('\u1c4d',
+        '\u1c4f'), ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'), ('\u1ce9', '\u1cec'), ('\u1cee',
+        '\u1cf1'), ('\u1cf2', '\u1cf3'), ('\u1cf5', '\u1cf6'), ('\u1d00', '\u1d2b'), ('\u1d2c',
+        '\u1d6a'), ('\u1d6b', '\u1d77'), ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'), ('\u1d9b',
+        '\u1dbf'), ('\u1de7', '\u1df4'), ('\u1e00', '\u1f15'), ('\u1f18', '\u1f1d'), ('\u1f20',
+        '\u1f45'), ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'), ('\u1f5b',
+        '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'), ('\u1fb6',
+        '\u1fbc'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fd0',
+        '\u1fd3'), ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'), ('\u1ff6',
+        '\u1ffc'), ('\u2071', '\u2071'), ('\u207f', '\u207f'), ('\u2090', '\u209c'), ('\u2102',
+        '\u2102'), ('\u2107', '\u2107'), ('\u210a', '\u2113'), ('\u2115', '\u2115'), ('\u2119',
+        '\u211d'), ('\u2124', '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a',
+        '\u212d'), ('\u212f', '\u2134'), ('\u2135', '\u2138'), ('\u2139', '\u2139'), ('\u213c',
+        '\u213f'), ('\u2145', '\u2149'), ('\u214e', '\u214e'), ('\u2160', '\u2182'), ('\u2183',
+        '\u2184'), ('\u2185', '\u2188'), ('\u24b6', '\u24e9'), ('\u2c00', '\u2c2e'), ('\u2c30',
+        '\u2c5e'), ('\u2c60', '\u2c7b'), ('\u2c7c', '\u2c7d'), ('\u2c7e', '\u2ce4'), ('\u2ceb',
+        '\u2cee'), ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d',
+        '\u2d2d'), ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'), ('\u2d80', '\u2d96'), ('\u2da0',
+        '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0',
+        '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'), ('\u2de0',
+        '\u2dff'), ('\u2e2f', '\u2e2f'), ('\u3005', '\u3005'), ('\u3006', '\u3006'), ('\u3007',
+        '\u3007'), ('\u3021', '\u3029'), ('\u3031', '\u3035'), ('\u3038', '\u303a'), ('\u303b',
+        '\u303b'), ('\u303c', '\u303c'), ('\u3041', '\u3096'), ('\u309d', '\u309e'), ('\u309f',
+        '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'), ('\u3105',
+        '\u312d'), ('\u3131', '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400',
+        '\u4db5'), ('\u4e00', '\u9fcc'), ('\ua000', '\ua014'), ('\ua015', '\ua015'), ('\ua016',
+        '\ua48c'), ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'), ('\ua60c',
+        '\ua60c'), ('\ua610', '\ua61f'), ('\ua62a', '\ua62b'), ('\ua640', '\ua66d'), ('\ua66e',
+        '\ua66e'), ('\ua674', '\ua67b'), ('\ua67f', '\ua67f'), ('\ua680', '\ua69b'), ('\ua69c',
+        '\ua69d'), ('\ua69f', '\ua69f'), ('\ua6a0', '\ua6e5'), ('\ua6e6', '\ua6ef'), ('\ua717',
+        '\ua71f'), ('\ua722', '\ua76f'), ('\ua770', '\ua770'), ('\ua771', '\ua787'), ('\ua788',
+        '\ua788'), ('\ua78b', '\ua78e'), ('\ua790', '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\ua7f7',
+        '\ua7f7'), ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'), ('\ua7fb', '\ua801'), ('\ua803',
+        '\ua805'), ('\ua807', '\ua80a'), ('\ua80c', '\ua822'), ('\ua823', '\ua824'), ('\ua825',
+        '\ua826'), ('\ua827', '\ua827'), ('\ua840', '\ua873'), ('\ua880', '\ua881'), ('\ua882',
+        '\ua8b3'), ('\ua8b4', '\ua8c3'), ('\ua8f2', '\ua8f7'), ('\ua8fb', '\ua8fb'), ('\ua90a',
+        '\ua925'), ('\ua926', '\ua92a'), ('\ua930', '\ua946'), ('\ua947', '\ua951'), ('\ua952',
+        '\ua952'), ('\ua960', '\ua97c'), ('\ua980', '\ua982'), ('\ua983', '\ua983'), ('\ua984',
+        '\ua9b2'), ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'), ('\ua9ba', '\ua9bb'), ('\ua9bc',
+        '\ua9bc'), ('\ua9bd', '\ua9bf'), ('\ua9cf', '\ua9cf'), ('\ua9e0', '\ua9e4'), ('\ua9e6',
+        '\ua9e6'), ('\ua9e7', '\ua9ef'), ('\ua9fa', '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa29',
+        '\uaa2e'), ('\uaa2f', '\uaa30'), ('\uaa31', '\uaa32'), ('\uaa33', '\uaa34'), ('\uaa35',
+        '\uaa36'), ('\uaa40', '\uaa42'), ('\uaa43', '\uaa43'), ('\uaa44', '\uaa4b'), ('\uaa4c',
+        '\uaa4c'), ('\uaa4d', '\uaa4d'), ('\uaa60', '\uaa6f'), ('\uaa70', '\uaa70'), ('\uaa71',
+        '\uaa76'), ('\uaa7a', '\uaa7a'), ('\uaa7e', '\uaaaf'), ('\uaab0', '\uaab0'), ('\uaab1',
+        '\uaab1'), ('\uaab2', '\uaab4'), ('\uaab5', '\uaab6'), ('\uaab7', '\uaab8'), ('\uaab9',
+        '\uaabd'), ('\uaabe', '\uaabe'), ('\uaac0', '\uaac0'), ('\uaac2', '\uaac2'), ('\uaadb',
+        '\uaadc'), ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'), ('\uaaeb', '\uaaeb'), ('\uaaec',
+        '\uaaed'), ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'), ('\uaaf5',
+        '\uaaf5'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'), ('\uab11', '\uab16'), ('\uab20',
+        '\uab26'), ('\uab28', '\uab2e'), ('\uab30', '\uab5a'), ('\uab5c', '\uab5f'), ('\uab64',
+        '\uab65'), ('\uabc0', '\uabe2'), ('\uabe3', '\uabe4'), ('\uabe5', '\uabe5'), ('\uabe6',
+        '\uabe7'), ('\uabe8', '\uabe8'), ('\uabe9', '\uabea'), ('\uac00', '\ud7a3'), ('\ud7b0',
+        '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb00',
+        '\ufb06'), ('\ufb13', '\ufb17'), ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'), ('\ufb1f',
+        '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'), ('\ufb40',
+        '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufd3d'), ('\ufd50',
+        '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdfb'), ('\ufe70', '\ufe74'), ('\ufe76',
+        '\ufefc'), ('\uff21', '\uff3a'), ('\uff41', '\uff5a'), ('\uff66', '\uff6f'), ('\uff70',
+        '\uff70'), ('\uff71', '\uff9d'), ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'), ('\uffc2',
+        '\uffc7'), ('\uffca', '\uffcf'), ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'), ('\U00010000',
+        '\U0001000b'), ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'), ('\U0001003c',
+        '\U0001003d'), ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'), ('\U00010080',
+        '\U000100fa'), ('\U00010140', '\U00010174'), ('\U00010280', '\U0001029c'), ('\U000102a0',
+        '\U000102d0'), ('\U00010300', '\U0001031f'), ('\U00010330', '\U00010340'), ('\U00010341',
+        '\U00010341'), ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'), ('\U00010350',
+        '\U00010375'), ('\U00010376', '\U0001037a'), ('\U00010380', '\U0001039d'), ('\U000103a0',
+        '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'), ('\U00010400',
+        '\U0001044f'), ('\U00010450', '\U0001049d'), ('\U00010500', '\U00010527'), ('\U00010530',
+        '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'), ('\U00010760',
+        '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'), ('\U0001080a',
+        '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'), ('\U0001083f',
+        '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'), ('\U00010900',
+        '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'), ('\U000109be',
+        '\U000109bf'), ('\U00010a00', '\U00010a00'), ('\U00010a01', '\U00010a03'), ('\U00010a05',
+        '\U00010a06'), ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'), ('\U00010a15',
+        '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a60', '\U00010a7c'), ('\U00010a80',
+        '\U00010a9c'), ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae4'), ('\U00010b00',
+        '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'), ('\U00010b80',
+        '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'), ('\U00011001',
+        '\U00011001'), ('\U00011002', '\U00011002'), ('\U00011003', '\U00011037'), ('\U00011038',
+        '\U00011045'), ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'), ('\U000110b0',
+        '\U000110b2'), ('\U000110b3', '\U000110b6'), ('\U000110b7', '\U000110b8'), ('\U000110d0',
+        '\U000110e8'), ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'), ('\U00011127',
+        '\U0001112b'), ('\U0001112c', '\U0001112c'), ('\U0001112d', '\U00011132'), ('\U00011150',
+        '\U00011172'), ('\U00011176', '\U00011176'), ('\U00011180', '\U00011181'), ('\U00011182',
+        '\U00011182'), ('\U00011183', '\U000111b2'), ('\U000111b3', '\U000111b5'), ('\U000111b6',
+        '\U000111be'), ('\U000111bf', '\U000111bf'), ('\U000111c1', '\U000111c4'), ('\U000111da',
+        '\U000111da'), ('\U00011200', '\U00011211'), ('\U00011213', '\U0001122b'), ('\U0001122c',
+        '\U0001122e'), ('\U0001122f', '\U00011231'), ('\U00011232', '\U00011233'), ('\U00011234',
+        '\U00011234'), ('\U00011237', '\U00011237'), ('\U000112b0', '\U000112de'), ('\U000112df',
+        '\U000112df'), ('\U000112e0', '\U000112e2'), ('\U000112e3', '\U000112e8'), ('\U00011301',
+        '\U00011301'), ('\U00011302', '\U00011303'), ('\U00011305', '\U0001130c'), ('\U0001130f',
+        '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'), ('\U00011332',
+        '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133d', '\U0001133d'), ('\U0001133e',
+        '\U0001133f'), ('\U00011340', '\U00011340'), ('\U00011341', '\U00011344'), ('\U00011347',
+        '\U00011348'), ('\U0001134b', '\U0001134c'), ('\U00011357', '\U00011357'), ('\U0001135d',
+        '\U00011361'), ('\U00011362', '\U00011363'), ('\U00011480', '\U000114af'), ('\U000114b0',
+        '\U000114b2'), ('\U000114b3', '\U000114b8'), ('\U000114b9', '\U000114b9'), ('\U000114ba',
+        '\U000114ba'), ('\U000114bb', '\U000114be'), ('\U000114bf', '\U000114c0'), ('\U000114c1',
+        '\U000114c1'), ('\U000114c4', '\U000114c5'), ('\U000114c7', '\U000114c7'), ('\U00011580',
+        '\U000115ae'), ('\U000115af', '\U000115b1'), ('\U000115b2', '\U000115b5'), ('\U000115b8',
+        '\U000115bb'), ('\U000115bc', '\U000115bd'), ('\U000115be', '\U000115be'), ('\U00011600',
+        '\U0001162f'), ('\U00011630', '\U00011632'), ('\U00011633', '\U0001163a'), ('\U0001163b',
+        '\U0001163c'), ('\U0001163d', '\U0001163d'), ('\U0001163e', '\U0001163e'), ('\U00011640',
+        '\U00011640'), ('\U00011644', '\U00011644'), ('\U00011680', '\U000116aa'), ('\U000116ab',
+        '\U000116ab'), ('\U000116ac', '\U000116ac'), ('\U000116ad', '\U000116ad'), ('\U000116ae',
+        '\U000116af'), ('\U000116b0', '\U000116b5'), ('\U000118a0', '\U000118df'), ('\U000118ff',
+        '\U000118ff'), ('\U00011ac0', '\U00011af8'), ('\U00012000', '\U00012398'), ('\U00012400',
+        '\U0001246e'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'), ('\U00016a40',
+        '\U00016a5e'), ('\U00016ad0', '\U00016aed'), ('\U00016b00', '\U00016b2f'), ('\U00016b30',
+        '\U00016b36'), ('\U00016b40', '\U00016b43'), ('\U00016b63', '\U00016b77'), ('\U00016b7d',
+        '\U00016b8f'), ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f51',
+        '\U00016f7e'), ('\U00016f93', '\U00016f9f'), ('\U0001b000', '\U0001b001'), ('\U0001bc00',
+        '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80', '\U0001bc88'), ('\U0001bc90',
+        '\U0001bc99'), ('\U0001bc9e', '\U0001bc9e'), ('\U0001d400', '\U0001d454'), ('\U0001d456',
+        '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5',
+        '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb',
+        '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'), ('\U0001d507',
+        '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'), ('\U0001d51e',
+        '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'), ('\U0001d546',
+        '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8',
+        '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fc',
+        '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'), ('\U0001d750',
+        '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'), ('\U0001d7aa',
+        '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001e800', '\U0001e8c4'), ('\U0001ee00',
+        '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'), ('\U0001ee24',
+        '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'), ('\U0001ee34',
+        '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42',
+        '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b',
+        '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'), ('\U0001ee54',
+        '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b',
+        '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61',
+        '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c',
+        '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e',
+        '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1',
+        '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'), ('\U0001f130',
+        '\U0001f149'), ('\U0001f150', '\U0001f169'), ('\U0001f170', '\U0001f189'), ('\U00020000',
+        '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'), ('\U0002f800',
+        '\U0002fa1d')
+    ];
+
+    pub fn Alphabetic(c: char) -> bool {
+        super::bsearch_range_table(c, Alphabetic_table)
+    }
+
+    pub static Lowercase_table: &'static [(char, char)] = &[
+        ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xb5', '\xb5'), ('\xba', '\xba'), ('\xdf', '\xf6'),
+        ('\xf8', '\xff'), ('\u0101', '\u0101'), ('\u0103', '\u0103'), ('\u0105', '\u0105'),
+        ('\u0107', '\u0107'), ('\u0109', '\u0109'), ('\u010b', '\u010b'), ('\u010d', '\u010d'),
+        ('\u010f', '\u010f'), ('\u0111', '\u0111'), ('\u0113', '\u0113'), ('\u0115', '\u0115'),
+        ('\u0117', '\u0117'), ('\u0119', '\u0119'), ('\u011b', '\u011b'), ('\u011d', '\u011d'),
+        ('\u011f', '\u011f'), ('\u0121', '\u0121'), ('\u0123', '\u0123'), ('\u0125', '\u0125'),
+        ('\u0127', '\u0127'), ('\u0129', '\u0129'), ('\u012b', '\u012b'), ('\u012d', '\u012d'),
+        ('\u012f', '\u012f'), ('\u0131', '\u0131'), ('\u0133', '\u0133'), ('\u0135', '\u0135'),
+        ('\u0137', '\u0138'), ('\u013a', '\u013a'), ('\u013c', '\u013c'), ('\u013e', '\u013e'),
+        ('\u0140', '\u0140'), ('\u0142', '\u0142'), ('\u0144', '\u0144'), ('\u0146', '\u0146'),
+        ('\u0148', '\u0149'), ('\u014b', '\u014b'), ('\u014d', '\u014d'), ('\u014f', '\u014f'),
+        ('\u0151', '\u0151'), ('\u0153', '\u0153'), ('\u0155', '\u0155'), ('\u0157', '\u0157'),
+        ('\u0159', '\u0159'), ('\u015b', '\u015b'), ('\u015d', '\u015d'), ('\u015f', '\u015f'),
+        ('\u0161', '\u0161'), ('\u0163', '\u0163'), ('\u0165', '\u0165'), ('\u0167', '\u0167'),
+        ('\u0169', '\u0169'), ('\u016b', '\u016b'), ('\u016d', '\u016d'), ('\u016f', '\u016f'),
+        ('\u0171', '\u0171'), ('\u0173', '\u0173'), ('\u0175', '\u0175'), ('\u0177', '\u0177'),
+        ('\u017a', '\u017a'), ('\u017c', '\u017c'), ('\u017e', '\u0180'), ('\u0183', '\u0183'),
+        ('\u0185', '\u0185'), ('\u0188', '\u0188'), ('\u018c', '\u018d'), ('\u0192', '\u0192'),
+        ('\u0195', '\u0195'), ('\u0199', '\u019b'), ('\u019e', '\u019e'), ('\u01a1', '\u01a1'),
+        ('\u01a3', '\u01a3'), ('\u01a5', '\u01a5'), ('\u01a8', '\u01a8'), ('\u01aa', '\u01ab'),
+        ('\u01ad', '\u01ad'), ('\u01b0', '\u01b0'), ('\u01b4', '\u01b4'), ('\u01b6', '\u01b6'),
+        ('\u01b9', '\u01ba'), ('\u01bd', '\u01bf'), ('\u01c6', '\u01c6'), ('\u01c9', '\u01c9'),
+        ('\u01cc', '\u01cc'), ('\u01ce', '\u01ce'), ('\u01d0', '\u01d0'), ('\u01d2', '\u01d2'),
+        ('\u01d4', '\u01d4'), ('\u01d6', '\u01d6'), ('\u01d8', '\u01d8'), ('\u01da', '\u01da'),
+        ('\u01dc', '\u01dd'), ('\u01df', '\u01df'), ('\u01e1', '\u01e1'), ('\u01e3', '\u01e3'),
+        ('\u01e5', '\u01e5'), ('\u01e7', '\u01e7'), ('\u01e9', '\u01e9'), ('\u01eb', '\u01eb'),
+        ('\u01ed', '\u01ed'), ('\u01ef', '\u01f0'), ('\u01f3', '\u01f3'), ('\u01f5', '\u01f5'),
+        ('\u01f9', '\u01f9'), ('\u01fb', '\u01fb'), ('\u01fd', '\u01fd'), ('\u01ff', '\u01ff'),
+        ('\u0201', '\u0201'), ('\u0203', '\u0203'), ('\u0205', '\u0205'), ('\u0207', '\u0207'),
+        ('\u0209', '\u0209'), ('\u020b', '\u020b'), ('\u020d', '\u020d'), ('\u020f', '\u020f'),
+        ('\u0211', '\u0211'), ('\u0213', '\u0213'), ('\u0215', '\u0215'), ('\u0217', '\u0217'),
+        ('\u0219', '\u0219'), ('\u021b', '\u021b'), ('\u021d', '\u021d'), ('\u021f', '\u021f'),
+        ('\u0221', '\u0221'), ('\u0223', '\u0223'), ('\u0225', '\u0225'), ('\u0227', '\u0227'),
+        ('\u0229', '\u0229'), ('\u022b', '\u022b'), ('\u022d', '\u022d'), ('\u022f', '\u022f'),
+        ('\u0231', '\u0231'), ('\u0233', '\u0239'), ('\u023c', '\u023c'), ('\u023f', '\u0240'),
+        ('\u0242', '\u0242'), ('\u0247', '\u0247'), ('\u0249', '\u0249'), ('\u024b', '\u024b'),
+        ('\u024d', '\u024d'), ('\u024f', '\u0293'), ('\u0295', '\u02af'), ('\u02b0', '\u02b8'),
+        ('\u02c0', '\u02c1'), ('\u02e0', '\u02e4'), ('\u0345', '\u0345'), ('\u0371', '\u0371'),
+        ('\u0373', '\u0373'), ('\u0377', '\u0377'), ('\u037a', '\u037a'), ('\u037b', '\u037d'),
+        ('\u0390', '\u0390'), ('\u03ac', '\u03ce'), ('\u03d0', '\u03d1'), ('\u03d5', '\u03d7'),
+        ('\u03d9', '\u03d9'), ('\u03db', '\u03db'), ('\u03dd', '\u03dd'), ('\u03df', '\u03df'),
+        ('\u03e1', '\u03e1'), ('\u03e3', '\u03e3'), ('\u03e5', '\u03e5'), ('\u03e7', '\u03e7'),
+        ('\u03e9', '\u03e9'), ('\u03eb', '\u03eb'), ('\u03ed', '\u03ed'), ('\u03ef', '\u03f3'),
+        ('\u03f5', '\u03f5'), ('\u03f8', '\u03f8'), ('\u03fb', '\u03fc'), ('\u0430', '\u045f'),
+        ('\u0461', '\u0461'), ('\u0463', '\u0463'), ('\u0465', '\u0465'), ('\u0467', '\u0467'),
+        ('\u0469', '\u0469'), ('\u046b', '\u046b'), ('\u046d', '\u046d'), ('\u046f', '\u046f'),
+        ('\u0471', '\u0471'), ('\u0473', '\u0473'), ('\u0475', '\u0475'), ('\u0477', '\u0477'),
+        ('\u0479', '\u0479'), ('\u047b', '\u047b'), ('\u047d', '\u047d'), ('\u047f', '\u047f'),
+        ('\u0481', '\u0481'), ('\u048b', '\u048b'), ('\u048d', '\u048d'), ('\u048f', '\u048f'),
+        ('\u0491', '\u0491'), ('\u0493', '\u0493'), ('\u0495', '\u0495'), ('\u0497', '\u0497'),
+        ('\u0499', '\u0499'), ('\u049b', '\u049b'), ('\u049d', '\u049d'), ('\u049f', '\u049f'),
+        ('\u04a1', '\u04a1'), ('\u04a3', '\u04a3'), ('\u04a5', '\u04a5'), ('\u04a7', '\u04a7'),
+        ('\u04a9', '\u04a9'), ('\u04ab', '\u04ab'), ('\u04ad', '\u04ad'), ('\u04af', '\u04af'),
+        ('\u04b1', '\u04b1'), ('\u04b3', '\u04b3'), ('\u04b5', '\u04b5'), ('\u04b7', '\u04b7'),
+        ('\u04b9', '\u04b9'), ('\u04bb', '\u04bb'), ('\u04bd', '\u04bd'), ('\u04bf', '\u04bf'),
+        ('\u04c2', '\u04c2'), ('\u04c4', '\u04c4'), ('\u04c6', '\u04c6'), ('\u04c8', '\u04c8'),
+        ('\u04ca', '\u04ca'), ('\u04cc', '\u04cc'), ('\u04ce', '\u04cf'), ('\u04d1', '\u04d1'),
+        ('\u04d3', '\u04d3'), ('\u04d5', '\u04d5'), ('\u04d7', '\u04d7'), ('\u04d9', '\u04d9'),
+        ('\u04db', '\u04db'), ('\u04dd', '\u04dd'), ('\u04df', '\u04df'), ('\u04e1', '\u04e1'),
+        ('\u04e3', '\u04e3'), ('\u04e5', '\u04e5'), ('\u04e7', '\u04e7'), ('\u04e9', '\u04e9'),
+        ('\u04eb', '\u04eb'), ('\u04ed', '\u04ed'), ('\u04ef', '\u04ef'), ('\u04f1', '\u04f1'),
+        ('\u04f3', '\u04f3'), ('\u04f5', '\u04f5'), ('\u04f7', '\u04f7'), ('\u04f9', '\u04f9'),
+        ('\u04fb', '\u04fb'), ('\u04fd', '\u04fd'), ('\u04ff', '\u04ff'), ('\u0501', '\u0501'),
+        ('\u0503', '\u0503'), ('\u0505', '\u0505'), ('\u0507', '\u0507'), ('\u0509', '\u0509'),
+        ('\u050b', '\u050b'), ('\u050d', '\u050d'), ('\u050f', '\u050f'), ('\u0511', '\u0511'),
+        ('\u0513', '\u0513'), ('\u0515', '\u0515'), ('\u0517', '\u0517'), ('\u0519', '\u0519'),
+        ('\u051b', '\u051b'), ('\u051d', '\u051d'), ('\u051f', '\u051f'), ('\u0521', '\u0521'),
+        ('\u0523', '\u0523'), ('\u0525', '\u0525'), ('\u0527', '\u0527'), ('\u0529', '\u0529'),
+        ('\u052b', '\u052b'), ('\u052d', '\u052d'), ('\u052f', '\u052f'), ('\u0561', '\u0587'),
+        ('\u1d00', '\u1d2b'), ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'), ('\u1d78', '\u1d78'),
+        ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbf'), ('\u1e01', '\u1e01'), ('\u1e03', '\u1e03'),
+        ('\u1e05', '\u1e05'), ('\u1e07', '\u1e07'), ('\u1e09', '\u1e09'), ('\u1e0b', '\u1e0b'),
+        ('\u1e0d', '\u1e0d'), ('\u1e0f', '\u1e0f'), ('\u1e11', '\u1e11'), ('\u1e13', '\u1e13'),
+        ('\u1e15', '\u1e15'), ('\u1e17', '\u1e17'), ('\u1e19', '\u1e19'), ('\u1e1b', '\u1e1b'),
+        ('\u1e1d', '\u1e1d'), ('\u1e1f', '\u1e1f'), ('\u1e21', '\u1e21'), ('\u1e23', '\u1e23'),
+        ('\u1e25', '\u1e25'), ('\u1e27', '\u1e27'), ('\u1e29', '\u1e29'), ('\u1e2b', '\u1e2b'),
+        ('\u1e2d', '\u1e2d'), ('\u1e2f', '\u1e2f'), ('\u1e31', '\u1e31'), ('\u1e33', '\u1e33'),
+        ('\u1e35', '\u1e35'), ('\u1e37', '\u1e37'), ('\u1e39', '\u1e39'), ('\u1e3b', '\u1e3b'),
+        ('\u1e3d', '\u1e3d'), ('\u1e3f', '\u1e3f'), ('\u1e41', '\u1e41'), ('\u1e43', '\u1e43'),
+        ('\u1e45', '\u1e45'), ('\u1e47', '\u1e47'), ('\u1e49', '\u1e49'), ('\u1e4b', '\u1e4b'),
+        ('\u1e4d', '\u1e4d'), ('\u1e4f', '\u1e4f'), ('\u1e51', '\u1e51'), ('\u1e53', '\u1e53'),
+        ('\u1e55', '\u1e55'), ('\u1e57', '\u1e57'), ('\u1e59', '\u1e59'), ('\u1e5b', '\u1e5b'),
+        ('\u1e5d', '\u1e5d'), ('\u1e5f', '\u1e5f'), ('\u1e61', '\u1e61'), ('\u1e63', '\u1e63'),
+        ('\u1e65', '\u1e65'), ('\u1e67', '\u1e67'), ('\u1e69', '\u1e69'), ('\u1e6b', '\u1e6b'),
+        ('\u1e6d', '\u1e6d'), ('\u1e6f', '\u1e6f'), ('\u1e71', '\u1e71'), ('\u1e73', '\u1e73'),
+        ('\u1e75', '\u1e75'), ('\u1e77', '\u1e77'), ('\u1e79', '\u1e79'), ('\u1e7b', '\u1e7b'),
+        ('\u1e7d', '\u1e7d'), ('\u1e7f', '\u1e7f'), ('\u1e81', '\u1e81'), ('\u1e83', '\u1e83'),
+        ('\u1e85', '\u1e85'), ('\u1e87', '\u1e87'), ('\u1e89', '\u1e89'), ('\u1e8b', '\u1e8b'),
+        ('\u1e8d', '\u1e8d'), ('\u1e8f', '\u1e8f'), ('\u1e91', '\u1e91'), ('\u1e93', '\u1e93'),
+        ('\u1e95', '\u1e9d'), ('\u1e9f', '\u1e9f'), ('\u1ea1', '\u1ea1'), ('\u1ea3', '\u1ea3'),
+        ('\u1ea5', '\u1ea5'), ('\u1ea7', '\u1ea7'), ('\u1ea9', '\u1ea9'), ('\u1eab', '\u1eab'),
+        ('\u1ead', '\u1ead'), ('\u1eaf', '\u1eaf'), ('\u1eb1', '\u1eb1'), ('\u1eb3', '\u1eb3'),
+        ('\u1eb5', '\u1eb5'), ('\u1eb7', '\u1eb7'), ('\u1eb9', '\u1eb9'), ('\u1ebb', '\u1ebb'),
+        ('\u1ebd', '\u1ebd'), ('\u1ebf', '\u1ebf'), ('\u1ec1', '\u1ec1'), ('\u1ec3', '\u1ec3'),
+        ('\u1ec5', '\u1ec5'), ('\u1ec7', '\u1ec7'), ('\u1ec9', '\u1ec9'), ('\u1ecb', '\u1ecb'),
+        ('\u1ecd', '\u1ecd'), ('\u1ecf', '\u1ecf'), ('\u1ed1', '\u1ed1'), ('\u1ed3', '\u1ed3'),
+        ('\u1ed5', '\u1ed5'), ('\u1ed7', '\u1ed7'), ('\u1ed9', '\u1ed9'), ('\u1edb', '\u1edb'),
+        ('\u1edd', '\u1edd'), ('\u1edf', '\u1edf'), ('\u1ee1', '\u1ee1'), ('\u1ee3', '\u1ee3'),
+        ('\u1ee5', '\u1ee5'), ('\u1ee7', '\u1ee7'), ('\u1ee9', '\u1ee9'), ('\u1eeb', '\u1eeb'),
+        ('\u1eed', '\u1eed'), ('\u1eef', '\u1eef'), ('\u1ef1', '\u1ef1'), ('\u1ef3', '\u1ef3'),
+        ('\u1ef5', '\u1ef5'), ('\u1ef7', '\u1ef7'), ('\u1ef9', '\u1ef9'), ('\u1efb', '\u1efb'),
+        ('\u1efd', '\u1efd'), ('\u1eff', '\u1f07'), ('\u1f10', '\u1f15'), ('\u1f20', '\u1f27'),
+        ('\u1f30', '\u1f37'), ('\u1f40', '\u1f45'), ('\u1f50', '\u1f57'), ('\u1f60', '\u1f67'),
+        ('\u1f70', '\u1f7d'), ('\u1f80', '\u1f87'), ('\u1f90', '\u1f97'), ('\u1fa0', '\u1fa7'),
+        ('\u1fb0', '\u1fb4'), ('\u1fb6', '\u1fb7'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
+        ('\u1fc6', '\u1fc7'), ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fd7'), ('\u1fe0', '\u1fe7'),
+        ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ff7'), ('\u2071', '\u2071'), ('\u207f', '\u207f'),
+        ('\u2090', '\u209c'), ('\u210a', '\u210a'), ('\u210e', '\u210f'), ('\u2113', '\u2113'),
+        ('\u212f', '\u212f'), ('\u2134', '\u2134'), ('\u2139', '\u2139'), ('\u213c', '\u213d'),
+        ('\u2146', '\u2149'), ('\u214e', '\u214e'), ('\u2170', '\u217f'), ('\u2184', '\u2184'),
+        ('\u24d0', '\u24e9'), ('\u2c30', '\u2c5e'), ('\u2c61', '\u2c61'), ('\u2c65', '\u2c66'),
+        ('\u2c68', '\u2c68'), ('\u2c6a', '\u2c6a'), ('\u2c6c', '\u2c6c'), ('\u2c71', '\u2c71'),
+        ('\u2c73', '\u2c74'), ('\u2c76', '\u2c7b'), ('\u2c7c', '\u2c7d'), ('\u2c81', '\u2c81'),
+        ('\u2c83', '\u2c83'), ('\u2c85', '\u2c85'), ('\u2c87', '\u2c87'), ('\u2c89', '\u2c89'),
+        ('\u2c8b', '\u2c8b'), ('\u2c8d', '\u2c8d'), ('\u2c8f', '\u2c8f'), ('\u2c91', '\u2c91'),
+        ('\u2c93', '\u2c93'), ('\u2c95', '\u2c95'), ('\u2c97', '\u2c97'), ('\u2c99', '\u2c99'),
+        ('\u2c9b', '\u2c9b'), ('\u2c9d', '\u2c9d'), ('\u2c9f', '\u2c9f'), ('\u2ca1', '\u2ca1'),
+        ('\u2ca3', '\u2ca3'), ('\u2ca5', '\u2ca5'), ('\u2ca7', '\u2ca7'), ('\u2ca9', '\u2ca9'),
+        ('\u2cab', '\u2cab'), ('\u2cad', '\u2cad'), ('\u2caf', '\u2caf'), ('\u2cb1', '\u2cb1'),
+        ('\u2cb3', '\u2cb3'), ('\u2cb5', '\u2cb5'), ('\u2cb7', '\u2cb7'), ('\u2cb9', '\u2cb9'),
+        ('\u2cbb', '\u2cbb'), ('\u2cbd', '\u2cbd'), ('\u2cbf', '\u2cbf'), ('\u2cc1', '\u2cc1'),
+        ('\u2cc3', '\u2cc3'), ('\u2cc5', '\u2cc5'), ('\u2cc7', '\u2cc7'), ('\u2cc9', '\u2cc9'),
+        ('\u2ccb', '\u2ccb'), ('\u2ccd', '\u2ccd'), ('\u2ccf', '\u2ccf'), ('\u2cd1', '\u2cd1'),
+        ('\u2cd3', '\u2cd3'), ('\u2cd5', '\u2cd5'), ('\u2cd7', '\u2cd7'), ('\u2cd9', '\u2cd9'),
+        ('\u2cdb', '\u2cdb'), ('\u2cdd', '\u2cdd'), ('\u2cdf', '\u2cdf'), ('\u2ce1', '\u2ce1'),
+        ('\u2ce3', '\u2ce4'), ('\u2cec', '\u2cec'), ('\u2cee', '\u2cee'), ('\u2cf3', '\u2cf3'),
+        ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\ua641', '\ua641'),
+        ('\ua643', '\ua643'), ('\ua645', '\ua645'), ('\ua647', '\ua647'), ('\ua649', '\ua649'),
+        ('\ua64b', '\ua64b'), ('\ua64d', '\ua64d'), ('\ua64f', '\ua64f'), ('\ua651', '\ua651'),
+        ('\ua653', '\ua653'), ('\ua655', '\ua655'), ('\ua657', '\ua657'), ('\ua659', '\ua659'),
+        ('\ua65b', '\ua65b'), ('\ua65d', '\ua65d'), ('\ua65f', '\ua65f'), ('\ua661', '\ua661'),
+        ('\ua663', '\ua663'), ('\ua665', '\ua665'), ('\ua667', '\ua667'), ('\ua669', '\ua669'),
+        ('\ua66b', '\ua66b'), ('\ua66d', '\ua66d'), ('\ua681', '\ua681'), ('\ua683', '\ua683'),
+        ('\ua685', '\ua685'), ('\ua687', '\ua687'), ('\ua689', '\ua689'), ('\ua68b', '\ua68b'),
+        ('\ua68d', '\ua68d'), ('\ua68f', '\ua68f'), ('\ua691', '\ua691'), ('\ua693', '\ua693'),
+        ('\ua695', '\ua695'), ('\ua697', '\ua697'), ('\ua699', '\ua699'), ('\ua69b', '\ua69b'),
+        ('\ua69c', '\ua69d'), ('\ua723', '\ua723'), ('\ua725', '\ua725'), ('\ua727', '\ua727'),
+        ('\ua729', '\ua729'), ('\ua72b', '\ua72b'), ('\ua72d', '\ua72d'), ('\ua72f', '\ua731'),
+        ('\ua733', '\ua733'), ('\ua735', '\ua735'), ('\ua737', '\ua737'), ('\ua739', '\ua739'),
+        ('\ua73b', '\ua73b'), ('\ua73d', '\ua73d'), ('\ua73f', '\ua73f'), ('\ua741', '\ua741'),
+        ('\ua743', '\ua743'), ('\ua745', '\ua745'), ('\ua747', '\ua747'), ('\ua749', '\ua749'),
+        ('\ua74b', '\ua74b'), ('\ua74d', '\ua74d'), ('\ua74f', '\ua74f'), ('\ua751', '\ua751'),
+        ('\ua753', '\ua753'), ('\ua755', '\ua755'), ('\ua757', '\ua757'), ('\ua759', '\ua759'),
+        ('\ua75b', '\ua75b'), ('\ua75d', '\ua75d'), ('\ua75f', '\ua75f'), ('\ua761', '\ua761'),
+        ('\ua763', '\ua763'), ('\ua765', '\ua765'), ('\ua767', '\ua767'), ('\ua769', '\ua769'),
+        ('\ua76b', '\ua76b'), ('\ua76d', '\ua76d'), ('\ua76f', '\ua76f'), ('\ua770', '\ua770'),
+        ('\ua771', '\ua778'), ('\ua77a', '\ua77a'), ('\ua77c', '\ua77c'), ('\ua77f', '\ua77f'),
+        ('\ua781', '\ua781'), ('\ua783', '\ua783'), ('\ua785', '\ua785'), ('\ua787', '\ua787'),
+        ('\ua78c', '\ua78c'), ('\ua78e', '\ua78e'), ('\ua791', '\ua791'), ('\ua793', '\ua795'),
+        ('\ua797', '\ua797'), ('\ua799', '\ua799'), ('\ua79b', '\ua79b'), ('\ua79d', '\ua79d'),
+        ('\ua79f', '\ua79f'), ('\ua7a1', '\ua7a1'), ('\ua7a3', '\ua7a3'), ('\ua7a5', '\ua7a5'),
+        ('\ua7a7', '\ua7a7'), ('\ua7a9', '\ua7a9'), ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'),
+        ('\uab30', '\uab5a'), ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\ufb00', '\ufb06'),
+        ('\ufb13', '\ufb17'), ('\uff41', '\uff5a'), ('\U00010428', '\U0001044f'), ('\U000118c0',
+        '\U000118df'), ('\U0001d41a', '\U0001d433'), ('\U0001d44e', '\U0001d454'), ('\U0001d456',
+        '\U0001d467'), ('\U0001d482', '\U0001d49b'), ('\U0001d4b6', '\U0001d4b9'), ('\U0001d4bb',
+        '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d4cf'), ('\U0001d4ea',
+        '\U0001d503'), ('\U0001d51e', '\U0001d537'), ('\U0001d552', '\U0001d56b'), ('\U0001d586',
+        '\U0001d59f'), ('\U0001d5ba', '\U0001d5d3'), ('\U0001d5ee', '\U0001d607'), ('\U0001d622',
+        '\U0001d63b'), ('\U0001d656', '\U0001d66f'), ('\U0001d68a', '\U0001d6a5'), ('\U0001d6c2',
+        '\U0001d6da'), ('\U0001d6dc', '\U0001d6e1'), ('\U0001d6fc', '\U0001d714'), ('\U0001d716',
+        '\U0001d71b'), ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d755'), ('\U0001d770',
+        '\U0001d788'), ('\U0001d78a', '\U0001d78f'), ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4',
+        '\U0001d7c9'), ('\U0001d7cb', '\U0001d7cb')
+    ];
+
+    pub fn Lowercase(c: char) -> bool {
+        super::bsearch_range_table(c, Lowercase_table)
+    }
+
+    pub static Uppercase_table: &'static [(char, char)] = &[
+        ('\x41', '\x5a'), ('\xc0', '\xd6'), ('\xd8', '\xde'), ('\u0100', '\u0100'), ('\u0102',
+        '\u0102'), ('\u0104', '\u0104'), ('\u0106', '\u0106'), ('\u0108', '\u0108'), ('\u010a',
+        '\u010a'), ('\u010c', '\u010c'), ('\u010e', '\u010e'), ('\u0110', '\u0110'), ('\u0112',
+        '\u0112'), ('\u0114', '\u0114'), ('\u0116', '\u0116'), ('\u0118', '\u0118'), ('\u011a',
+        '\u011a'), ('\u011c', '\u011c'), ('\u011e', '\u011e'), ('\u0120', '\u0120'), ('\u0122',
+        '\u0122'), ('\u0124', '\u0124'), ('\u0126', '\u0126'), ('\u0128', '\u0128'), ('\u012a',
+        '\u012a'), ('\u012c', '\u012c'), ('\u012e', '\u012e'), ('\u0130', '\u0130'), ('\u0132',
+        '\u0132'), ('\u0134', '\u0134'), ('\u0136', '\u0136'), ('\u0139', '\u0139'), ('\u013b',
+        '\u013b'), ('\u013d', '\u013d'), ('\u013f', '\u013f'), ('\u0141', '\u0141'), ('\u0143',
+        '\u0143'), ('\u0145', '\u0145'), ('\u0147', '\u0147'), ('\u014a', '\u014a'), ('\u014c',
+        '\u014c'), ('\u014e', '\u014e'), ('\u0150', '\u0150'), ('\u0152', '\u0152'), ('\u0154',
+        '\u0154'), ('\u0156', '\u0156'), ('\u0158', '\u0158'), ('\u015a', '\u015a'), ('\u015c',
+        '\u015c'), ('\u015e', '\u015e'), ('\u0160', '\u0160'), ('\u0162', '\u0162'), ('\u0164',
+        '\u0164'), ('\u0166', '\u0166'), ('\u0168', '\u0168'), ('\u016a', '\u016a'), ('\u016c',
+        '\u016c'), ('\u016e', '\u016e'), ('\u0170', '\u0170'), ('\u0172', '\u0172'), ('\u0174',
+        '\u0174'), ('\u0176', '\u0176'), ('\u0178', '\u0179'), ('\u017b', '\u017b'), ('\u017d',
+        '\u017d'), ('\u0181', '\u0182'), ('\u0184', '\u0184'), ('\u0186', '\u0187'), ('\u0189',
+        '\u018b'), ('\u018e', '\u0191'), ('\u0193', '\u0194'), ('\u0196', '\u0198'), ('\u019c',
+        '\u019d'), ('\u019f', '\u01a0'), ('\u01a2', '\u01a2'), ('\u01a4', '\u01a4'), ('\u01a6',
+        '\u01a7'), ('\u01a9', '\u01a9'), ('\u01ac', '\u01ac'), ('\u01ae', '\u01af'), ('\u01b1',
+        '\u01b3'), ('\u01b5', '\u01b5'), ('\u01b7', '\u01b8'), ('\u01bc', '\u01bc'), ('\u01c4',
+        '\u01c4'), ('\u01c7', '\u01c7'), ('\u01ca', '\u01ca'), ('\u01cd', '\u01cd'), ('\u01cf',
+        '\u01cf'), ('\u01d1', '\u01d1'), ('\u01d3', '\u01d3'), ('\u01d5', '\u01d5'), ('\u01d7',
+        '\u01d7'), ('\u01d9', '\u01d9'), ('\u01db', '\u01db'), ('\u01de', '\u01de'), ('\u01e0',
+        '\u01e0'), ('\u01e2', '\u01e2'), ('\u01e4', '\u01e4'), ('\u01e6', '\u01e6'), ('\u01e8',
+        '\u01e8'), ('\u01ea', '\u01ea'), ('\u01ec', '\u01ec'), ('\u01ee', '\u01ee'), ('\u01f1',
+        '\u01f1'), ('\u01f4', '\u01f4'), ('\u01f6', '\u01f8'), ('\u01fa', '\u01fa'), ('\u01fc',
+        '\u01fc'), ('\u01fe', '\u01fe'), ('\u0200', '\u0200'), ('\u0202', '\u0202'), ('\u0204',
+        '\u0204'), ('\u0206', '\u0206'), ('\u0208', '\u0208'), ('\u020a', '\u020a'), ('\u020c',
+        '\u020c'), ('\u020e', '\u020e'), ('\u0210', '\u0210'), ('\u0212', '\u0212'), ('\u0214',
+        '\u0214'), ('\u0216', '\u0216'), ('\u0218', '\u0218'), ('\u021a', '\u021a'), ('\u021c',
+        '\u021c'), ('\u021e', '\u021e'), ('\u0220', '\u0220'), ('\u0222', '\u0222'), ('\u0224',
+        '\u0224'), ('\u0226', '\u0226'), ('\u0228', '\u0228'), ('\u022a', '\u022a'), ('\u022c',
+        '\u022c'), ('\u022e', '\u022e'), ('\u0230', '\u0230'), ('\u0232', '\u0232'), ('\u023a',
+        '\u023b'), ('\u023d', '\u023e'), ('\u0241', '\u0241'), ('\u0243', '\u0246'), ('\u0248',
+        '\u0248'), ('\u024a', '\u024a'), ('\u024c', '\u024c'), ('\u024e', '\u024e'), ('\u0370',
+        '\u0370'), ('\u0372', '\u0372'), ('\u0376', '\u0376'), ('\u037f', '\u037f'), ('\u0386',
+        '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u038f'), ('\u0391',
+        '\u03a1'), ('\u03a3', '\u03ab'), ('\u03cf', '\u03cf'), ('\u03d2', '\u03d4'), ('\u03d8',
+        '\u03d8'), ('\u03da', '\u03da'), ('\u03dc', '\u03dc'), ('\u03de', '\u03de'), ('\u03e0',
+        '\u03e0'), ('\u03e2', '\u03e2'), ('\u03e4', '\u03e4'), ('\u03e6', '\u03e6'), ('\u03e8',
+        '\u03e8'), ('\u03ea', '\u03ea'), ('\u03ec', '\u03ec'), ('\u03ee', '\u03ee'), ('\u03f4',
+        '\u03f4'), ('\u03f7', '\u03f7'), ('\u03f9', '\u03fa'), ('\u03fd', '\u042f'), ('\u0460',
+        '\u0460'), ('\u0462', '\u0462'), ('\u0464', '\u0464'), ('\u0466', '\u0466'), ('\u0468',
+        '\u0468'), ('\u046a', '\u046a'), ('\u046c', '\u046c'), ('\u046e', '\u046e'), ('\u0470',
+        '\u0470'), ('\u0472', '\u0472'), ('\u0474', '\u0474'), ('\u0476', '\u0476'), ('\u0478',
+        '\u0478'), ('\u047a', '\u047a'), ('\u047c', '\u047c'), ('\u047e', '\u047e'), ('\u0480',
+        '\u0480'), ('\u048a', '\u048a'), ('\u048c', '\u048c'), ('\u048e', '\u048e'), ('\u0490',
+        '\u0490'), ('\u0492', '\u0492'), ('\u0494', '\u0494'), ('\u0496', '\u0496'), ('\u0498',
+        '\u0498'), ('\u049a', '\u049a'), ('\u049c', '\u049c'), ('\u049e', '\u049e'), ('\u04a0',
+        '\u04a0'), ('\u04a2', '\u04a2'), ('\u04a4', '\u04a4'), ('\u04a6', '\u04a6'), ('\u04a8',
+        '\u04a8'), ('\u04aa', '\u04aa'), ('\u04ac', '\u04ac'), ('\u04ae', '\u04ae'), ('\u04b0',
+        '\u04b0'), ('\u04b2', '\u04b2'), ('\u04b4', '\u04b4'), ('\u04b6', '\u04b6'), ('\u04b8',
+        '\u04b8'), ('\u04ba', '\u04ba'), ('\u04bc', '\u04bc'), ('\u04be', '\u04be'), ('\u04c0',
+        '\u04c1'), ('\u04c3', '\u04c3'), ('\u04c5', '\u04c5'), ('\u04c7', '\u04c7'), ('\u04c9',
+        '\u04c9'), ('\u04cb', '\u04cb'), ('\u04cd', '\u04cd'), ('\u04d0', '\u04d0'), ('\u04d2',
+        '\u04d2'), ('\u04d4', '\u04d4'), ('\u04d6', '\u04d6'), ('\u04d8', '\u04d8'), ('\u04da',
+        '\u04da'), ('\u04dc', '\u04dc'), ('\u04de', '\u04de'), ('\u04e0', '\u04e0'), ('\u04e2',
+        '\u04e2'), ('\u04e4', '\u04e4'), ('\u04e6', '\u04e6'), ('\u04e8', '\u04e8'), ('\u04ea',
+        '\u04ea'), ('\u04ec', '\u04ec'), ('\u04ee', '\u04ee'), ('\u04f0', '\u04f0'), ('\u04f2',
+        '\u04f2'), ('\u04f4', '\u04f4'), ('\u04f6', '\u04f6'), ('\u04f8', '\u04f8'), ('\u04fa',
+        '\u04fa'), ('\u04fc', '\u04fc'), ('\u04fe', '\u04fe'), ('\u0500', '\u0500'), ('\u0502',
+        '\u0502'), ('\u0504', '\u0504'), ('\u0506', '\u0506'), ('\u0508', '\u0508'), ('\u050a',
+        '\u050a'), ('\u050c', '\u050c'), ('\u050e', '\u050e'), ('\u0510', '\u0510'), ('\u0512',
+        '\u0512'), ('\u0514', '\u0514'), ('\u0516', '\u0516'), ('\u0518', '\u0518'), ('\u051a',
+        '\u051a'), ('\u051c', '\u051c'), ('\u051e', '\u051e'), ('\u0520', '\u0520'), ('\u0522',
+        '\u0522'), ('\u0524', '\u0524'), ('\u0526', '\u0526'), ('\u0528', '\u0528'), ('\u052a',
+        '\u052a'), ('\u052c', '\u052c'), ('\u052e', '\u052e'), ('\u0531', '\u0556'), ('\u10a0',
+        '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u1e00', '\u1e00'), ('\u1e02',
+        '\u1e02'), ('\u1e04', '\u1e04'), ('\u1e06', '\u1e06'), ('\u1e08', '\u1e08'), ('\u1e0a',
+        '\u1e0a'), ('\u1e0c', '\u1e0c'), ('\u1e0e', '\u1e0e'), ('\u1e10', '\u1e10'), ('\u1e12',
+        '\u1e12'), ('\u1e14', '\u1e14'), ('\u1e16', '\u1e16'), ('\u1e18', '\u1e18'), ('\u1e1a',
+        '\u1e1a'), ('\u1e1c', '\u1e1c'), ('\u1e1e', '\u1e1e'), ('\u1e20', '\u1e20'), ('\u1e22',
+        '\u1e22'), ('\u1e24', '\u1e24'), ('\u1e26', '\u1e26'), ('\u1e28', '\u1e28'), ('\u1e2a',
+        '\u1e2a'), ('\u1e2c', '\u1e2c'), ('\u1e2e', '\u1e2e'), ('\u1e30', '\u1e30'), ('\u1e32',
+        '\u1e32'), ('\u1e34', '\u1e34'), ('\u1e36', '\u1e36'), ('\u1e38', '\u1e38'), ('\u1e3a',
+        '\u1e3a'), ('\u1e3c', '\u1e3c'), ('\u1e3e', '\u1e3e'), ('\u1e40', '\u1e40'), ('\u1e42',
+        '\u1e42'), ('\u1e44', '\u1e44'), ('\u1e46', '\u1e46'), ('\u1e48', '\u1e48'), ('\u1e4a',
+        '\u1e4a'), ('\u1e4c', '\u1e4c'), ('\u1e4e', '\u1e4e'), ('\u1e50', '\u1e50'), ('\u1e52',
+        '\u1e52'), ('\u1e54', '\u1e54'), ('\u1e56', '\u1e56'), ('\u1e58', '\u1e58'), ('\u1e5a',
+        '\u1e5a'), ('\u1e5c', '\u1e5c'), ('\u1e5e', '\u1e5e'), ('\u1e60', '\u1e60'), ('\u1e62',
+        '\u1e62'), ('\u1e64', '\u1e64'), ('\u1e66', '\u1e66'), ('\u1e68', '\u1e68'), ('\u1e6a',
+        '\u1e6a'), ('\u1e6c', '\u1e6c'), ('\u1e6e', '\u1e6e'), ('\u1e70', '\u1e70'), ('\u1e72',
+        '\u1e72'), ('\u1e74', '\u1e74'), ('\u1e76', '\u1e76'), ('\u1e78', '\u1e78'), ('\u1e7a',
+        '\u1e7a'), ('\u1e7c', '\u1e7c'), ('\u1e7e', '\u1e7e'), ('\u1e80', '\u1e80'), ('\u1e82',
+        '\u1e82'), ('\u1e84', '\u1e84'), ('\u1e86', '\u1e86'), ('\u1e88', '\u1e88'), ('\u1e8a',
+        '\u1e8a'), ('\u1e8c', '\u1e8c'), ('\u1e8e', '\u1e8e'), ('\u1e90', '\u1e90'), ('\u1e92',
+        '\u1e92'), ('\u1e94', '\u1e94'), ('\u1e9e', '\u1e9e'), ('\u1ea0', '\u1ea0'), ('\u1ea2',
+        '\u1ea2'), ('\u1ea4', '\u1ea4'), ('\u1ea6', '\u1ea6'), ('\u1ea8', '\u1ea8'), ('\u1eaa',
+        '\u1eaa'), ('\u1eac', '\u1eac'), ('\u1eae', '\u1eae'), ('\u1eb0', '\u1eb0'), ('\u1eb2',
+        '\u1eb2'), ('\u1eb4', '\u1eb4'), ('\u1eb6', '\u1eb6'), ('\u1eb8', '\u1eb8'), ('\u1eba',
+        '\u1eba'), ('\u1ebc', '\u1ebc'), ('\u1ebe', '\u1ebe'), ('\u1ec0', '\u1ec0'), ('\u1ec2',
+        '\u1ec2'), ('\u1ec4', '\u1ec4'), ('\u1ec6', '\u1ec6'), ('\u1ec8', '\u1ec8'), ('\u1eca',
+        '\u1eca'), ('\u1ecc', '\u1ecc'), ('\u1ece', '\u1ece'), ('\u1ed0', '\u1ed0'), ('\u1ed2',
+        '\u1ed2'), ('\u1ed4', '\u1ed4'), ('\u1ed6', '\u1ed6'), ('\u1ed8', '\u1ed8'), ('\u1eda',
+        '\u1eda'), ('\u1edc', '\u1edc'), ('\u1ede', '\u1ede'), ('\u1ee0', '\u1ee0'), ('\u1ee2',
+        '\u1ee2'), ('\u1ee4', '\u1ee4'), ('\u1ee6', '\u1ee6'), ('\u1ee8', '\u1ee8'), ('\u1eea',
+        '\u1eea'), ('\u1eec', '\u1eec'), ('\u1eee', '\u1eee'), ('\u1ef0', '\u1ef0'), ('\u1ef2',
+        '\u1ef2'), ('\u1ef4', '\u1ef4'), ('\u1ef6', '\u1ef6'), ('\u1ef8', '\u1ef8'), ('\u1efa',
+        '\u1efa'), ('\u1efc', '\u1efc'), ('\u1efe', '\u1efe'), ('\u1f08', '\u1f0f'), ('\u1f18',
+        '\u1f1d'), ('\u1f28', '\u1f2f'), ('\u1f38', '\u1f3f'), ('\u1f48', '\u1f4d'), ('\u1f59',
+        '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f5f'), ('\u1f68',
+        '\u1f6f'), ('\u1fb8', '\u1fbb'), ('\u1fc8', '\u1fcb'), ('\u1fd8', '\u1fdb'), ('\u1fe8',
+        '\u1fec'), ('\u1ff8', '\u1ffb'), ('\u2102', '\u2102'), ('\u2107', '\u2107'), ('\u210b',
+        '\u210d'), ('\u2110', '\u2112'), ('\u2115', '\u2115'), ('\u2119', '\u211d'), ('\u2124',
+        '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u2130',
+        '\u2133'), ('\u213e', '\u213f'), ('\u2145', '\u2145'), ('\u2160', '\u216f'), ('\u2183',
+        '\u2183'), ('\u24b6', '\u24cf'), ('\u2c00', '\u2c2e'), ('\u2c60', '\u2c60'), ('\u2c62',
+        '\u2c64'), ('\u2c67', '\u2c67'), ('\u2c69', '\u2c69'), ('\u2c6b', '\u2c6b'), ('\u2c6d',
+        '\u2c70'), ('\u2c72', '\u2c72'), ('\u2c75', '\u2c75'), ('\u2c7e', '\u2c80'), ('\u2c82',
+        '\u2c82'), ('\u2c84', '\u2c84'), ('\u2c86', '\u2c86'), ('\u2c88', '\u2c88'), ('\u2c8a',
+        '\u2c8a'), ('\u2c8c', '\u2c8c'), ('\u2c8e', '\u2c8e'), ('\u2c90', '\u2c90'), ('\u2c92',
+        '\u2c92'), ('\u2c94', '\u2c94'), ('\u2c96', '\u2c96'), ('\u2c98', '\u2c98'), ('\u2c9a',
+        '\u2c9a'), ('\u2c9c', '\u2c9c'), ('\u2c9e', '\u2c9e'), ('\u2ca0', '\u2ca0'), ('\u2ca2',
+        '\u2ca2'), ('\u2ca4', '\u2ca4'), ('\u2ca6', '\u2ca6'), ('\u2ca8', '\u2ca8'), ('\u2caa',
+        '\u2caa'), ('\u2cac', '\u2cac'), ('\u2cae', '\u2cae'), ('\u2cb0', '\u2cb0'), ('\u2cb2',
+        '\u2cb2'), ('\u2cb4', '\u2cb4'), ('\u2cb6', '\u2cb6'), ('\u2cb8', '\u2cb8'), ('\u2cba',
+        '\u2cba'), ('\u2cbc', '\u2cbc'), ('\u2cbe', '\u2cbe'), ('\u2cc0', '\u2cc0'), ('\u2cc2',
+        '\u2cc2'), ('\u2cc4', '\u2cc4'), ('\u2cc6', '\u2cc6'), ('\u2cc8', '\u2cc8'), ('\u2cca',
+        '\u2cca'), ('\u2ccc', '\u2ccc'), ('\u2cce', '\u2cce'), ('\u2cd0', '\u2cd0'), ('\u2cd2',
+        '\u2cd2'), ('\u2cd4', '\u2cd4'), ('\u2cd6', '\u2cd6'), ('\u2cd8', '\u2cd8'), ('\u2cda',
+        '\u2cda'), ('\u2cdc', '\u2cdc'), ('\u2cde', '\u2cde'), ('\u2ce0', '\u2ce0'), ('\u2ce2',
+        '\u2ce2'), ('\u2ceb', '\u2ceb'), ('\u2ced', '\u2ced'), ('\u2cf2', '\u2cf2'), ('\ua640',
+        '\ua640'), ('\ua642', '\ua642'), ('\ua644', '\ua644'), ('\ua646', '\ua646'), ('\ua648',
+        '\ua648'), ('\ua64a', '\ua64a'), ('\ua64c', '\ua64c'), ('\ua64e', '\ua64e'), ('\ua650',
+        '\ua650'), ('\ua652', '\ua652'), ('\ua654', '\ua654'), ('\ua656', '\ua656'), ('\ua658',
+        '\ua658'), ('\ua65a', '\ua65a'), ('\ua65c', '\ua65c'), ('\ua65e', '\ua65e'), ('\ua660',
+        '\ua660'), ('\ua662', '\ua662'), ('\ua664', '\ua664'), ('\ua666', '\ua666'), ('\ua668',
+        '\ua668'), ('\ua66a', '\ua66a'), ('\ua66c', '\ua66c'), ('\ua680', '\ua680'), ('\ua682',
+        '\ua682'), ('\ua684', '\ua684'), ('\ua686', '\ua686'), ('\ua688', '\ua688'), ('\ua68a',
+        '\ua68a'), ('\ua68c', '\ua68c'), ('\ua68e', '\ua68e'), ('\ua690', '\ua690'), ('\ua692',
+        '\ua692'), ('\ua694', '\ua694'), ('\ua696', '\ua696'), ('\ua698', '\ua698'), ('\ua69a',
+        '\ua69a'), ('\ua722', '\ua722'), ('\ua724', '\ua724'), ('\ua726', '\ua726'), ('\ua728',
+        '\ua728'), ('\ua72a', '\ua72a'), ('\ua72c', '\ua72c'), ('\ua72e', '\ua72e'), ('\ua732',
+        '\ua732'), ('\ua734', '\ua734'), ('\ua736', '\ua736'), ('\ua738', '\ua738'), ('\ua73a',
+        '\ua73a'), ('\ua73c', '\ua73c'), ('\ua73e', '\ua73e'), ('\ua740', '\ua740'), ('\ua742',
+        '\ua742'), ('\ua744', '\ua744'), ('\ua746', '\ua746'), ('\ua748', '\ua748'), ('\ua74a',
+        '\ua74a'), ('\ua74c', '\ua74c'), ('\ua74e', '\ua74e'), ('\ua750', '\ua750'), ('\ua752',
+        '\ua752'), ('\ua754', '\ua754'), ('\ua756', '\ua756'), ('\ua758', '\ua758'), ('\ua75a',
+        '\ua75a'), ('\ua75c', '\ua75c'), ('\ua75e', '\ua75e'), ('\ua760', '\ua760'), ('\ua762',
+        '\ua762'), ('\ua764', '\ua764'), ('\ua766', '\ua766'), ('\ua768', '\ua768'), ('\ua76a',
+        '\ua76a'), ('\ua76c', '\ua76c'), ('\ua76e', '\ua76e'), ('\ua779', '\ua779'), ('\ua77b',
+        '\ua77b'), ('\ua77d', '\ua77e'), ('\ua780', '\ua780'), ('\ua782', '\ua782'), ('\ua784',
+        '\ua784'), ('\ua786', '\ua786'), ('\ua78b', '\ua78b'), ('\ua78d', '\ua78d'), ('\ua790',
+        '\ua790'), ('\ua792', '\ua792'), ('\ua796', '\ua796'), ('\ua798', '\ua798'), ('\ua79a',
+        '\ua79a'), ('\ua79c', '\ua79c'), ('\ua79e', '\ua79e'), ('\ua7a0', '\ua7a0'), ('\ua7a2',
+        '\ua7a2'), ('\ua7a4', '\ua7a4'), ('\ua7a6', '\ua7a6'), ('\ua7a8', '\ua7a8'), ('\ua7aa',
+        '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\uff21', '\uff3a'), ('\U00010400', '\U00010427'),
+        ('\U000118a0', '\U000118bf'), ('\U0001d400', '\U0001d419'), ('\U0001d434', '\U0001d44d'),
+        ('\U0001d468', '\U0001d481'), ('\U0001d49c', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
+        ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
+        ('\U0001d4ae', '\U0001d4b5'), ('\U0001d4d0', '\U0001d4e9'), ('\U0001d504', '\U0001d505'),
+        ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'),
+        ('\U0001d538', '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
+        ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d56c', '\U0001d585'),
+        ('\U0001d5a0', '\U0001d5b9'), ('\U0001d5d4', '\U0001d5ed'), ('\U0001d608', '\U0001d621'),
+        ('\U0001d63c', '\U0001d655'), ('\U0001d670', '\U0001d689'), ('\U0001d6a8', '\U0001d6c0'),
+        ('\U0001d6e2', '\U0001d6fa'), ('\U0001d71c', '\U0001d734'), ('\U0001d756', '\U0001d76e'),
+        ('\U0001d790', '\U0001d7a8'), ('\U0001d7ca', '\U0001d7ca'), ('\U0001f130', '\U0001f149'),
+        ('\U0001f150', '\U0001f169'), ('\U0001f170', '\U0001f189')
+    ];
+
+    pub fn Uppercase(c: char) -> bool {
+        super::bsearch_range_table(c, Uppercase_table)
+    }
+
+    pub static XID_Continue_table: &'static [(char, char)] = &[
+        ('\x30', '\x39'), ('\x41', '\x5a'), ('\x5f', '\x5f'), ('\x61', '\x7a'), ('\xaa', '\xaa'),
+        ('\xb5', '\xb5'), ('\xb7', '\xb7'), ('\xba', '\xba'), ('\xc0', '\xd6'), ('\xd8', '\xf6'),
+        ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'), ('\u01c0', '\u01c3'),
+        ('\u01c4', '\u0293'), ('\u0294', '\u0294'), ('\u0295', '\u02af'), ('\u02b0', '\u02c1'),
+        ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'), ('\u02ee', '\u02ee'),
+        ('\u0300', '\u036f'), ('\u0370', '\u0373'), ('\u0374', '\u0374'), ('\u0376', '\u0377'),
+        ('\u037b', '\u037d'), ('\u037f', '\u037f'), ('\u0386', '\u0386'), ('\u0387', '\u0387'),
+        ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'),
+        ('\u03f7', '\u0481'), ('\u0483', '\u0487'), ('\u048a', '\u052f'), ('\u0531', '\u0556'),
+        ('\u0559', '\u0559'), ('\u0561', '\u0587'), ('\u0591', '\u05bd'), ('\u05bf', '\u05bf'),
+        ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u05d0', '\u05ea'),
+        ('\u05f0', '\u05f2'), ('\u0610', '\u061a'), ('\u0620', '\u063f'), ('\u0640', '\u0640'),
+        ('\u0641', '\u064a'), ('\u064b', '\u065f'), ('\u0660', '\u0669'), ('\u066e', '\u066f'),
+        ('\u0670', '\u0670'), ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'), ('\u06d6', '\u06dc'),
+        ('\u06df', '\u06e4'), ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'), ('\u06ea', '\u06ed'),
+        ('\u06ee', '\u06ef'), ('\u06f0', '\u06f9'), ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'),
+        ('\u0710', '\u0710'), ('\u0711', '\u0711'), ('\u0712', '\u072f'), ('\u0730', '\u074a'),
+        ('\u074d', '\u07a5'), ('\u07a6', '\u07b0'), ('\u07b1', '\u07b1'), ('\u07c0', '\u07c9'),
+        ('\u07ca', '\u07ea'), ('\u07eb', '\u07f3'), ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
+        ('\u0800', '\u0815'), ('\u0816', '\u0819'), ('\u081a', '\u081a'), ('\u081b', '\u0823'),
+        ('\u0824', '\u0824'), ('\u0825', '\u0827'), ('\u0828', '\u0828'), ('\u0829', '\u082d'),
+        ('\u0840', '\u0858'), ('\u0859', '\u085b'), ('\u08a0', '\u08b2'), ('\u08e4', '\u0902'),
+        ('\u0903', '\u0903'), ('\u0904', '\u0939'), ('\u093a', '\u093a'), ('\u093b', '\u093b'),
+        ('\u093c', '\u093c'), ('\u093d', '\u093d'), ('\u093e', '\u0940'), ('\u0941', '\u0948'),
+        ('\u0949', '\u094c'), ('\u094d', '\u094d'), ('\u094e', '\u094f'), ('\u0950', '\u0950'),
+        ('\u0951', '\u0957'), ('\u0958', '\u0961'), ('\u0962', '\u0963'), ('\u0966', '\u096f'),
+        ('\u0971', '\u0971'), ('\u0972', '\u0980'), ('\u0981', '\u0981'), ('\u0982', '\u0983'),
+        ('\u0985', '\u098c'), ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
+        ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'), ('\u09bc', '\u09bc'), ('\u09bd', '\u09bd'),
+        ('\u09be', '\u09c0'), ('\u09c1', '\u09c4'), ('\u09c7', '\u09c8'), ('\u09cb', '\u09cc'),
+        ('\u09cd', '\u09cd'), ('\u09ce', '\u09ce'), ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'),
+        ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'), ('\u09e6', '\u09ef'), ('\u09f0', '\u09f1'),
+        ('\u0a01', '\u0a02'), ('\u0a03', '\u0a03'), ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'),
+        ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'),
+        ('\u0a38', '\u0a39'), ('\u0a3c', '\u0a3c'), ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
+        ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'), ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
+        ('\u0a5e', '\u0a5e'), ('\u0a66', '\u0a6f'), ('\u0a70', '\u0a71'), ('\u0a72', '\u0a74'),
+        ('\u0a75', '\u0a75'), ('\u0a81', '\u0a82'), ('\u0a83', '\u0a83'), ('\u0a85', '\u0a8d'),
+        ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'),
+        ('\u0ab5', '\u0ab9'), ('\u0abc', '\u0abc'), ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'),
+        ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'), ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
+        ('\u0acd', '\u0acd'), ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0ae2', '\u0ae3'),
+        ('\u0ae6', '\u0aef'), ('\u0b01', '\u0b01'), ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'),
+        ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'),
+        ('\u0b35', '\u0b39'), ('\u0b3c', '\u0b3c'), ('\u0b3d', '\u0b3d'), ('\u0b3e', '\u0b3e'),
+        ('\u0b3f', '\u0b3f'), ('\u0b40', '\u0b40'), ('\u0b41', '\u0b44'), ('\u0b47', '\u0b48'),
+        ('\u0b4b', '\u0b4c'), ('\u0b4d', '\u0b4d'), ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'),
+        ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b62', '\u0b63'), ('\u0b66', '\u0b6f'),
+        ('\u0b71', '\u0b71'), ('\u0b82', '\u0b82'), ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'),
+        ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'),
+        ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'),
+        ('\u0bbe', '\u0bbf'), ('\u0bc0', '\u0bc0'), ('\u0bc1', '\u0bc2'), ('\u0bc6', '\u0bc8'),
+        ('\u0bca', '\u0bcc'), ('\u0bcd', '\u0bcd'), ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'),
+        ('\u0be6', '\u0bef'), ('\u0c00', '\u0c00'), ('\u0c01', '\u0c03'), ('\u0c05', '\u0c0c'),
+        ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d', '\u0c3d'),
+        ('\u0c3e', '\u0c40'), ('\u0c41', '\u0c44'), ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'),
+        ('\u0c55', '\u0c56'), ('\u0c58', '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c62', '\u0c63'),
+        ('\u0c66', '\u0c6f'), ('\u0c81', '\u0c81'), ('\u0c82', '\u0c83'), ('\u0c85', '\u0c8c'),
+        ('\u0c8e', '\u0c90'), ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'),
+        ('\u0cbc', '\u0cbc'), ('\u0cbd', '\u0cbd'), ('\u0cbe', '\u0cbe'), ('\u0cbf', '\u0cbf'),
+        ('\u0cc0', '\u0cc4'), ('\u0cc6', '\u0cc6'), ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'),
+        ('\u0ccc', '\u0ccd'), ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'),
+        ('\u0ce2', '\u0ce3'), ('\u0ce6', '\u0cef'), ('\u0cf1', '\u0cf2'), ('\u0d01', '\u0d01'),
+        ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'), ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'),
+        ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'), ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'),
+        ('\u0d4a', '\u0d4c'), ('\u0d4d', '\u0d4d'), ('\u0d4e', '\u0d4e'), ('\u0d57', '\u0d57'),
+        ('\u0d60', '\u0d61'), ('\u0d62', '\u0d63'), ('\u0d66', '\u0d6f'), ('\u0d7a', '\u0d7f'),
+        ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
+        ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd1'),
+        ('\u0dd2', '\u0dd4'), ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'), ('\u0de6', '\u0def'),
+        ('\u0df2', '\u0df3'), ('\u0e01', '\u0e30'), ('\u0e31', '\u0e31'), ('\u0e32', '\u0e33'),
+        ('\u0e34', '\u0e3a'), ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'), ('\u0e47', '\u0e4e'),
+        ('\u0e50', '\u0e59'), ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'), ('\u0e87', '\u0e88'),
+        ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'), ('\u0e99', '\u0e9f'),
+        ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'), ('\u0eaa', '\u0eab'),
+        ('\u0ead', '\u0eb0'), ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'), ('\u0eb4', '\u0eb9'),
+        ('\u0ebb', '\u0ebc'), ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'),
+        ('\u0ec8', '\u0ecd'), ('\u0ed0', '\u0ed9'), ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'),
+        ('\u0f18', '\u0f19'), ('\u0f20', '\u0f29'), ('\u0f35', '\u0f35'), ('\u0f37', '\u0f37'),
+        ('\u0f39', '\u0f39'), ('\u0f3e', '\u0f3f'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'),
+        ('\u0f71', '\u0f7e'), ('\u0f7f', '\u0f7f'), ('\u0f80', '\u0f84'), ('\u0f86', '\u0f87'),
+        ('\u0f88', '\u0f8c'), ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'), ('\u0fc6', '\u0fc6'),
+        ('\u1000', '\u102a'), ('\u102b', '\u102c'), ('\u102d', '\u1030'), ('\u1031', '\u1031'),
+        ('\u1032', '\u1037'), ('\u1038', '\u1038'), ('\u1039', '\u103a'), ('\u103b', '\u103c'),
+        ('\u103d', '\u103e'), ('\u103f', '\u103f'), ('\u1040', '\u1049'), ('\u1050', '\u1055'),
+        ('\u1056', '\u1057'), ('\u1058', '\u1059'), ('\u105a', '\u105d'), ('\u105e', '\u1060'),
+        ('\u1061', '\u1061'), ('\u1062', '\u1064'), ('\u1065', '\u1066'), ('\u1067', '\u106d'),
+        ('\u106e', '\u1070'), ('\u1071', '\u1074'), ('\u1075', '\u1081'), ('\u1082', '\u1082'),
+        ('\u1083', '\u1084'), ('\u1085', '\u1086'), ('\u1087', '\u108c'), ('\u108d', '\u108d'),
+        ('\u108e', '\u108e'), ('\u108f', '\u108f'), ('\u1090', '\u1099'), ('\u109a', '\u109c'),
+        ('\u109d', '\u109d'), ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
+        ('\u10d0', '\u10fa'), ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'), ('\u124a', '\u124d'),
+        ('\u1250', '\u1256'), ('\u1258', '\u1258'), ('\u125a', '\u125d'), ('\u1260', '\u1288'),
+        ('\u128a', '\u128d'), ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'),
+        ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'),
+        ('\u1312', '\u1315'), ('\u1318', '\u135a'), ('\u135d', '\u135f'), ('\u1369', '\u1371'),
+        ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401', '\u166c'), ('\u166f', '\u167f'),
+        ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'), ('\u16f1', '\u16f8'),
+        ('\u1700', '\u170c'), ('\u170e', '\u1711'), ('\u1712', '\u1714'), ('\u1720', '\u1731'),
+        ('\u1732', '\u1734'), ('\u1740', '\u1751'), ('\u1752', '\u1753'), ('\u1760', '\u176c'),
+        ('\u176e', '\u1770'), ('\u1772', '\u1773'), ('\u1780', '\u17b3'), ('\u17b4', '\u17b5'),
+        ('\u17b6', '\u17b6'), ('\u17b7', '\u17bd'), ('\u17be', '\u17c5'), ('\u17c6', '\u17c6'),
+        ('\u17c7', '\u17c8'), ('\u17c9', '\u17d3'), ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'),
+        ('\u17dd', '\u17dd'), ('\u17e0', '\u17e9'), ('\u180b', '\u180d'), ('\u1810', '\u1819'),
+        ('\u1820', '\u1842'), ('\u1843', '\u1843'), ('\u1844', '\u1877'), ('\u1880', '\u18a8'),
+        ('\u18a9', '\u18a9'), ('\u18aa', '\u18aa'), ('\u18b0', '\u18f5'), ('\u1900', '\u191e'),
+        ('\u1920', '\u1922'), ('\u1923', '\u1926'), ('\u1927', '\u1928'), ('\u1929', '\u192b'),
+        ('\u1930', '\u1931'), ('\u1932', '\u1932'), ('\u1933', '\u1938'), ('\u1939', '\u193b'),
+        ('\u1946', '\u194f'), ('\u1950', '\u196d'), ('\u1970', '\u1974'), ('\u1980', '\u19ab'),
+        ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'), ('\u19c8', '\u19c9'), ('\u19d0', '\u19d9'),
+        ('\u19da', '\u19da'), ('\u1a00', '\u1a16'), ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'),
+        ('\u1a1b', '\u1a1b'), ('\u1a20', '\u1a54'), ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'),
+        ('\u1a57', '\u1a57'), ('\u1a58', '\u1a5e'), ('\u1a60', '\u1a60'), ('\u1a61', '\u1a61'),
+        ('\u1a62', '\u1a62'), ('\u1a63', '\u1a64'), ('\u1a65', '\u1a6c'), ('\u1a6d', '\u1a72'),
+        ('\u1a73', '\u1a7c'), ('\u1a7f', '\u1a7f'), ('\u1a80', '\u1a89'), ('\u1a90', '\u1a99'),
+        ('\u1aa7', '\u1aa7'), ('\u1ab0', '\u1abd'), ('\u1b00', '\u1b03'), ('\u1b04', '\u1b04'),
+        ('\u1b05', '\u1b33'), ('\u1b34', '\u1b34'), ('\u1b35', '\u1b35'), ('\u1b36', '\u1b3a'),
+        ('\u1b3b', '\u1b3b'), ('\u1b3c', '\u1b3c'), ('\u1b3d', '\u1b41'), ('\u1b42', '\u1b42'),
+        ('\u1b43', '\u1b44'), ('\u1b45', '\u1b4b'), ('\u1b50', '\u1b59'), ('\u1b6b', '\u1b73'),
+        ('\u1b80', '\u1b81'), ('\u1b82', '\u1b82'), ('\u1b83', '\u1ba0'), ('\u1ba1', '\u1ba1'),
+        ('\u1ba2', '\u1ba5'), ('\u1ba6', '\u1ba7'), ('\u1ba8', '\u1ba9'), ('\u1baa', '\u1baa'),
+        ('\u1bab', '\u1bad'), ('\u1bae', '\u1baf'), ('\u1bb0', '\u1bb9'), ('\u1bba', '\u1be5'),
+        ('\u1be6', '\u1be6'), ('\u1be7', '\u1be7'), ('\u1be8', '\u1be9'), ('\u1bea', '\u1bec'),
+        ('\u1bed', '\u1bed'), ('\u1bee', '\u1bee'), ('\u1bef', '\u1bf1'), ('\u1bf2', '\u1bf3'),
+        ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'), ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
+        ('\u1c36', '\u1c37'), ('\u1c40', '\u1c49'), ('\u1c4d', '\u1c4f'), ('\u1c50', '\u1c59'),
+        ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'), ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1ce0'),
+        ('\u1ce1', '\u1ce1'), ('\u1ce2', '\u1ce8'), ('\u1ce9', '\u1cec'), ('\u1ced', '\u1ced'),
+        ('\u1cee', '\u1cf1'), ('\u1cf2', '\u1cf3'), ('\u1cf4', '\u1cf4'), ('\u1cf5', '\u1cf6'),
+        ('\u1cf8', '\u1cf9'), ('\u1d00', '\u1d2b'), ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
+        ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbf'), ('\u1dc0', '\u1df5'),
+        ('\u1dfc', '\u1dff'), ('\u1e00', '\u1f15'), ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
+        ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
+        ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
+        ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
+        ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
+        ('\u203f', '\u2040'), ('\u2054', '\u2054'), ('\u2071', '\u2071'), ('\u207f', '\u207f'),
+        ('\u2090', '\u209c'), ('\u20d0', '\u20dc'), ('\u20e1', '\u20e1'), ('\u20e5', '\u20f0'),
+        ('\u2102', '\u2102'), ('\u2107', '\u2107'), ('\u210a', '\u2113'), ('\u2115', '\u2115'),
+        ('\u2118', '\u2118'), ('\u2119', '\u211d'), ('\u2124', '\u2124'), ('\u2126', '\u2126'),
+        ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u212e', '\u212e'), ('\u212f', '\u2134'),
+        ('\u2135', '\u2138'), ('\u2139', '\u2139'), ('\u213c', '\u213f'), ('\u2145', '\u2149'),
+        ('\u214e', '\u214e'), ('\u2160', '\u2182'), ('\u2183', '\u2184'), ('\u2185', '\u2188'),
+        ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'), ('\u2c7c', '\u2c7d'),
+        ('\u2c7e', '\u2ce4'), ('\u2ceb', '\u2cee'), ('\u2cef', '\u2cf1'), ('\u2cf2', '\u2cf3'),
+        ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\u2d30', '\u2d67'),
+        ('\u2d6f', '\u2d6f'), ('\u2d7f', '\u2d7f'), ('\u2d80', '\u2d96'), ('\u2da0', '\u2da6'),
+        ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0', '\u2dc6'),
+        ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'), ('\u2de0', '\u2dff'),
+        ('\u3005', '\u3005'), ('\u3006', '\u3006'), ('\u3007', '\u3007'), ('\u3021', '\u3029'),
+        ('\u302a', '\u302d'), ('\u302e', '\u302f'), ('\u3031', '\u3035'), ('\u3038', '\u303a'),
+        ('\u303b', '\u303b'), ('\u303c', '\u303c'), ('\u3041', '\u3096'), ('\u3099', '\u309a'),
+        ('\u309d', '\u309e'), ('\u309f', '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30fe'),
+        ('\u30ff', '\u30ff'), ('\u3105', '\u312d'), ('\u3131', '\u318e'), ('\u31a0', '\u31ba'),
+        ('\u31f0', '\u31ff'), ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'), ('\ua000', '\ua014'),
+        ('\ua015', '\ua015'), ('\ua016', '\ua48c'), ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'),
+        ('\ua500', '\ua60b'), ('\ua60c', '\ua60c'), ('\ua610', '\ua61f'), ('\ua620', '\ua629'),
+        ('\ua62a', '\ua62b'), ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'), ('\ua66f', '\ua66f'),
+        ('\ua674', '\ua67d'), ('\ua67f', '\ua67f'), ('\ua680', '\ua69b'), ('\ua69c', '\ua69d'),
+        ('\ua69f', '\ua69f'), ('\ua6a0', '\ua6e5'), ('\ua6e6', '\ua6ef'), ('\ua6f0', '\ua6f1'),
+        ('\ua717', '\ua71f'), ('\ua722', '\ua76f'), ('\ua770', '\ua770'), ('\ua771', '\ua787'),
+        ('\ua788', '\ua788'), ('\ua78b', '\ua78e'), ('\ua790', '\ua7ad'), ('\ua7b0', '\ua7b1'),
+        ('\ua7f7', '\ua7f7'), ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'), ('\ua7fb', '\ua801'),
+        ('\ua802', '\ua802'), ('\ua803', '\ua805'), ('\ua806', '\ua806'), ('\ua807', '\ua80a'),
+        ('\ua80b', '\ua80b'), ('\ua80c', '\ua822'), ('\ua823', '\ua824'), ('\ua825', '\ua826'),
+        ('\ua827', '\ua827'), ('\ua840', '\ua873'), ('\ua880', '\ua881'), ('\ua882', '\ua8b3'),
+        ('\ua8b4', '\ua8c3'), ('\ua8c4', '\ua8c4'), ('\ua8d0', '\ua8d9'), ('\ua8e0', '\ua8f1'),
+        ('\ua8f2', '\ua8f7'), ('\ua8fb', '\ua8fb'), ('\ua900', '\ua909'), ('\ua90a', '\ua925'),
+        ('\ua926', '\ua92d'), ('\ua930', '\ua946'), ('\ua947', '\ua951'), ('\ua952', '\ua953'),
+        ('\ua960', '\ua97c'), ('\ua980', '\ua982'), ('\ua983', '\ua983'), ('\ua984', '\ua9b2'),
+        ('\ua9b3', '\ua9b3'), ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'), ('\ua9ba', '\ua9bb'),
+        ('\ua9bc', '\ua9bc'), ('\ua9bd', '\ua9c0'), ('\ua9cf', '\ua9cf'), ('\ua9d0', '\ua9d9'),
+        ('\ua9e0', '\ua9e4'), ('\ua9e5', '\ua9e5'), ('\ua9e6', '\ua9e6'), ('\ua9e7', '\ua9ef'),
+        ('\ua9f0', '\ua9f9'), ('\ua9fa', '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa29', '\uaa2e'),
+        ('\uaa2f', '\uaa30'), ('\uaa31', '\uaa32'), ('\uaa33', '\uaa34'), ('\uaa35', '\uaa36'),
+        ('\uaa40', '\uaa42'), ('\uaa43', '\uaa43'), ('\uaa44', '\uaa4b'), ('\uaa4c', '\uaa4c'),
+        ('\uaa4d', '\uaa4d'), ('\uaa50', '\uaa59'), ('\uaa60', '\uaa6f'), ('\uaa70', '\uaa70'),
+        ('\uaa71', '\uaa76'), ('\uaa7a', '\uaa7a'), ('\uaa7b', '\uaa7b'), ('\uaa7c', '\uaa7c'),
+        ('\uaa7d', '\uaa7d'), ('\uaa7e', '\uaaaf'), ('\uaab0', '\uaab0'), ('\uaab1', '\uaab1'),
+        ('\uaab2', '\uaab4'), ('\uaab5', '\uaab6'), ('\uaab7', '\uaab8'), ('\uaab9', '\uaabd'),
+        ('\uaabe', '\uaabf'), ('\uaac0', '\uaac0'), ('\uaac1', '\uaac1'), ('\uaac2', '\uaac2'),
+        ('\uaadb', '\uaadc'), ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'), ('\uaaeb', '\uaaeb'),
+        ('\uaaec', '\uaaed'), ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'),
+        ('\uaaf5', '\uaaf5'), ('\uaaf6', '\uaaf6'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
+        ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e'), ('\uab30', '\uab5a'),
+        ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\uabc0', '\uabe2'), ('\uabe3', '\uabe4'),
+        ('\uabe5', '\uabe5'), ('\uabe6', '\uabe7'), ('\uabe8', '\uabe8'), ('\uabe9', '\uabea'),
+        ('\uabec', '\uabec'), ('\uabed', '\uabed'), ('\uabf0', '\uabf9'), ('\uac00', '\ud7a3'),
+        ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
+        ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'), ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'),
+        ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
+        ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufc5d'),
+        ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdf9'),
+        ('\ufe00', '\ufe0f'), ('\ufe20', '\ufe2d'), ('\ufe33', '\ufe34'), ('\ufe4d', '\ufe4f'),
+        ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'), ('\ufe77', '\ufe77'), ('\ufe79', '\ufe79'),
+        ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'), ('\ufe7f', '\ufefc'), ('\uff10', '\uff19'),
+        ('\uff21', '\uff3a'), ('\uff3f', '\uff3f'), ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
+        ('\uff70', '\uff70'), ('\uff71', '\uff9d'), ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'),
+        ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'), ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'),
+        ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'),
+        ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
+        ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'), ('\U000101fd', '\U000101fd'),
+        ('\U00010280', '\U0001029c'), ('\U000102a0', '\U000102d0'), ('\U000102e0', '\U000102e0'),
+        ('\U00010300', '\U0001031f'), ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'),
+        ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'), ('\U00010350', '\U00010375'),
+        ('\U00010376', '\U0001037a'), ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'),
+        ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'), ('\U00010400', '\U0001044f'),
+        ('\U00010450', '\U0001049d'), ('\U000104a0', '\U000104a9'), ('\U00010500', '\U00010527'),
+        ('\U00010530', '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'),
+        ('\U00010760', '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'),
+        ('\U0001080a', '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
+        ('\U0001083f', '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'),
+        ('\U00010900', '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
+        ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'), ('\U00010a01', '\U00010a03'),
+        ('\U00010a05', '\U00010a06'), ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'),
+        ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a38', '\U00010a3a'),
+        ('\U00010a3f', '\U00010a3f'), ('\U00010a60', '\U00010a7c'), ('\U00010a80', '\U00010a9c'),
+        ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae4'), ('\U00010ae5', '\U00010ae6'),
+        ('\U00010b00', '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
+        ('\U00010b80', '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'),
+        ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'), ('\U00011003', '\U00011037'),
+        ('\U00011038', '\U00011046'), ('\U00011066', '\U0001106f'), ('\U0001107f', '\U00011081'),
+        ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'), ('\U000110b0', '\U000110b2'),
+        ('\U000110b3', '\U000110b6'), ('\U000110b7', '\U000110b8'), ('\U000110b9', '\U000110ba'),
+        ('\U000110d0', '\U000110e8'), ('\U000110f0', '\U000110f9'), ('\U00011100', '\U00011102'),
+        ('\U00011103', '\U00011126'), ('\U00011127', '\U0001112b'), ('\U0001112c', '\U0001112c'),
+        ('\U0001112d', '\U00011134'), ('\U00011136', '\U0001113f'), ('\U00011150', '\U00011172'),
+        ('\U00011173', '\U00011173'), ('\U00011176', '\U00011176'), ('\U00011180', '\U00011181'),
+        ('\U00011182', '\U00011182'), ('\U00011183', '\U000111b2'), ('\U000111b3', '\U000111b5'),
+        ('\U000111b6', '\U000111be'), ('\U000111bf', '\U000111c0'), ('\U000111c1', '\U000111c4'),
+        ('\U000111d0', '\U000111d9'), ('\U000111da', '\U000111da'), ('\U00011200', '\U00011211'),
+        ('\U00011213', '\U0001122b'), ('\U0001122c', '\U0001122e'), ('\U0001122f', '\U00011231'),
+        ('\U00011232', '\U00011233'), ('\U00011234', '\U00011234'), ('\U00011235', '\U00011235'),
+        ('\U00011236', '\U00011237'), ('\U000112b0', '\U000112de'), ('\U000112df', '\U000112df'),
+        ('\U000112e0', '\U000112e2'), ('\U000112e3', '\U000112ea'), ('\U000112f0', '\U000112f9'),
+        ('\U00011301', '\U00011301'), ('\U00011302', '\U00011303'), ('\U00011305', '\U0001130c'),
+        ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'),
+        ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133c', '\U0001133c'),
+        ('\U0001133d', '\U0001133d'), ('\U0001133e', '\U0001133f'), ('\U00011340', '\U00011340'),
+        ('\U00011341', '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'),
+        ('\U00011357', '\U00011357'), ('\U0001135d', '\U00011361'), ('\U00011362', '\U00011363'),
+        ('\U00011366', '\U0001136c'), ('\U00011370', '\U00011374'), ('\U00011480', '\U000114af'),
+        ('\U000114b0', '\U000114b2'), ('\U000114b3', '\U000114b8'), ('\U000114b9', '\U000114b9'),
+        ('\U000114ba', '\U000114ba'), ('\U000114bb', '\U000114be'), ('\U000114bf', '\U000114c0'),
+        ('\U000114c1', '\U000114c1'), ('\U000114c2', '\U000114c3'), ('\U000114c4', '\U000114c5'),
+        ('\U000114c7', '\U000114c7'), ('\U000114d0', '\U000114d9'), ('\U00011580', '\U000115ae'),
+        ('\U000115af', '\U000115b1'), ('\U000115b2', '\U000115b5'), ('\U000115b8', '\U000115bb'),
+        ('\U000115bc', '\U000115bd'), ('\U000115be', '\U000115be'), ('\U000115bf', '\U000115c0'),
+        ('\U00011600', '\U0001162f'), ('\U00011630', '\U00011632'), ('\U00011633', '\U0001163a'),
+        ('\U0001163b', '\U0001163c'), ('\U0001163d', '\U0001163d'), ('\U0001163e', '\U0001163e'),
+        ('\U0001163f', '\U00011640'), ('\U00011644', '\U00011644'), ('\U00011650', '\U00011659'),
+        ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'), ('\U000116ac', '\U000116ac'),
+        ('\U000116ad', '\U000116ad'), ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
+        ('\U000116b6', '\U000116b6'), ('\U000116b7', '\U000116b7'), ('\U000116c0', '\U000116c9'),
+        ('\U000118a0', '\U000118df'), ('\U000118e0', '\U000118e9'), ('\U000118ff', '\U000118ff'),
+        ('\U00011ac0', '\U00011af8'), ('\U00012000', '\U00012398'), ('\U00012400', '\U0001246e'),
+        ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'), ('\U00016a40', '\U00016a5e'),
+        ('\U00016a60', '\U00016a69'), ('\U00016ad0', '\U00016aed'), ('\U00016af0', '\U00016af4'),
+        ('\U00016b00', '\U00016b2f'), ('\U00016b30', '\U00016b36'), ('\U00016b40', '\U00016b43'),
+        ('\U00016b50', '\U00016b59'), ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'),
+        ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f51', '\U00016f7e'),
+        ('\U00016f8f', '\U00016f92'), ('\U00016f93', '\U00016f9f'), ('\U0001b000', '\U0001b001'),
+        ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80', '\U0001bc88'),
+        ('\U0001bc90', '\U0001bc99'), ('\U0001bc9d', '\U0001bc9e'), ('\U0001d165', '\U0001d166'),
+        ('\U0001d167', '\U0001d169'), ('\U0001d16d', '\U0001d172'), ('\U0001d17b', '\U0001d182'),
+        ('\U0001d185', '\U0001d18b'), ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'),
+        ('\U0001d400', '\U0001d454'), ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
+        ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
+        ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'),
+        ('\U0001d4c5', '\U0001d505'), ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
+        ('\U0001d516', '\U0001d51c'), ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'),
+        ('\U0001d540', '\U0001d544'), ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
+        ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'),
+        ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'),
+        ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'),
+        ('\U0001d78a', '\U0001d7a8'), ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'),
+        ('\U0001d7ce', '\U0001d7ff'), ('\U0001e800', '\U0001e8c4'), ('\U0001e8d0', '\U0001e8d6'),
+        ('\U0001ee00', '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
+        ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'),
+        ('\U0001ee34', '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
+        ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'),
+        ('\U0001ee4b', '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
+        ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'),
+        ('\U0001ee5b', '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
+        ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'),
+        ('\U0001ee6c', '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
+        ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'),
+        ('\U0001eea1', '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
+        ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'),
+        ('\U0002f800', '\U0002fa1d'), ('\U000e0100', '\U000e01ef')
+    ];
+
+    pub fn XID_Continue(c: char) -> bool {
+        super::bsearch_range_table(c, XID_Continue_table)
+    }
+
+    pub static XID_Start_table: &'static [(char, char)] = &[
+        ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xb5', '\xb5'), ('\xba', '\xba'),
+        ('\xc0', '\xd6'), ('\xd8', '\xf6'), ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'), ('\u01bc',
+        '\u01bf'), ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'), ('\u0294', '\u0294'), ('\u0295',
+        '\u02af'), ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec',
+        '\u02ec'), ('\u02ee', '\u02ee'), ('\u0370', '\u0373'), ('\u0374', '\u0374'), ('\u0376',
+        '\u0377'), ('\u037b', '\u037d'), ('\u037f', '\u037f'), ('\u0386', '\u0386'), ('\u0388',
+        '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'), ('\u03f7',
+        '\u0481'), ('\u048a', '\u052f'), ('\u0531', '\u0556'), ('\u0559', '\u0559'), ('\u0561',
+        '\u0587'), ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'), ('\u0620', '\u063f'), ('\u0640',
+        '\u0640'), ('\u0641', '\u064a'), ('\u066e', '\u066f'), ('\u0671', '\u06d3'), ('\u06d5',
+        '\u06d5'), ('\u06e5', '\u06e6'), ('\u06ee', '\u06ef'), ('\u06fa', '\u06fc'), ('\u06ff',
+        '\u06ff'), ('\u0710', '\u0710'), ('\u0712', '\u072f'), ('\u074d', '\u07a5'), ('\u07b1',
+        '\u07b1'), ('\u07ca', '\u07ea'), ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'), ('\u0800',
+        '\u0815'), ('\u081a', '\u081a'), ('\u0824', '\u0824'), ('\u0828', '\u0828'), ('\u0840',
+        '\u0858'), ('\u08a0', '\u08b2'), ('\u0904', '\u0939'), ('\u093d', '\u093d'), ('\u0950',
+        '\u0950'), ('\u0958', '\u0961'), ('\u0971', '\u0971'), ('\u0972', '\u0980'), ('\u0985',
+        '\u098c'), ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2',
+        '\u09b2'), ('\u09b6', '\u09b9'), ('\u09bd', '\u09bd'), ('\u09ce', '\u09ce'), ('\u09dc',
+        '\u09dd'), ('\u09df', '\u09e1'), ('\u09f0', '\u09f1'), ('\u0a05', '\u0a0a'), ('\u0a0f',
+        '\u0a10'), ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35',
+        '\u0a36'), ('\u0a38', '\u0a39'), ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'), ('\u0a72',
+        '\u0a74'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa',
+        '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abd', '\u0abd'), ('\u0ad0',
+        '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'), ('\u0b13',
+        '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'), ('\u0b3d',
+        '\u0b3d'), ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b71', '\u0b71'), ('\u0b83',
+        '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99',
+        '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8',
+        '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bd0', '\u0bd0'), ('\u0c05', '\u0c0c'), ('\u0c0e',
+        '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d', '\u0c3d'), ('\u0c58',
+        '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'), ('\u0c92',
+        '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'), ('\u0cbd', '\u0cbd'), ('\u0cde',
+        '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0cf1', '\u0cf2'), ('\u0d05', '\u0d0c'), ('\u0d0e',
+        '\u0d10'), ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d4e', '\u0d4e'), ('\u0d60',
+        '\u0d61'), ('\u0d7a', '\u0d7f'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3',
+        '\u0dbb'), ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0e01', '\u0e30'), ('\u0e32',
+        '\u0e32'), ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'), ('\u0e81', '\u0e82'), ('\u0e84',
+        '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94',
+        '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7',
+        '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'), ('\u0eb2', '\u0eb2'), ('\u0ebd',
+        '\u0ebd'), ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0edc', '\u0edf'), ('\u0f00',
+        '\u0f00'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'), ('\u0f88', '\u0f8c'), ('\u1000',
+        '\u102a'), ('\u103f', '\u103f'), ('\u1050', '\u1055'), ('\u105a', '\u105d'), ('\u1061',
+        '\u1061'), ('\u1065', '\u1066'), ('\u106e', '\u1070'), ('\u1075', '\u1081'), ('\u108e',
+        '\u108e'), ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0',
+        '\u10fa'), ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'), ('\u124a', '\u124d'), ('\u1250',
+        '\u1256'), ('\u1258', '\u1258'), ('\u125a', '\u125d'), ('\u1260', '\u1288'), ('\u128a',
+        '\u128d'), ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0',
+        '\u12c0'), ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'), ('\u1312',
+        '\u1315'), ('\u1318', '\u135a'), ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401',
+        '\u166c'), ('\u166f', '\u167f'), ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16ee',
+        '\u16f0'), ('\u16f1', '\u16f8'), ('\u1700', '\u170c'), ('\u170e', '\u1711'), ('\u1720',
+        '\u1731'), ('\u1740', '\u1751'), ('\u1760', '\u176c'), ('\u176e', '\u1770'), ('\u1780',
+        '\u17b3'), ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'), ('\u1820', '\u1842'), ('\u1843',
+        '\u1843'), ('\u1844', '\u1877'), ('\u1880', '\u18a8'), ('\u18aa', '\u18aa'), ('\u18b0',
+        '\u18f5'), ('\u1900', '\u191e'), ('\u1950', '\u196d'), ('\u1970', '\u1974'), ('\u1980',
+        '\u19ab'), ('\u19c1', '\u19c7'), ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'), ('\u1aa7',
+        '\u1aa7'), ('\u1b05', '\u1b33'), ('\u1b45', '\u1b4b'), ('\u1b83', '\u1ba0'), ('\u1bae',
+        '\u1baf'), ('\u1bba', '\u1be5'), ('\u1c00', '\u1c23'), ('\u1c4d', '\u1c4f'), ('\u1c5a',
+        '\u1c77'), ('\u1c78', '\u1c7d'), ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'), ('\u1cf5',
+        '\u1cf6'), ('\u1d00', '\u1d2b'), ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'), ('\u1d78',
+        '\u1d78'), ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbf'), ('\u1e00', '\u1f15'), ('\u1f18',
+        '\u1f1d'), ('\u1f20', '\u1f45'), ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59',
+        '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80',
+        '\u1fb4'), ('\u1fb6', '\u1fbc'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6',
+        '\u1fcc'), ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2',
+        '\u1ff4'), ('\u1ff6', '\u1ffc'), ('\u2071', '\u2071'), ('\u207f', '\u207f'), ('\u2090',
+        '\u209c'), ('\u2102', '\u2102'), ('\u2107', '\u2107'), ('\u210a', '\u2113'), ('\u2115',
+        '\u2115'), ('\u2118', '\u2118'), ('\u2119', '\u211d'), ('\u2124', '\u2124'), ('\u2126',
+        '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u212e', '\u212e'), ('\u212f',
+        '\u2134'), ('\u2135', '\u2138'), ('\u2139', '\u2139'), ('\u213c', '\u213f'), ('\u2145',
+        '\u2149'), ('\u214e', '\u214e'), ('\u2160', '\u2182'), ('\u2183', '\u2184'), ('\u2185',
+        '\u2188'), ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'), ('\u2c7c',
+        '\u2c7d'), ('\u2c7e', '\u2ce4'), ('\u2ceb', '\u2cee'), ('\u2cf2', '\u2cf3'), ('\u2d00',
+        '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\u2d30', '\u2d67'), ('\u2d6f',
+        '\u2d6f'), ('\u2d80', '\u2d96'), ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0',
+        '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0',
+        '\u2dd6'), ('\u2dd8', '\u2dde'), ('\u3005', '\u3005'), ('\u3006', '\u3006'), ('\u3007',
+        '\u3007'), ('\u3021', '\u3029'), ('\u3031', '\u3035'), ('\u3038', '\u303a'), ('\u303b',
+        '\u303b'), ('\u303c', '\u303c'), ('\u3041', '\u3096'), ('\u309d', '\u309e'), ('\u309f',
+        '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'), ('\u3105',
+        '\u312d'), ('\u3131', '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400',
+        '\u4db5'), ('\u4e00', '\u9fcc'), ('\ua000', '\ua014'), ('\ua015', '\ua015'), ('\ua016',
+        '\ua48c'), ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'), ('\ua60c',
+        '\ua60c'), ('\ua610', '\ua61f'), ('\ua62a', '\ua62b'), ('\ua640', '\ua66d'), ('\ua66e',
+        '\ua66e'), ('\ua67f', '\ua67f'), ('\ua680', '\ua69b'), ('\ua69c', '\ua69d'), ('\ua6a0',
+        '\ua6e5'), ('\ua6e6', '\ua6ef'), ('\ua717', '\ua71f'), ('\ua722', '\ua76f'), ('\ua770',
+        '\ua770'), ('\ua771', '\ua787'), ('\ua788', '\ua788'), ('\ua78b', '\ua78e'), ('\ua790',
+        '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\ua7f7', '\ua7f7'), ('\ua7f8', '\ua7f9'), ('\ua7fa',
+        '\ua7fa'), ('\ua7fb', '\ua801'), ('\ua803', '\ua805'), ('\ua807', '\ua80a'), ('\ua80c',
+        '\ua822'), ('\ua840', '\ua873'), ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'), ('\ua8fb',
+        '\ua8fb'), ('\ua90a', '\ua925'), ('\ua930', '\ua946'), ('\ua960', '\ua97c'), ('\ua984',
+        '\ua9b2'), ('\ua9cf', '\ua9cf'), ('\ua9e0', '\ua9e4'), ('\ua9e6', '\ua9e6'), ('\ua9e7',
+        '\ua9ef'), ('\ua9fa', '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa40', '\uaa42'), ('\uaa44',
+        '\uaa4b'), ('\uaa60', '\uaa6f'), ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'), ('\uaa7a',
+        '\uaa7a'), ('\uaa7e', '\uaaaf'), ('\uaab1', '\uaab1'), ('\uaab5', '\uaab6'), ('\uaab9',
+        '\uaabd'), ('\uaac0', '\uaac0'), ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'), ('\uaadd',
+        '\uaadd'), ('\uaae0', '\uaaea'), ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'), ('\uab01',
+        '\uab06'), ('\uab09', '\uab0e'), ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28',
+        '\uab2e'), ('\uab30', '\uab5a'), ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\uabc0',
+        '\uabe2'), ('\uac00', '\ud7a3'), ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900',
+        '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'), ('\ufb1d',
+        '\ufb1d'), ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e',
+        '\ufb3e'), ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3',
+        '\ufc5d'), ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0',
+        '\ufdf9'), ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'), ('\ufe77', '\ufe77'), ('\ufe79',
+        '\ufe79'), ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'), ('\ufe7f', '\ufefc'), ('\uff21',
+        '\uff3a'), ('\uff41', '\uff5a'), ('\uff66', '\uff6f'), ('\uff70', '\uff70'), ('\uff71',
+        '\uff9d'), ('\uffa0', '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'), ('\uffd2',
+        '\uffd7'), ('\uffda', '\uffdc'), ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'),
+        ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'),
+        ('\U00010050', '\U0001005d'), ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'),
+        ('\U00010280', '\U0001029c'), ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031f'),
+        ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'), ('\U00010342', '\U00010349'),
+        ('\U0001034a', '\U0001034a'), ('\U00010350', '\U00010375'), ('\U00010380', '\U0001039d'),
+        ('\U000103a0', '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'),
+        ('\U00010400', '\U0001044f'), ('\U00010450', '\U0001049d'), ('\U00010500', '\U00010527'),
+        ('\U00010530', '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'),
+        ('\U00010760', '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'),
+        ('\U0001080a', '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
+        ('\U0001083f', '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'),
+        ('\U00010900', '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
+        ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'), ('\U00010a10', '\U00010a13'),
+        ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a60', '\U00010a7c'),
+        ('\U00010a80', '\U00010a9c'), ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae4'),
+        ('\U00010b00', '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
+        ('\U00010b80', '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011003', '\U00011037'),
+        ('\U00011083', '\U000110af'), ('\U000110d0', '\U000110e8'), ('\U00011103', '\U00011126'),
+        ('\U00011150', '\U00011172'), ('\U00011176', '\U00011176'), ('\U00011183', '\U000111b2'),
+        ('\U000111c1', '\U000111c4'), ('\U000111da', '\U000111da'), ('\U00011200', '\U00011211'),
+        ('\U00011213', '\U0001122b'), ('\U000112b0', '\U000112de'), ('\U00011305', '\U0001130c'),
+        ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'),
+        ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133d', '\U0001133d'),
+        ('\U0001135d', '\U00011361'), ('\U00011480', '\U000114af'), ('\U000114c4', '\U000114c5'),
+        ('\U000114c7', '\U000114c7'), ('\U00011580', '\U000115ae'), ('\U00011600', '\U0001162f'),
+        ('\U00011644', '\U00011644'), ('\U00011680', '\U000116aa'), ('\U000118a0', '\U000118df'),
+        ('\U000118ff', '\U000118ff'), ('\U00011ac0', '\U00011af8'), ('\U00012000', '\U00012398'),
+        ('\U00012400', '\U0001246e'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
+        ('\U00016a40', '\U00016a5e'), ('\U00016ad0', '\U00016aed'), ('\U00016b00', '\U00016b2f'),
+        ('\U00016b40', '\U00016b43'), ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'),
+        ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f93', '\U00016f9f'),
+        ('\U0001b000', '\U0001b001'), ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'),
+        ('\U0001bc80', '\U0001bc88'), ('\U0001bc90', '\U0001bc99'), ('\U0001d400', '\U0001d454'),
+        ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
+        ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'),
+        ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
+        ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'),
+        ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
+        ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'),
+        ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
+        ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'),
+        ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
+        ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001e800', '\U0001e8c4'),
+        ('\U0001ee00', '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
+        ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'),
+        ('\U0001ee34', '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
+        ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'),
+        ('\U0001ee4b', '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
+        ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'),
+        ('\U0001ee5b', '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
+        ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'),
+        ('\U0001ee6c', '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
+        ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'),
+        ('\U0001eea1', '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
+        ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'),
+        ('\U0002f800', '\U0002fa1d')
+    ];
+
+    pub fn XID_Start(c: char) -> bool {
+        super::bsearch_range_table(c, XID_Start_table)
+    }
+
+}
+
+pub mod script {
+    pub static Arabic_table: &'static [(char, char)] = &[
+        ('\u0600', '\u0604'), ('\u0606', '\u0608'), ('\u0609', '\u060a'), ('\u060b', '\u060b'),
+        ('\u060d', '\u060d'), ('\u060e', '\u060f'), ('\u0610', '\u061a'), ('\u061e', '\u061e'),
+        ('\u0620', '\u063f'), ('\u0641', '\u064a'), ('\u0656', '\u065f'), ('\u066a', '\u066d'),
+        ('\u066e', '\u066f'), ('\u0671', '\u06d3'), ('\u06d4', '\u06d4'), ('\u06d5', '\u06d5'),
+        ('\u06d6', '\u06dc'), ('\u06de', '\u06de'), ('\u06df', '\u06e4'), ('\u06e5', '\u06e6'),
+        ('\u06e7', '\u06e8'), ('\u06e9', '\u06e9'), ('\u06ea', '\u06ed'), ('\u06ee', '\u06ef'),
+        ('\u06f0', '\u06f9'), ('\u06fa', '\u06fc'), ('\u06fd', '\u06fe'), ('\u06ff', '\u06ff'),
+        ('\u0750', '\u077f'), ('\u08a0', '\u08b2'), ('\u08e4', '\u08ff'), ('\ufb50', '\ufbb1'),
+        ('\ufbb2', '\ufbc1'), ('\ufbd3', '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'),
+        ('\ufdf0', '\ufdfb'), ('\ufdfc', '\ufdfc'), ('\ufdfd', '\ufdfd'), ('\ufe70', '\ufe74'),
+        ('\ufe76', '\ufefc'), ('\U00010e60', '\U00010e7e'), ('\U0001ee00', '\U0001ee03'),
+        ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'), ('\U0001ee24', '\U0001ee24'),
+        ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'),
+        ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42', '\U0001ee42'),
+        ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'),
+        ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'), ('\U0001ee54', '\U0001ee54'),
+        ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'),
+        ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61', '\U0001ee62'),
+        ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'),
+        ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e', '\U0001ee7e'),
+        ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'),
+        ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'), ('\U0001eef0', '\U0001eef1')
+    ];
+
+    pub static Armenian_table: &'static [(char, char)] = &[
+        ('\u0531', '\u0556'), ('\u0559', '\u0559'), ('\u055a', '\u055f'), ('\u0561', '\u0587'),
+        ('\u058a', '\u058a'), ('\u058d', '\u058e'), ('\u058f', '\u058f'), ('\ufb13', '\ufb17')
+    ];
+
+    pub static Avestan_table: &'static [(char, char)] = &[
+        ('\U00010b00', '\U00010b35'), ('\U00010b39', '\U00010b3f')
+    ];
+
+    pub static Balinese_table: &'static [(char, char)] = &[
+        ('\u1b00', '\u1b03'), ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'), ('\u1b34', '\u1b34'),
+        ('\u1b35', '\u1b35'), ('\u1b36', '\u1b3a'), ('\u1b3b', '\u1b3b'), ('\u1b3c', '\u1b3c'),
+        ('\u1b3d', '\u1b41'), ('\u1b42', '\u1b42'), ('\u1b43', '\u1b44'), ('\u1b45', '\u1b4b'),
+        ('\u1b50', '\u1b59'), ('\u1b5a', '\u1b60'), ('\u1b61', '\u1b6a'), ('\u1b6b', '\u1b73'),
+        ('\u1b74', '\u1b7c')
+    ];
+
+    pub static Bamum_table: &'static [(char, char)] = &[
+        ('\ua6a0', '\ua6e5'), ('\ua6e6', '\ua6ef'), ('\ua6f0', '\ua6f1'), ('\ua6f2', '\ua6f7'),
+        ('\U00016800', '\U00016a38')
+    ];
+
+    pub static Bassa_Vah_table: &'static [(char, char)] = &[
+        ('\U00016ad0', '\U00016aed'), ('\U00016af0', '\U00016af4'), ('\U00016af5', '\U00016af5')
+    ];
+
+    pub static Batak_table: &'static [(char, char)] = &[
+        ('\u1bc0', '\u1be5'), ('\u1be6', '\u1be6'), ('\u1be7', '\u1be7'), ('\u1be8', '\u1be9'),
+        ('\u1bea', '\u1bec'), ('\u1bed', '\u1bed'), ('\u1bee', '\u1bee'), ('\u1bef', '\u1bf1'),
+        ('\u1bf2', '\u1bf3'), ('\u1bfc', '\u1bff')
+    ];
+
+    pub static Bengali_table: &'static [(char, char)] = &[
+        ('\u0980', '\u0980'), ('\u0981', '\u0981'), ('\u0982', '\u0983'), ('\u0985', '\u098c'),
+        ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2', '\u09b2'),
+        ('\u09b6', '\u09b9'), ('\u09bc', '\u09bc'), ('\u09bd', '\u09bd'), ('\u09be', '\u09c0'),
+        ('\u09c1', '\u09c4'), ('\u09c7', '\u09c8'), ('\u09cb', '\u09cc'), ('\u09cd', '\u09cd'),
+        ('\u09ce', '\u09ce'), ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'), ('\u09df', '\u09e1'),
+        ('\u09e2', '\u09e3'), ('\u09e6', '\u09ef'), ('\u09f0', '\u09f1'), ('\u09f2', '\u09f3'),
+        ('\u09f4', '\u09f9'), ('\u09fa', '\u09fa'), ('\u09fb', '\u09fb')
+    ];
+
+    pub static Bopomofo_table: &'static [(char, char)] = &[
+        ('\u02ea', '\u02eb'), ('\u3105', '\u312d'), ('\u31a0', '\u31ba')
+    ];
+
+    pub static Brahmi_table: &'static [(char, char)] = &[
+        ('\U00011000', '\U00011000'), ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'),
+        ('\U00011003', '\U00011037'), ('\U00011038', '\U00011046'), ('\U00011047', '\U0001104d'),
+        ('\U00011052', '\U00011065'), ('\U00011066', '\U0001106f'), ('\U0001107f', '\U0001107f')
+    ];
+
+    pub static Braille_table: &'static [(char, char)] = &[
+        ('\u2800', '\u28ff')
+    ];
+
+    pub static Buginese_table: &'static [(char, char)] = &[
+        ('\u1a00', '\u1a16'), ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'), ('\u1a1b', '\u1a1b'),
+        ('\u1a1e', '\u1a1f')
+    ];
+
+    pub static Buhid_table: &'static [(char, char)] = &[
+        ('\u1740', '\u1751'), ('\u1752', '\u1753')
+    ];
+
+    pub static Canadian_Aboriginal_table: &'static [(char, char)] = &[
+        ('\u1400', '\u1400'), ('\u1401', '\u166c'), ('\u166d', '\u166e'), ('\u166f', '\u167f'),
+        ('\u18b0', '\u18f5')
+    ];
+
+    pub static Carian_table: &'static [(char, char)] = &[
+        ('\U000102a0', '\U000102d0')
+    ];
+
+    pub static Caucasian_Albanian_table: &'static [(char, char)] = &[
+        ('\U00010530', '\U00010563'), ('\U0001056f', '\U0001056f')
+    ];
+
+    pub static Chakma_table: &'static [(char, char)] = &[
+        ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'), ('\U00011127', '\U0001112b'),
+        ('\U0001112c', '\U0001112c'), ('\U0001112d', '\U00011134'), ('\U00011136', '\U0001113f'),
+        ('\U00011140', '\U00011143')
+    ];
+
+    pub static Cham_table: &'static [(char, char)] = &[
+        ('\uaa00', '\uaa28'), ('\uaa29', '\uaa2e'), ('\uaa2f', '\uaa30'), ('\uaa31', '\uaa32'),
+        ('\uaa33', '\uaa34'), ('\uaa35', '\uaa36'), ('\uaa40', '\uaa42'), ('\uaa43', '\uaa43'),
+        ('\uaa44', '\uaa4b'), ('\uaa4c', '\uaa4c'), ('\uaa4d', '\uaa4d'), ('\uaa50', '\uaa59'),
+        ('\uaa5c', '\uaa5f')
+    ];
+
+    pub static Cherokee_table: &'static [(char, char)] = &[
+        ('\u13a0', '\u13f4')
+    ];
+
+    pub static Common_table: &'static [(char, char)] = &[
+        ('\x00', '\x1f'), ('\x20', '\x20'), ('\x21', '\x23'), ('\x24', '\x24'), ('\x25', '\x27'),
+        ('\x28', '\x28'), ('\x29', '\x29'), ('\x2a', '\x2a'), ('\x2b', '\x2b'), ('\x2c', '\x2c'),
+        ('\x2d', '\x2d'), ('\x2e', '\x2f'), ('\x30', '\x39'), ('\x3a', '\x3b'), ('\x3c', '\x3e'),
+        ('\x3f', '\x40'), ('\x5b', '\x5b'), ('\x5c', '\x5c'), ('\x5d', '\x5d'), ('\x5e', '\x5e'),
+        ('\x5f', '\x5f'), ('\x60', '\x60'), ('\x7b', '\x7b'), ('\x7c', '\x7c'), ('\x7d', '\x7d'),
+        ('\x7e', '\x7e'), ('\x7f', '\x9f'), ('\xa0', '\xa0'), ('\xa1', '\xa1'), ('\xa2', '\xa5'),
+        ('\xa6', '\xa6'), ('\xa7', '\xa7'), ('\xa8', '\xa8'), ('\xa9', '\xa9'), ('\xab', '\xab'),
+        ('\xac', '\xac'), ('\xad', '\xad'), ('\xae', '\xae'), ('\xaf', '\xaf'), ('\xb0', '\xb0'),
+        ('\xb1', '\xb1'), ('\xb2', '\xb3'), ('\xb4', '\xb4'), ('\xb5', '\xb5'), ('\xb6', '\xb7'),
+        ('\xb8', '\xb8'), ('\xb9', '\xb9'), ('\xbb', '\xbb'), ('\xbc', '\xbe'), ('\xbf', '\xbf'),
+        ('\xd7', '\xd7'), ('\xf7', '\xf7'), ('\u02b9', '\u02c1'), ('\u02c2', '\u02c5'), ('\u02c6',
+        '\u02d1'), ('\u02d2', '\u02df'), ('\u02e5', '\u02e9'), ('\u02ec', '\u02ec'), ('\u02ed',
+        '\u02ed'), ('\u02ee', '\u02ee'), ('\u02ef', '\u02ff'), ('\u0374', '\u0374'), ('\u037e',
+        '\u037e'), ('\u0385', '\u0385'), ('\u0387', '\u0387'), ('\u0589', '\u0589'), ('\u0605',
+        '\u0605'), ('\u060c', '\u060c'), ('\u061b', '\u061b'), ('\u061c', '\u061c'), ('\u061f',
+        '\u061f'), ('\u0640', '\u0640'), ('\u0660', '\u0669'), ('\u06dd', '\u06dd'), ('\u0964',
+        '\u0965'), ('\u0e3f', '\u0e3f'), ('\u0fd5', '\u0fd8'), ('\u10fb', '\u10fb'), ('\u16eb',
+        '\u16ed'), ('\u1735', '\u1736'), ('\u1802', '\u1803'), ('\u1805', '\u1805'), ('\u1cd3',
+        '\u1cd3'), ('\u1ce1', '\u1ce1'), ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'), ('\u1cf2',
+        '\u1cf3'), ('\u1cf5', '\u1cf6'), ('\u2000', '\u200a'), ('\u200b', '\u200b'), ('\u200e',
+        '\u200f'), ('\u2010', '\u2015'), ('\u2016', '\u2017'), ('\u2018', '\u2018'), ('\u2019',
+        '\u2019'), ('\u201a', '\u201a'), ('\u201b', '\u201c'), ('\u201d', '\u201d'), ('\u201e',
+        '\u201e'), ('\u201f', '\u201f'), ('\u2020', '\u2027'), ('\u2028', '\u2028'), ('\u2029',
+        '\u2029'), ('\u202a', '\u202e'), ('\u202f', '\u202f'), ('\u2030', '\u2038'), ('\u2039',
+        '\u2039'), ('\u203a', '\u203a'), ('\u203b', '\u203e'), ('\u203f', '\u2040'), ('\u2041',
+        '\u2043'), ('\u2044', '\u2044'), ('\u2045', '\u2045'), ('\u2046', '\u2046'), ('\u2047',
+        '\u2051'), ('\u2052', '\u2052'), ('\u2053', '\u2053'), ('\u2054', '\u2054'), ('\u2055',
+        '\u205e'), ('\u205f', '\u205f'), ('\u2060', '\u2064'), ('\u2066', '\u206f'), ('\u2070',
+        '\u2070'), ('\u2074', '\u2079'), ('\u207a', '\u207c'), ('\u207d', '\u207d'), ('\u207e',
+        '\u207e'), ('\u2080', '\u2089'), ('\u208a', '\u208c'), ('\u208d', '\u208d'), ('\u208e',
+        '\u208e'), ('\u20a0', '\u20bd'), ('\u2100', '\u2101'), ('\u2102', '\u2102'), ('\u2103',
+        '\u2106'), ('\u2107', '\u2107'), ('\u2108', '\u2109'), ('\u210a', '\u2113'), ('\u2114',
+        '\u2114'), ('\u2115', '\u2115'), ('\u2116', '\u2117'), ('\u2118', '\u2118'), ('\u2119',
+        '\u211d'), ('\u211e', '\u2123'), ('\u2124', '\u2124'), ('\u2125', '\u2125'), ('\u2127',
+        '\u2127'), ('\u2128', '\u2128'), ('\u2129', '\u2129'), ('\u212c', '\u212d'), ('\u212e',
+        '\u212e'), ('\u212f', '\u2131'), ('\u2133', '\u2134'), ('\u2135', '\u2138'), ('\u2139',
+        '\u2139'), ('\u213a', '\u213b'), ('\u213c', '\u213f'), ('\u2140', '\u2144'), ('\u2145',
+        '\u2149'), ('\u214a', '\u214a'), ('\u214b', '\u214b'), ('\u214c', '\u214d'), ('\u214f',
+        '\u214f'), ('\u2150', '\u215f'), ('\u2189', '\u2189'), ('\u2190', '\u2194'), ('\u2195',
+        '\u2199'), ('\u219a', '\u219b'), ('\u219c', '\u219f'), ('\u21a0', '\u21a0'), ('\u21a1',
+        '\u21a2'), ('\u21a3', '\u21a3'), ('\u21a4', '\u21a5'), ('\u21a6', '\u21a6'), ('\u21a7',
+        '\u21ad'), ('\u21ae', '\u21ae'), ('\u21af', '\u21cd'), ('\u21ce', '\u21cf'), ('\u21d0',
+        '\u21d1'), ('\u21d2', '\u21d2'), ('\u21d3', '\u21d3'), ('\u21d4', '\u21d4'), ('\u21d5',
+        '\u21f3'), ('\u21f4', '\u22ff'), ('\u2300', '\u2307'), ('\u2308', '\u2308'), ('\u2309',
+        '\u2309'), ('\u230a', '\u230a'), ('\u230b', '\u230b'), ('\u230c', '\u231f'), ('\u2320',
+        '\u2321'), ('\u2322', '\u2328'), ('\u2329', '\u2329'), ('\u232a', '\u232a'), ('\u232b',
+        '\u237b'), ('\u237c', '\u237c'), ('\u237d', '\u239a'), ('\u239b', '\u23b3'), ('\u23b4',
+        '\u23db'), ('\u23dc', '\u23e1'), ('\u23e2', '\u23fa'), ('\u2400', '\u2426'), ('\u2440',
+        '\u244a'), ('\u2460', '\u249b'), ('\u249c', '\u24e9'), ('\u24ea', '\u24ff'), ('\u2500',
+        '\u25b6'), ('\u25b7', '\u25b7'), ('\u25b8', '\u25c0'), ('\u25c1', '\u25c1'), ('\u25c2',
+        '\u25f7'), ('\u25f8', '\u25ff'), ('\u2600', '\u266e'), ('\u266f', '\u266f'), ('\u2670',
+        '\u2767'), ('\u2768', '\u2768'), ('\u2769', '\u2769'), ('\u276a', '\u276a'), ('\u276b',
+        '\u276b'), ('\u276c', '\u276c'), ('\u276d', '\u276d'), ('\u276e', '\u276e'), ('\u276f',
+        '\u276f'), ('\u2770', '\u2770'), ('\u2771', '\u2771'), ('\u2772', '\u2772'), ('\u2773',
+        '\u2773'), ('\u2774', '\u2774'), ('\u2775', '\u2775'), ('\u2776', '\u2793'), ('\u2794',
+        '\u27bf'), ('\u27c0', '\u27c4'), ('\u27c5', '\u27c5'), ('\u27c6', '\u27c6'), ('\u27c7',
+        '\u27e5'), ('\u27e6', '\u27e6'), ('\u27e7', '\u27e7'), ('\u27e8', '\u27e8'), ('\u27e9',
+        '\u27e9'), ('\u27ea', '\u27ea'), ('\u27eb', '\u27eb'), ('\u27ec', '\u27ec'), ('\u27ed',
+        '\u27ed'), ('\u27ee', '\u27ee'), ('\u27ef', '\u27ef'), ('\u27f0', '\u27ff'), ('\u2900',
+        '\u2982'), ('\u2983', '\u2983'), ('\u2984', '\u2984'), ('\u2985', '\u2985'), ('\u2986',
+        '\u2986'), ('\u2987', '\u2987'), ('\u2988', '\u2988'), ('\u2989', '\u2989'), ('\u298a',
+        '\u298a'), ('\u298b', '\u298b'), ('\u298c', '\u298c'), ('\u298d', '\u298d'), ('\u298e',
+        '\u298e'), ('\u298f', '\u298f'), ('\u2990', '\u2990'), ('\u2991', '\u2991'), ('\u2992',
+        '\u2992'), ('\u2993', '\u2993'), ('\u2994', '\u2994'), ('\u2995', '\u2995'), ('\u2996',
+        '\u2996'), ('\u2997', '\u2997'), ('\u2998', '\u2998'), ('\u2999', '\u29d7'), ('\u29d8',
+        '\u29d8'), ('\u29d9', '\u29d9'), ('\u29da', '\u29da'), ('\u29db', '\u29db'), ('\u29dc',
+        '\u29fb'), ('\u29fc', '\u29fc'), ('\u29fd', '\u29fd'), ('\u29fe', '\u2aff'), ('\u2b00',
+        '\u2b2f'), ('\u2b30', '\u2b44'), ('\u2b45', '\u2b46'), ('\u2b47', '\u2b4c'), ('\u2b4d',
+        '\u2b73'), ('\u2b76', '\u2b95'), ('\u2b98', '\u2bb9'), ('\u2bbd', '\u2bc8'), ('\u2bca',
+        '\u2bd1'), ('\u2e00', '\u2e01'), ('\u2e02', '\u2e02'), ('\u2e03', '\u2e03'), ('\u2e04',
+        '\u2e04'), ('\u2e05', '\u2e05'), ('\u2e06', '\u2e08'), ('\u2e09', '\u2e09'), ('\u2e0a',
+        '\u2e0a'), ('\u2e0b', '\u2e0b'), ('\u2e0c', '\u2e0c'), ('\u2e0d', '\u2e0d'), ('\u2e0e',
+        '\u2e16'), ('\u2e17', '\u2e17'), ('\u2e18', '\u2e19'), ('\u2e1a', '\u2e1a'), ('\u2e1b',
+        '\u2e1b'), ('\u2e1c', '\u2e1c'), ('\u2e1d', '\u2e1d'), ('\u2e1e', '\u2e1f'), ('\u2e20',
+        '\u2e20'), ('\u2e21', '\u2e21'), ('\u2e22', '\u2e22'), ('\u2e23', '\u2e23'), ('\u2e24',
+        '\u2e24'), ('\u2e25', '\u2e25'), ('\u2e26', '\u2e26'), ('\u2e27', '\u2e27'), ('\u2e28',
+        '\u2e28'), ('\u2e29', '\u2e29'), ('\u2e2a', '\u2e2e'), ('\u2e2f', '\u2e2f'), ('\u2e30',
+        '\u2e39'), ('\u2e3a', '\u2e3b'), ('\u2e3c', '\u2e3f'), ('\u2e40', '\u2e40'), ('\u2e41',
+        '\u2e41'), ('\u2e42', '\u2e42'), ('\u2ff0', '\u2ffb'), ('\u3000', '\u3000'), ('\u3001',
+        '\u3003'), ('\u3004', '\u3004'), ('\u3006', '\u3006'), ('\u3008', '\u3008'), ('\u3009',
+        '\u3009'), ('\u300a', '\u300a'), ('\u300b', '\u300b'), ('\u300c', '\u300c'), ('\u300d',
+        '\u300d'), ('\u300e', '\u300e'), ('\u300f', '\u300f'), ('\u3010', '\u3010'), ('\u3011',
+        '\u3011'), ('\u3012', '\u3013'), ('\u3014', '\u3014'), ('\u3015', '\u3015'), ('\u3016',
+        '\u3016'), ('\u3017', '\u3017'), ('\u3018', '\u3018'), ('\u3019', '\u3019'), ('\u301a',
+        '\u301a'), ('\u301b', '\u301b'), ('\u301c', '\u301c'), ('\u301d', '\u301d'), ('\u301e',
+        '\u301f'), ('\u3020', '\u3020'), ('\u3030', '\u3030'), ('\u3031', '\u3035'), ('\u3036',
+        '\u3037'), ('\u303c', '\u303c'), ('\u303d', '\u303d'), ('\u303e', '\u303f'), ('\u309b',
+        '\u309c'), ('\u30a0', '\u30a0'), ('\u30fb', '\u30fb'), ('\u30fc', '\u30fc'), ('\u3190',
+        '\u3191'), ('\u3192', '\u3195'), ('\u3196', '\u319f'), ('\u31c0', '\u31e3'), ('\u3220',
+        '\u3229'), ('\u322a', '\u3247'), ('\u3248', '\u324f'), ('\u3250', '\u3250'), ('\u3251',
+        '\u325f'), ('\u327f', '\u327f'), ('\u3280', '\u3289'), ('\u328a', '\u32b0'), ('\u32b1',
+        '\u32bf'), ('\u32c0', '\u32cf'), ('\u3358', '\u33ff'), ('\u4dc0', '\u4dff'), ('\ua700',
+        '\ua716'), ('\ua717', '\ua71f'), ('\ua720', '\ua721'), ('\ua788', '\ua788'), ('\ua789',
+        '\ua78a'), ('\ua830', '\ua835'), ('\ua836', '\ua837'), ('\ua838', '\ua838'), ('\ua839',
+        '\ua839'), ('\ua92e', '\ua92e'), ('\ua9cf', '\ua9cf'), ('\uab5b', '\uab5b'), ('\ufd3e',
+        '\ufd3e'), ('\ufd3f', '\ufd3f'), ('\ufe10', '\ufe16'), ('\ufe17', '\ufe17'), ('\ufe18',
+        '\ufe18'), ('\ufe19', '\ufe19'), ('\ufe30', '\ufe30'), ('\ufe31', '\ufe32'), ('\ufe33',
+        '\ufe34'), ('\ufe35', '\ufe35'), ('\ufe36', '\ufe36'), ('\ufe37', '\ufe37'), ('\ufe38',
+        '\ufe38'), ('\ufe39', '\ufe39'), ('\ufe3a', '\ufe3a'), ('\ufe3b', '\ufe3b'), ('\ufe3c',
+        '\ufe3c'), ('\ufe3d', '\ufe3d'), ('\ufe3e', '\ufe3e'), ('\ufe3f', '\ufe3f'), ('\ufe40',
+        '\ufe40'), ('\ufe41', '\ufe41'), ('\ufe42', '\ufe42'), ('\ufe43', '\ufe43'), ('\ufe44',
+        '\ufe44'), ('\ufe45', '\ufe46'), ('\ufe47', '\ufe47'), ('\ufe48', '\ufe48'), ('\ufe49',
+        '\ufe4c'), ('\ufe4d', '\ufe4f'), ('\ufe50', '\ufe52'), ('\ufe54', '\ufe57'), ('\ufe58',
+        '\ufe58'), ('\ufe59', '\ufe59'), ('\ufe5a', '\ufe5a'), ('\ufe5b', '\ufe5b'), ('\ufe5c',
+        '\ufe5c'), ('\ufe5d', '\ufe5d'), ('\ufe5e', '\ufe5e'), ('\ufe5f', '\ufe61'), ('\ufe62',
+        '\ufe62'), ('\ufe63', '\ufe63'), ('\ufe64', '\ufe66'), ('\ufe68', '\ufe68'), ('\ufe69',
+        '\ufe69'), ('\ufe6a', '\ufe6b'), ('\ufeff', '\ufeff'), ('\uff01', '\uff03'), ('\uff04',
+        '\uff04'), ('\uff05', '\uff07'), ('\uff08', '\uff08'), ('\uff09', '\uff09'), ('\uff0a',
+        '\uff0a'), ('\uff0b', '\uff0b'), ('\uff0c', '\uff0c'), ('\uff0d', '\uff0d'), ('\uff0e',
+        '\uff0f'), ('\uff10', '\uff19'), ('\uff1a', '\uff1b'), ('\uff1c', '\uff1e'), ('\uff1f',
+        '\uff20'), ('\uff3b', '\uff3b'), ('\uff3c', '\uff3c'), ('\uff3d', '\uff3d'), ('\uff3e',
+        '\uff3e'), ('\uff3f', '\uff3f'), ('\uff40', '\uff40'), ('\uff5b', '\uff5b'), ('\uff5c',
+        '\uff5c'), ('\uff5d', '\uff5d'), ('\uff5e', '\uff5e'), ('\uff5f', '\uff5f'), ('\uff60',
+        '\uff60'), ('\uff61', '\uff61'), ('\uff62', '\uff62'), ('\uff63', '\uff63'), ('\uff64',
+        '\uff65'), ('\uff70', '\uff70'), ('\uff9e', '\uff9f'), ('\uffe0', '\uffe1'), ('\uffe2',
+        '\uffe2'), ('\uffe3', '\uffe3'), ('\uffe4', '\uffe4'), ('\uffe5', '\uffe6'), ('\uffe8',
+        '\uffe8'), ('\uffe9', '\uffec'), ('\uffed', '\uffee'), ('\ufff9', '\ufffb'), ('\ufffc',
+        '\ufffd'), ('\U00010100', '\U00010102'), ('\U00010107', '\U00010133'), ('\U00010137',
+        '\U0001013f'), ('\U00010190', '\U0001019b'), ('\U000101d0', '\U000101fc'), ('\U000102e1',
+        '\U000102fb'), ('\U0001bca0', '\U0001bca3'), ('\U0001d000', '\U0001d0f5'), ('\U0001d100',
+        '\U0001d126'), ('\U0001d129', '\U0001d164'), ('\U0001d165', '\U0001d166'), ('\U0001d16a',
+        '\U0001d16c'), ('\U0001d16d', '\U0001d172'), ('\U0001d173', '\U0001d17a'), ('\U0001d183',
+        '\U0001d184'), ('\U0001d18c', '\U0001d1a9'), ('\U0001d1ae', '\U0001d1dd'), ('\U0001d300',
+        '\U0001d356'), ('\U0001d360', '\U0001d371'), ('\U0001d400', '\U0001d454'), ('\U0001d456',
+        '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5',
+        '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb',
+        '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'), ('\U0001d507',
+        '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'), ('\U0001d51e',
+        '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'), ('\U0001d546',
+        '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8',
+        '\U0001d6c0'), ('\U0001d6c1', '\U0001d6c1'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6db',
+        '\U0001d6db'), ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fb', '\U0001d6fb'), ('\U0001d6fc',
+        '\U0001d714'), ('\U0001d715', '\U0001d715'), ('\U0001d716', '\U0001d734'), ('\U0001d735',
+        '\U0001d735'), ('\U0001d736', '\U0001d74e'), ('\U0001d74f', '\U0001d74f'), ('\U0001d750',
+        '\U0001d76e'), ('\U0001d76f', '\U0001d76f'), ('\U0001d770', '\U0001d788'), ('\U0001d789',
+        '\U0001d789'), ('\U0001d78a', '\U0001d7a8'), ('\U0001d7a9', '\U0001d7a9'), ('\U0001d7aa',
+        '\U0001d7c2'), ('\U0001d7c3', '\U0001d7c3'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001d7ce',
+        '\U0001d7ff'), ('\U0001f000', '\U0001f02b'), ('\U0001f030', '\U0001f093'), ('\U0001f0a0',
+        '\U0001f0ae'), ('\U0001f0b1', '\U0001f0bf'), ('\U0001f0c1', '\U0001f0cf'), ('\U0001f0d1',
+        '\U0001f0f5'), ('\U0001f100', '\U0001f10c'), ('\U0001f110', '\U0001f12e'), ('\U0001f130',
+        '\U0001f16b'), ('\U0001f170', '\U0001f19a'), ('\U0001f1e6', '\U0001f1ff'), ('\U0001f201',
+        '\U0001f202'), ('\U0001f210', '\U0001f23a'), ('\U0001f240', '\U0001f248'), ('\U0001f250',
+        '\U0001f251'), ('\U0001f300', '\U0001f32c'), ('\U0001f330', '\U0001f37d'), ('\U0001f380',
+        '\U0001f3ce'), ('\U0001f3d4', '\U0001f3f7'), ('\U0001f400', '\U0001f4fe'), ('\U0001f500',
+        '\U0001f54a'), ('\U0001f550', '\U0001f579'), ('\U0001f57b', '\U0001f5a3'), ('\U0001f5a5',
+        '\U0001f642'), ('\U0001f645', '\U0001f6cf'), ('\U0001f6e0', '\U0001f6ec'), ('\U0001f6f0',
+        '\U0001f6f3'), ('\U0001f700', '\U0001f773'), ('\U0001f780', '\U0001f7d4'), ('\U0001f800',
+        '\U0001f80b'), ('\U0001f810', '\U0001f847'), ('\U0001f850', '\U0001f859'), ('\U0001f860',
+        '\U0001f887'), ('\U0001f890', '\U0001f8ad'), ('\U000e0001', '\U000e0001'), ('\U000e0020',
+        '\U000e007f')
+    ];
+
+    pub static Coptic_table: &'static [(char, char)] = &[
+        ('\u03e2', '\u03ef'), ('\u2c80', '\u2ce4'), ('\u2ce5', '\u2cea'), ('\u2ceb', '\u2cee'),
+        ('\u2cef', '\u2cf1'), ('\u2cf2', '\u2cf3'), ('\u2cf9', '\u2cfc'), ('\u2cfd', '\u2cfd'),
+        ('\u2cfe', '\u2cff')
+    ];
+
+    pub static Cuneiform_table: &'static [(char, char)] = &[
+        ('\U00012000', '\U00012398'), ('\U00012400', '\U0001246e'), ('\U00012470', '\U00012474')
+    ];
+
+    pub static Cypriot_table: &'static [(char, char)] = &[
+        ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
+        ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'), ('\U0001083f', '\U0001083f')
+    ];
+
+    pub static Cyrillic_table: &'static [(char, char)] = &[
+        ('\u0400', '\u0481'), ('\u0482', '\u0482'), ('\u0483', '\u0484'), ('\u0487', '\u0487'),
+        ('\u0488', '\u0489'), ('\u048a', '\u052f'), ('\u1d2b', '\u1d2b'), ('\u1d78', '\u1d78'),
+        ('\u2de0', '\u2dff'), ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'), ('\ua66f', '\ua66f'),
+        ('\ua670', '\ua672'), ('\ua673', '\ua673'), ('\ua674', '\ua67d'), ('\ua67e', '\ua67e'),
+        ('\ua67f', '\ua67f'), ('\ua680', '\ua69b'), ('\ua69c', '\ua69d'), ('\ua69f', '\ua69f')
+    ];
+
+    pub static Deseret_table: &'static [(char, char)] = &[
+        ('\U00010400', '\U0001044f')
+    ];
+
+    pub static Devanagari_table: &'static [(char, char)] = &[
+        ('\u0900', '\u0902'), ('\u0903', '\u0903'), ('\u0904', '\u0939'), ('\u093a', '\u093a'),
+        ('\u093b', '\u093b'), ('\u093c', '\u093c'), ('\u093d', '\u093d'), ('\u093e', '\u0940'),
+        ('\u0941', '\u0948'), ('\u0949', '\u094c'), ('\u094d', '\u094d'), ('\u094e', '\u094f'),
+        ('\u0950', '\u0950'), ('\u0953', '\u0957'), ('\u0958', '\u0961'), ('\u0962', '\u0963'),
+        ('\u0966', '\u096f'), ('\u0970', '\u0970'), ('\u0971', '\u0971'), ('\u0972', '\u097f'),
+        ('\ua8e0', '\ua8f1'), ('\ua8f2', '\ua8f7'), ('\ua8f8', '\ua8fa'), ('\ua8fb', '\ua8fb')
+    ];
+
+    pub static Duployan_table: &'static [(char, char)] = &[
+        ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80', '\U0001bc88'),
+        ('\U0001bc90', '\U0001bc99'), ('\U0001bc9c', '\U0001bc9c'), ('\U0001bc9d', '\U0001bc9e'),
+        ('\U0001bc9f', '\U0001bc9f')
+    ];
+
+    pub static Egyptian_Hieroglyphs_table: &'static [(char, char)] = &[
+        ('\U00013000', '\U0001342e')
+    ];
+
+    pub static Elbasan_table: &'static [(char, char)] = &[
+        ('\U00010500', '\U00010527')
+    ];
+
+    pub static Ethiopic_table: &'static [(char, char)] = &[
+        ('\u1200', '\u1248'), ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258', '\u1258'),
+        ('\u125a', '\u125d'), ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290', '\u12b0'),
+        ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'),
+        ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318', '\u135a'),
+        ('\u135d', '\u135f'), ('\u1360', '\u1368'), ('\u1369', '\u137c'), ('\u1380', '\u138f'),
+        ('\u1390', '\u1399'), ('\u2d80', '\u2d96'), ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'),
+        ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'),
+        ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
+        ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e')
+    ];
+
+    pub static Georgian_table: &'static [(char, char)] = &[
+        ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'),
+        ('\u10fc', '\u10fc'), ('\u10fd', '\u10ff'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'),
+        ('\u2d2d', '\u2d2d')
+    ];
+
+    pub static Glagolitic_table: &'static [(char, char)] = &[
+        ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e')
+    ];
+
+    pub static Gothic_table: &'static [(char, char)] = &[
+        ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'), ('\U00010342', '\U00010349'),
+        ('\U0001034a', '\U0001034a')
+    ];
+
+    pub static Grantha_table: &'static [(char, char)] = &[
+        ('\U00011301', '\U00011301'), ('\U00011302', '\U00011303'), ('\U00011305', '\U0001130c'),
+        ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'),
+        ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133c', '\U0001133c'),
+        ('\U0001133d', '\U0001133d'), ('\U0001133e', '\U0001133f'), ('\U00011340', '\U00011340'),
+        ('\U00011341', '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'),
+        ('\U00011357', '\U00011357'), ('\U0001135d', '\U00011361'), ('\U00011362', '\U00011363'),
+        ('\U00011366', '\U0001136c'), ('\U00011370', '\U00011374')
+    ];
+
+    pub static Greek_table: &'static [(char, char)] = &[
+        ('\u0370', '\u0373'), ('\u0375', '\u0375'), ('\u0376', '\u0377'), ('\u037a', '\u037a'),
+        ('\u037b', '\u037d'), ('\u037f', '\u037f'), ('\u0384', '\u0384'), ('\u0386', '\u0386'),
+        ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'), ('\u03a3', '\u03e1'),
+        ('\u03f0', '\u03f5'), ('\u03f6', '\u03f6'), ('\u03f7', '\u03ff'), ('\u1d26', '\u1d2a'),
+        ('\u1d5d', '\u1d61'), ('\u1d66', '\u1d6a'), ('\u1dbf', '\u1dbf'), ('\u1f00', '\u1f15'),
+        ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'), ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
+        ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
+        ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'), ('\u1fbd', '\u1fbd'), ('\u1fbe', '\u1fbe'),
+        ('\u1fbf', '\u1fc1'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fcd', '\u1fcf'),
+        ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fdb'), ('\u1fdd', '\u1fdf'), ('\u1fe0', '\u1fec'),
+        ('\u1fed', '\u1fef'), ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'), ('\u1ffd', '\u1ffe'),
+        ('\u2126', '\u2126'), ('\uab65', '\uab65'), ('\U00010140', '\U00010174'), ('\U00010175',
+        '\U00010178'), ('\U00010179', '\U00010189'), ('\U0001018a', '\U0001018b'), ('\U0001018c',
+        '\U0001018c'), ('\U000101a0', '\U000101a0'), ('\U0001d200', '\U0001d241'), ('\U0001d242',
+        '\U0001d244'), ('\U0001d245', '\U0001d245')
+    ];
+
+    pub static Gujarati_table: &'static [(char, char)] = &[
+        ('\u0a81', '\u0a82'), ('\u0a83', '\u0a83'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'),
+        ('\u0a93', '\u0aa8'), ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'),
+        ('\u0abc', '\u0abc'), ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'), ('\u0ac1', '\u0ac5'),
+        ('\u0ac7', '\u0ac8'), ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'), ('\u0acd', '\u0acd'),
+        ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0ae2', '\u0ae3'), ('\u0ae6', '\u0aef'),
+        ('\u0af0', '\u0af0'), ('\u0af1', '\u0af1')
+    ];
+
+    pub static Gurmukhi_table: &'static [(char, char)] = &[
+        ('\u0a01', '\u0a02'), ('\u0a03', '\u0a03'), ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'),
+        ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'),
+        ('\u0a38', '\u0a39'), ('\u0a3c', '\u0a3c'), ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
+        ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'), ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
+        ('\u0a5e', '\u0a5e'), ('\u0a66', '\u0a6f'), ('\u0a70', '\u0a71'), ('\u0a72', '\u0a74'),
+        ('\u0a75', '\u0a75')
+    ];
+
+    pub static Han_table: &'static [(char, char)] = &[
+        ('\u2e80', '\u2e99'), ('\u2e9b', '\u2ef3'), ('\u2f00', '\u2fd5'), ('\u3005', '\u3005'),
+        ('\u3007', '\u3007'), ('\u3021', '\u3029'), ('\u3038', '\u303a'), ('\u303b', '\u303b'),
+        ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'), ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
+        ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'),
+        ('\U0002f800', '\U0002fa1d')
+    ];
+
+    pub static Hangul_table: &'static [(char, char)] = &[
+        ('\u1100', '\u11ff'), ('\u302e', '\u302f'), ('\u3131', '\u318e'), ('\u3200', '\u321e'),
+        ('\u3260', '\u327e'), ('\ua960', '\ua97c'), ('\uac00', '\ud7a3'), ('\ud7b0', '\ud7c6'),
+        ('\ud7cb', '\ud7fb'), ('\uffa0', '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
+        ('\uffd2', '\uffd7'), ('\uffda', '\uffdc')
+    ];
+
+    pub static Hanunoo_table: &'static [(char, char)] = &[
+        ('\u1720', '\u1731'), ('\u1732', '\u1734')
+    ];
+
+    pub static Hebrew_table: &'static [(char, char)] = &[
+        ('\u0591', '\u05bd'), ('\u05be', '\u05be'), ('\u05bf', '\u05bf'), ('\u05c0', '\u05c0'),
+        ('\u05c1', '\u05c2'), ('\u05c3', '\u05c3'), ('\u05c4', '\u05c5'), ('\u05c6', '\u05c6'),
+        ('\u05c7', '\u05c7'), ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'), ('\u05f3', '\u05f4'),
+        ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'), ('\ufb1f', '\ufb28'), ('\ufb29', '\ufb29'),
+        ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'), ('\ufb40', '\ufb41'),
+        ('\ufb43', '\ufb44'), ('\ufb46', '\ufb4f')
+    ];
+
+    pub static Hiragana_table: &'static [(char, char)] = &[
+        ('\u3041', '\u3096'), ('\u309d', '\u309e'), ('\u309f', '\u309f'), ('\U0001b001',
+        '\U0001b001'), ('\U0001f200', '\U0001f200')
+    ];
+
+    pub static Imperial_Aramaic_table: &'static [(char, char)] = &[
+        ('\U00010840', '\U00010855'), ('\U00010857', '\U00010857'), ('\U00010858', '\U0001085f')
+    ];
+
+    pub static Inherited_table: &'static [(char, char)] = &[
+        ('\u0300', '\u036f'), ('\u0485', '\u0486'), ('\u064b', '\u0655'), ('\u0670', '\u0670'),
+        ('\u0951', '\u0952'), ('\u1ab0', '\u1abd'), ('\u1abe', '\u1abe'), ('\u1cd0', '\u1cd2'),
+        ('\u1cd4', '\u1ce0'), ('\u1ce2', '\u1ce8'), ('\u1ced', '\u1ced'), ('\u1cf4', '\u1cf4'),
+        ('\u1cf8', '\u1cf9'), ('\u1dc0', '\u1df5'), ('\u1dfc', '\u1dff'), ('\u200c', '\u200d'),
+        ('\u20d0', '\u20dc'), ('\u20dd', '\u20e0'), ('\u20e1', '\u20e1'), ('\u20e2', '\u20e4'),
+        ('\u20e5', '\u20f0'), ('\u302a', '\u302d'), ('\u3099', '\u309a'), ('\ufe00', '\ufe0f'),
+        ('\ufe20', '\ufe2d'), ('\U000101fd', '\U000101fd'), ('\U000102e0', '\U000102e0'),
+        ('\U0001d167', '\U0001d169'), ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'),
+        ('\U0001d1aa', '\U0001d1ad'), ('\U000e0100', '\U000e01ef')
+    ];
+
+    pub static Inscriptional_Pahlavi_table: &'static [(char, char)] = &[
+        ('\U00010b60', '\U00010b72'), ('\U00010b78', '\U00010b7f')
+    ];
+
+    pub static Inscriptional_Parthian_table: &'static [(char, char)] = &[
+        ('\U00010b40', '\U00010b55'), ('\U00010b58', '\U00010b5f')
+    ];
+
+    pub static Javanese_table: &'static [(char, char)] = &[
+        ('\ua980', '\ua982'), ('\ua983', '\ua983'), ('\ua984', '\ua9b2'), ('\ua9b3', '\ua9b3'),
+        ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'), ('\ua9ba', '\ua9bb'), ('\ua9bc', '\ua9bc'),
+        ('\ua9bd', '\ua9c0'), ('\ua9c1', '\ua9cd'), ('\ua9d0', '\ua9d9'), ('\ua9de', '\ua9df')
+    ];
+
+    pub static Kaithi_table: &'static [(char, char)] = &[
+        ('\U00011080', '\U00011081'), ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'),
+        ('\U000110b0', '\U000110b2'), ('\U000110b3', '\U000110b6'), ('\U000110b7', '\U000110b8'),
+        ('\U000110b9', '\U000110ba'), ('\U000110bb', '\U000110bc'), ('\U000110bd', '\U000110bd'),
+        ('\U000110be', '\U000110c1')
+    ];
+
+    pub static Kannada_table: &'static [(char, char)] = &[
+        ('\u0c81', '\u0c81'), ('\u0c82', '\u0c83'), ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'),
+        ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'), ('\u0cbc', '\u0cbc'),
+        ('\u0cbd', '\u0cbd'), ('\u0cbe', '\u0cbe'), ('\u0cbf', '\u0cbf'), ('\u0cc0', '\u0cc4'),
+        ('\u0cc6', '\u0cc6'), ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'), ('\u0ccc', '\u0ccd'),
+        ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0ce2', '\u0ce3'),
+        ('\u0ce6', '\u0cef'), ('\u0cf1', '\u0cf2')
+    ];
+
+    pub static Katakana_table: &'static [(char, char)] = &[
+        ('\u30a1', '\u30fa'), ('\u30fd', '\u30fe'), ('\u30ff', '\u30ff'), ('\u31f0', '\u31ff'),
+        ('\u32d0', '\u32fe'), ('\u3300', '\u3357'), ('\uff66', '\uff6f'), ('\uff71', '\uff9d'),
+        ('\U0001b000', '\U0001b000')
+    ];
+
+    pub static Kayah_Li_table: &'static [(char, char)] = &[
+        ('\ua900', '\ua909'), ('\ua90a', '\ua925'), ('\ua926', '\ua92d'), ('\ua92f', '\ua92f')
+    ];
+
+    pub static Kharoshthi_table: &'static [(char, char)] = &[
+        ('\U00010a00', '\U00010a00'), ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'),
+        ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'), ('\U00010a15', '\U00010a17'),
+        ('\U00010a19', '\U00010a33'), ('\U00010a38', '\U00010a3a'), ('\U00010a3f', '\U00010a3f'),
+        ('\U00010a40', '\U00010a47'), ('\U00010a50', '\U00010a58')
+    ];
+
+    pub static Khmer_table: &'static [(char, char)] = &[
+        ('\u1780', '\u17b3'), ('\u17b4', '\u17b5'), ('\u17b6', '\u17b6'), ('\u17b7', '\u17bd'),
+        ('\u17be', '\u17c5'), ('\u17c6', '\u17c6'), ('\u17c7', '\u17c8'), ('\u17c9', '\u17d3'),
+        ('\u17d4', '\u17d6'), ('\u17d7', '\u17d7'), ('\u17d8', '\u17da'), ('\u17db', '\u17db'),
+        ('\u17dc', '\u17dc'), ('\u17dd', '\u17dd'), ('\u17e0', '\u17e9'), ('\u17f0', '\u17f9'),
+        ('\u19e0', '\u19ff')
+    ];
+
+    pub static Khojki_table: &'static [(char, char)] = &[
+        ('\U00011200', '\U00011211'), ('\U00011213', '\U0001122b'), ('\U0001122c', '\U0001122e'),
+        ('\U0001122f', '\U00011231'), ('\U00011232', '\U00011233'), ('\U00011234', '\U00011234'),
+        ('\U00011235', '\U00011235'), ('\U00011236', '\U00011237'), ('\U00011238', '\U0001123d')
+    ];
+
+    pub static Khudawadi_table: &'static [(char, char)] = &[
+        ('\U000112b0', '\U000112de'), ('\U000112df', '\U000112df'), ('\U000112e0', '\U000112e2'),
+        ('\U000112e3', '\U000112ea'), ('\U000112f0', '\U000112f9')
+    ];
+
+    pub static Lao_table: &'static [(char, char)] = &[
+        ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
+        ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
+        ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
+        ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'), ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
+        ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0ec8', '\u0ecd'),
+        ('\u0ed0', '\u0ed9'), ('\u0edc', '\u0edf')
+    ];
+
+    pub static Latin_table: &'static [(char, char)] = &[
+        ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xba', '\xba'), ('\xc0', '\xd6'),
+        ('\xd8', '\xf6'), ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'), ('\u01c0',
+        '\u01c3'), ('\u01c4', '\u0293'), ('\u0294', '\u0294'), ('\u0295', '\u02af'), ('\u02b0',
+        '\u02b8'), ('\u02e0', '\u02e4'), ('\u1d00', '\u1d25'), ('\u1d2c', '\u1d5c'), ('\u1d62',
+        '\u1d65'), ('\u1d6b', '\u1d77'), ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbe'), ('\u1e00',
+        '\u1eff'), ('\u2071', '\u2071'), ('\u207f', '\u207f'), ('\u2090', '\u209c'), ('\u212a',
+        '\u212b'), ('\u2132', '\u2132'), ('\u214e', '\u214e'), ('\u2160', '\u2182'), ('\u2183',
+        '\u2184'), ('\u2185', '\u2188'), ('\u2c60', '\u2c7b'), ('\u2c7c', '\u2c7d'), ('\u2c7e',
+        '\u2c7f'), ('\ua722', '\ua76f'), ('\ua770', '\ua770'), ('\ua771', '\ua787'), ('\ua78b',
+        '\ua78e'), ('\ua790', '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\ua7f7', '\ua7f7'), ('\ua7f8',
+        '\ua7f9'), ('\ua7fa', '\ua7fa'), ('\ua7fb', '\ua7ff'), ('\uab30', '\uab5a'), ('\uab5c',
+        '\uab5f'), ('\uab64', '\uab64'), ('\ufb00', '\ufb06'), ('\uff21', '\uff3a'), ('\uff41',
+        '\uff5a')
+    ];
+
+    pub static Lepcha_table: &'static [(char, char)] = &[
+        ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'), ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
+        ('\u1c36', '\u1c37'), ('\u1c3b', '\u1c3f'), ('\u1c40', '\u1c49'), ('\u1c4d', '\u1c4f')
+    ];
+
+    pub static Limbu_table: &'static [(char, char)] = &[
+        ('\u1900', '\u191e'), ('\u1920', '\u1922'), ('\u1923', '\u1926'), ('\u1927', '\u1928'),
+        ('\u1929', '\u192b'), ('\u1930', '\u1931'), ('\u1932', '\u1932'), ('\u1933', '\u1938'),
+        ('\u1939', '\u193b'), ('\u1940', '\u1940'), ('\u1944', '\u1945'), ('\u1946', '\u194f')
+    ];
+
+    pub static Linear_A_table: &'static [(char, char)] = &[
+        ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'), ('\U00010760', '\U00010767')
+    ];
+
+    pub static Linear_B_table: &'static [(char, char)] = &[
+        ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'),
+        ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
+        ('\U00010080', '\U000100fa')
+    ];
+
+    pub static Lisu_table: &'static [(char, char)] = &[
+        ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'), ('\ua4fe', '\ua4ff')
+    ];
+
+    pub static Lycian_table: &'static [(char, char)] = &[
+        ('\U00010280', '\U0001029c')
+    ];
+
+    pub static Lydian_table: &'static [(char, char)] = &[
+        ('\U00010920', '\U00010939'), ('\U0001093f', '\U0001093f')
+    ];
+
+    pub static Mahajani_table: &'static [(char, char)] = &[
+        ('\U00011150', '\U00011172'), ('\U00011173', '\U00011173'), ('\U00011174', '\U00011175'),
+        ('\U00011176', '\U00011176')
+    ];
+
+    pub static Malayalam_table: &'static [(char, char)] = &[
+        ('\u0d01', '\u0d01'), ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'), ('\u0d0e', '\u0d10'),
+        ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'), ('\u0d41', '\u0d44'),
+        ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4c'), ('\u0d4d', '\u0d4d'), ('\u0d4e', '\u0d4e'),
+        ('\u0d57', '\u0d57'), ('\u0d60', '\u0d61'), ('\u0d62', '\u0d63'), ('\u0d66', '\u0d6f'),
+        ('\u0d70', '\u0d75'), ('\u0d79', '\u0d79'), ('\u0d7a', '\u0d7f')
+    ];
+
+    pub static Mandaic_table: &'static [(char, char)] = &[
+        ('\u0840', '\u0858'), ('\u0859', '\u085b'), ('\u085e', '\u085e')
+    ];
+
+    pub static Manichaean_table: &'static [(char, char)] = &[
+        ('\U00010ac0', '\U00010ac7'), ('\U00010ac8', '\U00010ac8'), ('\U00010ac9', '\U00010ae4'),
+        ('\U00010ae5', '\U00010ae6'), ('\U00010aeb', '\U00010aef'), ('\U00010af0', '\U00010af6')
+    ];
+
+    pub static Meetei_Mayek_table: &'static [(char, char)] = &[
+        ('\uaae0', '\uaaea'), ('\uaaeb', '\uaaeb'), ('\uaaec', '\uaaed'), ('\uaaee', '\uaaef'),
+        ('\uaaf0', '\uaaf1'), ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'), ('\uaaf5', '\uaaf5'),
+        ('\uaaf6', '\uaaf6'), ('\uabc0', '\uabe2'), ('\uabe3', '\uabe4'), ('\uabe5', '\uabe5'),
+        ('\uabe6', '\uabe7'), ('\uabe8', '\uabe8'), ('\uabe9', '\uabea'), ('\uabeb', '\uabeb'),
+        ('\uabec', '\uabec'), ('\uabed', '\uabed'), ('\uabf0', '\uabf9')
+    ];
+
+    pub static Mende_Kikakui_table: &'static [(char, char)] = &[
+        ('\U0001e800', '\U0001e8c4'), ('\U0001e8c7', '\U0001e8cf'), ('\U0001e8d0', '\U0001e8d6')
+    ];
+
+    pub static Meroitic_Cursive_table: &'static [(char, char)] = &[
+        ('\U000109a0', '\U000109b7'), ('\U000109be', '\U000109bf')
+    ];
+
+    pub static Meroitic_Hieroglyphs_table: &'static [(char, char)] = &[
+        ('\U00010980', '\U0001099f')
+    ];
+
+    pub static Miao_table: &'static [(char, char)] = &[
+        ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f51', '\U00016f7e'),
+        ('\U00016f8f', '\U00016f92'), ('\U00016f93', '\U00016f9f')
+    ];
+
+    pub static Modi_table: &'static [(char, char)] = &[
+        ('\U00011600', '\U0001162f'), ('\U00011630', '\U00011632'), ('\U00011633', '\U0001163a'),
+        ('\U0001163b', '\U0001163c'), ('\U0001163d', '\U0001163d'), ('\U0001163e', '\U0001163e'),
+        ('\U0001163f', '\U00011640'), ('\U00011641', '\U00011643'), ('\U00011644', '\U00011644'),
+        ('\U00011650', '\U00011659')
+    ];
+
+    pub static Mongolian_table: &'static [(char, char)] = &[
+        ('\u1800', '\u1801'), ('\u1804', '\u1804'), ('\u1806', '\u1806'), ('\u1807', '\u180a'),
+        ('\u180b', '\u180d'), ('\u180e', '\u180e'), ('\u1810', '\u1819'), ('\u1820', '\u1842'),
+        ('\u1843', '\u1843'), ('\u1844', '\u1877'), ('\u1880', '\u18a8'), ('\u18a9', '\u18a9'),
+        ('\u18aa', '\u18aa')
+    ];
+
+    pub static Mro_table: &'static [(char, char)] = &[
+        ('\U00016a40', '\U00016a5e'), ('\U00016a60', '\U00016a69'), ('\U00016a6e', '\U00016a6f')
+    ];
+
+    pub static Myanmar_table: &'static [(char, char)] = &[
+        ('\u1000', '\u102a'), ('\u102b', '\u102c'), ('\u102d', '\u1030'), ('\u1031', '\u1031'),
+        ('\u1032', '\u1037'), ('\u1038', '\u1038'), ('\u1039', '\u103a'), ('\u103b', '\u103c'),
+        ('\u103d', '\u103e'), ('\u103f', '\u103f'), ('\u1040', '\u1049'), ('\u104a', '\u104f'),
+        ('\u1050', '\u1055'), ('\u1056', '\u1057'), ('\u1058', '\u1059'), ('\u105a', '\u105d'),
+        ('\u105e', '\u1060'), ('\u1061', '\u1061'), ('\u1062', '\u1064'), ('\u1065', '\u1066'),
+        ('\u1067', '\u106d'), ('\u106e', '\u1070'), ('\u1071', '\u1074'), ('\u1075', '\u1081'),
+        ('\u1082', '\u1082'), ('\u1083', '\u1084'), ('\u1085', '\u1086'), ('\u1087', '\u108c'),
+        ('\u108d', '\u108d'), ('\u108e', '\u108e'), ('\u108f', '\u108f'), ('\u1090', '\u1099'),
+        ('\u109a', '\u109c'), ('\u109d', '\u109d'), ('\u109e', '\u109f'), ('\ua9e0', '\ua9e4'),
+        ('\ua9e5', '\ua9e5'), ('\ua9e6', '\ua9e6'), ('\ua9e7', '\ua9ef'), ('\ua9f0', '\ua9f9'),
+        ('\ua9fa', '\ua9fe'), ('\uaa60', '\uaa6f'), ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
+        ('\uaa77', '\uaa79'), ('\uaa7a', '\uaa7a'), ('\uaa7b', '\uaa7b'), ('\uaa7c', '\uaa7c'),
+        ('\uaa7d', '\uaa7d'), ('\uaa7e', '\uaa7f')
+    ];
+
+    pub static Nabataean_table: &'static [(char, char)] = &[
+        ('\U00010880', '\U0001089e'), ('\U000108a7', '\U000108af')
+    ];
+
+    pub static New_Tai_Lue_table: &'static [(char, char)] = &[
+        ('\u1980', '\u19ab'), ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'), ('\u19c8', '\u19c9'),
+        ('\u19d0', '\u19d9'), ('\u19da', '\u19da'), ('\u19de', '\u19df')
+    ];
+
+    pub static Nko_table: &'static [(char, char)] = &[
+        ('\u07c0', '\u07c9'), ('\u07ca', '\u07ea'), ('\u07eb', '\u07f3'), ('\u07f4', '\u07f5'),
+        ('\u07f6', '\u07f6'), ('\u07f7', '\u07f9'), ('\u07fa', '\u07fa')
+    ];
+
+    pub static Ogham_table: &'static [(char, char)] = &[
+        ('\u1680', '\u1680'), ('\u1681', '\u169a'), ('\u169b', '\u169b'), ('\u169c', '\u169c')
+    ];
+
+    pub static Ol_Chiki_table: &'static [(char, char)] = &[
+        ('\u1c50', '\u1c59'), ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'), ('\u1c7e', '\u1c7f')
+    ];
+
+    pub static Old_Italic_table: &'static [(char, char)] = &[
+        ('\U00010300', '\U0001031f'), ('\U00010320', '\U00010323')
+    ];
+
+    pub static Old_North_Arabian_table: &'static [(char, char)] = &[
+        ('\U00010a80', '\U00010a9c'), ('\U00010a9d', '\U00010a9f')
+    ];
+
+    pub static Old_Permic_table: &'static [(char, char)] = &[
+        ('\U00010350', '\U00010375'), ('\U00010376', '\U0001037a')
+    ];
+
+    pub static Old_Persian_table: &'static [(char, char)] = &[
+        ('\U000103a0', '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U000103d0', '\U000103d0'),
+        ('\U000103d1', '\U000103d5')
+    ];
+
+    pub static Old_South_Arabian_table: &'static [(char, char)] = &[
+        ('\U00010a60', '\U00010a7c'), ('\U00010a7d', '\U00010a7e'), ('\U00010a7f', '\U00010a7f')
+    ];
+
+    pub static Old_Turkic_table: &'static [(char, char)] = &[
+        ('\U00010c00', '\U00010c48')
+    ];
+
+    pub static Oriya_table: &'static [(char, char)] = &[
+        ('\u0b01', '\u0b01'), ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'),
+        ('\u0b13', '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'),
+        ('\u0b3c', '\u0b3c'), ('\u0b3d', '\u0b3d'), ('\u0b3e', '\u0b3e'), ('\u0b3f', '\u0b3f'),
+        ('\u0b40', '\u0b40'), ('\u0b41', '\u0b44'), ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4c'),
+        ('\u0b4d', '\u0b4d'), ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'), ('\u0b5c', '\u0b5d'),
+        ('\u0b5f', '\u0b61'), ('\u0b62', '\u0b63'), ('\u0b66', '\u0b6f'), ('\u0b70', '\u0b70'),
+        ('\u0b71', '\u0b71'), ('\u0b72', '\u0b77')
+    ];
+
+    pub static Osmanya_table: &'static [(char, char)] = &[
+        ('\U00010480', '\U0001049d'), ('\U000104a0', '\U000104a9')
+    ];
+
+    pub static Pahawh_Hmong_table: &'static [(char, char)] = &[
+        ('\U00016b00', '\U00016b2f'), ('\U00016b30', '\U00016b36'), ('\U00016b37', '\U00016b3b'),
+        ('\U00016b3c', '\U00016b3f'), ('\U00016b40', '\U00016b43'), ('\U00016b44', '\U00016b44'),
+        ('\U00016b45', '\U00016b45'), ('\U00016b50', '\U00016b59'), ('\U00016b5b', '\U00016b61'),
+        ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f')
+    ];
+
+    pub static Palmyrene_table: &'static [(char, char)] = &[
+        ('\U00010860', '\U00010876'), ('\U00010877', '\U00010878'), ('\U00010879', '\U0001087f')
+    ];
+
+    pub static Pau_Cin_Hau_table: &'static [(char, char)] = &[
+        ('\U00011ac0', '\U00011af8')
+    ];
+
+    pub static Phags_Pa_table: &'static [(char, char)] = &[
+        ('\ua840', '\ua873'), ('\ua874', '\ua877')
+    ];
+
+    pub static Phoenician_table: &'static [(char, char)] = &[
+        ('\U00010900', '\U00010915'), ('\U00010916', '\U0001091b'), ('\U0001091f', '\U0001091f')
+    ];
+
+    pub static Psalter_Pahlavi_table: &'static [(char, char)] = &[
+        ('\U00010b80', '\U00010b91'), ('\U00010b99', '\U00010b9c'), ('\U00010ba9', '\U00010baf')
+    ];
+
+    pub static Rejang_table: &'static [(char, char)] = &[
+        ('\ua930', '\ua946'), ('\ua947', '\ua951'), ('\ua952', '\ua953'), ('\ua95f', '\ua95f')
+    ];
+
+    pub static Runic_table: &'static [(char, char)] = &[
+        ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'), ('\u16f1', '\u16f8')
+    ];
+
+    pub static Samaritan_table: &'static [(char, char)] = &[
+        ('\u0800', '\u0815'), ('\u0816', '\u0819'), ('\u081a', '\u081a'), ('\u081b', '\u0823'),
+        ('\u0824', '\u0824'), ('\u0825', '\u0827'), ('\u0828', '\u0828'), ('\u0829', '\u082d'),
+        ('\u0830', '\u083e')
+    ];
+
+    pub static Saurashtra_table: &'static [(char, char)] = &[
+        ('\ua880', '\ua881'), ('\ua882', '\ua8b3'), ('\ua8b4', '\ua8c3'), ('\ua8c4', '\ua8c4'),
+        ('\ua8ce', '\ua8cf'), ('\ua8d0', '\ua8d9')
+    ];
+
+    pub static Sharada_table: &'static [(char, char)] = &[
+        ('\U00011180', '\U00011181'), ('\U00011182', '\U00011182'), ('\U00011183', '\U000111b2'),
+        ('\U000111b3', '\U000111b5'), ('\U000111b6', '\U000111be'), ('\U000111bf', '\U000111c0'),
+        ('\U000111c1', '\U000111c4'), ('\U000111c5', '\U000111c8'), ('\U000111cd', '\U000111cd'),
+        ('\U000111d0', '\U000111d9'), ('\U000111da', '\U000111da')
+    ];
+
+    pub static Shavian_table: &'static [(char, char)] = &[
+        ('\U00010450', '\U0001047f')
+    ];
+
+    pub static Siddham_table: &'static [(char, char)] = &[
+        ('\U00011580', '\U000115ae'), ('\U000115af', '\U000115b1'), ('\U000115b2', '\U000115b5'),
+        ('\U000115b8', '\U000115bb'), ('\U000115bc', '\U000115bd'), ('\U000115be', '\U000115be'),
+        ('\U000115bf', '\U000115c0'), ('\U000115c1', '\U000115c9')
+    ];
+
+    pub static Sinhala_table: &'static [(char, char)] = &[
+        ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
+        ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd1'),
+        ('\u0dd2', '\u0dd4'), ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'), ('\u0de6', '\u0def'),
+        ('\u0df2', '\u0df3'), ('\u0df4', '\u0df4'), ('\U000111e1', '\U000111f4')
+    ];
+
+    pub static Sora_Sompeng_table: &'static [(char, char)] = &[
+        ('\U000110d0', '\U000110e8'), ('\U000110f0', '\U000110f9')
+    ];
+
+    pub static Sundanese_table: &'static [(char, char)] = &[
+        ('\u1b80', '\u1b81'), ('\u1b82', '\u1b82'), ('\u1b83', '\u1ba0'), ('\u1ba1', '\u1ba1'),
+        ('\u1ba2', '\u1ba5'), ('\u1ba6', '\u1ba7'), ('\u1ba8', '\u1ba9'), ('\u1baa', '\u1baa'),
+        ('\u1bab', '\u1bad'), ('\u1bae', '\u1baf'), ('\u1bb0', '\u1bb9'), ('\u1bba', '\u1bbf'),
+        ('\u1cc0', '\u1cc7')
+    ];
+
+    pub static Syloti_Nagri_table: &'static [(char, char)] = &[
+        ('\ua800', '\ua801'), ('\ua802', '\ua802'), ('\ua803', '\ua805'), ('\ua806', '\ua806'),
+        ('\ua807', '\ua80a'), ('\ua80b', '\ua80b'), ('\ua80c', '\ua822'), ('\ua823', '\ua824'),
+        ('\ua825', '\ua826'), ('\ua827', '\ua827'), ('\ua828', '\ua82b')
+    ];
+
+    pub static Syriac_table: &'static [(char, char)] = &[
+        ('\u0700', '\u070d'), ('\u070f', '\u070f'), ('\u0710', '\u0710'), ('\u0711', '\u0711'),
+        ('\u0712', '\u072f'), ('\u0730', '\u074a'), ('\u074d', '\u074f')
+    ];
+
+    pub static Tagalog_table: &'static [(char, char)] = &[
+        ('\u1700', '\u170c'), ('\u170e', '\u1711'), ('\u1712', '\u1714')
+    ];
+
+    pub static Tagbanwa_table: &'static [(char, char)] = &[
+        ('\u1760', '\u176c'), ('\u176e', '\u1770'), ('\u1772', '\u1773')
+    ];
+
+    pub static Tai_Le_table: &'static [(char, char)] = &[
+        ('\u1950', '\u196d'), ('\u1970', '\u1974')
+    ];
+
+    pub static Tai_Tham_table: &'static [(char, char)] = &[
+        ('\u1a20', '\u1a54'), ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'), ('\u1a57', '\u1a57'),
+        ('\u1a58', '\u1a5e'), ('\u1a60', '\u1a60'), ('\u1a61', '\u1a61'), ('\u1a62', '\u1a62'),
+        ('\u1a63', '\u1a64'), ('\u1a65', '\u1a6c'), ('\u1a6d', '\u1a72'), ('\u1a73', '\u1a7c'),
+        ('\u1a7f', '\u1a7f'), ('\u1a80', '\u1a89'), ('\u1a90', '\u1a99'), ('\u1aa0', '\u1aa6'),
+        ('\u1aa7', '\u1aa7'), ('\u1aa8', '\u1aad')
+    ];
+
+    pub static Tai_Viet_table: &'static [(char, char)] = &[
+        ('\uaa80', '\uaaaf'), ('\uaab0', '\uaab0'), ('\uaab1', '\uaab1'), ('\uaab2', '\uaab4'),
+        ('\uaab5', '\uaab6'), ('\uaab7', '\uaab8'), ('\uaab9', '\uaabd'), ('\uaabe', '\uaabf'),
+        ('\uaac0', '\uaac0'), ('\uaac1', '\uaac1'), ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
+        ('\uaadd', '\uaadd'), ('\uaade', '\uaadf')
+    ];
+
+    pub static Takri_table: &'static [(char, char)] = &[
+        ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'), ('\U000116ac', '\U000116ac'),
+        ('\U000116ad', '\U000116ad'), ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
+        ('\U000116b6', '\U000116b6'), ('\U000116b7', '\U000116b7'), ('\U000116c0', '\U000116c9')
+    ];
+
+    pub static Tamil_table: &'static [(char, char)] = &[
+        ('\u0b82', '\u0b82'), ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'),
+        ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'),
+        ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bbe', '\u0bbf'),
+        ('\u0bc0', '\u0bc0'), ('\u0bc1', '\u0bc2'), ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcc'),
+        ('\u0bcd', '\u0bcd'), ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'), ('\u0be6', '\u0bef'),
+        ('\u0bf0', '\u0bf2'), ('\u0bf3', '\u0bf8'), ('\u0bf9', '\u0bf9'), ('\u0bfa', '\u0bfa')
+    ];
+
+    pub static Telugu_table: &'static [(char, char)] = &[
+        ('\u0c00', '\u0c00'), ('\u0c01', '\u0c03'), ('\u0c05', '\u0c0c'), ('\u0c0e', '\u0c10'),
+        ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d', '\u0c3d'), ('\u0c3e', '\u0c40'),
+        ('\u0c41', '\u0c44'), ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'), ('\u0c55', '\u0c56'),
+        ('\u0c58', '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c62', '\u0c63'), ('\u0c66', '\u0c6f'),
+        ('\u0c78', '\u0c7e'), ('\u0c7f', '\u0c7f')
+    ];
+
+    pub static Thaana_table: &'static [(char, char)] = &[
+        ('\u0780', '\u07a5'), ('\u07a6', '\u07b0'), ('\u07b1', '\u07b1')
+    ];
+
+    pub static Thai_table: &'static [(char, char)] = &[
+        ('\u0e01', '\u0e30'), ('\u0e31', '\u0e31'), ('\u0e32', '\u0e33'), ('\u0e34', '\u0e3a'),
+        ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'), ('\u0e47', '\u0e4e'), ('\u0e4f', '\u0e4f'),
+        ('\u0e50', '\u0e59'), ('\u0e5a', '\u0e5b')
+    ];
+
+    pub static Tibetan_table: &'static [(char, char)] = &[
+        ('\u0f00', '\u0f00'), ('\u0f01', '\u0f03'), ('\u0f04', '\u0f12'), ('\u0f13', '\u0f13'),
+        ('\u0f14', '\u0f14'), ('\u0f15', '\u0f17'), ('\u0f18', '\u0f19'), ('\u0f1a', '\u0f1f'),
+        ('\u0f20', '\u0f29'), ('\u0f2a', '\u0f33'), ('\u0f34', '\u0f34'), ('\u0f35', '\u0f35'),
+        ('\u0f36', '\u0f36'), ('\u0f37', '\u0f37'), ('\u0f38', '\u0f38'), ('\u0f39', '\u0f39'),
+        ('\u0f3a', '\u0f3a'), ('\u0f3b', '\u0f3b'), ('\u0f3c', '\u0f3c'), ('\u0f3d', '\u0f3d'),
+        ('\u0f3e', '\u0f3f'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'), ('\u0f71', '\u0f7e'),
+        ('\u0f7f', '\u0f7f'), ('\u0f80', '\u0f84'), ('\u0f85', '\u0f85'), ('\u0f86', '\u0f87'),
+        ('\u0f88', '\u0f8c'), ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'), ('\u0fbe', '\u0fc5'),
+        ('\u0fc6', '\u0fc6'), ('\u0fc7', '\u0fcc'), ('\u0fce', '\u0fcf'), ('\u0fd0', '\u0fd4'),
+        ('\u0fd9', '\u0fda')
+    ];
+
+    pub static Tifinagh_table: &'static [(char, char)] = &[
+        ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'), ('\u2d70', '\u2d70'), ('\u2d7f', '\u2d7f')
+    ];
+
+    pub static Tirhuta_table: &'static [(char, char)] = &[
+        ('\U00011480', '\U000114af'), ('\U000114b0', '\U000114b2'), ('\U000114b3', '\U000114b8'),
+        ('\U000114b9', '\U000114b9'), ('\U000114ba', '\U000114ba'), ('\U000114bb', '\U000114be'),
+        ('\U000114bf', '\U000114c0'), ('\U000114c1', '\U000114c1'), ('\U000114c2', '\U000114c3'),
+        ('\U000114c4', '\U000114c5'), ('\U000114c6', '\U000114c6'), ('\U000114c7', '\U000114c7'),
+        ('\U000114d0', '\U000114d9')
+    ];
+
+    pub static Ugaritic_table: &'static [(char, char)] = &[
+        ('\U00010380', '\U0001039d'), ('\U0001039f', '\U0001039f')
+    ];
+
+    pub static Vai_table: &'static [(char, char)] = &[
+        ('\ua500', '\ua60b'), ('\ua60c', '\ua60c'), ('\ua60d', '\ua60f'), ('\ua610', '\ua61f'),
+        ('\ua620', '\ua629'), ('\ua62a', '\ua62b')
+    ];
+
+    pub static Warang_Citi_table: &'static [(char, char)] = &[
+        ('\U000118a0', '\U000118df'), ('\U000118e0', '\U000118e9'), ('\U000118ea', '\U000118f2'),
+        ('\U000118ff', '\U000118ff')
+    ];
+
+    pub static Yi_table: &'static [(char, char)] = &[
+        ('\ua000', '\ua014'), ('\ua015', '\ua015'), ('\ua016', '\ua48c'), ('\ua490', '\ua4c6')
+    ];
+
+}
+
+pub mod property {
+    pub static Join_Control_table: &'static [(char, char)] = &[
+        ('\u200c', '\u200d')
+    ];
+
+    pub static White_Space_table: &'static [(char, char)] = &[
+        ('\x09', '\x0d'), ('\x20', '\x20'), ('\x85', '\x85'), ('\xa0', '\xa0'), ('\u1680',
+        '\u1680'), ('\u2000', '\u200a'), ('\u2028', '\u2028'), ('\u2029', '\u2029'), ('\u202f',
+        '\u202f'), ('\u205f', '\u205f'), ('\u3000', '\u3000')
+    ];
+
+    pub fn White_Space(c: char) -> bool {
+        super::bsearch_range_table(c, White_Space_table)
+    }
+
+}
+
+pub mod regex {
+    pub static UNICODE_CLASSES: &'static [(&'static str, &'static [(char, char)])] = &[
+        ("Alphabetic", super::derived_property::Alphabetic_table), ("Arabic",
+        super::script::Arabic_table), ("Armenian", super::script::Armenian_table), ("Avestan",
+        super::script::Avestan_table), ("Balinese", super::script::Balinese_table), ("Bamum",
+        super::script::Bamum_table), ("Bassa_Vah", super::script::Bassa_Vah_table), ("Batak",
+        super::script::Batak_table), ("Bengali", super::script::Bengali_table), ("Bopomofo",
+        super::script::Bopomofo_table), ("Brahmi", super::script::Brahmi_table), ("Braille",
+        super::script::Braille_table), ("Buginese", super::script::Buginese_table), ("Buhid",
+        super::script::Buhid_table), ("C", super::general_category::C_table),
+        ("Canadian_Aboriginal", super::script::Canadian_Aboriginal_table), ("Carian",
+        super::script::Carian_table), ("Caucasian_Albanian",
+        super::script::Caucasian_Albanian_table), ("Cc", super::general_category::Cc_table), ("Cf",
+        super::general_category::Cf_table), ("Chakma", super::script::Chakma_table), ("Cham",
+        super::script::Cham_table), ("Cherokee", super::script::Cherokee_table), ("Co",
+        super::general_category::Co_table), ("Common", super::script::Common_table), ("Coptic",
+        super::script::Coptic_table), ("Cuneiform", super::script::Cuneiform_table), ("Cypriot",
+        super::script::Cypriot_table), ("Cyrillic", super::script::Cyrillic_table), ("Deseret",
+        super::script::Deseret_table), ("Devanagari", super::script::Devanagari_table), ("Duployan",
+        super::script::Duployan_table), ("Egyptian_Hieroglyphs",
+        super::script::Egyptian_Hieroglyphs_table), ("Elbasan", super::script::Elbasan_table),
+        ("Ethiopic", super::script::Ethiopic_table), ("Georgian", super::script::Georgian_table),
+        ("Glagolitic", super::script::Glagolitic_table), ("Gothic", super::script::Gothic_table),
+        ("Grantha", super::script::Grantha_table), ("Greek", super::script::Greek_table),
+        ("Gujarati", super::script::Gujarati_table), ("Gurmukhi", super::script::Gurmukhi_table),
+        ("Han", super::script::Han_table), ("Hangul", super::script::Hangul_table), ("Hanunoo",
+        super::script::Hanunoo_table), ("Hebrew", super::script::Hebrew_table), ("Hiragana",
+        super::script::Hiragana_table), ("Imperial_Aramaic", super::script::Imperial_Aramaic_table),
+        ("Inherited", super::script::Inherited_table), ("Inscriptional_Pahlavi",
+        super::script::Inscriptional_Pahlavi_table), ("Inscriptional_Parthian",
+        super::script::Inscriptional_Parthian_table), ("Javanese", super::script::Javanese_table),
+        ("Join_Control", super::property::Join_Control_table), ("Kaithi",
+        super::script::Kaithi_table), ("Kannada", super::script::Kannada_table), ("Katakana",
+        super::script::Katakana_table), ("Kayah_Li", super::script::Kayah_Li_table), ("Kharoshthi",
+        super::script::Kharoshthi_table), ("Khmer", super::script::Khmer_table), ("Khojki",
+        super::script::Khojki_table), ("Khudawadi", super::script::Khudawadi_table), ("L",
+        super::general_category::L_table), ("LC", super::general_category::LC_table), ("Lao",
+        super::script::Lao_table), ("Latin", super::script::Latin_table), ("Lepcha",
+        super::script::Lepcha_table), ("Limbu", super::script::Limbu_table), ("Linear_A",
+        super::script::Linear_A_table), ("Linear_B", super::script::Linear_B_table), ("Lisu",
+        super::script::Lisu_table), ("Ll", super::general_category::Ll_table), ("Lm",
+        super::general_category::Lm_table), ("Lo", super::general_category::Lo_table), ("Lowercase",
+        super::derived_property::Lowercase_table), ("Lt", super::general_category::Lt_table), ("Lu",
+        super::general_category::Lu_table), ("Lycian", super::script::Lycian_table), ("Lydian",
+        super::script::Lydian_table), ("M", super::general_category::M_table), ("Mahajani",
+        super::script::Mahajani_table), ("Malayalam", super::script::Malayalam_table), ("Mandaic",
+        super::script::Mandaic_table), ("Manichaean", super::script::Manichaean_table), ("Mc",
+        super::general_category::Mc_table), ("Me", super::general_category::Me_table),
+        ("Meetei_Mayek", super::script::Meetei_Mayek_table), ("Mende_Kikakui",
+        super::script::Mende_Kikakui_table), ("Meroitic_Cursive",
+        super::script::Meroitic_Cursive_table), ("Meroitic_Hieroglyphs",
+        super::script::Meroitic_Hieroglyphs_table), ("Miao", super::script::Miao_table), ("Mn",
+        super::general_category::Mn_table), ("Modi", super::script::Modi_table), ("Mongolian",
+        super::script::Mongolian_table), ("Mro", super::script::Mro_table), ("Myanmar",
+        super::script::Myanmar_table), ("N", super::general_category::N_table), ("Nabataean",
+        super::script::Nabataean_table), ("Nd", super::general_category::Nd_table), ("New_Tai_Lue",
+        super::script::New_Tai_Lue_table), ("Nko", super::script::Nko_table), ("Nl",
+        super::general_category::Nl_table), ("No", super::general_category::No_table), ("Ogham",
+        super::script::Ogham_table), ("Ol_Chiki", super::script::Ol_Chiki_table), ("Old_Italic",
+        super::script::Old_Italic_table), ("Old_North_Arabian",
+        super::script::Old_North_Arabian_table), ("Old_Permic", super::script::Old_Permic_table),
+        ("Old_Persian", super::script::Old_Persian_table), ("Old_South_Arabian",
+        super::script::Old_South_Arabian_table), ("Old_Turkic", super::script::Old_Turkic_table),
+        ("Oriya", super::script::Oriya_table), ("Osmanya", super::script::Osmanya_table), ("P",
+        super::general_category::P_table), ("Pahawh_Hmong", super::script::Pahawh_Hmong_table),
+        ("Palmyrene", super::script::Palmyrene_table), ("Pau_Cin_Hau",
+        super::script::Pau_Cin_Hau_table), ("Pc", super::general_category::Pc_table), ("Pd",
+        super::general_category::Pd_table), ("Pe", super::general_category::Pe_table), ("Pf",
+        super::general_category::Pf_table), ("Phags_Pa", super::script::Phags_Pa_table),
+        ("Phoenician", super::script::Phoenician_table), ("Pi", super::general_category::Pi_table),
+        ("Po", super::general_category::Po_table), ("Ps", super::general_category::Ps_table),
+        ("Psalter_Pahlavi", super::script::Psalter_Pahlavi_table), ("Rejang",
+        super::script::Rejang_table), ("Runic", super::script::Runic_table), ("S",
+        super::general_category::S_table), ("Samaritan", super::script::Samaritan_table),
+        ("Saurashtra", super::script::Saurashtra_table), ("Sc", super::general_category::Sc_table),
+        ("Sharada", super::script::Sharada_table), ("Shavian", super::script::Shavian_table),
+        ("Siddham", super::script::Siddham_table), ("Sinhala", super::script::Sinhala_table), ("Sk",
+        super::general_category::Sk_table), ("Sm", super::general_category::Sm_table), ("So",
+        super::general_category::So_table), ("Sora_Sompeng", super::script::Sora_Sompeng_table),
+        ("Sundanese", super::script::Sundanese_table), ("Syloti_Nagri",
+        super::script::Syloti_Nagri_table), ("Syriac", super::script::Syriac_table), ("Tagalog",
+        super::script::Tagalog_table), ("Tagbanwa", super::script::Tagbanwa_table), ("Tai_Le",
+        super::script::Tai_Le_table), ("Tai_Tham", super::script::Tai_Tham_table), ("Tai_Viet",
+        super::script::Tai_Viet_table), ("Takri", super::script::Takri_table), ("Tamil",
+        super::script::Tamil_table), ("Telugu", super::script::Telugu_table), ("Thaana",
+        super::script::Thaana_table), ("Thai", super::script::Thai_table), ("Tibetan",
+        super::script::Tibetan_table), ("Tifinagh", super::script::Tifinagh_table), ("Tirhuta",
+        super::script::Tirhuta_table), ("Ugaritic", super::script::Ugaritic_table), ("Uppercase",
+        super::derived_property::Uppercase_table), ("Vai", super::script::Vai_table),
+        ("Warang_Citi", super::script::Warang_Citi_table), ("White_Space",
+        super::property::White_Space_table), ("XID_Continue",
+        super::derived_property::XID_Continue_table), ("XID_Start",
+        super::derived_property::XID_Start_table), ("Yi", super::script::Yi_table), ("Z",
+        super::general_category::Z_table), ("Zl", super::general_category::Zl_table), ("Zp",
+        super::general_category::Zp_table), ("Zs", super::general_category::Zs_table)
+    ];
+
+    pub static PERLD: &'static [(char, char)] = super::general_category::Nd_table;
+
+    pub static PERLS: &'static [(char, char)] = super::property::White_Space_table;
+
+    pub static PERLW: &'static [(char, char)] = &[
+        ('\x30', '\x39'), ('\x41', '\x5a'), ('\x5f', '\x5f'), ('\x61', '\x7a'), ('\xaa', '\xaa'),
+        ('\xb5', '\xb5'), ('\xba', '\xba'), ('\xc0', '\xd6'), ('\xd8', '\xf6'), ('\xf8', '\u02c1'),
+        ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'), ('\u02ee', '\u02ee'),
+        ('\u0300', '\u0374'), ('\u0376', '\u0377'), ('\u037a', '\u037d'), ('\u037f', '\u037f'),
+        ('\u0386', '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'),
+        ('\u03a3', '\u03f5'), ('\u03f7', '\u0481'), ('\u0483', '\u052f'), ('\u0531', '\u0556'),
+        ('\u0559', '\u0559'), ('\u0561', '\u0587'), ('\u0591', '\u05bd'), ('\u05bf', '\u05bf'),
+        ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u05d0', '\u05ea'),
+        ('\u05f0', '\u05f2'), ('\u0610', '\u061a'), ('\u0620', '\u0669'), ('\u066e', '\u06d3'),
+        ('\u06d5', '\u06dc'), ('\u06df', '\u06e8'), ('\u06ea', '\u06fc'), ('\u06ff', '\u06ff'),
+        ('\u0710', '\u074a'), ('\u074d', '\u07b1'), ('\u07c0', '\u07f5'), ('\u07fa', '\u07fa'),
+        ('\u0800', '\u082d'), ('\u0840', '\u085b'), ('\u08a0', '\u08b2'), ('\u08e4', '\u0963'),
+        ('\u0966', '\u096f'), ('\u0971', '\u0983'), ('\u0985', '\u098c'), ('\u098f', '\u0990'),
+        ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
+        ('\u09bc', '\u09c4'), ('\u09c7', '\u09c8'), ('\u09cb', '\u09ce'), ('\u09d7', '\u09d7'),
+        ('\u09dc', '\u09dd'), ('\u09df', '\u09e3'), ('\u09e6', '\u09f1'), ('\u0a01', '\u0a03'),
+        ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'),
+        ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'), ('\u0a3c', '\u0a3c'),
+        ('\u0a3e', '\u0a42'), ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'), ('\u0a51', '\u0a51'),
+        ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'), ('\u0a66', '\u0a75'), ('\u0a81', '\u0a83'),
+        ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa', '\u0ab0'),
+        ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abc', '\u0ac5'), ('\u0ac7', '\u0ac9'),
+        ('\u0acb', '\u0acd'), ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae3'), ('\u0ae6', '\u0aef'),
+        ('\u0b01', '\u0b03'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'),
+        ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'), ('\u0b3c', '\u0b44'),
+        ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4d'), ('\u0b56', '\u0b57'), ('\u0b5c', '\u0b5d'),
+        ('\u0b5f', '\u0b63'), ('\u0b66', '\u0b6f'), ('\u0b71', '\u0b71'), ('\u0b82', '\u0b83'),
+        ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'),
+        ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'),
+        ('\u0bae', '\u0bb9'), ('\u0bbe', '\u0bc2'), ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcd'),
+        ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'), ('\u0be6', '\u0bef'), ('\u0c00', '\u0c03'),
+        ('\u0c05', '\u0c0c'), ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'),
+        ('\u0c3d', '\u0c44'), ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'), ('\u0c55', '\u0c56'),
+        ('\u0c58', '\u0c59'), ('\u0c60', '\u0c63'), ('\u0c66', '\u0c6f'), ('\u0c81', '\u0c83'),
+        ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'), ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'),
+        ('\u0cb5', '\u0cb9'), ('\u0cbc', '\u0cc4'), ('\u0cc6', '\u0cc8'), ('\u0cca', '\u0ccd'),
+        ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce3'), ('\u0ce6', '\u0cef'),
+        ('\u0cf1', '\u0cf2'), ('\u0d01', '\u0d03'), ('\u0d05', '\u0d0c'), ('\u0d0e', '\u0d10'),
+        ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d44'), ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4e'),
+        ('\u0d57', '\u0d57'), ('\u0d60', '\u0d63'), ('\u0d66', '\u0d6f'), ('\u0d7a', '\u0d7f'),
+        ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
+        ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd4'),
+        ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'), ('\u0de6', '\u0def'), ('\u0df2', '\u0df3'),
+        ('\u0e01', '\u0e3a'), ('\u0e40', '\u0e4e'), ('\u0e50', '\u0e59'), ('\u0e81', '\u0e82'),
+        ('\u0e84', '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'),
+        ('\u0e94', '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'),
+        ('\u0ea7', '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb9'), ('\u0ebb', '\u0ebd'),
+        ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0ec8', '\u0ecd'), ('\u0ed0', '\u0ed9'),
+        ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'), ('\u0f18', '\u0f19'), ('\u0f20', '\u0f29'),
+        ('\u0f35', '\u0f35'), ('\u0f37', '\u0f37'), ('\u0f39', '\u0f39'), ('\u0f3e', '\u0f47'),
+        ('\u0f49', '\u0f6c'), ('\u0f71', '\u0f84'), ('\u0f86', '\u0f97'), ('\u0f99', '\u0fbc'),
+        ('\u0fc6', '\u0fc6'), ('\u1000', '\u1049'), ('\u1050', '\u109d'), ('\u10a0', '\u10c5'),
+        ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'), ('\u10fc', '\u1248'),
+        ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258', '\u1258'), ('\u125a', '\u125d'),
+        ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'),
+        ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'),
+        ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318', '\u135a'), ('\u135d', '\u135f'),
+        ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401', '\u166c'), ('\u166f', '\u167f'),
+        ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16ee', '\u16f8'), ('\u1700', '\u170c'),
+        ('\u170e', '\u1714'), ('\u1720', '\u1734'), ('\u1740', '\u1753'), ('\u1760', '\u176c'),
+        ('\u176e', '\u1770'), ('\u1772', '\u1773'), ('\u1780', '\u17d3'), ('\u17d7', '\u17d7'),
+        ('\u17dc', '\u17dd'), ('\u17e0', '\u17e9'), ('\u180b', '\u180d'), ('\u1810', '\u1819'),
+        ('\u1820', '\u1877'), ('\u1880', '\u18aa'), ('\u18b0', '\u18f5'), ('\u1900', '\u191e'),
+        ('\u1920', '\u192b'), ('\u1930', '\u193b'), ('\u1946', '\u196d'), ('\u1970', '\u1974'),
+        ('\u1980', '\u19ab'), ('\u19b0', '\u19c9'), ('\u19d0', '\u19d9'), ('\u1a00', '\u1a1b'),
+        ('\u1a20', '\u1a5e'), ('\u1a60', '\u1a7c'), ('\u1a7f', '\u1a89'), ('\u1a90', '\u1a99'),
+        ('\u1aa7', '\u1aa7'), ('\u1ab0', '\u1abe'), ('\u1b00', '\u1b4b'), ('\u1b50', '\u1b59'),
+        ('\u1b6b', '\u1b73'), ('\u1b80', '\u1bf3'), ('\u1c00', '\u1c37'), ('\u1c40', '\u1c49'),
+        ('\u1c4d', '\u1c7d'), ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1cf6'), ('\u1cf8', '\u1cf9'),
+        ('\u1d00', '\u1df5'), ('\u1dfc', '\u1f15'), ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
+        ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
+        ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
+        ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
+        ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
+        ('\u200c', '\u200d'), ('\u203f', '\u2040'), ('\u2054', '\u2054'), ('\u2071', '\u2071'),
+        ('\u207f', '\u207f'), ('\u2090', '\u209c'), ('\u20d0', '\u20f0'), ('\u2102', '\u2102'),
+        ('\u2107', '\u2107'), ('\u210a', '\u2113'), ('\u2115', '\u2115'), ('\u2119', '\u211d'),
+        ('\u2124', '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'),
+        ('\u212f', '\u2139'), ('\u213c', '\u213f'), ('\u2145', '\u2149'), ('\u214e', '\u214e'),
+        ('\u2160', '\u2188'), ('\u24b6', '\u24e9'), ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'),
+        ('\u2c60', '\u2ce4'), ('\u2ceb', '\u2cf3'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'),
+        ('\u2d2d', '\u2d2d'), ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'), ('\u2d7f', '\u2d96'),
+        ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'),
+        ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'),
+        ('\u2de0', '\u2dff'), ('\u2e2f', '\u2e2f'), ('\u3005', '\u3007'), ('\u3021', '\u302f'),
+        ('\u3031', '\u3035'), ('\u3038', '\u303c'), ('\u3041', '\u3096'), ('\u3099', '\u309a'),
+        ('\u309d', '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30ff'), ('\u3105', '\u312d'),
+        ('\u3131', '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400', '\u4db5'),
+        ('\u4e00', '\u9fcc'), ('\ua000', '\ua48c'), ('\ua4d0', '\ua4fd'), ('\ua500', '\ua60c'),
+        ('\ua610', '\ua62b'), ('\ua640', '\ua672'), ('\ua674', '\ua67d'), ('\ua67f', '\ua69d'),
+        ('\ua69f', '\ua6f1'), ('\ua717', '\ua71f'), ('\ua722', '\ua788'), ('\ua78b', '\ua78e'),
+        ('\ua790', '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\ua7f7', '\ua827'), ('\ua840', '\ua873'),
+        ('\ua880', '\ua8c4'), ('\ua8d0', '\ua8d9'), ('\ua8e0', '\ua8f7'), ('\ua8fb', '\ua8fb'),
+        ('\ua900', '\ua92d'), ('\ua930', '\ua953'), ('\ua960', '\ua97c'), ('\ua980', '\ua9c0'),
+        ('\ua9cf', '\ua9d9'), ('\ua9e0', '\ua9fe'), ('\uaa00', '\uaa36'), ('\uaa40', '\uaa4d'),
+        ('\uaa50', '\uaa59'), ('\uaa60', '\uaa76'), ('\uaa7a', '\uaac2'), ('\uaadb', '\uaadd'),
+        ('\uaae0', '\uaaef'), ('\uaaf2', '\uaaf6'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
+        ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e'), ('\uab30', '\uab5a'),
+        ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\uabc0', '\uabea'), ('\uabec', '\uabed'),
+        ('\uabf0', '\uabf9'), ('\uac00', '\ud7a3'), ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'),
+        ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'),
+        ('\ufb1d', '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
+        ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufd3d'),
+        ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdfb'), ('\ufe00', '\ufe0f'),
+        ('\ufe20', '\ufe2d'), ('\ufe33', '\ufe34'), ('\ufe4d', '\ufe4f'), ('\ufe70', '\ufe74'),
+        ('\ufe76', '\ufefc'), ('\uff10', '\uff19'), ('\uff21', '\uff3a'), ('\uff3f', '\uff3f'),
+        ('\uff41', '\uff5a'), ('\uff66', '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
+        ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'), ('\U00010000', '\U0001000b'), ('\U0001000d',
+        '\U00010026'), ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'), ('\U0001003f',
+        '\U0001004d'), ('\U00010050', '\U0001005d'), ('\U00010080', '\U000100fa'), ('\U00010140',
+        '\U00010174'), ('\U000101fd', '\U000101fd'), ('\U00010280', '\U0001029c'), ('\U000102a0',
+        '\U000102d0'), ('\U000102e0', '\U000102e0'), ('\U00010300', '\U0001031f'), ('\U00010330',
+        '\U0001034a'), ('\U00010350', '\U0001037a'), ('\U00010380', '\U0001039d'), ('\U000103a0',
+        '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'), ('\U00010400',
+        '\U0001049d'), ('\U000104a0', '\U000104a9'), ('\U00010500', '\U00010527'), ('\U00010530',
+        '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'), ('\U00010760',
+        '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'), ('\U0001080a',
+        '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'), ('\U0001083f',
+        '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'), ('\U00010900',
+        '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'), ('\U000109be',
+        '\U000109bf'), ('\U00010a00', '\U00010a03'), ('\U00010a05', '\U00010a06'), ('\U00010a0c',
+        '\U00010a13'), ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a38',
+        '\U00010a3a'), ('\U00010a3f', '\U00010a3f'), ('\U00010a60', '\U00010a7c'), ('\U00010a80',
+        '\U00010a9c'), ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae6'), ('\U00010b00',
+        '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'), ('\U00010b80',
+        '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011046'), ('\U00011066',
+        '\U0001106f'), ('\U0001107f', '\U000110ba'), ('\U000110d0', '\U000110e8'), ('\U000110f0',
+        '\U000110f9'), ('\U00011100', '\U00011134'), ('\U00011136', '\U0001113f'), ('\U00011150',
+        '\U00011173'), ('\U00011176', '\U00011176'), ('\U00011180', '\U000111c4'), ('\U000111d0',
+        '\U000111da'), ('\U00011200', '\U00011211'), ('\U00011213', '\U00011237'), ('\U000112b0',
+        '\U000112ea'), ('\U000112f0', '\U000112f9'), ('\U00011301', '\U00011303'), ('\U00011305',
+        '\U0001130c'), ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a',
+        '\U00011330'), ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133c',
+        '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'), ('\U00011357',
+        '\U00011357'), ('\U0001135d', '\U00011363'), ('\U00011366', '\U0001136c'), ('\U00011370',
+        '\U00011374'), ('\U00011480', '\U000114c5'), ('\U000114c7', '\U000114c7'), ('\U000114d0',
+        '\U000114d9'), ('\U00011580', '\U000115b5'), ('\U000115b8', '\U000115c0'), ('\U00011600',
+        '\U00011640'), ('\U00011644', '\U00011644'), ('\U00011650', '\U00011659'), ('\U00011680',
+        '\U000116b7'), ('\U000116c0', '\U000116c9'), ('\U000118a0', '\U000118e9'), ('\U000118ff',
+        '\U000118ff'), ('\U00011ac0', '\U00011af8'), ('\U00012000', '\U00012398'), ('\U00012400',
+        '\U0001246e'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'), ('\U00016a40',
+        '\U00016a5e'), ('\U00016a60', '\U00016a69'), ('\U00016ad0', '\U00016aed'), ('\U00016af0',
+        '\U00016af4'), ('\U00016b00', '\U00016b36'), ('\U00016b40', '\U00016b43'), ('\U00016b50',
+        '\U00016b59'), ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'), ('\U00016f00',
+        '\U00016f44'), ('\U00016f50', '\U00016f7e'), ('\U00016f8f', '\U00016f9f'), ('\U0001b000',
+        '\U0001b001'), ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80',
+        '\U0001bc88'), ('\U0001bc90', '\U0001bc99'), ('\U0001bc9d', '\U0001bc9e'), ('\U0001d165',
+        '\U0001d169'), ('\U0001d16d', '\U0001d172'), ('\U0001d17b', '\U0001d182'), ('\U0001d185',
+        '\U0001d18b'), ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'), ('\U0001d400',
+        '\U0001d454'), ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2',
+        '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae',
+        '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5',
+        '\U0001d505'), ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516',
+        '\U0001d51c'), ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540',
+        '\U0001d544'), ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552',
+        '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc',
+        '\U0001d6fa'), ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736',
+        '\U0001d74e'), ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a',
+        '\U0001d7a8'), ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001d7ce',
+        '\U0001d7ff'), ('\U0001e800', '\U0001e8c4'), ('\U0001e8d0', '\U0001e8d6'), ('\U0001ee00',
+        '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'), ('\U0001ee24',
+        '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'), ('\U0001ee34',
+        '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42',
+        '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b',
+        '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'), ('\U0001ee54',
+        '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b',
+        '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61',
+        '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c',
+        '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e',
+        '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1',
+        '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'), ('\U0001f130',
+        '\U0001f149'), ('\U0001f150', '\U0001f169'), ('\U0001f170', '\U0001f189'), ('\U00020000',
+        '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'), ('\U0002f800',
+        '\U0002fa1d'), ('\U000e0100', '\U000e01ef')
+    ];
+
+}
+
+pub mod normalization {
+    // Canonical decompositions
+    pub static canonical_table: &'static [(char, &'static [char])] = &[
+        ('\xc0', &['\x41', '\u0300']), ('\xc1', &['\x41', '\u0301']), ('\xc2', &['\x41', '\u0302']),
+        ('\xc3', &['\x41', '\u0303']), ('\xc4', &['\x41', '\u0308']), ('\xc5', &['\x41', '\u030a']),
+        ('\xc7', &['\x43', '\u0327']), ('\xc8', &['\x45', '\u0300']), ('\xc9', &['\x45', '\u0301']),
+        ('\xca', &['\x45', '\u0302']), ('\xcb', &['\x45', '\u0308']), ('\xcc', &['\x49', '\u0300']),
+        ('\xcd', &['\x49', '\u0301']), ('\xce', &['\x49', '\u0302']), ('\xcf', &['\x49', '\u0308']),
+        ('\xd1', &['\x4e', '\u0303']), ('\xd2', &['\x4f', '\u0300']), ('\xd3', &['\x4f', '\u0301']),
+        ('\xd4', &['\x4f', '\u0302']), ('\xd5', &['\x4f', '\u0303']), ('\xd6', &['\x4f', '\u0308']),
+        ('\xd9', &['\x55', '\u0300']), ('\xda', &['\x55', '\u0301']), ('\xdb', &['\x55', '\u0302']),
+        ('\xdc', &['\x55', '\u0308']), ('\xdd', &['\x59', '\u0301']), ('\xe0', &['\x61', '\u0300']),
+        ('\xe1', &['\x61', '\u0301']), ('\xe2', &['\x61', '\u0302']), ('\xe3', &['\x61', '\u0303']),
+        ('\xe4', &['\x61', '\u0308']), ('\xe5', &['\x61', '\u030a']), ('\xe7', &['\x63', '\u0327']),
+        ('\xe8', &['\x65', '\u0300']), ('\xe9', &['\x65', '\u0301']), ('\xea', &['\x65', '\u0302']),
+        ('\xeb', &['\x65', '\u0308']), ('\xec', &['\x69', '\u0300']), ('\xed', &['\x69', '\u0301']),
+        ('\xee', &['\x69', '\u0302']), ('\xef', &['\x69', '\u0308']), ('\xf1', &['\x6e', '\u0303']),
+        ('\xf2', &['\x6f', '\u0300']), ('\xf3', &['\x6f', '\u0301']), ('\xf4', &['\x6f', '\u0302']),
+        ('\xf5', &['\x6f', '\u0303']), ('\xf6', &['\x6f', '\u0308']), ('\xf9', &['\x75', '\u0300']),
+        ('\xfa', &['\x75', '\u0301']), ('\xfb', &['\x75', '\u0302']), ('\xfc', &['\x75', '\u0308']),
+        ('\xfd', &['\x79', '\u0301']), ('\xff', &['\x79', '\u0308']), ('\u0100', &['\x41',
+        '\u0304']), ('\u0101', &['\x61', '\u0304']), ('\u0102', &['\x41', '\u0306']), ('\u0103',
+        &['\x61', '\u0306']), ('\u0104', &['\x41', '\u0328']), ('\u0105', &['\x61', '\u0328']),
+        ('\u0106', &['\x43', '\u0301']), ('\u0107', &['\x63', '\u0301']), ('\u0108', &['\x43',
+        '\u0302']), ('\u0109', &['\x63', '\u0302']), ('\u010a', &['\x43', '\u0307']), ('\u010b',
+        &['\x63', '\u0307']), ('\u010c', &['\x43', '\u030c']), ('\u010d', &['\x63', '\u030c']),
+        ('\u010e', &['\x44', '\u030c']), ('\u010f', &['\x64', '\u030c']), ('\u0112', &['\x45',
+        '\u0304']), ('\u0113', &['\x65', '\u0304']), ('\u0114', &['\x45', '\u0306']), ('\u0115',
+        &['\x65', '\u0306']), ('\u0116', &['\x45', '\u0307']), ('\u0117', &['\x65', '\u0307']),
+        ('\u0118', &['\x45', '\u0328']), ('\u0119', &['\x65', '\u0328']), ('\u011a', &['\x45',
+        '\u030c']), ('\u011b', &['\x65', '\u030c']), ('\u011c', &['\x47', '\u0302']), ('\u011d',
+        &['\x67', '\u0302']), ('\u011e', &['\x47', '\u0306']), ('\u011f', &['\x67', '\u0306']),
+        ('\u0120', &['\x47', '\u0307']), ('\u0121', &['\x67', '\u0307']), ('\u0122', &['\x47',
+        '\u0327']), ('\u0123', &['\x67', '\u0327']), ('\u0124', &['\x48', '\u0302']), ('\u0125',
+        &['\x68', '\u0302']), ('\u0128', &['\x49', '\u0303']), ('\u0129', &['\x69', '\u0303']),
+        ('\u012a', &['\x49', '\u0304']), ('\u012b', &['\x69', '\u0304']), ('\u012c', &['\x49',
+        '\u0306']), ('\u012d', &['\x69', '\u0306']), ('\u012e', &['\x49', '\u0328']), ('\u012f',
+        &['\x69', '\u0328']), ('\u0130', &['\x49', '\u0307']), ('\u0134', &['\x4a', '\u0302']),
+        ('\u0135', &['\x6a', '\u0302']), ('\u0136', &['\x4b', '\u0327']), ('\u0137', &['\x6b',
+        '\u0327']), ('\u0139', &['\x4c', '\u0301']), ('\u013a', &['\x6c', '\u0301']), ('\u013b',
+        &['\x4c', '\u0327']), ('\u013c', &['\x6c', '\u0327']), ('\u013d', &['\x4c', '\u030c']),
+        ('\u013e', &['\x6c', '\u030c']), ('\u0143', &['\x4e', '\u0301']), ('\u0144', &['\x6e',
+        '\u0301']), ('\u0145', &['\x4e', '\u0327']), ('\u0146', &['\x6e', '\u0327']), ('\u0147',
+        &['\x4e', '\u030c']), ('\u0148', &['\x6e', '\u030c']), ('\u014c', &['\x4f', '\u0304']),
+        ('\u014d', &['\x6f', '\u0304']), ('\u014e', &['\x4f', '\u0306']), ('\u014f', &['\x6f',
+        '\u0306']), ('\u0150', &['\x4f', '\u030b']), ('\u0151', &['\x6f', '\u030b']), ('\u0154',
+        &['\x52', '\u0301']), ('\u0155', &['\x72', '\u0301']), ('\u0156', &['\x52', '\u0327']),
+        ('\u0157', &['\x72', '\u0327']), ('\u0158', &['\x52', '\u030c']), ('\u0159', &['\x72',
+        '\u030c']), ('\u015a', &['\x53', '\u0301']), ('\u015b', &['\x73', '\u0301']), ('\u015c',
+        &['\x53', '\u0302']), ('\u015d', &['\x73', '\u0302']), ('\u015e', &['\x53', '\u0327']),
+        ('\u015f', &['\x73', '\u0327']), ('\u0160', &['\x53', '\u030c']), ('\u0161', &['\x73',
+        '\u030c']), ('\u0162', &['\x54', '\u0327']), ('\u0163', &['\x74', '\u0327']), ('\u0164',
+        &['\x54', '\u030c']), ('\u0165', &['\x74', '\u030c']), ('\u0168', &['\x55', '\u0303']),
+        ('\u0169', &['\x75', '\u0303']), ('\u016a', &['\x55', '\u0304']), ('\u016b', &['\x75',
+        '\u0304']), ('\u016c', &['\x55', '\u0306']), ('\u016d', &['\x75', '\u0306']), ('\u016e',
+        &['\x55', '\u030a']), ('\u016f', &['\x75', '\u030a']), ('\u0170', &['\x55', '\u030b']),
+        ('\u0171', &['\x75', '\u030b']), ('\u0172', &['\x55', '\u0328']), ('\u0173', &['\x75',
+        '\u0328']), ('\u0174', &['\x57', '\u0302']), ('\u0175', &['\x77', '\u0302']), ('\u0176',
+        &['\x59', '\u0302']), ('\u0177', &['\x79', '\u0302']), ('\u0178', &['\x59', '\u0308']),
+        ('\u0179', &['\x5a', '\u0301']), ('\u017a', &['\x7a', '\u0301']), ('\u017b', &['\x5a',
+        '\u0307']), ('\u017c', &['\x7a', '\u0307']), ('\u017d', &['\x5a', '\u030c']), ('\u017e',
+        &['\x7a', '\u030c']), ('\u01a0', &['\x4f', '\u031b']), ('\u01a1', &['\x6f', '\u031b']),
+        ('\u01af', &['\x55', '\u031b']), ('\u01b0', &['\x75', '\u031b']), ('\u01cd', &['\x41',
+        '\u030c']), ('\u01ce', &['\x61', '\u030c']), ('\u01cf', &['\x49', '\u030c']), ('\u01d0',
+        &['\x69', '\u030c']), ('\u01d1', &['\x4f', '\u030c']), ('\u01d2', &['\x6f', '\u030c']),
+        ('\u01d3', &['\x55', '\u030c']), ('\u01d4', &['\x75', '\u030c']), ('\u01d5', &['\xdc',
+        '\u0304']), ('\u01d6', &['\xfc', '\u0304']), ('\u01d7', &['\xdc', '\u0301']), ('\u01d8',
+        &['\xfc', '\u0301']), ('\u01d9', &['\xdc', '\u030c']), ('\u01da', &['\xfc', '\u030c']),
+        ('\u01db', &['\xdc', '\u0300']), ('\u01dc', &['\xfc', '\u0300']), ('\u01de', &['\xc4',
+        '\u0304']), ('\u01df', &['\xe4', '\u0304']), ('\u01e0', &['\u0226', '\u0304']), ('\u01e1',
+        &['\u0227', '\u0304']), ('\u01e2', &['\xc6', '\u0304']), ('\u01e3', &['\xe6', '\u0304']),
+        ('\u01e6', &['\x47', '\u030c']), ('\u01e7', &['\x67', '\u030c']), ('\u01e8', &['\x4b',
+        '\u030c']), ('\u01e9', &['\x6b', '\u030c']), ('\u01ea', &['\x4f', '\u0328']), ('\u01eb',
+        &['\x6f', '\u0328']), ('\u01ec', &['\u01ea', '\u0304']), ('\u01ed', &['\u01eb', '\u0304']),
+        ('\u01ee', &['\u01b7', '\u030c']), ('\u01ef', &['\u0292', '\u030c']), ('\u01f0', &['\x6a',
+        '\u030c']), ('\u01f4', &['\x47', '\u0301']), ('\u01f5', &['\x67', '\u0301']), ('\u01f8',
+        &['\x4e', '\u0300']), ('\u01f9', &['\x6e', '\u0300']), ('\u01fa', &['\xc5', '\u0301']),
+        ('\u01fb', &['\xe5', '\u0301']), ('\u01fc', &['\xc6', '\u0301']), ('\u01fd', &['\xe6',
+        '\u0301']), ('\u01fe', &['\xd8', '\u0301']), ('\u01ff', &['\xf8', '\u0301']), ('\u0200',
+        &['\x41', '\u030f']), ('\u0201', &['\x61', '\u030f']), ('\u0202', &['\x41', '\u0311']),
+        ('\u0203', &['\x61', '\u0311']), ('\u0204', &['\x45', '\u030f']), ('\u0205', &['\x65',
+        '\u030f']), ('\u0206', &['\x45', '\u0311']), ('\u0207', &['\x65', '\u0311']), ('\u0208',
+        &['\x49', '\u030f']), ('\u0209', &['\x69', '\u030f']), ('\u020a', &['\x49', '\u0311']),
+        ('\u020b', &['\x69', '\u0311']), ('\u020c', &['\x4f', '\u030f']), ('\u020d', &['\x6f',
+        '\u030f']), ('\u020e', &['\x4f', '\u0311']), ('\u020f', &['\x6f', '\u0311']), ('\u0210',
+        &['\x52', '\u030f']), ('\u0211', &['\x72', '\u030f']), ('\u0212', &['\x52', '\u0311']),
+        ('\u0213', &['\x72', '\u0311']), ('\u0214', &['\x55', '\u030f']), ('\u0215', &['\x75',
+        '\u030f']), ('\u0216', &['\x55', '\u0311']), ('\u0217', &['\x75', '\u0311']), ('\u0218',
+        &['\x53', '\u0326']), ('\u0219', &['\x73', '\u0326']), ('\u021a', &['\x54', '\u0326']),
+        ('\u021b', &['\x74', '\u0326']), ('\u021e', &['\x48', '\u030c']), ('\u021f', &['\x68',
+        '\u030c']), ('\u0226', &['\x41', '\u0307']), ('\u0227', &['\x61', '\u0307']), ('\u0228',
+        &['\x45', '\u0327']), ('\u0229', &['\x65', '\u0327']), ('\u022a', &['\xd6', '\u0304']),
+        ('\u022b', &['\xf6', '\u0304']), ('\u022c', &['\xd5', '\u0304']), ('\u022d', &['\xf5',
+        '\u0304']), ('\u022e', &['\x4f', '\u0307']), ('\u022f', &['\x6f', '\u0307']), ('\u0230',
+        &['\u022e', '\u0304']), ('\u0231', &['\u022f', '\u0304']), ('\u0232', &['\x59', '\u0304']),
+        ('\u0233', &['\x79', '\u0304']), ('\u0340', &['\u0300']), ('\u0341', &['\u0301']),
+        ('\u0343', &['\u0313']), ('\u0344', &['\u0308', '\u0301']), ('\u0374', &['\u02b9']),
+        ('\u037e', &['\x3b']), ('\u0385', &['\xa8', '\u0301']), ('\u0386', &['\u0391', '\u0301']),
+        ('\u0387', &['\xb7']), ('\u0388', &['\u0395', '\u0301']), ('\u0389', &['\u0397', '\u0301']),
+        ('\u038a', &['\u0399', '\u0301']), ('\u038c', &['\u039f', '\u0301']), ('\u038e', &['\u03a5',
+        '\u0301']), ('\u038f', &['\u03a9', '\u0301']), ('\u0390', &['\u03ca', '\u0301']), ('\u03aa',
+        &['\u0399', '\u0308']), ('\u03ab', &['\u03a5', '\u0308']), ('\u03ac', &['\u03b1',
+        '\u0301']), ('\u03ad', &['\u03b5', '\u0301']), ('\u03ae', &['\u03b7', '\u0301']), ('\u03af',
+        &['\u03b9', '\u0301']), ('\u03b0', &['\u03cb', '\u0301']), ('\u03ca', &['\u03b9',
+        '\u0308']), ('\u03cb', &['\u03c5', '\u0308']), ('\u03cc', &['\u03bf', '\u0301']), ('\u03cd',
+        &['\u03c5', '\u0301']), ('\u03ce', &['\u03c9', '\u0301']), ('\u03d3', &['\u03d2',
+        '\u0301']), ('\u03d4', &['\u03d2', '\u0308']), ('\u0400', &['\u0415', '\u0300']), ('\u0401',
+        &['\u0415', '\u0308']), ('\u0403', &['\u0413', '\u0301']), ('\u0407', &['\u0406',
+        '\u0308']), ('\u040c', &['\u041a', '\u0301']), ('\u040d', &['\u0418', '\u0300']), ('\u040e',
+        &['\u0423', '\u0306']), ('\u0419', &['\u0418', '\u0306']), ('\u0439', &['\u0438',
+        '\u0306']), ('\u0450', &['\u0435', '\u0300']), ('\u0451', &['\u0435', '\u0308']), ('\u0453',
+        &['\u0433', '\u0301']), ('\u0457', &['\u0456', '\u0308']), ('\u045c', &['\u043a',
+        '\u0301']), ('\u045d', &['\u0438', '\u0300']), ('\u045e', &['\u0443', '\u0306']), ('\u0476',
+        &['\u0474', '\u030f']), ('\u0477', &['\u0475', '\u030f']), ('\u04c1', &['\u0416',
+        '\u0306']), ('\u04c2', &['\u0436', '\u0306']), ('\u04d0', &['\u0410', '\u0306']), ('\u04d1',
+        &['\u0430', '\u0306']), ('\u04d2', &['\u0410', '\u0308']), ('\u04d3', &['\u0430',
+        '\u0308']), ('\u04d6', &['\u0415', '\u0306']), ('\u04d7', &['\u0435', '\u0306']), ('\u04da',
+        &['\u04d8', '\u0308']), ('\u04db', &['\u04d9', '\u0308']), ('\u04dc', &['\u0416',
+        '\u0308']), ('\u04dd', &['\u0436', '\u0308']), ('\u04de', &['\u0417', '\u0308']), ('\u04df',
+        &['\u0437', '\u0308']), ('\u04e2', &['\u0418', '\u0304']), ('\u04e3', &['\u0438',
+        '\u0304']), ('\u04e4', &['\u0418', '\u0308']), ('\u04e5', &['\u0438', '\u0308']), ('\u04e6',
+        &['\u041e', '\u0308']), ('\u04e7', &['\u043e', '\u0308']), ('\u04ea', &['\u04e8',
+        '\u0308']), ('\u04eb', &['\u04e9', '\u0308']), ('\u04ec', &['\u042d', '\u0308']), ('\u04ed',
+        &['\u044d', '\u0308']), ('\u04ee', &['\u0423', '\u0304']), ('\u04ef', &['\u0443',
+        '\u0304']), ('\u04f0', &['\u0423', '\u0308']), ('\u04f1', &['\u0443', '\u0308']), ('\u04f2',
+        &['\u0423', '\u030b']), ('\u04f3', &['\u0443', '\u030b']), ('\u04f4', &['\u0427',
+        '\u0308']), ('\u04f5', &['\u0447', '\u0308']), ('\u04f8', &['\u042b', '\u0308']), ('\u04f9',
+        &['\u044b', '\u0308']), ('\u0622', &['\u0627', '\u0653']), ('\u0623', &['\u0627',
+        '\u0654']), ('\u0624', &['\u0648', '\u0654']), ('\u0625', &['\u0627', '\u0655']), ('\u0626',
+        &['\u064a', '\u0654']), ('\u06c0', &['\u06d5', '\u0654']), ('\u06c2', &['\u06c1',
+        '\u0654']), ('\u06d3', &['\u06d2', '\u0654']), ('\u0929', &['\u0928', '\u093c']), ('\u0931',
+        &['\u0930', '\u093c']), ('\u0934', &['\u0933', '\u093c']), ('\u0958', &['\u0915',
+        '\u093c']), ('\u0959', &['\u0916', '\u093c']), ('\u095a', &['\u0917', '\u093c']), ('\u095b',
+        &['\u091c', '\u093c']), ('\u095c', &['\u0921', '\u093c']), ('\u095d', &['\u0922',
+        '\u093c']), ('\u095e', &['\u092b', '\u093c']), ('\u095f', &['\u092f', '\u093c']), ('\u09cb',
+        &['\u09c7', '\u09be']), ('\u09cc', &['\u09c7', '\u09d7']), ('\u09dc', &['\u09a1',
+        '\u09bc']), ('\u09dd', &['\u09a2', '\u09bc']), ('\u09df', &['\u09af', '\u09bc']), ('\u0a33',
+        &['\u0a32', '\u0a3c']), ('\u0a36', &['\u0a38', '\u0a3c']), ('\u0a59', &['\u0a16',
+        '\u0a3c']), ('\u0a5a', &['\u0a17', '\u0a3c']), ('\u0a5b', &['\u0a1c', '\u0a3c']), ('\u0a5e',
+        &['\u0a2b', '\u0a3c']), ('\u0b48', &['\u0b47', '\u0b56']), ('\u0b4b', &['\u0b47',
+        '\u0b3e']), ('\u0b4c', &['\u0b47', '\u0b57']), ('\u0b5c', &['\u0b21', '\u0b3c']), ('\u0b5d',
+        &['\u0b22', '\u0b3c']), ('\u0b94', &['\u0b92', '\u0bd7']), ('\u0bca', &['\u0bc6',
+        '\u0bbe']), ('\u0bcb', &['\u0bc7', '\u0bbe']), ('\u0bcc', &['\u0bc6', '\u0bd7']), ('\u0c48',
+        &['\u0c46', '\u0c56']), ('\u0cc0', &['\u0cbf', '\u0cd5']), ('\u0cc7', &['\u0cc6',
+        '\u0cd5']), ('\u0cc8', &['\u0cc6', '\u0cd6']), ('\u0cca', &['\u0cc6', '\u0cc2']), ('\u0ccb',
+        &['\u0cca', '\u0cd5']), ('\u0d4a', &['\u0d46', '\u0d3e']), ('\u0d4b', &['\u0d47',
+        '\u0d3e']), ('\u0d4c', &['\u0d46', '\u0d57']), ('\u0dda', &['\u0dd9', '\u0dca']), ('\u0ddc',
+        &['\u0dd9', '\u0dcf']), ('\u0ddd', &['\u0ddc', '\u0dca']), ('\u0dde', &['\u0dd9',
+        '\u0ddf']), ('\u0f43', &['\u0f42', '\u0fb7']), ('\u0f4d', &['\u0f4c', '\u0fb7']), ('\u0f52',
+        &['\u0f51', '\u0fb7']), ('\u0f57', &['\u0f56', '\u0fb7']), ('\u0f5c', &['\u0f5b',
+        '\u0fb7']), ('\u0f69', &['\u0f40', '\u0fb5']), ('\u0f73', &['\u0f71', '\u0f72']), ('\u0f75',
+        &['\u0f71', '\u0f74']), ('\u0f76', &['\u0fb2', '\u0f80']), ('\u0f78', &['\u0fb3',
+        '\u0f80']), ('\u0f81', &['\u0f71', '\u0f80']), ('\u0f93', &['\u0f92', '\u0fb7']), ('\u0f9d',
+        &['\u0f9c', '\u0fb7']), ('\u0fa2', &['\u0fa1', '\u0fb7']), ('\u0fa7', &['\u0fa6',
+        '\u0fb7']), ('\u0fac', &['\u0fab', '\u0fb7']), ('\u0fb9', &['\u0f90', '\u0fb5']), ('\u1026',
+        &['\u1025', '\u102e']), ('\u1b06', &['\u1b05', '\u1b35']), ('\u1b08', &['\u1b07',
+        '\u1b35']), ('\u1b0a', &['\u1b09', '\u1b35']), ('\u1b0c', &['\u1b0b', '\u1b35']), ('\u1b0e',
+        &['\u1b0d', '\u1b35']), ('\u1b12', &['\u1b11', '\u1b35']), ('\u1b3b', &['\u1b3a',
+        '\u1b35']), ('\u1b3d', &['\u1b3c', '\u1b35']), ('\u1b40', &['\u1b3e', '\u1b35']), ('\u1b41',
+        &['\u1b3f', '\u1b35']), ('\u1b43', &['\u1b42', '\u1b35']), ('\u1e00', &['\x41', '\u0325']),
+        ('\u1e01', &['\x61', '\u0325']), ('\u1e02', &['\x42', '\u0307']), ('\u1e03', &['\x62',
+        '\u0307']), ('\u1e04', &['\x42', '\u0323']), ('\u1e05', &['\x62', '\u0323']), ('\u1e06',
+        &['\x42', '\u0331']), ('\u1e07', &['\x62', '\u0331']), ('\u1e08', &['\xc7', '\u0301']),
+        ('\u1e09', &['\xe7', '\u0301']), ('\u1e0a', &['\x44', '\u0307']), ('\u1e0b', &['\x64',
+        '\u0307']), ('\u1e0c', &['\x44', '\u0323']), ('\u1e0d', &['\x64', '\u0323']), ('\u1e0e',
+        &['\x44', '\u0331']), ('\u1e0f', &['\x64', '\u0331']), ('\u1e10', &['\x44', '\u0327']),
+        ('\u1e11', &['\x64', '\u0327']), ('\u1e12', &['\x44', '\u032d']), ('\u1e13', &['\x64',
+        '\u032d']), ('\u1e14', &['\u0112', '\u0300']), ('\u1e15', &['\u0113', '\u0300']), ('\u1e16',
+        &['\u0112', '\u0301']), ('\u1e17', &['\u0113', '\u0301']), ('\u1e18', &['\x45', '\u032d']),
+        ('\u1e19', &['\x65', '\u032d']), ('\u1e1a', &['\x45', '\u0330']), ('\u1e1b', &['\x65',
+        '\u0330']), ('\u1e1c', &['\u0228', '\u0306']), ('\u1e1d', &['\u0229', '\u0306']), ('\u1e1e',
+        &['\x46', '\u0307']), ('\u1e1f', &['\x66', '\u0307']), ('\u1e20', &['\x47', '\u0304']),
+        ('\u1e21', &['\x67', '\u0304']), ('\u1e22', &['\x48', '\u0307']), ('\u1e23', &['\x68',
+        '\u0307']), ('\u1e24', &['\x48', '\u0323']), ('\u1e25', &['\x68', '\u0323']), ('\u1e26',
+        &['\x48', '\u0308']), ('\u1e27', &['\x68', '\u0308']), ('\u1e28', &['\x48', '\u0327']),
+        ('\u1e29', &['\x68', '\u0327']), ('\u1e2a', &['\x48', '\u032e']), ('\u1e2b', &['\x68',
+        '\u032e']), ('\u1e2c', &['\x49', '\u0330']), ('\u1e2d', &['\x69', '\u0330']), ('\u1e2e',
+        &['\xcf', '\u0301']), ('\u1e2f', &['\xef', '\u0301']), ('\u1e30', &['\x4b', '\u0301']),
+        ('\u1e31', &['\x6b', '\u0301']), ('\u1e32', &['\x4b', '\u0323']), ('\u1e33', &['\x6b',
+        '\u0323']), ('\u1e34', &['\x4b', '\u0331']), ('\u1e35', &['\x6b', '\u0331']), ('\u1e36',
+        &['\x4c', '\u0323']), ('\u1e37', &['\x6c', '\u0323']), ('\u1e38', &['\u1e36', '\u0304']),
+        ('\u1e39', &['\u1e37', '\u0304']), ('\u1e3a', &['\x4c', '\u0331']), ('\u1e3b', &['\x6c',
+        '\u0331']), ('\u1e3c', &['\x4c', '\u032d']), ('\u1e3d', &['\x6c', '\u032d']), ('\u1e3e',
+        &['\x4d', '\u0301']), ('\u1e3f', &['\x6d', '\u0301']), ('\u1e40', &['\x4d', '\u0307']),
+        ('\u1e41', &['\x6d', '\u0307']), ('\u1e42', &['\x4d', '\u0323']), ('\u1e43', &['\x6d',
+        '\u0323']), ('\u1e44', &['\x4e', '\u0307']), ('\u1e45', &['\x6e', '\u0307']), ('\u1e46',
+        &['\x4e', '\u0323']), ('\u1e47', &['\x6e', '\u0323']), ('\u1e48', &['\x4e', '\u0331']),
+        ('\u1e49', &['\x6e', '\u0331']), ('\u1e4a', &['\x4e', '\u032d']), ('\u1e4b', &['\x6e',
+        '\u032d']), ('\u1e4c', &['\xd5', '\u0301']), ('\u1e4d', &['\xf5', '\u0301']), ('\u1e4e',
+        &['\xd5', '\u0308']), ('\u1e4f', &['\xf5', '\u0308']), ('\u1e50', &['\u014c', '\u0300']),
+        ('\u1e51', &['\u014d', '\u0300']), ('\u1e52', &['\u014c', '\u0301']), ('\u1e53', &['\u014d',
+        '\u0301']), ('\u1e54', &['\x50', '\u0301']), ('\u1e55', &['\x70', '\u0301']), ('\u1e56',
+        &['\x50', '\u0307']), ('\u1e57', &['\x70', '\u0307']), ('\u1e58', &['\x52', '\u0307']),
+        ('\u1e59', &['\x72', '\u0307']), ('\u1e5a', &['\x52', '\u0323']), ('\u1e5b', &['\x72',
+        '\u0323']), ('\u1e5c', &['\u1e5a', '\u0304']), ('\u1e5d', &['\u1e5b', '\u0304']), ('\u1e5e',
+        &['\x52', '\u0331']), ('\u1e5f', &['\x72', '\u0331']), ('\u1e60', &['\x53', '\u0307']),
+        ('\u1e61', &['\x73', '\u0307']), ('\u1e62', &['\x53', '\u0323']), ('\u1e63', &['\x73',
+        '\u0323']), ('\u1e64', &['\u015a', '\u0307']), ('\u1e65', &['\u015b', '\u0307']), ('\u1e66',
+        &['\u0160', '\u0307']), ('\u1e67', &['\u0161', '\u0307']), ('\u1e68', &['\u1e62',
+        '\u0307']), ('\u1e69', &['\u1e63', '\u0307']), ('\u1e6a', &['\x54', '\u0307']), ('\u1e6b',
+        &['\x74', '\u0307']), ('\u1e6c', &['\x54', '\u0323']), ('\u1e6d', &['\x74', '\u0323']),
+        ('\u1e6e', &['\x54', '\u0331']), ('\u1e6f', &['\x74', '\u0331']), ('\u1e70', &['\x54',
+        '\u032d']), ('\u1e71', &['\x74', '\u032d']), ('\u1e72', &['\x55', '\u0324']), ('\u1e73',
+        &['\x75', '\u0324']), ('\u1e74', &['\x55', '\u0330']), ('\u1e75', &['\x75', '\u0330']),
+        ('\u1e76', &['\x55', '\u032d']), ('\u1e77', &['\x75', '\u032d']), ('\u1e78', &['\u0168',
+        '\u0301']), ('\u1e79', &['\u0169', '\u0301']), ('\u1e7a', &['\u016a', '\u0308']), ('\u1e7b',
+        &['\u016b', '\u0308']), ('\u1e7c', &['\x56', '\u0303']), ('\u1e7d', &['\x76', '\u0303']),
+        ('\u1e7e', &['\x56', '\u0323']), ('\u1e7f', &['\x76', '\u0323']), ('\u1e80', &['\x57',
+        '\u0300']), ('\u1e81', &['\x77', '\u0300']), ('\u1e82', &['\x57', '\u0301']), ('\u1e83',
+        &['\x77', '\u0301']), ('\u1e84', &['\x57', '\u0308']), ('\u1e85', &['\x77', '\u0308']),
+        ('\u1e86', &['\x57', '\u0307']), ('\u1e87', &['\x77', '\u0307']), ('\u1e88', &['\x57',
+        '\u0323']), ('\u1e89', &['\x77', '\u0323']), ('\u1e8a', &['\x58', '\u0307']), ('\u1e8b',
+        &['\x78', '\u0307']), ('\u1e8c', &['\x58', '\u0308']), ('\u1e8d', &['\x78', '\u0308']),
+        ('\u1e8e', &['\x59', '\u0307']), ('\u1e8f', &['\x79', '\u0307']), ('\u1e90', &['\x5a',
+        '\u0302']), ('\u1e91', &['\x7a', '\u0302']), ('\u1e92', &['\x5a', '\u0323']), ('\u1e93',
+        &['\x7a', '\u0323']), ('\u1e94', &['\x5a', '\u0331']), ('\u1e95', &['\x7a', '\u0331']),
+        ('\u1e96', &['\x68', '\u0331']), ('\u1e97', &['\x74', '\u0308']), ('\u1e98', &['\x77',
+        '\u030a']), ('\u1e99', &['\x79', '\u030a']), ('\u1e9b', &['\u017f', '\u0307']), ('\u1ea0',
+        &['\x41', '\u0323']), ('\u1ea1', &['\x61', '\u0323']), ('\u1ea2', &['\x41', '\u0309']),
+        ('\u1ea3', &['\x61', '\u0309']), ('\u1ea4', &['\xc2', '\u0301']), ('\u1ea5', &['\xe2',
+        '\u0301']), ('\u1ea6', &['\xc2', '\u0300']), ('\u1ea7', &['\xe2', '\u0300']), ('\u1ea8',
+        &['\xc2', '\u0309']), ('\u1ea9', &['\xe2', '\u0309']), ('\u1eaa', &['\xc2', '\u0303']),
+        ('\u1eab', &['\xe2', '\u0303']), ('\u1eac', &['\u1ea0', '\u0302']), ('\u1ead', &['\u1ea1',
+        '\u0302']), ('\u1eae', &['\u0102', '\u0301']), ('\u1eaf', &['\u0103', '\u0301']), ('\u1eb0',
+        &['\u0102', '\u0300']), ('\u1eb1', &['\u0103', '\u0300']), ('\u1eb2', &['\u0102',
+        '\u0309']), ('\u1eb3', &['\u0103', '\u0309']), ('\u1eb4', &['\u0102', '\u0303']), ('\u1eb5',
+        &['\u0103', '\u0303']), ('\u1eb6', &['\u1ea0', '\u0306']), ('\u1eb7', &['\u1ea1',
+        '\u0306']), ('\u1eb8', &['\x45', '\u0323']), ('\u1eb9', &['\x65', '\u0323']), ('\u1eba',
+        &['\x45', '\u0309']), ('\u1ebb', &['\x65', '\u0309']), ('\u1ebc', &['\x45', '\u0303']),
+        ('\u1ebd', &['\x65', '\u0303']), ('\u1ebe', &['\xca', '\u0301']), ('\u1ebf', &['\xea',
+        '\u0301']), ('\u1ec0', &['\xca', '\u0300']), ('\u1ec1', &['\xea', '\u0300']), ('\u1ec2',
+        &['\xca', '\u0309']), ('\u1ec3', &['\xea', '\u0309']), ('\u1ec4', &['\xca', '\u0303']),
+        ('\u1ec5', &['\xea', '\u0303']), ('\u1ec6', &['\u1eb8', '\u0302']), ('\u1ec7', &['\u1eb9',
+        '\u0302']), ('\u1ec8', &['\x49', '\u0309']), ('\u1ec9', &['\x69', '\u0309']), ('\u1eca',
+        &['\x49', '\u0323']), ('\u1ecb', &['\x69', '\u0323']), ('\u1ecc', &['\x4f', '\u0323']),
+        ('\u1ecd', &['\x6f', '\u0323']), ('\u1ece', &['\x4f', '\u0309']), ('\u1ecf', &['\x6f',
+        '\u0309']), ('\u1ed0', &['\xd4', '\u0301']), ('\u1ed1', &['\xf4', '\u0301']), ('\u1ed2',
+        &['\xd4', '\u0300']), ('\u1ed3', &['\xf4', '\u0300']), ('\u1ed4', &['\xd4', '\u0309']),
+        ('\u1ed5', &['\xf4', '\u0309']), ('\u1ed6', &['\xd4', '\u0303']), ('\u1ed7', &['\xf4',
+        '\u0303']), ('\u1ed8', &['\u1ecc', '\u0302']), ('\u1ed9', &['\u1ecd', '\u0302']), ('\u1eda',
+        &['\u01a0', '\u0301']), ('\u1edb', &['\u01a1', '\u0301']), ('\u1edc', &['\u01a0',
+        '\u0300']), ('\u1edd', &['\u01a1', '\u0300']), ('\u1ede', &['\u01a0', '\u0309']), ('\u1edf',
+        &['\u01a1', '\u0309']), ('\u1ee0', &['\u01a0', '\u0303']), ('\u1ee1', &['\u01a1',
+        '\u0303']), ('\u1ee2', &['\u01a0', '\u0323']), ('\u1ee3', &['\u01a1', '\u0323']), ('\u1ee4',
+        &['\x55', '\u0323']), ('\u1ee5', &['\x75', '\u0323']), ('\u1ee6', &['\x55', '\u0309']),
+        ('\u1ee7', &['\x75', '\u0309']), ('\u1ee8', &['\u01af', '\u0301']), ('\u1ee9', &['\u01b0',
+        '\u0301']), ('\u1eea', &['\u01af', '\u0300']), ('\u1eeb', &['\u01b0', '\u0300']), ('\u1eec',
+        &['\u01af', '\u0309']), ('\u1eed', &['\u01b0', '\u0309']), ('\u1eee', &['\u01af',
+        '\u0303']), ('\u1eef', &['\u01b0', '\u0303']), ('\u1ef0', &['\u01af', '\u0323']), ('\u1ef1',
+        &['\u01b0', '\u0323']), ('\u1ef2', &['\x59', '\u0300']), ('\u1ef3', &['\x79', '\u0300']),
+        ('\u1ef4', &['\x59', '\u0323']), ('\u1ef5', &['\x79', '\u0323']), ('\u1ef6', &['\x59',
+        '\u0309']), ('\u1ef7', &['\x79', '\u0309']), ('\u1ef8', &['\x59', '\u0303']), ('\u1ef9',
+        &['\x79', '\u0303']), ('\u1f00', &['\u03b1', '\u0313']), ('\u1f01', &['\u03b1', '\u0314']),
+        ('\u1f02', &['\u1f00', '\u0300']), ('\u1f03', &['\u1f01', '\u0300']), ('\u1f04', &['\u1f00',
+        '\u0301']), ('\u1f05', &['\u1f01', '\u0301']), ('\u1f06', &['\u1f00', '\u0342']), ('\u1f07',
+        &['\u1f01', '\u0342']), ('\u1f08', &['\u0391', '\u0313']), ('\u1f09', &['\u0391',
+        '\u0314']), ('\u1f0a', &['\u1f08', '\u0300']), ('\u1f0b', &['\u1f09', '\u0300']), ('\u1f0c',
+        &['\u1f08', '\u0301']), ('\u1f0d', &['\u1f09', '\u0301']), ('\u1f0e', &['\u1f08',
+        '\u0342']), ('\u1f0f', &['\u1f09', '\u0342']), ('\u1f10', &['\u03b5', '\u0313']), ('\u1f11',
+        &['\u03b5', '\u0314']), ('\u1f12', &['\u1f10', '\u0300']), ('\u1f13', &['\u1f11',
+        '\u0300']), ('\u1f14', &['\u1f10', '\u0301']), ('\u1f15', &['\u1f11', '\u0301']), ('\u1f18',
+        &['\u0395', '\u0313']), ('\u1f19', &['\u0395', '\u0314']), ('\u1f1a', &['\u1f18',
+        '\u0300']), ('\u1f1b', &['\u1f19', '\u0300']), ('\u1f1c', &['\u1f18', '\u0301']), ('\u1f1d',
+        &['\u1f19', '\u0301']), ('\u1f20', &['\u03b7', '\u0313']), ('\u1f21', &['\u03b7',
+        '\u0314']), ('\u1f22', &['\u1f20', '\u0300']), ('\u1f23', &['\u1f21', '\u0300']), ('\u1f24',
+        &['\u1f20', '\u0301']), ('\u1f25', &['\u1f21', '\u0301']), ('\u1f26', &['\u1f20',
+        '\u0342']), ('\u1f27', &['\u1f21', '\u0342']), ('\u1f28', &['\u0397', '\u0313']), ('\u1f29',
+        &['\u0397', '\u0314']), ('\u1f2a', &['\u1f28', '\u0300']), ('\u1f2b', &['\u1f29',
+        '\u0300']), ('\u1f2c', &['\u1f28', '\u0301']), ('\u1f2d', &['\u1f29', '\u0301']), ('\u1f2e',
+        &['\u1f28', '\u0342']), ('\u1f2f', &['\u1f29', '\u0342']), ('\u1f30', &['\u03b9',
+        '\u0313']), ('\u1f31', &['\u03b9', '\u0314']), ('\u1f32', &['\u1f30', '\u0300']), ('\u1f33',
+        &['\u1f31', '\u0300']), ('\u1f34', &['\u1f30', '\u0301']), ('\u1f35', &['\u1f31',
+        '\u0301']), ('\u1f36', &['\u1f30', '\u0342']), ('\u1f37', &['\u1f31', '\u0342']), ('\u1f38',
+        &['\u0399', '\u0313']), ('\u1f39', &['\u0399', '\u0314']), ('\u1f3a', &['\u1f38',
+        '\u0300']), ('\u1f3b', &['\u1f39', '\u0300']), ('\u1f3c', &['\u1f38', '\u0301']), ('\u1f3d',
+        &['\u1f39', '\u0301']), ('\u1f3e', &['\u1f38', '\u0342']), ('\u1f3f', &['\u1f39',
+        '\u0342']), ('\u1f40', &['\u03bf', '\u0313']), ('\u1f41', &['\u03bf', '\u0314']), ('\u1f42',
+        &['\u1f40', '\u0300']), ('\u1f43', &['\u1f41', '\u0300']), ('\u1f44', &['\u1f40',
+        '\u0301']), ('\u1f45', &['\u1f41', '\u0301']), ('\u1f48', &['\u039f', '\u0313']), ('\u1f49',
+        &['\u039f', '\u0314']), ('\u1f4a', &['\u1f48', '\u0300']), ('\u1f4b', &['\u1f49',
+        '\u0300']), ('\u1f4c', &['\u1f48', '\u0301']), ('\u1f4d', &['\u1f49', '\u0301']), ('\u1f50',
+        &['\u03c5', '\u0313']), ('\u1f51', &['\u03c5', '\u0314']), ('\u1f52', &['\u1f50',
+        '\u0300']), ('\u1f53', &['\u1f51', '\u0300']), ('\u1f54', &['\u1f50', '\u0301']), ('\u1f55',
+        &['\u1f51', '\u0301']), ('\u1f56', &['\u1f50', '\u0342']), ('\u1f57', &['\u1f51',
+        '\u0342']), ('\u1f59', &['\u03a5', '\u0314']), ('\u1f5b', &['\u1f59', '\u0300']), ('\u1f5d',
+        &['\u1f59', '\u0301']), ('\u1f5f', &['\u1f59', '\u0342']), ('\u1f60', &['\u03c9',
+        '\u0313']), ('\u1f61', &['\u03c9', '\u0314']), ('\u1f62', &['\u1f60', '\u0300']), ('\u1f63',
+        &['\u1f61', '\u0300']), ('\u1f64', &['\u1f60', '\u0301']), ('\u1f65', &['\u1f61',
+        '\u0301']), ('\u1f66', &['\u1f60', '\u0342']), ('\u1f67', &['\u1f61', '\u0342']), ('\u1f68',
+        &['\u03a9', '\u0313']), ('\u1f69', &['\u03a9', '\u0314']), ('\u1f6a', &['\u1f68',
+        '\u0300']), ('\u1f6b', &['\u1f69', '\u0300']), ('\u1f6c', &['\u1f68', '\u0301']), ('\u1f6d',
+        &['\u1f69', '\u0301']), ('\u1f6e', &['\u1f68', '\u0342']), ('\u1f6f', &['\u1f69',
+        '\u0342']), ('\u1f70', &['\u03b1', '\u0300']), ('\u1f71', &['\u03ac']), ('\u1f72',
+        &['\u03b5', '\u0300']), ('\u1f73', &['\u03ad']), ('\u1f74', &['\u03b7', '\u0300']),
+        ('\u1f75', &['\u03ae']), ('\u1f76', &['\u03b9', '\u0300']), ('\u1f77', &['\u03af']),
+        ('\u1f78', &['\u03bf', '\u0300']), ('\u1f79', &['\u03cc']), ('\u1f7a', &['\u03c5',
+        '\u0300']), ('\u1f7b', &['\u03cd']), ('\u1f7c', &['\u03c9', '\u0300']), ('\u1f7d',
+        &['\u03ce']), ('\u1f80', &['\u1f00', '\u0345']), ('\u1f81', &['\u1f01', '\u0345']),
+        ('\u1f82', &['\u1f02', '\u0345']), ('\u1f83', &['\u1f03', '\u0345']), ('\u1f84', &['\u1f04',
+        '\u0345']), ('\u1f85', &['\u1f05', '\u0345']), ('\u1f86', &['\u1f06', '\u0345']), ('\u1f87',
+        &['\u1f07', '\u0345']), ('\u1f88', &['\u1f08', '\u0345']), ('\u1f89', &['\u1f09',
+        '\u0345']), ('\u1f8a', &['\u1f0a', '\u0345']), ('\u1f8b', &['\u1f0b', '\u0345']), ('\u1f8c',
+        &['\u1f0c', '\u0345']), ('\u1f8d', &['\u1f0d', '\u0345']), ('\u1f8e', &['\u1f0e',
+        '\u0345']), ('\u1f8f', &['\u1f0f', '\u0345']), ('\u1f90', &['\u1f20', '\u0345']), ('\u1f91',
+        &['\u1f21', '\u0345']), ('\u1f92', &['\u1f22', '\u0345']), ('\u1f93', &['\u1f23',
+        '\u0345']), ('\u1f94', &['\u1f24', '\u0345']), ('\u1f95', &['\u1f25', '\u0345']), ('\u1f96',
+        &['\u1f26', '\u0345']), ('\u1f97', &['\u1f27', '\u0345']), ('\u1f98', &['\u1f28',
+        '\u0345']), ('\u1f99', &['\u1f29', '\u0345']), ('\u1f9a', &['\u1f2a', '\u0345']), ('\u1f9b',
+        &['\u1f2b', '\u0345']), ('\u1f9c', &['\u1f2c', '\u0345']), ('\u1f9d', &['\u1f2d',
+        '\u0345']), ('\u1f9e', &['\u1f2e', '\u0345']), ('\u1f9f', &['\u1f2f', '\u0345']), ('\u1fa0',
+        &['\u1f60', '\u0345']), ('\u1fa1', &['\u1f61', '\u0345']), ('\u1fa2', &['\u1f62',
+        '\u0345']), ('\u1fa3', &['\u1f63', '\u0345']), ('\u1fa4', &['\u1f64', '\u0345']), ('\u1fa5',
+        &['\u1f65', '\u0345']), ('\u1fa6', &['\u1f66', '\u0345']), ('\u1fa7', &['\u1f67',
+        '\u0345']), ('\u1fa8', &['\u1f68', '\u0345']), ('\u1fa9', &['\u1f69', '\u0345']), ('\u1faa',
+        &['\u1f6a', '\u0345']), ('\u1fab', &['\u1f6b', '\u0345']), ('\u1fac', &['\u1f6c',
+        '\u0345']), ('\u1fad', &['\u1f6d', '\u0345']), ('\u1fae', &['\u1f6e', '\u0345']), ('\u1faf',
+        &['\u1f6f', '\u0345']), ('\u1fb0', &['\u03b1', '\u0306']), ('\u1fb1', &['\u03b1',
+        '\u0304']), ('\u1fb2', &['\u1f70', '\u0345']), ('\u1fb3', &['\u03b1', '\u0345']), ('\u1fb4',
+        &['\u03ac', '\u0345']), ('\u1fb6', &['\u03b1', '\u0342']), ('\u1fb7', &['\u1fb6',
+        '\u0345']), ('\u1fb8', &['\u0391', '\u0306']), ('\u1fb9', &['\u0391', '\u0304']), ('\u1fba',
+        &['\u0391', '\u0300']), ('\u1fbb', &['\u0386']), ('\u1fbc', &['\u0391', '\u0345']),
+        ('\u1fbe', &['\u03b9']), ('\u1fc1', &['\xa8', '\u0342']), ('\u1fc2', &['\u1f74', '\u0345']),
+        ('\u1fc3', &['\u03b7', '\u0345']), ('\u1fc4', &['\u03ae', '\u0345']), ('\u1fc6', &['\u03b7',
+        '\u0342']), ('\u1fc7', &['\u1fc6', '\u0345']), ('\u1fc8', &['\u0395', '\u0300']), ('\u1fc9',
+        &['\u0388']), ('\u1fca', &['\u0397', '\u0300']), ('\u1fcb', &['\u0389']), ('\u1fcc',
+        &['\u0397', '\u0345']), ('\u1fcd', &['\u1fbf', '\u0300']), ('\u1fce', &['\u1fbf',
+        '\u0301']), ('\u1fcf', &['\u1fbf', '\u0342']), ('\u1fd0', &['\u03b9', '\u0306']), ('\u1fd1',
+        &['\u03b9', '\u0304']), ('\u1fd2', &['\u03ca', '\u0300']), ('\u1fd3', &['\u0390']),
+        ('\u1fd6', &['\u03b9', '\u0342']), ('\u1fd7', &['\u03ca', '\u0342']), ('\u1fd8', &['\u0399',
+        '\u0306']), ('\u1fd9', &['\u0399', '\u0304']), ('\u1fda', &['\u0399', '\u0300']), ('\u1fdb',
+        &['\u038a']), ('\u1fdd', &['\u1ffe', '\u0300']), ('\u1fde', &['\u1ffe', '\u0301']),
+        ('\u1fdf', &['\u1ffe', '\u0342']), ('\u1fe0', &['\u03c5', '\u0306']), ('\u1fe1', &['\u03c5',
+        '\u0304']), ('\u1fe2', &['\u03cb', '\u0300']), ('\u1fe3', &['\u03b0']), ('\u1fe4',
+        &['\u03c1', '\u0313']), ('\u1fe5', &['\u03c1', '\u0314']), ('\u1fe6', &['\u03c5',
+        '\u0342']), ('\u1fe7', &['\u03cb', '\u0342']), ('\u1fe8', &['\u03a5', '\u0306']), ('\u1fe9',
+        &['\u03a5', '\u0304']), ('\u1fea', &['\u03a5', '\u0300']), ('\u1feb', &['\u038e']),
+        ('\u1fec', &['\u03a1', '\u0314']), ('\u1fed', &['\xa8', '\u0300']), ('\u1fee', &['\u0385']),
+        ('\u1fef', &['\x60']), ('\u1ff2', &['\u1f7c', '\u0345']), ('\u1ff3', &['\u03c9', '\u0345']),
+        ('\u1ff4', &['\u03ce', '\u0345']), ('\u1ff6', &['\u03c9', '\u0342']), ('\u1ff7', &['\u1ff6',
+        '\u0345']), ('\u1ff8', &['\u039f', '\u0300']), ('\u1ff9', &['\u038c']), ('\u1ffa',
+        &['\u03a9', '\u0300']), ('\u1ffb', &['\u038f']), ('\u1ffc', &['\u03a9', '\u0345']),
+        ('\u1ffd', &['\xb4']), ('\u2000', &['\u2002']), ('\u2001', &['\u2003']), ('\u2126',
+        &['\u03a9']), ('\u212a', &['\x4b']), ('\u212b', &['\xc5']), ('\u219a', &['\u2190',
+        '\u0338']), ('\u219b', &['\u2192', '\u0338']), ('\u21ae', &['\u2194', '\u0338']), ('\u21cd',
+        &['\u21d0', '\u0338']), ('\u21ce', &['\u21d4', '\u0338']), ('\u21cf', &['\u21d2',
+        '\u0338']), ('\u2204', &['\u2203', '\u0338']), ('\u2209', &['\u2208', '\u0338']), ('\u220c',
+        &['\u220b', '\u0338']), ('\u2224', &['\u2223', '\u0338']), ('\u2226', &['\u2225',
+        '\u0338']), ('\u2241', &['\u223c', '\u0338']), ('\u2244', &['\u2243', '\u0338']), ('\u2247',
+        &['\u2245', '\u0338']), ('\u2249', &['\u2248', '\u0338']), ('\u2260', &['\x3d', '\u0338']),
+        ('\u2262', &['\u2261', '\u0338']), ('\u226d', &['\u224d', '\u0338']), ('\u226e', &['\x3c',
+        '\u0338']), ('\u226f', &['\x3e', '\u0338']), ('\u2270', &['\u2264', '\u0338']), ('\u2271',
+        &['\u2265', '\u0338']), ('\u2274', &['\u2272', '\u0338']), ('\u2275', &['\u2273',
+        '\u0338']), ('\u2278', &['\u2276', '\u0338']), ('\u2279', &['\u2277', '\u0338']), ('\u2280',
+        &['\u227a', '\u0338']), ('\u2281', &['\u227b', '\u0338']), ('\u2284', &['\u2282',
+        '\u0338']), ('\u2285', &['\u2283', '\u0338']), ('\u2288', &['\u2286', '\u0338']), ('\u2289',
+        &['\u2287', '\u0338']), ('\u22ac', &['\u22a2', '\u0338']), ('\u22ad', &['\u22a8',
+        '\u0338']), ('\u22ae', &['\u22a9', '\u0338']), ('\u22af', &['\u22ab', '\u0338']), ('\u22e0',
+        &['\u227c', '\u0338']), ('\u22e1', &['\u227d', '\u0338']), ('\u22e2', &['\u2291',
+        '\u0338']), ('\u22e3', &['\u2292', '\u0338']), ('\u22ea', &['\u22b2', '\u0338']), ('\u22eb',
+        &['\u22b3', '\u0338']), ('\u22ec', &['\u22b4', '\u0338']), ('\u22ed', &['\u22b5',
+        '\u0338']), ('\u2329', &['\u3008']), ('\u232a', &['\u3009']), ('\u2adc', &['\u2add',
+        '\u0338']), ('\u304c', &['\u304b', '\u3099']), ('\u304e', &['\u304d', '\u3099']), ('\u3050',
+        &['\u304f', '\u3099']), ('\u3052', &['\u3051', '\u3099']), ('\u3054', &['\u3053',
+        '\u3099']), ('\u3056', &['\u3055', '\u3099']), ('\u3058', &['\u3057', '\u3099']), ('\u305a',
+        &['\u3059', '\u3099']), ('\u305c', &['\u305b', '\u3099']), ('\u305e', &['\u305d',
+        '\u3099']), ('\u3060', &['\u305f', '\u3099']), ('\u3062', &['\u3061', '\u3099']), ('\u3065',
+        &['\u3064', '\u3099']), ('\u3067', &['\u3066', '\u3099']), ('\u3069', &['\u3068',
+        '\u3099']), ('\u3070', &['\u306f', '\u3099']), ('\u3071', &['\u306f', '\u309a']), ('\u3073',
+        &['\u3072', '\u3099']), ('\u3074', &['\u3072', '\u309a']), ('\u3076', &['\u3075',
+        '\u3099']), ('\u3077', &['\u3075', '\u309a']), ('\u3079', &['\u3078', '\u3099']), ('\u307a',
+        &['\u3078', '\u309a']), ('\u307c', &['\u307b', '\u3099']), ('\u307d', &['\u307b',
+        '\u309a']), ('\u3094', &['\u3046', '\u3099']), ('\u309e', &['\u309d', '\u3099']), ('\u30ac',
+        &['\u30ab', '\u3099']), ('\u30ae', &['\u30ad', '\u3099']), ('\u30b0', &['\u30af',
+        '\u3099']), ('\u30b2', &['\u30b1', '\u3099']), ('\u30b4', &['\u30b3', '\u3099']), ('\u30b6',
+        &['\u30b5', '\u3099']), ('\u30b8', &['\u30b7', '\u3099']), ('\u30ba', &['\u30b9',
+        '\u3099']), ('\u30bc', &['\u30bb', '\u3099']), ('\u30be', &['\u30bd', '\u3099']), ('\u30c0',
+        &['\u30bf', '\u3099']), ('\u30c2', &['\u30c1', '\u3099']), ('\u30c5', &['\u30c4',
+        '\u3099']), ('\u30c7', &['\u30c6', '\u3099']), ('\u30c9', &['\u30c8', '\u3099']), ('\u30d0',
+        &['\u30cf', '\u3099']), ('\u30d1', &['\u30cf', '\u309a']), ('\u30d3', &['\u30d2',
+        '\u3099']), ('\u30d4', &['\u30d2', '\u309a']), ('\u30d6', &['\u30d5', '\u3099']), ('\u30d7',
+        &['\u30d5', '\u309a']), ('\u30d9', &['\u30d8', '\u3099']), ('\u30da', &['\u30d8',
+        '\u309a']), ('\u30dc', &['\u30db', '\u3099']), ('\u30dd', &['\u30db', '\u309a']), ('\u30f4',
+        &['\u30a6', '\u3099']), ('\u30f7', &['\u30ef', '\u3099']), ('\u30f8', &['\u30f0',
+        '\u3099']), ('\u30f9', &['\u30f1', '\u3099']), ('\u30fa', &['\u30f2', '\u3099']), ('\u30fe',
+        &['\u30fd', '\u3099']), ('\uf900', &['\u8c48']), ('\uf901', &['\u66f4']), ('\uf902',
+        &['\u8eca']), ('\uf903', &['\u8cc8']), ('\uf904', &['\u6ed1']), ('\uf905', &['\u4e32']),
+        ('\uf906', &['\u53e5']), ('\uf907', &['\u9f9c']), ('\uf908', &['\u9f9c']), ('\uf909',
+        &['\u5951']), ('\uf90a', &['\u91d1']), ('\uf90b', &['\u5587']), ('\uf90c', &['\u5948']),
+        ('\uf90d', &['\u61f6']), ('\uf90e', &['\u7669']), ('\uf90f', &['\u7f85']), ('\uf910',
+        &['\u863f']), ('\uf911', &['\u87ba']), ('\uf912', &['\u88f8']), ('\uf913', &['\u908f']),
+        ('\uf914', &['\u6a02']), ('\uf915', &['\u6d1b']), ('\uf916', &['\u70d9']), ('\uf917',
+        &['\u73de']), ('\uf918', &['\u843d']), ('\uf919', &['\u916a']), ('\uf91a', &['\u99f1']),
+        ('\uf91b', &['\u4e82']), ('\uf91c', &['\u5375']), ('\uf91d', &['\u6b04']), ('\uf91e',
+        &['\u721b']), ('\uf91f', &['\u862d']), ('\uf920', &['\u9e1e']), ('\uf921', &['\u5d50']),
+        ('\uf922', &['\u6feb']), ('\uf923', &['\u85cd']), ('\uf924', &['\u8964']), ('\uf925',
+        &['\u62c9']), ('\uf926', &['\u81d8']), ('\uf927', &['\u881f']), ('\uf928', &['\u5eca']),
+        ('\uf929', &['\u6717']), ('\uf92a', &['\u6d6a']), ('\uf92b', &['\u72fc']), ('\uf92c',
+        &['\u90ce']), ('\uf92d', &['\u4f86']), ('\uf92e', &['\u51b7']), ('\uf92f', &['\u52de']),
+        ('\uf930', &['\u64c4']), ('\uf931', &['\u6ad3']), ('\uf932', &['\u7210']), ('\uf933',
+        &['\u76e7']), ('\uf934', &['\u8001']), ('\uf935', &['\u8606']), ('\uf936', &['\u865c']),
+        ('\uf937', &['\u8def']), ('\uf938', &['\u9732']), ('\uf939', &['\u9b6f']), ('\uf93a',
+        &['\u9dfa']), ('\uf93b', &['\u788c']), ('\uf93c', &['\u797f']), ('\uf93d', &['\u7da0']),
+        ('\uf93e', &['\u83c9']), ('\uf93f', &['\u9304']), ('\uf940', &['\u9e7f']), ('\uf941',
+        &['\u8ad6']), ('\uf942', &['\u58df']), ('\uf943', &['\u5f04']), ('\uf944', &['\u7c60']),
+        ('\uf945', &['\u807e']), ('\uf946', &['\u7262']), ('\uf947', &['\u78ca']), ('\uf948',
+        &['\u8cc2']), ('\uf949', &['\u96f7']), ('\uf94a', &['\u58d8']), ('\uf94b', &['\u5c62']),
+        ('\uf94c', &['\u6a13']), ('\uf94d', &['\u6dda']), ('\uf94e', &['\u6f0f']), ('\uf94f',
+        &['\u7d2f']), ('\uf950', &['\u7e37']), ('\uf951', &['\u964b']), ('\uf952', &['\u52d2']),
+        ('\uf953', &['\u808b']), ('\uf954', &['\u51dc']), ('\uf955', &['\u51cc']), ('\uf956',
+        &['\u7a1c']), ('\uf957', &['\u7dbe']), ('\uf958', &['\u83f1']), ('\uf959', &['\u9675']),
+        ('\uf95a', &['\u8b80']), ('\uf95b', &['\u62cf']), ('\uf95c', &['\u6a02']), ('\uf95d',
+        &['\u8afe']), ('\uf95e', &['\u4e39']), ('\uf95f', &['\u5be7']), ('\uf960', &['\u6012']),
+        ('\uf961', &['\u7387']), ('\uf962', &['\u7570']), ('\uf963', &['\u5317']), ('\uf964',
+        &['\u78fb']), ('\uf965', &['\u4fbf']), ('\uf966', &['\u5fa9']), ('\uf967', &['\u4e0d']),
+        ('\uf968', &['\u6ccc']), ('\uf969', &['\u6578']), ('\uf96a', &['\u7d22']), ('\uf96b',
+        &['\u53c3']), ('\uf96c', &['\u585e']), ('\uf96d', &['\u7701']), ('\uf96e', &['\u8449']),
+        ('\uf96f', &['\u8aaa']), ('\uf970', &['\u6bba']), ('\uf971', &['\u8fb0']), ('\uf972',
+        &['\u6c88']), ('\uf973', &['\u62fe']), ('\uf974', &['\u82e5']), ('\uf975', &['\u63a0']),
+        ('\uf976', &['\u7565']), ('\uf977', &['\u4eae']), ('\uf978', &['\u5169']), ('\uf979',
+        &['\u51c9']), ('\uf97a', &['\u6881']), ('\uf97b', &['\u7ce7']), ('\uf97c', &['\u826f']),
+        ('\uf97d', &['\u8ad2']), ('\uf97e', &['\u91cf']), ('\uf97f', &['\u52f5']), ('\uf980',
+        &['\u5442']), ('\uf981', &['\u5973']), ('\uf982', &['\u5eec']), ('\uf983', &['\u65c5']),
+        ('\uf984', &['\u6ffe']), ('\uf985', &['\u792a']), ('\uf986', &['\u95ad']), ('\uf987',
+        &['\u9a6a']), ('\uf988', &['\u9e97']), ('\uf989', &['\u9ece']), ('\uf98a', &['\u529b']),
+        ('\uf98b', &['\u66c6']), ('\uf98c', &['\u6b77']), ('\uf98d', &['\u8f62']), ('\uf98e',
+        &['\u5e74']), ('\uf98f', &['\u6190']), ('\uf990', &['\u6200']), ('\uf991', &['\u649a']),
+        ('\uf992', &['\u6f23']), ('\uf993', &['\u7149']), ('\uf994', &['\u7489']), ('\uf995',
+        &['\u79ca']), ('\uf996', &['\u7df4']), ('\uf997', &['\u806f']), ('\uf998', &['\u8f26']),
+        ('\uf999', &['\u84ee']), ('\uf99a', &['\u9023']), ('\uf99b', &['\u934a']), ('\uf99c',
+        &['\u5217']), ('\uf99d', &['\u52a3']), ('\uf99e', &['\u54bd']), ('\uf99f', &['\u70c8']),
+        ('\uf9a0', &['\u88c2']), ('\uf9a1', &['\u8aaa']), ('\uf9a2', &['\u5ec9']), ('\uf9a3',
+        &['\u5ff5']), ('\uf9a4', &['\u637b']), ('\uf9a5', &['\u6bae']), ('\uf9a6', &['\u7c3e']),
+        ('\uf9a7', &['\u7375']), ('\uf9a8', &['\u4ee4']), ('\uf9a9', &['\u56f9']), ('\uf9aa',
+        &['\u5be7']), ('\uf9ab', &['\u5dba']), ('\uf9ac', &['\u601c']), ('\uf9ad', &['\u73b2']),
+        ('\uf9ae', &['\u7469']), ('\uf9af', &['\u7f9a']), ('\uf9b0', &['\u8046']), ('\uf9b1',
+        &['\u9234']), ('\uf9b2', &['\u96f6']), ('\uf9b3', &['\u9748']), ('\uf9b4', &['\u9818']),
+        ('\uf9b5', &['\u4f8b']), ('\uf9b6', &['\u79ae']), ('\uf9b7', &['\u91b4']), ('\uf9b8',
+        &['\u96b8']), ('\uf9b9', &['\u60e1']), ('\uf9ba', &['\u4e86']), ('\uf9bb', &['\u50da']),
+        ('\uf9bc', &['\u5bee']), ('\uf9bd', &['\u5c3f']), ('\uf9be', &['\u6599']), ('\uf9bf',
+        &['\u6a02']), ('\uf9c0', &['\u71ce']), ('\uf9c1', &['\u7642']), ('\uf9c2', &['\u84fc']),
+        ('\uf9c3', &['\u907c']), ('\uf9c4', &['\u9f8d']), ('\uf9c5', &['\u6688']), ('\uf9c6',
+        &['\u962e']), ('\uf9c7', &['\u5289']), ('\uf9c8', &['\u677b']), ('\uf9c9', &['\u67f3']),
+        ('\uf9ca', &['\u6d41']), ('\uf9cb', &['\u6e9c']), ('\uf9cc', &['\u7409']), ('\uf9cd',
+        &['\u7559']), ('\uf9ce', &['\u786b']), ('\uf9cf', &['\u7d10']), ('\uf9d0', &['\u985e']),
+        ('\uf9d1', &['\u516d']), ('\uf9d2', &['\u622e']), ('\uf9d3', &['\u9678']), ('\uf9d4',
+        &['\u502b']), ('\uf9d5', &['\u5d19']), ('\uf9d6', &['\u6dea']), ('\uf9d7', &['\u8f2a']),
+        ('\uf9d8', &['\u5f8b']), ('\uf9d9', &['\u6144']), ('\uf9da', &['\u6817']), ('\uf9db',
+        &['\u7387']), ('\uf9dc', &['\u9686']), ('\uf9dd', &['\u5229']), ('\uf9de', &['\u540f']),
+        ('\uf9df', &['\u5c65']), ('\uf9e0', &['\u6613']), ('\uf9e1', &['\u674e']), ('\uf9e2',
+        &['\u68a8']), ('\uf9e3', &['\u6ce5']), ('\uf9e4', &['\u7406']), ('\uf9e5', &['\u75e2']),
+        ('\uf9e6', &['\u7f79']), ('\uf9e7', &['\u88cf']), ('\uf9e8', &['\u88e1']), ('\uf9e9',
+        &['\u91cc']), ('\uf9ea', &['\u96e2']), ('\uf9eb', &['\u533f']), ('\uf9ec', &['\u6eba']),
+        ('\uf9ed', &['\u541d']), ('\uf9ee', &['\u71d0']), ('\uf9ef', &['\u7498']), ('\uf9f0',
+        &['\u85fa']), ('\uf9f1', &['\u96a3']), ('\uf9f2', &['\u9c57']), ('\uf9f3', &['\u9e9f']),
+        ('\uf9f4', &['\u6797']), ('\uf9f5', &['\u6dcb']), ('\uf9f6', &['\u81e8']), ('\uf9f7',
+        &['\u7acb']), ('\uf9f8', &['\u7b20']), ('\uf9f9', &['\u7c92']), ('\uf9fa', &['\u72c0']),
+        ('\uf9fb', &['\u7099']), ('\uf9fc', &['\u8b58']), ('\uf9fd', &['\u4ec0']), ('\uf9fe',
+        &['\u8336']), ('\uf9ff', &['\u523a']), ('\ufa00', &['\u5207']), ('\ufa01', &['\u5ea6']),
+        ('\ufa02', &['\u62d3']), ('\ufa03', &['\u7cd6']), ('\ufa04', &['\u5b85']), ('\ufa05',
+        &['\u6d1e']), ('\ufa06', &['\u66b4']), ('\ufa07', &['\u8f3b']), ('\ufa08', &['\u884c']),
+        ('\ufa09', &['\u964d']), ('\ufa0a', &['\u898b']), ('\ufa0b', &['\u5ed3']), ('\ufa0c',
+        &['\u5140']), ('\ufa0d', &['\u55c0']), ('\ufa10', &['\u585a']), ('\ufa12', &['\u6674']),
+        ('\ufa15', &['\u51de']), ('\ufa16', &['\u732a']), ('\ufa17', &['\u76ca']), ('\ufa18',
+        &['\u793c']), ('\ufa19', &['\u795e']), ('\ufa1a', &['\u7965']), ('\ufa1b', &['\u798f']),
+        ('\ufa1c', &['\u9756']), ('\ufa1d', &['\u7cbe']), ('\ufa1e', &['\u7fbd']), ('\ufa20',
+        &['\u8612']), ('\ufa22', &['\u8af8']), ('\ufa25', &['\u9038']), ('\ufa26', &['\u90fd']),
+        ('\ufa2a', &['\u98ef']), ('\ufa2b', &['\u98fc']), ('\ufa2c', &['\u9928']), ('\ufa2d',
+        &['\u9db4']), ('\ufa2e', &['\u90de']), ('\ufa2f', &['\u96b7']), ('\ufa30', &['\u4fae']),
+        ('\ufa31', &['\u50e7']), ('\ufa32', &['\u514d']), ('\ufa33', &['\u52c9']), ('\ufa34',
+        &['\u52e4']), ('\ufa35', &['\u5351']), ('\ufa36', &['\u559d']), ('\ufa37', &['\u5606']),
+        ('\ufa38', &['\u5668']), ('\ufa39', &['\u5840']), ('\ufa3a', &['\u58a8']), ('\ufa3b',
+        &['\u5c64']), ('\ufa3c', &['\u5c6e']), ('\ufa3d', &['\u6094']), ('\ufa3e', &['\u6168']),
+        ('\ufa3f', &['\u618e']), ('\ufa40', &['\u61f2']), ('\ufa41', &['\u654f']), ('\ufa42',
+        &['\u65e2']), ('\ufa43', &['\u6691']), ('\ufa44', &['\u6885']), ('\ufa45', &['\u6d77']),
+        ('\ufa46', &['\u6e1a']), ('\ufa47', &['\u6f22']), ('\ufa48', &['\u716e']), ('\ufa49',
+        &['\u722b']), ('\ufa4a', &['\u7422']), ('\ufa4b', &['\u7891']), ('\ufa4c', &['\u793e']),
+        ('\ufa4d', &['\u7949']), ('\ufa4e', &['\u7948']), ('\ufa4f', &['\u7950']), ('\ufa50',
+        &['\u7956']), ('\ufa51', &['\u795d']), ('\ufa52', &['\u798d']), ('\ufa53', &['\u798e']),
+        ('\ufa54', &['\u7a40']), ('\ufa55', &['\u7a81']), ('\ufa56', &['\u7bc0']), ('\ufa57',
+        &['\u7df4']), ('\ufa58', &['\u7e09']), ('\ufa59', &['\u7e41']), ('\ufa5a', &['\u7f72']),
+        ('\ufa5b', &['\u8005']), ('\ufa5c', &['\u81ed']), ('\ufa5d', &['\u8279']), ('\ufa5e',
+        &['\u8279']), ('\ufa5f', &['\u8457']), ('\ufa60', &['\u8910']), ('\ufa61', &['\u8996']),
+        ('\ufa62', &['\u8b01']), ('\ufa63', &['\u8b39']), ('\ufa64', &['\u8cd3']), ('\ufa65',
+        &['\u8d08']), ('\ufa66', &['\u8fb6']), ('\ufa67', &['\u9038']), ('\ufa68', &['\u96e3']),
+        ('\ufa69', &['\u97ff']), ('\ufa6a', &['\u983b']), ('\ufa6b', &['\u6075']), ('\ufa6c',
+        &['\U000242ee']), ('\ufa6d', &['\u8218']), ('\ufa70', &['\u4e26']), ('\ufa71', &['\u51b5']),
+        ('\ufa72', &['\u5168']), ('\ufa73', &['\u4f80']), ('\ufa74', &['\u5145']), ('\ufa75',
+        &['\u5180']), ('\ufa76', &['\u52c7']), ('\ufa77', &['\u52fa']), ('\ufa78', &['\u559d']),
+        ('\ufa79', &['\u5555']), ('\ufa7a', &['\u5599']), ('\ufa7b', &['\u55e2']), ('\ufa7c',
+        &['\u585a']), ('\ufa7d', &['\u58b3']), ('\ufa7e', &['\u5944']), ('\ufa7f', &['\u5954']),
+        ('\ufa80', &['\u5a62']), ('\ufa81', &['\u5b28']), ('\ufa82', &['\u5ed2']), ('\ufa83',
+        &['\u5ed9']), ('\ufa84', &['\u5f69']), ('\ufa85', &['\u5fad']), ('\ufa86', &['\u60d8']),
+        ('\ufa87', &['\u614e']), ('\ufa88', &['\u6108']), ('\ufa89', &['\u618e']), ('\ufa8a',
+        &['\u6160']), ('\ufa8b', &['\u61f2']), ('\ufa8c', &['\u6234']), ('\ufa8d', &['\u63c4']),
+        ('\ufa8e', &['\u641c']), ('\ufa8f', &['\u6452']), ('\ufa90', &['\u6556']), ('\ufa91',
+        &['\u6674']), ('\ufa92', &['\u6717']), ('\ufa93', &['\u671b']), ('\ufa94', &['\u6756']),
+        ('\ufa95', &['\u6b79']), ('\ufa96', &['\u6bba']), ('\ufa97', &['\u6d41']), ('\ufa98',
+        &['\u6edb']), ('\ufa99', &['\u6ecb']), ('\ufa9a', &['\u6f22']), ('\ufa9b', &['\u701e']),
+        ('\ufa9c', &['\u716e']), ('\ufa9d', &['\u77a7']), ('\ufa9e', &['\u7235']), ('\ufa9f',
+        &['\u72af']), ('\ufaa0', &['\u732a']), ('\ufaa1', &['\u7471']), ('\ufaa2', &['\u7506']),
+        ('\ufaa3', &['\u753b']), ('\ufaa4', &['\u761d']), ('\ufaa5', &['\u761f']), ('\ufaa6',
+        &['\u76ca']), ('\ufaa7', &['\u76db']), ('\ufaa8', &['\u76f4']), ('\ufaa9', &['\u774a']),
+        ('\ufaaa', &['\u7740']), ('\ufaab', &['\u78cc']), ('\ufaac', &['\u7ab1']), ('\ufaad',
+        &['\u7bc0']), ('\ufaae', &['\u7c7b']), ('\ufaaf', &['\u7d5b']), ('\ufab0', &['\u7df4']),
+        ('\ufab1', &['\u7f3e']), ('\ufab2', &['\u8005']), ('\ufab3', &['\u8352']), ('\ufab4',
+        &['\u83ef']), ('\ufab5', &['\u8779']), ('\ufab6', &['\u8941']), ('\ufab7', &['\u8986']),
+        ('\ufab8', &['\u8996']), ('\ufab9', &['\u8abf']), ('\ufaba', &['\u8af8']), ('\ufabb',
+        &['\u8acb']), ('\ufabc', &['\u8b01']), ('\ufabd', &['\u8afe']), ('\ufabe', &['\u8aed']),
+        ('\ufabf', &['\u8b39']), ('\ufac0', &['\u8b8a']), ('\ufac1', &['\u8d08']), ('\ufac2',
+        &['\u8f38']), ('\ufac3', &['\u9072']), ('\ufac4', &['\u9199']), ('\ufac5', &['\u9276']),
+        ('\ufac6', &['\u967c']), ('\ufac7', &['\u96e3']), ('\ufac8', &['\u9756']), ('\ufac9',
+        &['\u97db']), ('\ufaca', &['\u97ff']), ('\ufacb', &['\u980b']), ('\ufacc', &['\u983b']),
+        ('\ufacd', &['\u9b12']), ('\uface', &['\u9f9c']), ('\ufacf', &['\U0002284a']), ('\ufad0',
+        &['\U00022844']), ('\ufad1', &['\U000233d5']), ('\ufad2', &['\u3b9d']), ('\ufad3',
+        &['\u4018']), ('\ufad4', &['\u4039']), ('\ufad5', &['\U00025249']), ('\ufad6',
+        &['\U00025cd0']), ('\ufad7', &['\U00027ed3']), ('\ufad8', &['\u9f43']), ('\ufad9',
+        &['\u9f8e']), ('\ufb1d', &['\u05d9', '\u05b4']), ('\ufb1f', &['\u05f2', '\u05b7']),
+        ('\ufb2a', &['\u05e9', '\u05c1']), ('\ufb2b', &['\u05e9', '\u05c2']), ('\ufb2c', &['\ufb49',
+        '\u05c1']), ('\ufb2d', &['\ufb49', '\u05c2']), ('\ufb2e', &['\u05d0', '\u05b7']), ('\ufb2f',
+        &['\u05d0', '\u05b8']), ('\ufb30', &['\u05d0', '\u05bc']), ('\ufb31', &['\u05d1',
+        '\u05bc']), ('\ufb32', &['\u05d2', '\u05bc']), ('\ufb33', &['\u05d3', '\u05bc']), ('\ufb34',
+        &['\u05d4', '\u05bc']), ('\ufb35', &['\u05d5', '\u05bc']), ('\ufb36', &['\u05d6',
+        '\u05bc']), ('\ufb38', &['\u05d8', '\u05bc']), ('\ufb39', &['\u05d9', '\u05bc']), ('\ufb3a',
+        &['\u05da', '\u05bc']), ('\ufb3b', &['\u05db', '\u05bc']), ('\ufb3c', &['\u05dc',
+        '\u05bc']), ('\ufb3e', &['\u05de', '\u05bc']), ('\ufb40', &['\u05e0', '\u05bc']), ('\ufb41',
+        &['\u05e1', '\u05bc']), ('\ufb43', &['\u05e3', '\u05bc']), ('\ufb44', &['\u05e4',
+        '\u05bc']), ('\ufb46', &['\u05e6', '\u05bc']), ('\ufb47', &['\u05e7', '\u05bc']), ('\ufb48',
+        &['\u05e8', '\u05bc']), ('\ufb49', &['\u05e9', '\u05bc']), ('\ufb4a', &['\u05ea',
+        '\u05bc']), ('\ufb4b', &['\u05d5', '\u05b9']), ('\ufb4c', &['\u05d1', '\u05bf']), ('\ufb4d',
+        &['\u05db', '\u05bf']), ('\ufb4e', &['\u05e4', '\u05bf']), ('\U0001109a', &['\U00011099',
+        '\U000110ba']), ('\U0001109c', &['\U0001109b', '\U000110ba']), ('\U000110ab',
+        &['\U000110a5', '\U000110ba']), ('\U0001112e', &['\U00011131', '\U00011127']),
+        ('\U0001112f', &['\U00011132', '\U00011127']), ('\U0001134b', &['\U00011347',
+        '\U0001133e']), ('\U0001134c', &['\U00011347', '\U00011357']), ('\U000114bb',
+        &['\U000114b9', '\U000114ba']), ('\U000114bc', &['\U000114b9', '\U000114b0']),
+        ('\U000114be', &['\U000114b9', '\U000114bd']), ('\U000115ba', &['\U000115b8',
+        '\U000115af']), ('\U000115bb', &['\U000115b9', '\U000115af']), ('\U0001d15e',
+        &['\U0001d157', '\U0001d165']), ('\U0001d15f', &['\U0001d158', '\U0001d165']),
+        ('\U0001d160', &['\U0001d15f', '\U0001d16e']), ('\U0001d161', &['\U0001d15f',
+        '\U0001d16f']), ('\U0001d162', &['\U0001d15f', '\U0001d170']), ('\U0001d163',
+        &['\U0001d15f', '\U0001d171']), ('\U0001d164', &['\U0001d15f', '\U0001d172']),
+        ('\U0001d1bb', &['\U0001d1b9', '\U0001d165']), ('\U0001d1bc', &['\U0001d1ba',
+        '\U0001d165']), ('\U0001d1bd', &['\U0001d1bb', '\U0001d16e']), ('\U0001d1be',
+        &['\U0001d1bc', '\U0001d16e']), ('\U0001d1bf', &['\U0001d1bb', '\U0001d16f']),
+        ('\U0001d1c0', &['\U0001d1bc', '\U0001d16f']), ('\U0002f800', &['\u4e3d']), ('\U0002f801',
+        &['\u4e38']), ('\U0002f802', &['\u4e41']), ('\U0002f803', &['\U00020122']), ('\U0002f804',
+        &['\u4f60']), ('\U0002f805', &['\u4fae']), ('\U0002f806', &['\u4fbb']), ('\U0002f807',
+        &['\u5002']), ('\U0002f808', &['\u507a']), ('\U0002f809', &['\u5099']), ('\U0002f80a',
+        &['\u50e7']), ('\U0002f80b', &['\u50cf']), ('\U0002f80c', &['\u349e']), ('\U0002f80d',
+        &['\U0002063a']), ('\U0002f80e', &['\u514d']), ('\U0002f80f', &['\u5154']), ('\U0002f810',
+        &['\u5164']), ('\U0002f811', &['\u5177']), ('\U0002f812', &['\U0002051c']), ('\U0002f813',
+        &['\u34b9']), ('\U0002f814', &['\u5167']), ('\U0002f815', &['\u518d']), ('\U0002f816',
+        &['\U0002054b']), ('\U0002f817', &['\u5197']), ('\U0002f818', &['\u51a4']), ('\U0002f819',
+        &['\u4ecc']), ('\U0002f81a', &['\u51ac']), ('\U0002f81b', &['\u51b5']), ('\U0002f81c',
+        &['\U000291df']), ('\U0002f81d', &['\u51f5']), ('\U0002f81e', &['\u5203']), ('\U0002f81f',
+        &['\u34df']), ('\U0002f820', &['\u523b']), ('\U0002f821', &['\u5246']), ('\U0002f822',
+        &['\u5272']), ('\U0002f823', &['\u5277']), ('\U0002f824', &['\u3515']), ('\U0002f825',
+        &['\u52c7']), ('\U0002f826', &['\u52c9']), ('\U0002f827', &['\u52e4']), ('\U0002f828',
+        &['\u52fa']), ('\U0002f829', &['\u5305']), ('\U0002f82a', &['\u5306']), ('\U0002f82b',
+        &['\u5317']), ('\U0002f82c', &['\u5349']), ('\U0002f82d', &['\u5351']), ('\U0002f82e',
+        &['\u535a']), ('\U0002f82f', &['\u5373']), ('\U0002f830', &['\u537d']), ('\U0002f831',
+        &['\u537f']), ('\U0002f832', &['\u537f']), ('\U0002f833', &['\u537f']), ('\U0002f834',
+        &['\U00020a2c']), ('\U0002f835', &['\u7070']), ('\U0002f836', &['\u53ca']), ('\U0002f837',
+        &['\u53df']), ('\U0002f838', &['\U00020b63']), ('\U0002f839', &['\u53eb']), ('\U0002f83a',
+        &['\u53f1']), ('\U0002f83b', &['\u5406']), ('\U0002f83c', &['\u549e']), ('\U0002f83d',
+        &['\u5438']), ('\U0002f83e', &['\u5448']), ('\U0002f83f', &['\u5468']), ('\U0002f840',
+        &['\u54a2']), ('\U0002f841', &['\u54f6']), ('\U0002f842', &['\u5510']), ('\U0002f843',
+        &['\u5553']), ('\U0002f844', &['\u5563']), ('\U0002f845', &['\u5584']), ('\U0002f846',
+        &['\u5584']), ('\U0002f847', &['\u5599']), ('\U0002f848', &['\u55ab']), ('\U0002f849',
+        &['\u55b3']), ('\U0002f84a', &['\u55c2']), ('\U0002f84b', &['\u5716']), ('\U0002f84c',
+        &['\u5606']), ('\U0002f84d', &['\u5717']), ('\U0002f84e', &['\u5651']), ('\U0002f84f',
+        &['\u5674']), ('\U0002f850', &['\u5207']), ('\U0002f851', &['\u58ee']), ('\U0002f852',
+        &['\u57ce']), ('\U0002f853', &['\u57f4']), ('\U0002f854', &['\u580d']), ('\U0002f855',
+        &['\u578b']), ('\U0002f856', &['\u5832']), ('\U0002f857', &['\u5831']), ('\U0002f858',
+        &['\u58ac']), ('\U0002f859', &['\U000214e4']), ('\U0002f85a', &['\u58f2']), ('\U0002f85b',
+        &['\u58f7']), ('\U0002f85c', &['\u5906']), ('\U0002f85d', &['\u591a']), ('\U0002f85e',
+        &['\u5922']), ('\U0002f85f', &['\u5962']), ('\U0002f860', &['\U000216a8']), ('\U0002f861',
+        &['\U000216ea']), ('\U0002f862', &['\u59ec']), ('\U0002f863', &['\u5a1b']), ('\U0002f864',
+        &['\u5a27']), ('\U0002f865', &['\u59d8']), ('\U0002f866', &['\u5a66']), ('\U0002f867',
+        &['\u36ee']), ('\U0002f868', &['\u36fc']), ('\U0002f869', &['\u5b08']), ('\U0002f86a',
+        &['\u5b3e']), ('\U0002f86b', &['\u5b3e']), ('\U0002f86c', &['\U000219c8']), ('\U0002f86d',
+        &['\u5bc3']), ('\U0002f86e', &['\u5bd8']), ('\U0002f86f', &['\u5be7']), ('\U0002f870',
+        &['\u5bf3']), ('\U0002f871', &['\U00021b18']), ('\U0002f872', &['\u5bff']), ('\U0002f873',
+        &['\u5c06']), ('\U0002f874', &['\u5f53']), ('\U0002f875', &['\u5c22']), ('\U0002f876',
+        &['\u3781']), ('\U0002f877', &['\u5c60']), ('\U0002f878', &['\u5c6e']), ('\U0002f879',
+        &['\u5cc0']), ('\U0002f87a', &['\u5c8d']), ('\U0002f87b', &['\U00021de4']), ('\U0002f87c',
+        &['\u5d43']), ('\U0002f87d', &['\U00021de6']), ('\U0002f87e', &['\u5d6e']), ('\U0002f87f',
+        &['\u5d6b']), ('\U0002f880', &['\u5d7c']), ('\U0002f881', &['\u5de1']), ('\U0002f882',
+        &['\u5de2']), ('\U0002f883', &['\u382f']), ('\U0002f884', &['\u5dfd']), ('\U0002f885',
+        &['\u5e28']), ('\U0002f886', &['\u5e3d']), ('\U0002f887', &['\u5e69']), ('\U0002f888',
+        &['\u3862']), ('\U0002f889', &['\U00022183']), ('\U0002f88a', &['\u387c']), ('\U0002f88b',
+        &['\u5eb0']), ('\U0002f88c', &['\u5eb3']), ('\U0002f88d', &['\u5eb6']), ('\U0002f88e',
+        &['\u5eca']), ('\U0002f88f', &['\U0002a392']), ('\U0002f890', &['\u5efe']), ('\U0002f891',
+        &['\U00022331']), ('\U0002f892', &['\U00022331']), ('\U0002f893', &['\u8201']),
+        ('\U0002f894', &['\u5f22']), ('\U0002f895', &['\u5f22']), ('\U0002f896', &['\u38c7']),
+        ('\U0002f897', &['\U000232b8']), ('\U0002f898', &['\U000261da']), ('\U0002f899',
+        &['\u5f62']), ('\U0002f89a', &['\u5f6b']), ('\U0002f89b', &['\u38e3']), ('\U0002f89c',
+        &['\u5f9a']), ('\U0002f89d', &['\u5fcd']), ('\U0002f89e', &['\u5fd7']), ('\U0002f89f',
+        &['\u5ff9']), ('\U0002f8a0', &['\u6081']), ('\U0002f8a1', &['\u393a']), ('\U0002f8a2',
+        &['\u391c']), ('\U0002f8a3', &['\u6094']), ('\U0002f8a4', &['\U000226d4']), ('\U0002f8a5',
+        &['\u60c7']), ('\U0002f8a6', &['\u6148']), ('\U0002f8a7', &['\u614c']), ('\U0002f8a8',
+        &['\u614e']), ('\U0002f8a9', &['\u614c']), ('\U0002f8aa', &['\u617a']), ('\U0002f8ab',
+        &['\u618e']), ('\U0002f8ac', &['\u61b2']), ('\U0002f8ad', &['\u61a4']), ('\U0002f8ae',
+        &['\u61af']), ('\U0002f8af', &['\u61de']), ('\U0002f8b0', &['\u61f2']), ('\U0002f8b1',
+        &['\u61f6']), ('\U0002f8b2', &['\u6210']), ('\U0002f8b3', &['\u621b']), ('\U0002f8b4',
+        &['\u625d']), ('\U0002f8b5', &['\u62b1']), ('\U0002f8b6', &['\u62d4']), ('\U0002f8b7',
+        &['\u6350']), ('\U0002f8b8', &['\U00022b0c']), ('\U0002f8b9', &['\u633d']), ('\U0002f8ba',
+        &['\u62fc']), ('\U0002f8bb', &['\u6368']), ('\U0002f8bc', &['\u6383']), ('\U0002f8bd',
+        &['\u63e4']), ('\U0002f8be', &['\U00022bf1']), ('\U0002f8bf', &['\u6422']), ('\U0002f8c0',
+        &['\u63c5']), ('\U0002f8c1', &['\u63a9']), ('\U0002f8c2', &['\u3a2e']), ('\U0002f8c3',
+        &['\u6469']), ('\U0002f8c4', &['\u647e']), ('\U0002f8c5', &['\u649d']), ('\U0002f8c6',
+        &['\u6477']), ('\U0002f8c7', &['\u3a6c']), ('\U0002f8c8', &['\u654f']), ('\U0002f8c9',
+        &['\u656c']), ('\U0002f8ca', &['\U0002300a']), ('\U0002f8cb', &['\u65e3']), ('\U0002f8cc',
+        &['\u66f8']), ('\U0002f8cd', &['\u6649']), ('\U0002f8ce', &['\u3b19']), ('\U0002f8cf',
+        &['\u6691']), ('\U0002f8d0', &['\u3b08']), ('\U0002f8d1', &['\u3ae4']), ('\U0002f8d2',
+        &['\u5192']), ('\U0002f8d3', &['\u5195']), ('\U0002f8d4', &['\u6700']), ('\U0002f8d5',
+        &['\u669c']), ('\U0002f8d6', &['\u80ad']), ('\U0002f8d7', &['\u43d9']), ('\U0002f8d8',
+        &['\u6717']), ('\U0002f8d9', &['\u671b']), ('\U0002f8da', &['\u6721']), ('\U0002f8db',
+        &['\u675e']), ('\U0002f8dc', &['\u6753']), ('\U0002f8dd', &['\U000233c3']), ('\U0002f8de',
+        &['\u3b49']), ('\U0002f8df', &['\u67fa']), ('\U0002f8e0', &['\u6785']), ('\U0002f8e1',
+        &['\u6852']), ('\U0002f8e2', &['\u6885']), ('\U0002f8e3', &['\U0002346d']), ('\U0002f8e4',
+        &['\u688e']), ('\U0002f8e5', &['\u681f']), ('\U0002f8e6', &['\u6914']), ('\U0002f8e7',
+        &['\u3b9d']), ('\U0002f8e8', &['\u6942']), ('\U0002f8e9', &['\u69a3']), ('\U0002f8ea',
+        &['\u69ea']), ('\U0002f8eb', &['\u6aa8']), ('\U0002f8ec', &['\U000236a3']), ('\U0002f8ed',
+        &['\u6adb']), ('\U0002f8ee', &['\u3c18']), ('\U0002f8ef', &['\u6b21']), ('\U0002f8f0',
+        &['\U000238a7']), ('\U0002f8f1', &['\u6b54']), ('\U0002f8f2', &['\u3c4e']), ('\U0002f8f3',
+        &['\u6b72']), ('\U0002f8f4', &['\u6b9f']), ('\U0002f8f5', &['\u6bba']), ('\U0002f8f6',
+        &['\u6bbb']), ('\U0002f8f7', &['\U00023a8d']), ('\U0002f8f8', &['\U00021d0b']),
+        ('\U0002f8f9', &['\U00023afa']), ('\U0002f8fa', &['\u6c4e']), ('\U0002f8fb',
+        &['\U00023cbc']), ('\U0002f8fc', &['\u6cbf']), ('\U0002f8fd', &['\u6ccd']), ('\U0002f8fe',
+        &['\u6c67']), ('\U0002f8ff', &['\u6d16']), ('\U0002f900', &['\u6d3e']), ('\U0002f901',
+        &['\u6d77']), ('\U0002f902', &['\u6d41']), ('\U0002f903', &['\u6d69']), ('\U0002f904',
+        &['\u6d78']), ('\U0002f905', &['\u6d85']), ('\U0002f906', &['\U00023d1e']), ('\U0002f907',
+        &['\u6d34']), ('\U0002f908', &['\u6e2f']), ('\U0002f909', &['\u6e6e']), ('\U0002f90a',
+        &['\u3d33']), ('\U0002f90b', &['\u6ecb']), ('\U0002f90c', &['\u6ec7']), ('\U0002f90d',
+        &['\U00023ed1']), ('\U0002f90e', &['\u6df9']), ('\U0002f90f', &['\u6f6e']), ('\U0002f910',
+        &['\U00023f5e']), ('\U0002f911', &['\U00023f8e']), ('\U0002f912', &['\u6fc6']),
+        ('\U0002f913', &['\u7039']), ('\U0002f914', &['\u701e']), ('\U0002f915', &['\u701b']),
+        ('\U0002f916', &['\u3d96']), ('\U0002f917', &['\u704a']), ('\U0002f918', &['\u707d']),
+        ('\U0002f919', &['\u7077']), ('\U0002f91a', &['\u70ad']), ('\U0002f91b', &['\U00020525']),
+        ('\U0002f91c', &['\u7145']), ('\U0002f91d', &['\U00024263']), ('\U0002f91e', &['\u719c']),
+        ('\U0002f91f', &['\U000243ab']), ('\U0002f920', &['\u7228']), ('\U0002f921', &['\u7235']),
+        ('\U0002f922', &['\u7250']), ('\U0002f923', &['\U00024608']), ('\U0002f924', &['\u7280']),
+        ('\U0002f925', &['\u7295']), ('\U0002f926', &['\U00024735']), ('\U0002f927',
+        &['\U00024814']), ('\U0002f928', &['\u737a']), ('\U0002f929', &['\u738b']), ('\U0002f92a',
+        &['\u3eac']), ('\U0002f92b', &['\u73a5']), ('\U0002f92c', &['\u3eb8']), ('\U0002f92d',
+        &['\u3eb8']), ('\U0002f92e', &['\u7447']), ('\U0002f92f', &['\u745c']), ('\U0002f930',
+        &['\u7471']), ('\U0002f931', &['\u7485']), ('\U0002f932', &['\u74ca']), ('\U0002f933',
+        &['\u3f1b']), ('\U0002f934', &['\u7524']), ('\U0002f935', &['\U00024c36']), ('\U0002f936',
+        &['\u753e']), ('\U0002f937', &['\U00024c92']), ('\U0002f938', &['\u7570']), ('\U0002f939',
+        &['\U0002219f']), ('\U0002f93a', &['\u7610']), ('\U0002f93b', &['\U00024fa1']),
+        ('\U0002f93c', &['\U00024fb8']), ('\U0002f93d', &['\U00025044']), ('\U0002f93e',
+        &['\u3ffc']), ('\U0002f93f', &['\u4008']), ('\U0002f940', &['\u76f4']), ('\U0002f941',
+        &['\U000250f3']), ('\U0002f942', &['\U000250f2']), ('\U0002f943', &['\U00025119']),
+        ('\U0002f944', &['\U00025133']), ('\U0002f945', &['\u771e']), ('\U0002f946', &['\u771f']),
+        ('\U0002f947', &['\u771f']), ('\U0002f948', &['\u774a']), ('\U0002f949', &['\u4039']),
+        ('\U0002f94a', &['\u778b']), ('\U0002f94b', &['\u4046']), ('\U0002f94c', &['\u4096']),
+        ('\U0002f94d', &['\U0002541d']), ('\U0002f94e', &['\u784e']), ('\U0002f94f', &['\u788c']),
+        ('\U0002f950', &['\u78cc']), ('\U0002f951', &['\u40e3']), ('\U0002f952', &['\U00025626']),
+        ('\U0002f953', &['\u7956']), ('\U0002f954', &['\U0002569a']), ('\U0002f955',
+        &['\U000256c5']), ('\U0002f956', &['\u798f']), ('\U0002f957', &['\u79eb']), ('\U0002f958',
+        &['\u412f']), ('\U0002f959', &['\u7a40']), ('\U0002f95a', &['\u7a4a']), ('\U0002f95b',
+        &['\u7a4f']), ('\U0002f95c', &['\U0002597c']), ('\U0002f95d', &['\U00025aa7']),
+        ('\U0002f95e', &['\U00025aa7']), ('\U0002f95f', &['\u7aee']), ('\U0002f960', &['\u4202']),
+        ('\U0002f961', &['\U00025bab']), ('\U0002f962', &['\u7bc6']), ('\U0002f963', &['\u7bc9']),
+        ('\U0002f964', &['\u4227']), ('\U0002f965', &['\U00025c80']), ('\U0002f966', &['\u7cd2']),
+        ('\U0002f967', &['\u42a0']), ('\U0002f968', &['\u7ce8']), ('\U0002f969', &['\u7ce3']),
+        ('\U0002f96a', &['\u7d00']), ('\U0002f96b', &['\U00025f86']), ('\U0002f96c', &['\u7d63']),
+        ('\U0002f96d', &['\u4301']), ('\U0002f96e', &['\u7dc7']), ('\U0002f96f', &['\u7e02']),
+        ('\U0002f970', &['\u7e45']), ('\U0002f971', &['\u4334']), ('\U0002f972', &['\U00026228']),
+        ('\U0002f973', &['\U00026247']), ('\U0002f974', &['\u4359']), ('\U0002f975',
+        &['\U000262d9']), ('\U0002f976', &['\u7f7a']), ('\U0002f977', &['\U0002633e']),
+        ('\U0002f978', &['\u7f95']), ('\U0002f979', &['\u7ffa']), ('\U0002f97a', &['\u8005']),
+        ('\U0002f97b', &['\U000264da']), ('\U0002f97c', &['\U00026523']), ('\U0002f97d',
+        &['\u8060']), ('\U0002f97e', &['\U000265a8']), ('\U0002f97f', &['\u8070']), ('\U0002f980',
+        &['\U0002335f']), ('\U0002f981', &['\u43d5']), ('\U0002f982', &['\u80b2']), ('\U0002f983',
+        &['\u8103']), ('\U0002f984', &['\u440b']), ('\U0002f985', &['\u813e']), ('\U0002f986',
+        &['\u5ab5']), ('\U0002f987', &['\U000267a7']), ('\U0002f988', &['\U000267b5']),
+        ('\U0002f989', &['\U00023393']), ('\U0002f98a', &['\U0002339c']), ('\U0002f98b',
+        &['\u8201']), ('\U0002f98c', &['\u8204']), ('\U0002f98d', &['\u8f9e']), ('\U0002f98e',
+        &['\u446b']), ('\U0002f98f', &['\u8291']), ('\U0002f990', &['\u828b']), ('\U0002f991',
+        &['\u829d']), ('\U0002f992', &['\u52b3']), ('\U0002f993', &['\u82b1']), ('\U0002f994',
+        &['\u82b3']), ('\U0002f995', &['\u82bd']), ('\U0002f996', &['\u82e6']), ('\U0002f997',
+        &['\U00026b3c']), ('\U0002f998', &['\u82e5']), ('\U0002f999', &['\u831d']), ('\U0002f99a',
+        &['\u8363']), ('\U0002f99b', &['\u83ad']), ('\U0002f99c', &['\u8323']), ('\U0002f99d',
+        &['\u83bd']), ('\U0002f99e', &['\u83e7']), ('\U0002f99f', &['\u8457']), ('\U0002f9a0',
+        &['\u8353']), ('\U0002f9a1', &['\u83ca']), ('\U0002f9a2', &['\u83cc']), ('\U0002f9a3',
+        &['\u83dc']), ('\U0002f9a4', &['\U00026c36']), ('\U0002f9a5', &['\U00026d6b']),
+        ('\U0002f9a6', &['\U00026cd5']), ('\U0002f9a7', &['\u452b']), ('\U0002f9a8', &['\u84f1']),
+        ('\U0002f9a9', &['\u84f3']), ('\U0002f9aa', &['\u8516']), ('\U0002f9ab', &['\U000273ca']),
+        ('\U0002f9ac', &['\u8564']), ('\U0002f9ad', &['\U00026f2c']), ('\U0002f9ae', &['\u455d']),
+        ('\U0002f9af', &['\u4561']), ('\U0002f9b0', &['\U00026fb1']), ('\U0002f9b1',
+        &['\U000270d2']), ('\U0002f9b2', &['\u456b']), ('\U0002f9b3', &['\u8650']), ('\U0002f9b4',
+        &['\u865c']), ('\U0002f9b5', &['\u8667']), ('\U0002f9b6', &['\u8669']), ('\U0002f9b7',
+        &['\u86a9']), ('\U0002f9b8', &['\u8688']), ('\U0002f9b9', &['\u870e']), ('\U0002f9ba',
+        &['\u86e2']), ('\U0002f9bb', &['\u8779']), ('\U0002f9bc', &['\u8728']), ('\U0002f9bd',
+        &['\u876b']), ('\U0002f9be', &['\u8786']), ('\U0002f9bf', &['\u45d7']), ('\U0002f9c0',
+        &['\u87e1']), ('\U0002f9c1', &['\u8801']), ('\U0002f9c2', &['\u45f9']), ('\U0002f9c3',
+        &['\u8860']), ('\U0002f9c4', &['\u8863']), ('\U0002f9c5', &['\U00027667']), ('\U0002f9c6',
+        &['\u88d7']), ('\U0002f9c7', &['\u88de']), ('\U0002f9c8', &['\u4635']), ('\U0002f9c9',
+        &['\u88fa']), ('\U0002f9ca', &['\u34bb']), ('\U0002f9cb', &['\U000278ae']), ('\U0002f9cc',
+        &['\U00027966']), ('\U0002f9cd', &['\u46be']), ('\U0002f9ce', &['\u46c7']), ('\U0002f9cf',
+        &['\u8aa0']), ('\U0002f9d0', &['\u8aed']), ('\U0002f9d1', &['\u8b8a']), ('\U0002f9d2',
+        &['\u8c55']), ('\U0002f9d3', &['\U00027ca8']), ('\U0002f9d4', &['\u8cab']), ('\U0002f9d5',
+        &['\u8cc1']), ('\U0002f9d6', &['\u8d1b']), ('\U0002f9d7', &['\u8d77']), ('\U0002f9d8',
+        &['\U00027f2f']), ('\U0002f9d9', &['\U00020804']), ('\U0002f9da', &['\u8dcb']),
+        ('\U0002f9db', &['\u8dbc']), ('\U0002f9dc', &['\u8df0']), ('\U0002f9dd', &['\U000208de']),
+        ('\U0002f9de', &['\u8ed4']), ('\U0002f9df', &['\u8f38']), ('\U0002f9e0', &['\U000285d2']),
+        ('\U0002f9e1', &['\U000285ed']), ('\U0002f9e2', &['\u9094']), ('\U0002f9e3', &['\u90f1']),
+        ('\U0002f9e4', &['\u9111']), ('\U0002f9e5', &['\U0002872e']), ('\U0002f9e6', &['\u911b']),
+        ('\U0002f9e7', &['\u9238']), ('\U0002f9e8', &['\u92d7']), ('\U0002f9e9', &['\u92d8']),
+        ('\U0002f9ea', &['\u927c']), ('\U0002f9eb', &['\u93f9']), ('\U0002f9ec', &['\u9415']),
+        ('\U0002f9ed', &['\U00028bfa']), ('\U0002f9ee', &['\u958b']), ('\U0002f9ef', &['\u4995']),
+        ('\U0002f9f0', &['\u95b7']), ('\U0002f9f1', &['\U00028d77']), ('\U0002f9f2', &['\u49e6']),
+        ('\U0002f9f3', &['\u96c3']), ('\U0002f9f4', &['\u5db2']), ('\U0002f9f5', &['\u9723']),
+        ('\U0002f9f6', &['\U00029145']), ('\U0002f9f7', &['\U0002921a']), ('\U0002f9f8',
+        &['\u4a6e']), ('\U0002f9f9', &['\u4a76']), ('\U0002f9fa', &['\u97e0']), ('\U0002f9fb',
+        &['\U0002940a']), ('\U0002f9fc', &['\u4ab2']), ('\U0002f9fd', &['\U00029496']),
+        ('\U0002f9fe', &['\u980b']), ('\U0002f9ff', &['\u980b']), ('\U0002fa00', &['\u9829']),
+        ('\U0002fa01', &['\U000295b6']), ('\U0002fa02', &['\u98e2']), ('\U0002fa03', &['\u4b33']),
+        ('\U0002fa04', &['\u9929']), ('\U0002fa05', &['\u99a7']), ('\U0002fa06', &['\u99c2']),
+        ('\U0002fa07', &['\u99fe']), ('\U0002fa08', &['\u4bce']), ('\U0002fa09', &['\U00029b30']),
+        ('\U0002fa0a', &['\u9b12']), ('\U0002fa0b', &['\u9c40']), ('\U0002fa0c', &['\u9cfd']),
+        ('\U0002fa0d', &['\u4cce']), ('\U0002fa0e', &['\u4ced']), ('\U0002fa0f', &['\u9d67']),
+        ('\U0002fa10', &['\U0002a0ce']), ('\U0002fa11', &['\u4cf8']), ('\U0002fa12',
+        &['\U0002a105']), ('\U0002fa13', &['\U0002a20e']), ('\U0002fa14', &['\U0002a291']),
+        ('\U0002fa15', &['\u9ebb']), ('\U0002fa16', &['\u4d56']), ('\U0002fa17', &['\u9ef9']),
+        ('\U0002fa18', &['\u9efe']), ('\U0002fa19', &['\u9f05']), ('\U0002fa1a', &['\u9f0f']),
+        ('\U0002fa1b', &['\u9f16']), ('\U0002fa1c', &['\u9f3b']), ('\U0002fa1d', &['\U0002a600'])
+    ];
+
+    // Compatibility decompositions
+    pub static compatibility_table: &'static [(char, &'static [char])] = &[
+        ('\xa0', &['\x20']), ('\xa8', &['\x20', '\u0308']), ('\xaa', &['\x61']), ('\xaf', &['\x20',
+        '\u0304']), ('\xb2', &['\x32']), ('\xb3', &['\x33']), ('\xb4', &['\x20', '\u0301']),
+        ('\xb5', &['\u03bc']), ('\xb8', &['\x20', '\u0327']), ('\xb9', &['\x31']), ('\xba',
+        &['\x6f']), ('\xbc', &['\x31', '\u2044', '\x34']), ('\xbd', &['\x31', '\u2044', '\x32']),
+        ('\xbe', &['\x33', '\u2044', '\x34']), ('\u0132', &['\x49', '\x4a']), ('\u0133', &['\x69',
+        '\x6a']), ('\u013f', &['\x4c', '\xb7']), ('\u0140', &['\x6c', '\xb7']), ('\u0149',
+        &['\u02bc', '\x6e']), ('\u017f', &['\x73']), ('\u01c4', &['\x44', '\u017d']), ('\u01c5',
+        &['\x44', '\u017e']), ('\u01c6', &['\x64', '\u017e']), ('\u01c7', &['\x4c', '\x4a']),
+        ('\u01c8', &['\x4c', '\x6a']), ('\u01c9', &['\x6c', '\x6a']), ('\u01ca', &['\x4e', '\x4a']),
+        ('\u01cb', &['\x4e', '\x6a']), ('\u01cc', &['\x6e', '\x6a']), ('\u01f1', &['\x44', '\x5a']),
+        ('\u01f2', &['\x44', '\x7a']), ('\u01f3', &['\x64', '\x7a']), ('\u02b0', &['\x68']),
+        ('\u02b1', &['\u0266']), ('\u02b2', &['\x6a']), ('\u02b3', &['\x72']), ('\u02b4',
+        &['\u0279']), ('\u02b5', &['\u027b']), ('\u02b6', &['\u0281']), ('\u02b7', &['\x77']),
+        ('\u02b8', &['\x79']), ('\u02d8', &['\x20', '\u0306']), ('\u02d9', &['\x20', '\u0307']),
+        ('\u02da', &['\x20', '\u030a']), ('\u02db', &['\x20', '\u0328']), ('\u02dc', &['\x20',
+        '\u0303']), ('\u02dd', &['\x20', '\u030b']), ('\u02e0', &['\u0263']), ('\u02e1', &['\x6c']),
+        ('\u02e2', &['\x73']), ('\u02e3', &['\x78']), ('\u02e4', &['\u0295']), ('\u037a', &['\x20',
+        '\u0345']), ('\u0384', &['\x20', '\u0301']), ('\u03d0', &['\u03b2']), ('\u03d1',
+        &['\u03b8']), ('\u03d2', &['\u03a5']), ('\u03d5', &['\u03c6']), ('\u03d6', &['\u03c0']),
+        ('\u03f0', &['\u03ba']), ('\u03f1', &['\u03c1']), ('\u03f2', &['\u03c2']), ('\u03f4',
+        &['\u0398']), ('\u03f5', &['\u03b5']), ('\u03f9', &['\u03a3']), ('\u0587', &['\u0565',
+        '\u0582']), ('\u0675', &['\u0627', '\u0674']), ('\u0676', &['\u0648', '\u0674']), ('\u0677',
+        &['\u06c7', '\u0674']), ('\u0678', &['\u064a', '\u0674']), ('\u0e33', &['\u0e4d',
+        '\u0e32']), ('\u0eb3', &['\u0ecd', '\u0eb2']), ('\u0edc', &['\u0eab', '\u0e99']), ('\u0edd',
+        &['\u0eab', '\u0ea1']), ('\u0f0c', &['\u0f0b']), ('\u0f77', &['\u0fb2', '\u0f81']),
+        ('\u0f79', &['\u0fb3', '\u0f81']), ('\u10fc', &['\u10dc']), ('\u1d2c', &['\x41']),
+        ('\u1d2d', &['\xc6']), ('\u1d2e', &['\x42']), ('\u1d30', &['\x44']), ('\u1d31', &['\x45']),
+        ('\u1d32', &['\u018e']), ('\u1d33', &['\x47']), ('\u1d34', &['\x48']), ('\u1d35',
+        &['\x49']), ('\u1d36', &['\x4a']), ('\u1d37', &['\x4b']), ('\u1d38', &['\x4c']), ('\u1d39',
+        &['\x4d']), ('\u1d3a', &['\x4e']), ('\u1d3c', &['\x4f']), ('\u1d3d', &['\u0222']),
+        ('\u1d3e', &['\x50']), ('\u1d3f', &['\x52']), ('\u1d40', &['\x54']), ('\u1d41', &['\x55']),
+        ('\u1d42', &['\x57']), ('\u1d43', &['\x61']), ('\u1d44', &['\u0250']), ('\u1d45',
+        &['\u0251']), ('\u1d46', &['\u1d02']), ('\u1d47', &['\x62']), ('\u1d48', &['\x64']),
+        ('\u1d49', &['\x65']), ('\u1d4a', &['\u0259']), ('\u1d4b', &['\u025b']), ('\u1d4c',
+        &['\u025c']), ('\u1d4d', &['\x67']), ('\u1d4f', &['\x6b']), ('\u1d50', &['\x6d']),
+        ('\u1d51', &['\u014b']), ('\u1d52', &['\x6f']), ('\u1d53', &['\u0254']), ('\u1d54',
+        &['\u1d16']), ('\u1d55', &['\u1d17']), ('\u1d56', &['\x70']), ('\u1d57', &['\x74']),
+        ('\u1d58', &['\x75']), ('\u1d59', &['\u1d1d']), ('\u1d5a', &['\u026f']), ('\u1d5b',
+        &['\x76']), ('\u1d5c', &['\u1d25']), ('\u1d5d', &['\u03b2']), ('\u1d5e', &['\u03b3']),
+        ('\u1d5f', &['\u03b4']), ('\u1d60', &['\u03c6']), ('\u1d61', &['\u03c7']), ('\u1d62',
+        &['\x69']), ('\u1d63', &['\x72']), ('\u1d64', &['\x75']), ('\u1d65', &['\x76']), ('\u1d66',
+        &['\u03b2']), ('\u1d67', &['\u03b3']), ('\u1d68', &['\u03c1']), ('\u1d69', &['\u03c6']),
+        ('\u1d6a', &['\u03c7']), ('\u1d78', &['\u043d']), ('\u1d9b', &['\u0252']), ('\u1d9c',
+        &['\x63']), ('\u1d9d', &['\u0255']), ('\u1d9e', &['\xf0']), ('\u1d9f', &['\u025c']),
+        ('\u1da0', &['\x66']), ('\u1da1', &['\u025f']), ('\u1da2', &['\u0261']), ('\u1da3',
+        &['\u0265']), ('\u1da4', &['\u0268']), ('\u1da5', &['\u0269']), ('\u1da6', &['\u026a']),
+        ('\u1da7', &['\u1d7b']), ('\u1da8', &['\u029d']), ('\u1da9', &['\u026d']), ('\u1daa',
+        &['\u1d85']), ('\u1dab', &['\u029f']), ('\u1dac', &['\u0271']), ('\u1dad', &['\u0270']),
+        ('\u1dae', &['\u0272']), ('\u1daf', &['\u0273']), ('\u1db0', &['\u0274']), ('\u1db1',
+        &['\u0275']), ('\u1db2', &['\u0278']), ('\u1db3', &['\u0282']), ('\u1db4', &['\u0283']),
+        ('\u1db5', &['\u01ab']), ('\u1db6', &['\u0289']), ('\u1db7', &['\u028a']), ('\u1db8',
+        &['\u1d1c']), ('\u1db9', &['\u028b']), ('\u1dba', &['\u028c']), ('\u1dbb', &['\x7a']),
+        ('\u1dbc', &['\u0290']), ('\u1dbd', &['\u0291']), ('\u1dbe', &['\u0292']), ('\u1dbf',
+        &['\u03b8']), ('\u1e9a', &['\x61', '\u02be']), ('\u1fbd', &['\x20', '\u0313']), ('\u1fbf',
+        &['\x20', '\u0313']), ('\u1fc0', &['\x20', '\u0342']), ('\u1ffe', &['\x20', '\u0314']),
+        ('\u2002', &['\x20']), ('\u2003', &['\x20']), ('\u2004', &['\x20']), ('\u2005', &['\x20']),
+        ('\u2006', &['\x20']), ('\u2007', &['\x20']), ('\u2008', &['\x20']), ('\u2009', &['\x20']),
+        ('\u200a', &['\x20']), ('\u2011', &['\u2010']), ('\u2017', &['\x20', '\u0333']), ('\u2024',
+        &['\x2e']), ('\u2025', &['\x2e', '\x2e']), ('\u2026', &['\x2e', '\x2e', '\x2e']), ('\u202f',
+        &['\x20']), ('\u2033', &['\u2032', '\u2032']), ('\u2034', &['\u2032', '\u2032', '\u2032']),
+        ('\u2036', &['\u2035', '\u2035']), ('\u2037', &['\u2035', '\u2035', '\u2035']), ('\u203c',
+        &['\x21', '\x21']), ('\u203e', &['\x20', '\u0305']), ('\u2047', &['\x3f', '\x3f']),
+        ('\u2048', &['\x3f', '\x21']), ('\u2049', &['\x21', '\x3f']), ('\u2057', &['\u2032',
+        '\u2032', '\u2032', '\u2032']), ('\u205f', &['\x20']), ('\u2070', &['\x30']), ('\u2071',
+        &['\x69']), ('\u2074', &['\x34']), ('\u2075', &['\x35']), ('\u2076', &['\x36']), ('\u2077',
+        &['\x37']), ('\u2078', &['\x38']), ('\u2079', &['\x39']), ('\u207a', &['\x2b']), ('\u207b',
+        &['\u2212']), ('\u207c', &['\x3d']), ('\u207d', &['\x28']), ('\u207e', &['\x29']),
+        ('\u207f', &['\x6e']), ('\u2080', &['\x30']), ('\u2081', &['\x31']), ('\u2082', &['\x32']),
+        ('\u2083', &['\x33']), ('\u2084', &['\x34']), ('\u2085', &['\x35']), ('\u2086', &['\x36']),
+        ('\u2087', &['\x37']), ('\u2088', &['\x38']), ('\u2089', &['\x39']), ('\u208a', &['\x2b']),
+        ('\u208b', &['\u2212']), ('\u208c', &['\x3d']), ('\u208d', &['\x28']), ('\u208e',
+        &['\x29']), ('\u2090', &['\x61']), ('\u2091', &['\x65']), ('\u2092', &['\x6f']), ('\u2093',
+        &['\x78']), ('\u2094', &['\u0259']), ('\u2095', &['\x68']), ('\u2096', &['\x6b']),
+        ('\u2097', &['\x6c']), ('\u2098', &['\x6d']), ('\u2099', &['\x6e']), ('\u209a', &['\x70']),
+        ('\u209b', &['\x73']), ('\u209c', &['\x74']), ('\u20a8', &['\x52', '\x73']), ('\u2100',
+        &['\x61', '\x2f', '\x63']), ('\u2101', &['\x61', '\x2f', '\x73']), ('\u2102', &['\x43']),
+        ('\u2103', &['\xb0', '\x43']), ('\u2105', &['\x63', '\x2f', '\x6f']), ('\u2106', &['\x63',
+        '\x2f', '\x75']), ('\u2107', &['\u0190']), ('\u2109', &['\xb0', '\x46']), ('\u210a',
+        &['\x67']), ('\u210b', &['\x48']), ('\u210c', &['\x48']), ('\u210d', &['\x48']), ('\u210e',
+        &['\x68']), ('\u210f', &['\u0127']), ('\u2110', &['\x49']), ('\u2111', &['\x49']),
+        ('\u2112', &['\x4c']), ('\u2113', &['\x6c']), ('\u2115', &['\x4e']), ('\u2116', &['\x4e',
+        '\x6f']), ('\u2119', &['\x50']), ('\u211a', &['\x51']), ('\u211b', &['\x52']), ('\u211c',
+        &['\x52']), ('\u211d', &['\x52']), ('\u2120', &['\x53', '\x4d']), ('\u2121', &['\x54',
+        '\x45', '\x4c']), ('\u2122', &['\x54', '\x4d']), ('\u2124', &['\x5a']), ('\u2128',
+        &['\x5a']), ('\u212c', &['\x42']), ('\u212d', &['\x43']), ('\u212f', &['\x65']), ('\u2130',
+        &['\x45']), ('\u2131', &['\x46']), ('\u2133', &['\x4d']), ('\u2134', &['\x6f']), ('\u2135',
+        &['\u05d0']), ('\u2136', &['\u05d1']), ('\u2137', &['\u05d2']), ('\u2138', &['\u05d3']),
+        ('\u2139', &['\x69']), ('\u213b', &['\x46', '\x41', '\x58']), ('\u213c', &['\u03c0']),
+        ('\u213d', &['\u03b3']), ('\u213e', &['\u0393']), ('\u213f', &['\u03a0']), ('\u2140',
+        &['\u2211']), ('\u2145', &['\x44']), ('\u2146', &['\x64']), ('\u2147', &['\x65']),
+        ('\u2148', &['\x69']), ('\u2149', &['\x6a']), ('\u2150', &['\x31', '\u2044', '\x37']),
+        ('\u2151', &['\x31', '\u2044', '\x39']), ('\u2152', &['\x31', '\u2044', '\x31', '\x30']),
+        ('\u2153', &['\x31', '\u2044', '\x33']), ('\u2154', &['\x32', '\u2044', '\x33']), ('\u2155',
+        &['\x31', '\u2044', '\x35']), ('\u2156', &['\x32', '\u2044', '\x35']), ('\u2157', &['\x33',
+        '\u2044', '\x35']), ('\u2158', &['\x34', '\u2044', '\x35']), ('\u2159', &['\x31', '\u2044',
+        '\x36']), ('\u215a', &['\x35', '\u2044', '\x36']), ('\u215b', &['\x31', '\u2044', '\x38']),
+        ('\u215c', &['\x33', '\u2044', '\x38']), ('\u215d', &['\x35', '\u2044', '\x38']), ('\u215e',
+        &['\x37', '\u2044', '\x38']), ('\u215f', &['\x31', '\u2044']), ('\u2160', &['\x49']),
+        ('\u2161', &['\x49', '\x49']), ('\u2162', &['\x49', '\x49', '\x49']), ('\u2163', &['\x49',
+        '\x56']), ('\u2164', &['\x56']), ('\u2165', &['\x56', '\x49']), ('\u2166', &['\x56', '\x49',
+        '\x49']), ('\u2167', &['\x56', '\x49', '\x49', '\x49']), ('\u2168', &['\x49', '\x58']),
+        ('\u2169', &['\x58']), ('\u216a', &['\x58', '\x49']), ('\u216b', &['\x58', '\x49', '\x49']),
+        ('\u216c', &['\x4c']), ('\u216d', &['\x43']), ('\u216e', &['\x44']), ('\u216f', &['\x4d']),
+        ('\u2170', &['\x69']), ('\u2171', &['\x69', '\x69']), ('\u2172', &['\x69', '\x69', '\x69']),
+        ('\u2173', &['\x69', '\x76']), ('\u2174', &['\x76']), ('\u2175', &['\x76', '\x69']),
+        ('\u2176', &['\x76', '\x69', '\x69']), ('\u2177', &['\x76', '\x69', '\x69', '\x69']),
+        ('\u2178', &['\x69', '\x78']), ('\u2179', &['\x78']), ('\u217a', &['\x78', '\x69']),
+        ('\u217b', &['\x78', '\x69', '\x69']), ('\u217c', &['\x6c']), ('\u217d', &['\x63']),
+        ('\u217e', &['\x64']), ('\u217f', &['\x6d']), ('\u2189', &['\x30', '\u2044', '\x33']),
+        ('\u222c', &['\u222b', '\u222b']), ('\u222d', &['\u222b', '\u222b', '\u222b']), ('\u222f',
+        &['\u222e', '\u222e']), ('\u2230', &['\u222e', '\u222e', '\u222e']), ('\u2460', &['\x31']),
+        ('\u2461', &['\x32']), ('\u2462', &['\x33']), ('\u2463', &['\x34']), ('\u2464', &['\x35']),
+        ('\u2465', &['\x36']), ('\u2466', &['\x37']), ('\u2467', &['\x38']), ('\u2468', &['\x39']),
+        ('\u2469', &['\x31', '\x30']), ('\u246a', &['\x31', '\x31']), ('\u246b', &['\x31', '\x32']),
+        ('\u246c', &['\x31', '\x33']), ('\u246d', &['\x31', '\x34']), ('\u246e', &['\x31', '\x35']),
+        ('\u246f', &['\x31', '\x36']), ('\u2470', &['\x31', '\x37']), ('\u2471', &['\x31', '\x38']),
+        ('\u2472', &['\x31', '\x39']), ('\u2473', &['\x32', '\x30']), ('\u2474', &['\x28', '\x31',
+        '\x29']), ('\u2475', &['\x28', '\x32', '\x29']), ('\u2476', &['\x28', '\x33', '\x29']),
+        ('\u2477', &['\x28', '\x34', '\x29']), ('\u2478', &['\x28', '\x35', '\x29']), ('\u2479',
+        &['\x28', '\x36', '\x29']), ('\u247a', &['\x28', '\x37', '\x29']), ('\u247b', &['\x28',
+        '\x38', '\x29']), ('\u247c', &['\x28', '\x39', '\x29']), ('\u247d', &['\x28', '\x31',
+        '\x30', '\x29']), ('\u247e', &['\x28', '\x31', '\x31', '\x29']), ('\u247f', &['\x28',
+        '\x31', '\x32', '\x29']), ('\u2480', &['\x28', '\x31', '\x33', '\x29']), ('\u2481',
+        &['\x28', '\x31', '\x34', '\x29']), ('\u2482', &['\x28', '\x31', '\x35', '\x29']),
+        ('\u2483', &['\x28', '\x31', '\x36', '\x29']), ('\u2484', &['\x28', '\x31', '\x37',
+        '\x29']), ('\u2485', &['\x28', '\x31', '\x38', '\x29']), ('\u2486', &['\x28', '\x31',
+        '\x39', '\x29']), ('\u2487', &['\x28', '\x32', '\x30', '\x29']), ('\u2488', &['\x31',
+        '\x2e']), ('\u2489', &['\x32', '\x2e']), ('\u248a', &['\x33', '\x2e']), ('\u248b', &['\x34',
+        '\x2e']), ('\u248c', &['\x35', '\x2e']), ('\u248d', &['\x36', '\x2e']), ('\u248e', &['\x37',
+        '\x2e']), ('\u248f', &['\x38', '\x2e']), ('\u2490', &['\x39', '\x2e']), ('\u2491', &['\x31',
+        '\x30', '\x2e']), ('\u2492', &['\x31', '\x31', '\x2e']), ('\u2493', &['\x31', '\x32',
+        '\x2e']), ('\u2494', &['\x31', '\x33', '\x2e']), ('\u2495', &['\x31', '\x34', '\x2e']),
+        ('\u2496', &['\x31', '\x35', '\x2e']), ('\u2497', &['\x31', '\x36', '\x2e']), ('\u2498',
+        &['\x31', '\x37', '\x2e']), ('\u2499', &['\x31', '\x38', '\x2e']), ('\u249a', &['\x31',
+        '\x39', '\x2e']), ('\u249b', &['\x32', '\x30', '\x2e']), ('\u249c', &['\x28', '\x61',
+        '\x29']), ('\u249d', &['\x28', '\x62', '\x29']), ('\u249e', &['\x28', '\x63', '\x29']),
+        ('\u249f', &['\x28', '\x64', '\x29']), ('\u24a0', &['\x28', '\x65', '\x29']), ('\u24a1',
+        &['\x28', '\x66', '\x29']), ('\u24a2', &['\x28', '\x67', '\x29']), ('\u24a3', &['\x28',
+        '\x68', '\x29']), ('\u24a4', &['\x28', '\x69', '\x29']), ('\u24a5', &['\x28', '\x6a',
+        '\x29']), ('\u24a6', &['\x28', '\x6b', '\x29']), ('\u24a7', &['\x28', '\x6c', '\x29']),
+        ('\u24a8', &['\x28', '\x6d', '\x29']), ('\u24a9', &['\x28', '\x6e', '\x29']), ('\u24aa',
+        &['\x28', '\x6f', '\x29']), ('\u24ab', &['\x28', '\x70', '\x29']), ('\u24ac', &['\x28',
+        '\x71', '\x29']), ('\u24ad', &['\x28', '\x72', '\x29']), ('\u24ae', &['\x28', '\x73',
+        '\x29']), ('\u24af', &['\x28', '\x74', '\x29']), ('\u24b0', &['\x28', '\x75', '\x29']),
+        ('\u24b1', &['\x28', '\x76', '\x29']), ('\u24b2', &['\x28', '\x77', '\x29']), ('\u24b3',
+        &['\x28', '\x78', '\x29']), ('\u24b4', &['\x28', '\x79', '\x29']), ('\u24b5', &['\x28',
+        '\x7a', '\x29']), ('\u24b6', &['\x41']), ('\u24b7', &['\x42']), ('\u24b8', &['\x43']),
+        ('\u24b9', &['\x44']), ('\u24ba', &['\x45']), ('\u24bb', &['\x46']), ('\u24bc', &['\x47']),
+        ('\u24bd', &['\x48']), ('\u24be', &['\x49']), ('\u24bf', &['\x4a']), ('\u24c0', &['\x4b']),
+        ('\u24c1', &['\x4c']), ('\u24c2', &['\x4d']), ('\u24c3', &['\x4e']), ('\u24c4', &['\x4f']),
+        ('\u24c5', &['\x50']), ('\u24c6', &['\x51']), ('\u24c7', &['\x52']), ('\u24c8', &['\x53']),
+        ('\u24c9', &['\x54']), ('\u24ca', &['\x55']), ('\u24cb', &['\x56']), ('\u24cc', &['\x57']),
+        ('\u24cd', &['\x58']), ('\u24ce', &['\x59']), ('\u24cf', &['\x5a']), ('\u24d0', &['\x61']),
+        ('\u24d1', &['\x62']), ('\u24d2', &['\x63']), ('\u24d3', &['\x64']), ('\u24d4', &['\x65']),
+        ('\u24d5', &['\x66']), ('\u24d6', &['\x67']), ('\u24d7', &['\x68']), ('\u24d8', &['\x69']),
+        ('\u24d9', &['\x6a']), ('\u24da', &['\x6b']), ('\u24db', &['\x6c']), ('\u24dc', &['\x6d']),
+        ('\u24dd', &['\x6e']), ('\u24de', &['\x6f']), ('\u24df', &['\x70']), ('\u24e0', &['\x71']),
+        ('\u24e1', &['\x72']), ('\u24e2', &['\x73']), ('\u24e3', &['\x74']), ('\u24e4', &['\x75']),
+        ('\u24e5', &['\x76']), ('\u24e6', &['\x77']), ('\u24e7', &['\x78']), ('\u24e8', &['\x79']),
+        ('\u24e9', &['\x7a']), ('\u24ea', &['\x30']), ('\u2a0c', &['\u222b', '\u222b', '\u222b',
+        '\u222b']), ('\u2a74', &['\x3a', '\x3a', '\x3d']), ('\u2a75', &['\x3d', '\x3d']), ('\u2a76',
+        &['\x3d', '\x3d', '\x3d']), ('\u2c7c', &['\x6a']), ('\u2c7d', &['\x56']), ('\u2d6f',
+        &['\u2d61']), ('\u2e9f', &['\u6bcd']), ('\u2ef3', &['\u9f9f']), ('\u2f00', &['\u4e00']),
+        ('\u2f01', &['\u4e28']), ('\u2f02', &['\u4e36']), ('\u2f03', &['\u4e3f']), ('\u2f04',
+        &['\u4e59']), ('\u2f05', &['\u4e85']), ('\u2f06', &['\u4e8c']), ('\u2f07', &['\u4ea0']),
+        ('\u2f08', &['\u4eba']), ('\u2f09', &['\u513f']), ('\u2f0a', &['\u5165']), ('\u2f0b',
+        &['\u516b']), ('\u2f0c', &['\u5182']), ('\u2f0d', &['\u5196']), ('\u2f0e', &['\u51ab']),
+        ('\u2f0f', &['\u51e0']), ('\u2f10', &['\u51f5']), ('\u2f11', &['\u5200']), ('\u2f12',
+        &['\u529b']), ('\u2f13', &['\u52f9']), ('\u2f14', &['\u5315']), ('\u2f15', &['\u531a']),
+        ('\u2f16', &['\u5338']), ('\u2f17', &['\u5341']), ('\u2f18', &['\u535c']), ('\u2f19',
+        &['\u5369']), ('\u2f1a', &['\u5382']), ('\u2f1b', &['\u53b6']), ('\u2f1c', &['\u53c8']),
+        ('\u2f1d', &['\u53e3']), ('\u2f1e', &['\u56d7']), ('\u2f1f', &['\u571f']), ('\u2f20',
+        &['\u58eb']), ('\u2f21', &['\u5902']), ('\u2f22', &['\u590a']), ('\u2f23', &['\u5915']),
+        ('\u2f24', &['\u5927']), ('\u2f25', &['\u5973']), ('\u2f26', &['\u5b50']), ('\u2f27',
+        &['\u5b80']), ('\u2f28', &['\u5bf8']), ('\u2f29', &['\u5c0f']), ('\u2f2a', &['\u5c22']),
+        ('\u2f2b', &['\u5c38']), ('\u2f2c', &['\u5c6e']), ('\u2f2d', &['\u5c71']), ('\u2f2e',
+        &['\u5ddb']), ('\u2f2f', &['\u5de5']), ('\u2f30', &['\u5df1']), ('\u2f31', &['\u5dfe']),
+        ('\u2f32', &['\u5e72']), ('\u2f33', &['\u5e7a']), ('\u2f34', &['\u5e7f']), ('\u2f35',
+        &['\u5ef4']), ('\u2f36', &['\u5efe']), ('\u2f37', &['\u5f0b']), ('\u2f38', &['\u5f13']),
+        ('\u2f39', &['\u5f50']), ('\u2f3a', &['\u5f61']), ('\u2f3b', &['\u5f73']), ('\u2f3c',
+        &['\u5fc3']), ('\u2f3d', &['\u6208']), ('\u2f3e', &['\u6236']), ('\u2f3f', &['\u624b']),
+        ('\u2f40', &['\u652f']), ('\u2f41', &['\u6534']), ('\u2f42', &['\u6587']), ('\u2f43',
+        &['\u6597']), ('\u2f44', &['\u65a4']), ('\u2f45', &['\u65b9']), ('\u2f46', &['\u65e0']),
+        ('\u2f47', &['\u65e5']), ('\u2f48', &['\u66f0']), ('\u2f49', &['\u6708']), ('\u2f4a',
+        &['\u6728']), ('\u2f4b', &['\u6b20']), ('\u2f4c', &['\u6b62']), ('\u2f4d', &['\u6b79']),
+        ('\u2f4e', &['\u6bb3']), ('\u2f4f', &['\u6bcb']), ('\u2f50', &['\u6bd4']), ('\u2f51',
+        &['\u6bdb']), ('\u2f52', &['\u6c0f']), ('\u2f53', &['\u6c14']), ('\u2f54', &['\u6c34']),
+        ('\u2f55', &['\u706b']), ('\u2f56', &['\u722a']), ('\u2f57', &['\u7236']), ('\u2f58',
+        &['\u723b']), ('\u2f59', &['\u723f']), ('\u2f5a', &['\u7247']), ('\u2f5b', &['\u7259']),
+        ('\u2f5c', &['\u725b']), ('\u2f5d', &['\u72ac']), ('\u2f5e', &['\u7384']), ('\u2f5f',
+        &['\u7389']), ('\u2f60', &['\u74dc']), ('\u2f61', &['\u74e6']), ('\u2f62', &['\u7518']),
+        ('\u2f63', &['\u751f']), ('\u2f64', &['\u7528']), ('\u2f65', &['\u7530']), ('\u2f66',
+        &['\u758b']), ('\u2f67', &['\u7592']), ('\u2f68', &['\u7676']), ('\u2f69', &['\u767d']),
+        ('\u2f6a', &['\u76ae']), ('\u2f6b', &['\u76bf']), ('\u2f6c', &['\u76ee']), ('\u2f6d',
+        &['\u77db']), ('\u2f6e', &['\u77e2']), ('\u2f6f', &['\u77f3']), ('\u2f70', &['\u793a']),
+        ('\u2f71', &['\u79b8']), ('\u2f72', &['\u79be']), ('\u2f73', &['\u7a74']), ('\u2f74',
+        &['\u7acb']), ('\u2f75', &['\u7af9']), ('\u2f76', &['\u7c73']), ('\u2f77', &['\u7cf8']),
+        ('\u2f78', &['\u7f36']), ('\u2f79', &['\u7f51']), ('\u2f7a', &['\u7f8a']), ('\u2f7b',
+        &['\u7fbd']), ('\u2f7c', &['\u8001']), ('\u2f7d', &['\u800c']), ('\u2f7e', &['\u8012']),
+        ('\u2f7f', &['\u8033']), ('\u2f80', &['\u807f']), ('\u2f81', &['\u8089']), ('\u2f82',
+        &['\u81e3']), ('\u2f83', &['\u81ea']), ('\u2f84', &['\u81f3']), ('\u2f85', &['\u81fc']),
+        ('\u2f86', &['\u820c']), ('\u2f87', &['\u821b']), ('\u2f88', &['\u821f']), ('\u2f89',
+        &['\u826e']), ('\u2f8a', &['\u8272']), ('\u2f8b', &['\u8278']), ('\u2f8c', &['\u864d']),
+        ('\u2f8d', &['\u866b']), ('\u2f8e', &['\u8840']), ('\u2f8f', &['\u884c']), ('\u2f90',
+        &['\u8863']), ('\u2f91', &['\u897e']), ('\u2f92', &['\u898b']), ('\u2f93', &['\u89d2']),
+        ('\u2f94', &['\u8a00']), ('\u2f95', &['\u8c37']), ('\u2f96', &['\u8c46']), ('\u2f97',
+        &['\u8c55']), ('\u2f98', &['\u8c78']), ('\u2f99', &['\u8c9d']), ('\u2f9a', &['\u8d64']),
+        ('\u2f9b', &['\u8d70']), ('\u2f9c', &['\u8db3']), ('\u2f9d', &['\u8eab']), ('\u2f9e',
+        &['\u8eca']), ('\u2f9f', &['\u8f9b']), ('\u2fa0', &['\u8fb0']), ('\u2fa1', &['\u8fb5']),
+        ('\u2fa2', &['\u9091']), ('\u2fa3', &['\u9149']), ('\u2fa4', &['\u91c6']), ('\u2fa5',
+        &['\u91cc']), ('\u2fa6', &['\u91d1']), ('\u2fa7', &['\u9577']), ('\u2fa8', &['\u9580']),
+        ('\u2fa9', &['\u961c']), ('\u2faa', &['\u96b6']), ('\u2fab', &['\u96b9']), ('\u2fac',
+        &['\u96e8']), ('\u2fad', &['\u9751']), ('\u2fae', &['\u975e']), ('\u2faf', &['\u9762']),
+        ('\u2fb0', &['\u9769']), ('\u2fb1', &['\u97cb']), ('\u2fb2', &['\u97ed']), ('\u2fb3',
+        &['\u97f3']), ('\u2fb4', &['\u9801']), ('\u2fb5', &['\u98a8']), ('\u2fb6', &['\u98db']),
+        ('\u2fb7', &['\u98df']), ('\u2fb8', &['\u9996']), ('\u2fb9', &['\u9999']), ('\u2fba',
+        &['\u99ac']), ('\u2fbb', &['\u9aa8']), ('\u2fbc', &['\u9ad8']), ('\u2fbd', &['\u9adf']),
+        ('\u2fbe', &['\u9b25']), ('\u2fbf', &['\u9b2f']), ('\u2fc0', &['\u9b32']), ('\u2fc1',
+        &['\u9b3c']), ('\u2fc2', &['\u9b5a']), ('\u2fc3', &['\u9ce5']), ('\u2fc4', &['\u9e75']),
+        ('\u2fc5', &['\u9e7f']), ('\u2fc6', &['\u9ea5']), ('\u2fc7', &['\u9ebb']), ('\u2fc8',
+        &['\u9ec3']), ('\u2fc9', &['\u9ecd']), ('\u2fca', &['\u9ed1']), ('\u2fcb', &['\u9ef9']),
+        ('\u2fcc', &['\u9efd']), ('\u2fcd', &['\u9f0e']), ('\u2fce', &['\u9f13']), ('\u2fcf',
+        &['\u9f20']), ('\u2fd0', &['\u9f3b']), ('\u2fd1', &['\u9f4a']), ('\u2fd2', &['\u9f52']),
+        ('\u2fd3', &['\u9f8d']), ('\u2fd4', &['\u9f9c']), ('\u2fd5', &['\u9fa0']), ('\u3000',
+        &['\x20']), ('\u3036', &['\u3012']), ('\u3038', &['\u5341']), ('\u3039', &['\u5344']),
+        ('\u303a', &['\u5345']), ('\u309b', &['\x20', '\u3099']), ('\u309c', &['\x20', '\u309a']),
+        ('\u309f', &['\u3088', '\u308a']), ('\u30ff', &['\u30b3', '\u30c8']), ('\u3131',
+        &['\u1100']), ('\u3132', &['\u1101']), ('\u3133', &['\u11aa']), ('\u3134', &['\u1102']),
+        ('\u3135', &['\u11ac']), ('\u3136', &['\u11ad']), ('\u3137', &['\u1103']), ('\u3138',
+        &['\u1104']), ('\u3139', &['\u1105']), ('\u313a', &['\u11b0']), ('\u313b', &['\u11b1']),
+        ('\u313c', &['\u11b2']), ('\u313d', &['\u11b3']), ('\u313e', &['\u11b4']), ('\u313f',
+        &['\u11b5']), ('\u3140', &['\u111a']), ('\u3141', &['\u1106']), ('\u3142', &['\u1107']),
+        ('\u3143', &['\u1108']), ('\u3144', &['\u1121']), ('\u3145', &['\u1109']), ('\u3146',
+        &['\u110a']), ('\u3147', &['\u110b']), ('\u3148', &['\u110c']), ('\u3149', &['\u110d']),
+        ('\u314a', &['\u110e']), ('\u314b', &['\u110f']), ('\u314c', &['\u1110']), ('\u314d',
+        &['\u1111']), ('\u314e', &['\u1112']), ('\u314f', &['\u1161']), ('\u3150', &['\u1162']),
+        ('\u3151', &['\u1163']), ('\u3152', &['\u1164']), ('\u3153', &['\u1165']), ('\u3154',
+        &['\u1166']), ('\u3155', &['\u1167']), ('\u3156', &['\u1168']), ('\u3157', &['\u1169']),
+        ('\u3158', &['\u116a']), ('\u3159', &['\u116b']), ('\u315a', &['\u116c']), ('\u315b',
+        &['\u116d']), ('\u315c', &['\u116e']), ('\u315d', &['\u116f']), ('\u315e', &['\u1170']),
+        ('\u315f', &['\u1171']), ('\u3160', &['\u1172']), ('\u3161', &['\u1173']), ('\u3162',
+        &['\u1174']), ('\u3163', &['\u1175']), ('\u3164', &['\u1160']), ('\u3165', &['\u1114']),
+        ('\u3166', &['\u1115']), ('\u3167', &['\u11c7']), ('\u3168', &['\u11c8']), ('\u3169',
+        &['\u11cc']), ('\u316a', &['\u11ce']), ('\u316b', &['\u11d3']), ('\u316c', &['\u11d7']),
+        ('\u316d', &['\u11d9']), ('\u316e', &['\u111c']), ('\u316f', &['\u11dd']), ('\u3170',
+        &['\u11df']), ('\u3171', &['\u111d']), ('\u3172', &['\u111e']), ('\u3173', &['\u1120']),
+        ('\u3174', &['\u1122']), ('\u3175', &['\u1123']), ('\u3176', &['\u1127']), ('\u3177',
+        &['\u1129']), ('\u3178', &['\u112b']), ('\u3179', &['\u112c']), ('\u317a', &['\u112d']),
+        ('\u317b', &['\u112e']), ('\u317c', &['\u112f']), ('\u317d', &['\u1132']), ('\u317e',
+        &['\u1136']), ('\u317f', &['\u1140']), ('\u3180', &['\u1147']), ('\u3181', &['\u114c']),
+        ('\u3182', &['\u11f1']), ('\u3183', &['\u11f2']), ('\u3184', &['\u1157']), ('\u3185',
+        &['\u1158']), ('\u3186', &['\u1159']), ('\u3187', &['\u1184']), ('\u3188', &['\u1185']),
+        ('\u3189', &['\u1188']), ('\u318a', &['\u1191']), ('\u318b', &['\u1192']), ('\u318c',
+        &['\u1194']), ('\u318d', &['\u119e']), ('\u318e', &['\u11a1']), ('\u3192', &['\u4e00']),
+        ('\u3193', &['\u4e8c']), ('\u3194', &['\u4e09']), ('\u3195', &['\u56db']), ('\u3196',
+        &['\u4e0a']), ('\u3197', &['\u4e2d']), ('\u3198', &['\u4e0b']), ('\u3199', &['\u7532']),
+        ('\u319a', &['\u4e59']), ('\u319b', &['\u4e19']), ('\u319c', &['\u4e01']), ('\u319d',
+        &['\u5929']), ('\u319e', &['\u5730']), ('\u319f', &['\u4eba']), ('\u3200', &['\x28',
+        '\u1100', '\x29']), ('\u3201', &['\x28', '\u1102', '\x29']), ('\u3202', &['\x28', '\u1103',
+        '\x29']), ('\u3203', &['\x28', '\u1105', '\x29']), ('\u3204', &['\x28', '\u1106', '\x29']),
+        ('\u3205', &['\x28', '\u1107', '\x29']), ('\u3206', &['\x28', '\u1109', '\x29']), ('\u3207',
+        &['\x28', '\u110b', '\x29']), ('\u3208', &['\x28', '\u110c', '\x29']), ('\u3209', &['\x28',
+        '\u110e', '\x29']), ('\u320a', &['\x28', '\u110f', '\x29']), ('\u320b', &['\x28', '\u1110',
+        '\x29']), ('\u320c', &['\x28', '\u1111', '\x29']), ('\u320d', &['\x28', '\u1112', '\x29']),
+        ('\u320e', &['\x28', '\u1100', '\u1161', '\x29']), ('\u320f', &['\x28', '\u1102', '\u1161',
+        '\x29']), ('\u3210', &['\x28', '\u1103', '\u1161', '\x29']), ('\u3211', &['\x28', '\u1105',
+        '\u1161', '\x29']), ('\u3212', &['\x28', '\u1106', '\u1161', '\x29']), ('\u3213', &['\x28',
+        '\u1107', '\u1161', '\x29']), ('\u3214', &['\x28', '\u1109', '\u1161', '\x29']), ('\u3215',
+        &['\x28', '\u110b', '\u1161', '\x29']), ('\u3216', &['\x28', '\u110c', '\u1161', '\x29']),
+        ('\u3217', &['\x28', '\u110e', '\u1161', '\x29']), ('\u3218', &['\x28', '\u110f', '\u1161',
+        '\x29']), ('\u3219', &['\x28', '\u1110', '\u1161', '\x29']), ('\u321a', &['\x28', '\u1111',
+        '\u1161', '\x29']), ('\u321b', &['\x28', '\u1112', '\u1161', '\x29']), ('\u321c', &['\x28',
+        '\u110c', '\u116e', '\x29']), ('\u321d', &['\x28', '\u110b', '\u1169', '\u110c', '\u1165',
+        '\u11ab', '\x29']), ('\u321e', &['\x28', '\u110b', '\u1169', '\u1112', '\u116e', '\x29']),
+        ('\u3220', &['\x28', '\u4e00', '\x29']), ('\u3221', &['\x28', '\u4e8c', '\x29']), ('\u3222',
+        &['\x28', '\u4e09', '\x29']), ('\u3223', &['\x28', '\u56db', '\x29']), ('\u3224', &['\x28',
+        '\u4e94', '\x29']), ('\u3225', &['\x28', '\u516d', '\x29']), ('\u3226', &['\x28', '\u4e03',
+        '\x29']), ('\u3227', &['\x28', '\u516b', '\x29']), ('\u3228', &['\x28', '\u4e5d', '\x29']),
+        ('\u3229', &['\x28', '\u5341', '\x29']), ('\u322a', &['\x28', '\u6708', '\x29']), ('\u322b',
+        &['\x28', '\u706b', '\x29']), ('\u322c', &['\x28', '\u6c34', '\x29']), ('\u322d', &['\x28',
+        '\u6728', '\x29']), ('\u322e', &['\x28', '\u91d1', '\x29']), ('\u322f', &['\x28', '\u571f',
+        '\x29']), ('\u3230', &['\x28', '\u65e5', '\x29']), ('\u3231', &['\x28', '\u682a', '\x29']),
+        ('\u3232', &['\x28', '\u6709', '\x29']), ('\u3233', &['\x28', '\u793e', '\x29']), ('\u3234',
+        &['\x28', '\u540d', '\x29']), ('\u3235', &['\x28', '\u7279', '\x29']), ('\u3236', &['\x28',
+        '\u8ca1', '\x29']), ('\u3237', &['\x28', '\u795d', '\x29']), ('\u3238', &['\x28', '\u52b4',
+        '\x29']), ('\u3239', &['\x28', '\u4ee3', '\x29']), ('\u323a', &['\x28', '\u547c', '\x29']),
+        ('\u323b', &['\x28', '\u5b66', '\x29']), ('\u323c', &['\x28', '\u76e3', '\x29']), ('\u323d',
+        &['\x28', '\u4f01', '\x29']), ('\u323e', &['\x28', '\u8cc7', '\x29']), ('\u323f', &['\x28',
+        '\u5354', '\x29']), ('\u3240', &['\x28', '\u796d', '\x29']), ('\u3241', &['\x28', '\u4f11',
+        '\x29']), ('\u3242', &['\x28', '\u81ea', '\x29']), ('\u3243', &['\x28', '\u81f3', '\x29']),
+        ('\u3244', &['\u554f']), ('\u3245', &['\u5e7c']), ('\u3246', &['\u6587']), ('\u3247',
+        &['\u7b8f']), ('\u3250', &['\x50', '\x54', '\x45']), ('\u3251', &['\x32', '\x31']),
+        ('\u3252', &['\x32', '\x32']), ('\u3253', &['\x32', '\x33']), ('\u3254', &['\x32', '\x34']),
+        ('\u3255', &['\x32', '\x35']), ('\u3256', &['\x32', '\x36']), ('\u3257', &['\x32', '\x37']),
+        ('\u3258', &['\x32', '\x38']), ('\u3259', &['\x32', '\x39']), ('\u325a', &['\x33', '\x30']),
+        ('\u325b', &['\x33', '\x31']), ('\u325c', &['\x33', '\x32']), ('\u325d', &['\x33', '\x33']),
+        ('\u325e', &['\x33', '\x34']), ('\u325f', &['\x33', '\x35']), ('\u3260', &['\u1100']),
+        ('\u3261', &['\u1102']), ('\u3262', &['\u1103']), ('\u3263', &['\u1105']), ('\u3264',
+        &['\u1106']), ('\u3265', &['\u1107']), ('\u3266', &['\u1109']), ('\u3267', &['\u110b']),
+        ('\u3268', &['\u110c']), ('\u3269', &['\u110e']), ('\u326a', &['\u110f']), ('\u326b',
+        &['\u1110']), ('\u326c', &['\u1111']), ('\u326d', &['\u1112']), ('\u326e', &['\u1100',
+        '\u1161']), ('\u326f', &['\u1102', '\u1161']), ('\u3270', &['\u1103', '\u1161']), ('\u3271',
+        &['\u1105', '\u1161']), ('\u3272', &['\u1106', '\u1161']), ('\u3273', &['\u1107',
+        '\u1161']), ('\u3274', &['\u1109', '\u1161']), ('\u3275', &['\u110b', '\u1161']), ('\u3276',
+        &['\u110c', '\u1161']), ('\u3277', &['\u110e', '\u1161']), ('\u3278', &['\u110f',
+        '\u1161']), ('\u3279', &['\u1110', '\u1161']), ('\u327a', &['\u1111', '\u1161']), ('\u327b',
+        &['\u1112', '\u1161']), ('\u327c', &['\u110e', '\u1161', '\u11b7', '\u1100', '\u1169']),
+        ('\u327d', &['\u110c', '\u116e', '\u110b', '\u1174']), ('\u327e', &['\u110b', '\u116e']),
+        ('\u3280', &['\u4e00']), ('\u3281', &['\u4e8c']), ('\u3282', &['\u4e09']), ('\u3283',
+        &['\u56db']), ('\u3284', &['\u4e94']), ('\u3285', &['\u516d']), ('\u3286', &['\u4e03']),
+        ('\u3287', &['\u516b']), ('\u3288', &['\u4e5d']), ('\u3289', &['\u5341']), ('\u328a',
+        &['\u6708']), ('\u328b', &['\u706b']), ('\u328c', &['\u6c34']), ('\u328d', &['\u6728']),
+        ('\u328e', &['\u91d1']), ('\u328f', &['\u571f']), ('\u3290', &['\u65e5']), ('\u3291',
+        &['\u682a']), ('\u3292', &['\u6709']), ('\u3293', &['\u793e']), ('\u3294', &['\u540d']),
+        ('\u3295', &['\u7279']), ('\u3296', &['\u8ca1']), ('\u3297', &['\u795d']), ('\u3298',
+        &['\u52b4']), ('\u3299', &['\u79d8']), ('\u329a', &['\u7537']), ('\u329b', &['\u5973']),
+        ('\u329c', &['\u9069']), ('\u329d', &['\u512a']), ('\u329e', &['\u5370']), ('\u329f',
+        &['\u6ce8']), ('\u32a0', &['\u9805']), ('\u32a1', &['\u4f11']), ('\u32a2', &['\u5199']),
+        ('\u32a3', &['\u6b63']), ('\u32a4', &['\u4e0a']), ('\u32a5', &['\u4e2d']), ('\u32a6',
+        &['\u4e0b']), ('\u32a7', &['\u5de6']), ('\u32a8', &['\u53f3']), ('\u32a9', &['\u533b']),
+        ('\u32aa', &['\u5b97']), ('\u32ab', &['\u5b66']), ('\u32ac', &['\u76e3']), ('\u32ad',
+        &['\u4f01']), ('\u32ae', &['\u8cc7']), ('\u32af', &['\u5354']), ('\u32b0', &['\u591c']),
+        ('\u32b1', &['\x33', '\x36']), ('\u32b2', &['\x33', '\x37']), ('\u32b3', &['\x33', '\x38']),
+        ('\u32b4', &['\x33', '\x39']), ('\u32b5', &['\x34', '\x30']), ('\u32b6', &['\x34', '\x31']),
+        ('\u32b7', &['\x34', '\x32']), ('\u32b8', &['\x34', '\x33']), ('\u32b9', &['\x34', '\x34']),
+        ('\u32ba', &['\x34', '\x35']), ('\u32bb', &['\x34', '\x36']), ('\u32bc', &['\x34', '\x37']),
+        ('\u32bd', &['\x34', '\x38']), ('\u32be', &['\x34', '\x39']), ('\u32bf', &['\x35', '\x30']),
+        ('\u32c0', &['\x31', '\u6708']), ('\u32c1', &['\x32', '\u6708']), ('\u32c2', &['\x33',
+        '\u6708']), ('\u32c3', &['\x34', '\u6708']), ('\u32c4', &['\x35', '\u6708']), ('\u32c5',
+        &['\x36', '\u6708']), ('\u32c6', &['\x37', '\u6708']), ('\u32c7', &['\x38', '\u6708']),
+        ('\u32c8', &['\x39', '\u6708']), ('\u32c9', &['\x31', '\x30', '\u6708']), ('\u32ca',
+        &['\x31', '\x31', '\u6708']), ('\u32cb', &['\x31', '\x32', '\u6708']), ('\u32cc', &['\x48',
+        '\x67']), ('\u32cd', &['\x65', '\x72', '\x67']), ('\u32ce', &['\x65', '\x56']), ('\u32cf',
+        &['\x4c', '\x54', '\x44']), ('\u32d0', &['\u30a2']), ('\u32d1', &['\u30a4']), ('\u32d2',
+        &['\u30a6']), ('\u32d3', &['\u30a8']), ('\u32d4', &['\u30aa']), ('\u32d5', &['\u30ab']),
+        ('\u32d6', &['\u30ad']), ('\u32d7', &['\u30af']), ('\u32d8', &['\u30b1']), ('\u32d9',
+        &['\u30b3']), ('\u32da', &['\u30b5']), ('\u32db', &['\u30b7']), ('\u32dc', &['\u30b9']),
+        ('\u32dd', &['\u30bb']), ('\u32de', &['\u30bd']), ('\u32df', &['\u30bf']), ('\u32e0',
+        &['\u30c1']), ('\u32e1', &['\u30c4']), ('\u32e2', &['\u30c6']), ('\u32e3', &['\u30c8']),
+        ('\u32e4', &['\u30ca']), ('\u32e5', &['\u30cb']), ('\u32e6', &['\u30cc']), ('\u32e7',
+        &['\u30cd']), ('\u32e8', &['\u30ce']), ('\u32e9', &['\u30cf']), ('\u32ea', &['\u30d2']),
+        ('\u32eb', &['\u30d5']), ('\u32ec', &['\u30d8']), ('\u32ed', &['\u30db']), ('\u32ee',
+        &['\u30de']), ('\u32ef', &['\u30df']), ('\u32f0', &['\u30e0']), ('\u32f1', &['\u30e1']),
+        ('\u32f2', &['\u30e2']), ('\u32f3', &['\u30e4']), ('\u32f4', &['\u30e6']), ('\u32f5',
+        &['\u30e8']), ('\u32f6', &['\u30e9']), ('\u32f7', &['\u30ea']), ('\u32f8', &['\u30eb']),
+        ('\u32f9', &['\u30ec']), ('\u32fa', &['\u30ed']), ('\u32fb', &['\u30ef']), ('\u32fc',
+        &['\u30f0']), ('\u32fd', &['\u30f1']), ('\u32fe', &['\u30f2']), ('\u3300', &['\u30a2',
+        '\u30d1', '\u30fc', '\u30c8']), ('\u3301', &['\u30a2', '\u30eb', '\u30d5', '\u30a1']),
+        ('\u3302', &['\u30a2', '\u30f3', '\u30da', '\u30a2']), ('\u3303', &['\u30a2', '\u30fc',
+        '\u30eb']), ('\u3304', &['\u30a4', '\u30cb', '\u30f3', '\u30b0']), ('\u3305', &['\u30a4',
+        '\u30f3', '\u30c1']), ('\u3306', &['\u30a6', '\u30a9', '\u30f3']), ('\u3307', &['\u30a8',
+        '\u30b9', '\u30af', '\u30fc', '\u30c9']), ('\u3308', &['\u30a8', '\u30fc', '\u30ab',
+        '\u30fc']), ('\u3309', &['\u30aa', '\u30f3', '\u30b9']), ('\u330a', &['\u30aa', '\u30fc',
+        '\u30e0']), ('\u330b', &['\u30ab', '\u30a4', '\u30ea']), ('\u330c', &['\u30ab', '\u30e9',
+        '\u30c3', '\u30c8']), ('\u330d', &['\u30ab', '\u30ed', '\u30ea', '\u30fc']), ('\u330e',
+        &['\u30ac', '\u30ed', '\u30f3']), ('\u330f', &['\u30ac', '\u30f3', '\u30de']), ('\u3310',
+        &['\u30ae', '\u30ac']), ('\u3311', &['\u30ae', '\u30cb', '\u30fc']), ('\u3312', &['\u30ad',
+        '\u30e5', '\u30ea', '\u30fc']), ('\u3313', &['\u30ae', '\u30eb', '\u30c0', '\u30fc']),
+        ('\u3314', &['\u30ad', '\u30ed']), ('\u3315', &['\u30ad', '\u30ed', '\u30b0', '\u30e9',
+        '\u30e0']), ('\u3316', &['\u30ad', '\u30ed', '\u30e1', '\u30fc', '\u30c8', '\u30eb']),
+        ('\u3317', &['\u30ad', '\u30ed', '\u30ef', '\u30c3', '\u30c8']), ('\u3318', &['\u30b0',
+        '\u30e9', '\u30e0']), ('\u3319', &['\u30b0', '\u30e9', '\u30e0', '\u30c8', '\u30f3']),
+        ('\u331a', &['\u30af', '\u30eb', '\u30bc', '\u30a4', '\u30ed']), ('\u331b', &['\u30af',
+        '\u30ed', '\u30fc', '\u30cd']), ('\u331c', &['\u30b1', '\u30fc', '\u30b9']), ('\u331d',
+        &['\u30b3', '\u30eb', '\u30ca']), ('\u331e', &['\u30b3', '\u30fc', '\u30dd']), ('\u331f',
+        &['\u30b5', '\u30a4', '\u30af', '\u30eb']), ('\u3320', &['\u30b5', '\u30f3', '\u30c1',
+        '\u30fc', '\u30e0']), ('\u3321', &['\u30b7', '\u30ea', '\u30f3', '\u30b0']), ('\u3322',
+        &['\u30bb', '\u30f3', '\u30c1']), ('\u3323', &['\u30bb', '\u30f3', '\u30c8']), ('\u3324',
+        &['\u30c0', '\u30fc', '\u30b9']), ('\u3325', &['\u30c7', '\u30b7']), ('\u3326', &['\u30c9',
+        '\u30eb']), ('\u3327', &['\u30c8', '\u30f3']), ('\u3328', &['\u30ca', '\u30ce']), ('\u3329',
+        &['\u30ce', '\u30c3', '\u30c8']), ('\u332a', &['\u30cf', '\u30a4', '\u30c4']), ('\u332b',
+        &['\u30d1', '\u30fc', '\u30bb', '\u30f3', '\u30c8']), ('\u332c', &['\u30d1', '\u30fc',
+        '\u30c4']), ('\u332d', &['\u30d0', '\u30fc', '\u30ec', '\u30eb']), ('\u332e', &['\u30d4',
+        '\u30a2', '\u30b9', '\u30c8', '\u30eb']), ('\u332f', &['\u30d4', '\u30af', '\u30eb']),
+        ('\u3330', &['\u30d4', '\u30b3']), ('\u3331', &['\u30d3', '\u30eb']), ('\u3332', &['\u30d5',
+        '\u30a1', '\u30e9', '\u30c3', '\u30c9']), ('\u3333', &['\u30d5', '\u30a3', '\u30fc',
+        '\u30c8']), ('\u3334', &['\u30d6', '\u30c3', '\u30b7', '\u30a7', '\u30eb']), ('\u3335',
+        &['\u30d5', '\u30e9', '\u30f3']), ('\u3336', &['\u30d8', '\u30af', '\u30bf', '\u30fc',
+        '\u30eb']), ('\u3337', &['\u30da', '\u30bd']), ('\u3338', &['\u30da', '\u30cb', '\u30d2']),
+        ('\u3339', &['\u30d8', '\u30eb', '\u30c4']), ('\u333a', &['\u30da', '\u30f3', '\u30b9']),
+        ('\u333b', &['\u30da', '\u30fc', '\u30b8']), ('\u333c', &['\u30d9', '\u30fc', '\u30bf']),
+        ('\u333d', &['\u30dd', '\u30a4', '\u30f3', '\u30c8']), ('\u333e', &['\u30dc', '\u30eb',
+        '\u30c8']), ('\u333f', &['\u30db', '\u30f3']), ('\u3340', &['\u30dd', '\u30f3', '\u30c9']),
+        ('\u3341', &['\u30db', '\u30fc', '\u30eb']), ('\u3342', &['\u30db', '\u30fc', '\u30f3']),
+        ('\u3343', &['\u30de', '\u30a4', '\u30af', '\u30ed']), ('\u3344', &['\u30de', '\u30a4',
+        '\u30eb']), ('\u3345', &['\u30de', '\u30c3', '\u30cf']), ('\u3346', &['\u30de', '\u30eb',
+        '\u30af']), ('\u3347', &['\u30de', '\u30f3', '\u30b7', '\u30e7', '\u30f3']), ('\u3348',
+        &['\u30df', '\u30af', '\u30ed', '\u30f3']), ('\u3349', &['\u30df', '\u30ea']), ('\u334a',
+        &['\u30df', '\u30ea', '\u30d0', '\u30fc', '\u30eb']), ('\u334b', &['\u30e1', '\u30ac']),
+        ('\u334c', &['\u30e1', '\u30ac', '\u30c8', '\u30f3']), ('\u334d', &['\u30e1', '\u30fc',
+        '\u30c8', '\u30eb']), ('\u334e', &['\u30e4', '\u30fc', '\u30c9']), ('\u334f', &['\u30e4',
+        '\u30fc', '\u30eb']), ('\u3350', &['\u30e6', '\u30a2', '\u30f3']), ('\u3351', &['\u30ea',
+        '\u30c3', '\u30c8', '\u30eb']), ('\u3352', &['\u30ea', '\u30e9']), ('\u3353', &['\u30eb',
+        '\u30d4', '\u30fc']), ('\u3354', &['\u30eb', '\u30fc', '\u30d6', '\u30eb']), ('\u3355',
+        &['\u30ec', '\u30e0']), ('\u3356', &['\u30ec', '\u30f3', '\u30c8', '\u30b2', '\u30f3']),
+        ('\u3357', &['\u30ef', '\u30c3', '\u30c8']), ('\u3358', &['\x30', '\u70b9']), ('\u3359',
+        &['\x31', '\u70b9']), ('\u335a', &['\x32', '\u70b9']), ('\u335b', &['\x33', '\u70b9']),
+        ('\u335c', &['\x34', '\u70b9']), ('\u335d', &['\x35', '\u70b9']), ('\u335e', &['\x36',
+        '\u70b9']), ('\u335f', &['\x37', '\u70b9']), ('\u3360', &['\x38', '\u70b9']), ('\u3361',
+        &['\x39', '\u70b9']), ('\u3362', &['\x31', '\x30', '\u70b9']), ('\u3363', &['\x31', '\x31',
+        '\u70b9']), ('\u3364', &['\x31', '\x32', '\u70b9']), ('\u3365', &['\x31', '\x33',
+        '\u70b9']), ('\u3366', &['\x31', '\x34', '\u70b9']), ('\u3367', &['\x31', '\x35',
+        '\u70b9']), ('\u3368', &['\x31', '\x36', '\u70b9']), ('\u3369', &['\x31', '\x37',
+        '\u70b9']), ('\u336a', &['\x31', '\x38', '\u70b9']), ('\u336b', &['\x31', '\x39',
+        '\u70b9']), ('\u336c', &['\x32', '\x30', '\u70b9']), ('\u336d', &['\x32', '\x31',
+        '\u70b9']), ('\u336e', &['\x32', '\x32', '\u70b9']), ('\u336f', &['\x32', '\x33',
+        '\u70b9']), ('\u3370', &['\x32', '\x34', '\u70b9']), ('\u3371', &['\x68', '\x50', '\x61']),
+        ('\u3372', &['\x64', '\x61']), ('\u3373', &['\x41', '\x55']), ('\u3374', &['\x62', '\x61',
+        '\x72']), ('\u3375', &['\x6f', '\x56']), ('\u3376', &['\x70', '\x63']), ('\u3377', &['\x64',
+        '\x6d']), ('\u3378', &['\x64', '\x6d', '\xb2']), ('\u3379', &['\x64', '\x6d', '\xb3']),
+        ('\u337a', &['\x49', '\x55']), ('\u337b', &['\u5e73', '\u6210']), ('\u337c', &['\u662d',
+        '\u548c']), ('\u337d', &['\u5927', '\u6b63']), ('\u337e', &['\u660e', '\u6cbb']), ('\u337f',
+        &['\u682a', '\u5f0f', '\u4f1a', '\u793e']), ('\u3380', &['\x70', '\x41']), ('\u3381',
+        &['\x6e', '\x41']), ('\u3382', &['\u03bc', '\x41']), ('\u3383', &['\x6d', '\x41']),
+        ('\u3384', &['\x6b', '\x41']), ('\u3385', &['\x4b', '\x42']), ('\u3386', &['\x4d', '\x42']),
+        ('\u3387', &['\x47', '\x42']), ('\u3388', &['\x63', '\x61', '\x6c']), ('\u3389', &['\x6b',
+        '\x63', '\x61', '\x6c']), ('\u338a', &['\x70', '\x46']), ('\u338b', &['\x6e', '\x46']),
+        ('\u338c', &['\u03bc', '\x46']), ('\u338d', &['\u03bc', '\x67']), ('\u338e', &['\x6d',
+        '\x67']), ('\u338f', &['\x6b', '\x67']), ('\u3390', &['\x48', '\x7a']), ('\u3391', &['\x6b',
+        '\x48', '\x7a']), ('\u3392', &['\x4d', '\x48', '\x7a']), ('\u3393', &['\x47', '\x48',
+        '\x7a']), ('\u3394', &['\x54', '\x48', '\x7a']), ('\u3395', &['\u03bc', '\u2113']),
+        ('\u3396', &['\x6d', '\u2113']), ('\u3397', &['\x64', '\u2113']), ('\u3398', &['\x6b',
+        '\u2113']), ('\u3399', &['\x66', '\x6d']), ('\u339a', &['\x6e', '\x6d']), ('\u339b',
+        &['\u03bc', '\x6d']), ('\u339c', &['\x6d', '\x6d']), ('\u339d', &['\x63', '\x6d']),
+        ('\u339e', &['\x6b', '\x6d']), ('\u339f', &['\x6d', '\x6d', '\xb2']), ('\u33a0', &['\x63',
+        '\x6d', '\xb2']), ('\u33a1', &['\x6d', '\xb2']), ('\u33a2', &['\x6b', '\x6d', '\xb2']),
+        ('\u33a3', &['\x6d', '\x6d', '\xb3']), ('\u33a4', &['\x63', '\x6d', '\xb3']), ('\u33a5',
+        &['\x6d', '\xb3']), ('\u33a6', &['\x6b', '\x6d', '\xb3']), ('\u33a7', &['\x6d', '\u2215',
+        '\x73']), ('\u33a8', &['\x6d', '\u2215', '\x73', '\xb2']), ('\u33a9', &['\x50', '\x61']),
+        ('\u33aa', &['\x6b', '\x50', '\x61']), ('\u33ab', &['\x4d', '\x50', '\x61']), ('\u33ac',
+        &['\x47', '\x50', '\x61']), ('\u33ad', &['\x72', '\x61', '\x64']), ('\u33ae', &['\x72',
+        '\x61', '\x64', '\u2215', '\x73']), ('\u33af', &['\x72', '\x61', '\x64', '\u2215', '\x73',
+        '\xb2']), ('\u33b0', &['\x70', '\x73']), ('\u33b1', &['\x6e', '\x73']), ('\u33b2',
+        &['\u03bc', '\x73']), ('\u33b3', &['\x6d', '\x73']), ('\u33b4', &['\x70', '\x56']),
+        ('\u33b5', &['\x6e', '\x56']), ('\u33b6', &['\u03bc', '\x56']), ('\u33b7', &['\x6d',
+        '\x56']), ('\u33b8', &['\x6b', '\x56']), ('\u33b9', &['\x4d', '\x56']), ('\u33ba', &['\x70',
+        '\x57']), ('\u33bb', &['\x6e', '\x57']), ('\u33bc', &['\u03bc', '\x57']), ('\u33bd',
+        &['\x6d', '\x57']), ('\u33be', &['\x6b', '\x57']), ('\u33bf', &['\x4d', '\x57']), ('\u33c0',
+        &['\x6b', '\u03a9']), ('\u33c1', &['\x4d', '\u03a9']), ('\u33c2', &['\x61', '\x2e', '\x6d',
+        '\x2e']), ('\u33c3', &['\x42', '\x71']), ('\u33c4', &['\x63', '\x63']), ('\u33c5', &['\x63',
+        '\x64']), ('\u33c6', &['\x43', '\u2215', '\x6b', '\x67']), ('\u33c7', &['\x43', '\x6f',
+        '\x2e']), ('\u33c8', &['\x64', '\x42']), ('\u33c9', &['\x47', '\x79']), ('\u33ca', &['\x68',
+        '\x61']), ('\u33cb', &['\x48', '\x50']), ('\u33cc', &['\x69', '\x6e']), ('\u33cd', &['\x4b',
+        '\x4b']), ('\u33ce', &['\x4b', '\x4d']), ('\u33cf', &['\x6b', '\x74']), ('\u33d0', &['\x6c',
+        '\x6d']), ('\u33d1', &['\x6c', '\x6e']), ('\u33d2', &['\x6c', '\x6f', '\x67']), ('\u33d3',
+        &['\x6c', '\x78']), ('\u33d4', &['\x6d', '\x62']), ('\u33d5', &['\x6d', '\x69', '\x6c']),
+        ('\u33d6', &['\x6d', '\x6f', '\x6c']), ('\u33d7', &['\x50', '\x48']), ('\u33d8', &['\x70',
+        '\x2e', '\x6d', '\x2e']), ('\u33d9', &['\x50', '\x50', '\x4d']), ('\u33da', &['\x50',
+        '\x52']), ('\u33db', &['\x73', '\x72']), ('\u33dc', &['\x53', '\x76']), ('\u33dd', &['\x57',
+        '\x62']), ('\u33de', &['\x56', '\u2215', '\x6d']), ('\u33df', &['\x41', '\u2215', '\x6d']),
+        ('\u33e0', &['\x31', '\u65e5']), ('\u33e1', &['\x32', '\u65e5']), ('\u33e2', &['\x33',
+        '\u65e5']), ('\u33e3', &['\x34', '\u65e5']), ('\u33e4', &['\x35', '\u65e5']), ('\u33e5',
+        &['\x36', '\u65e5']), ('\u33e6', &['\x37', '\u65e5']), ('\u33e7', &['\x38', '\u65e5']),
+        ('\u33e8', &['\x39', '\u65e5']), ('\u33e9', &['\x31', '\x30', '\u65e5']), ('\u33ea',
+        &['\x31', '\x31', '\u65e5']), ('\u33eb', &['\x31', '\x32', '\u65e5']), ('\u33ec', &['\x31',
+        '\x33', '\u65e5']), ('\u33ed', &['\x31', '\x34', '\u65e5']), ('\u33ee', &['\x31', '\x35',
+        '\u65e5']), ('\u33ef', &['\x31', '\x36', '\u65e5']), ('\u33f0', &['\x31', '\x37',
+        '\u65e5']), ('\u33f1', &['\x31', '\x38', '\u65e5']), ('\u33f2', &['\x31', '\x39',
+        '\u65e5']), ('\u33f3', &['\x32', '\x30', '\u65e5']), ('\u33f4', &['\x32', '\x31',
+        '\u65e5']), ('\u33f5', &['\x32', '\x32', '\u65e5']), ('\u33f6', &['\x32', '\x33',
+        '\u65e5']), ('\u33f7', &['\x32', '\x34', '\u65e5']), ('\u33f8', &['\x32', '\x35',
+        '\u65e5']), ('\u33f9', &['\x32', '\x36', '\u65e5']), ('\u33fa', &['\x32', '\x37',
+        '\u65e5']), ('\u33fb', &['\x32', '\x38', '\u65e5']), ('\u33fc', &['\x32', '\x39',
+        '\u65e5']), ('\u33fd', &['\x33', '\x30', '\u65e5']), ('\u33fe', &['\x33', '\x31',
+        '\u65e5']), ('\u33ff', &['\x67', '\x61', '\x6c']), ('\ua69c', &['\u044a']), ('\ua69d',
+        &['\u044c']), ('\ua770', &['\ua76f']), ('\ua7f8', &['\u0126']), ('\ua7f9', &['\u0153']),
+        ('\uab5c', &['\ua727']), ('\uab5d', &['\uab37']), ('\uab5e', &['\u026b']), ('\uab5f',
+        &['\uab52']), ('\ufb00', &['\x66', '\x66']), ('\ufb01', &['\x66', '\x69']), ('\ufb02',
+        &['\x66', '\x6c']), ('\ufb03', &['\x66', '\x66', '\x69']), ('\ufb04', &['\x66', '\x66',
+        '\x6c']), ('\ufb05', &['\u017f', '\x74']), ('\ufb06', &['\x73', '\x74']), ('\ufb13',
+        &['\u0574', '\u0576']), ('\ufb14', &['\u0574', '\u0565']), ('\ufb15', &['\u0574',
+        '\u056b']), ('\ufb16', &['\u057e', '\u0576']), ('\ufb17', &['\u0574', '\u056d']), ('\ufb20',
+        &['\u05e2']), ('\ufb21', &['\u05d0']), ('\ufb22', &['\u05d3']), ('\ufb23', &['\u05d4']),
+        ('\ufb24', &['\u05db']), ('\ufb25', &['\u05dc']), ('\ufb26', &['\u05dd']), ('\ufb27',
+        &['\u05e8']), ('\ufb28', &['\u05ea']), ('\ufb29', &['\x2b']), ('\ufb4f', &['\u05d0',
+        '\u05dc']), ('\ufb50', &['\u0671']), ('\ufb51', &['\u0671']), ('\ufb52', &['\u067b']),
+        ('\ufb53', &['\u067b']), ('\ufb54', &['\u067b']), ('\ufb55', &['\u067b']), ('\ufb56',
+        &['\u067e']), ('\ufb57', &['\u067e']), ('\ufb58', &['\u067e']), ('\ufb59', &['\u067e']),
+        ('\ufb5a', &['\u0680']), ('\ufb5b', &['\u0680']), ('\ufb5c', &['\u0680']), ('\ufb5d',
+        &['\u0680']), ('\ufb5e', &['\u067a']), ('\ufb5f', &['\u067a']), ('\ufb60', &['\u067a']),
+        ('\ufb61', &['\u067a']), ('\ufb62', &['\u067f']), ('\ufb63', &['\u067f']), ('\ufb64',
+        &['\u067f']), ('\ufb65', &['\u067f']), ('\ufb66', &['\u0679']), ('\ufb67', &['\u0679']),
+        ('\ufb68', &['\u0679']), ('\ufb69', &['\u0679']), ('\ufb6a', &['\u06a4']), ('\ufb6b',
+        &['\u06a4']), ('\ufb6c', &['\u06a4']), ('\ufb6d', &['\u06a4']), ('\ufb6e', &['\u06a6']),
+        ('\ufb6f', &['\u06a6']), ('\ufb70', &['\u06a6']), ('\ufb71', &['\u06a6']), ('\ufb72',
+        &['\u0684']), ('\ufb73', &['\u0684']), ('\ufb74', &['\u0684']), ('\ufb75', &['\u0684']),
+        ('\ufb76', &['\u0683']), ('\ufb77', &['\u0683']), ('\ufb78', &['\u0683']), ('\ufb79',
+        &['\u0683']), ('\ufb7a', &['\u0686']), ('\ufb7b', &['\u0686']), ('\ufb7c', &['\u0686']),
+        ('\ufb7d', &['\u0686']), ('\ufb7e', &['\u0687']), ('\ufb7f', &['\u0687']), ('\ufb80',
+        &['\u0687']), ('\ufb81', &['\u0687']), ('\ufb82', &['\u068d']), ('\ufb83', &['\u068d']),
+        ('\ufb84', &['\u068c']), ('\ufb85', &['\u068c']), ('\ufb86', &['\u068e']), ('\ufb87',
+        &['\u068e']), ('\ufb88', &['\u0688']), ('\ufb89', &['\u0688']), ('\ufb8a', &['\u0698']),
+        ('\ufb8b', &['\u0698']), ('\ufb8c', &['\u0691']), ('\ufb8d', &['\u0691']), ('\ufb8e',
+        &['\u06a9']), ('\ufb8f', &['\u06a9']), ('\ufb90', &['\u06a9']), ('\ufb91', &['\u06a9']),
+        ('\ufb92', &['\u06af']), ('\ufb93', &['\u06af']), ('\ufb94', &['\u06af']), ('\ufb95',
+        &['\u06af']), ('\ufb96', &['\u06b3']), ('\ufb97', &['\u06b3']), ('\ufb98', &['\u06b3']),
+        ('\ufb99', &['\u06b3']), ('\ufb9a', &['\u06b1']), ('\ufb9b', &['\u06b1']), ('\ufb9c',
+        &['\u06b1']), ('\ufb9d', &['\u06b1']), ('\ufb9e', &['\u06ba']), ('\ufb9f', &['\u06ba']),
+        ('\ufba0', &['\u06bb']), ('\ufba1', &['\u06bb']), ('\ufba2', &['\u06bb']), ('\ufba3',
+        &['\u06bb']), ('\ufba4', &['\u06c0']), ('\ufba5', &['\u06c0']), ('\ufba6', &['\u06c1']),
+        ('\ufba7', &['\u06c1']), ('\ufba8', &['\u06c1']), ('\ufba9', &['\u06c1']), ('\ufbaa',
+        &['\u06be']), ('\ufbab', &['\u06be']), ('\ufbac', &['\u06be']), ('\ufbad', &['\u06be']),
+        ('\ufbae', &['\u06d2']), ('\ufbaf', &['\u06d2']), ('\ufbb0', &['\u06d3']), ('\ufbb1',
+        &['\u06d3']), ('\ufbd3', &['\u06ad']), ('\ufbd4', &['\u06ad']), ('\ufbd5', &['\u06ad']),
+        ('\ufbd6', &['\u06ad']), ('\ufbd7', &['\u06c7']), ('\ufbd8', &['\u06c7']), ('\ufbd9',
+        &['\u06c6']), ('\ufbda', &['\u06c6']), ('\ufbdb', &['\u06c8']), ('\ufbdc', &['\u06c8']),
+        ('\ufbdd', &['\u0677']), ('\ufbde', &['\u06cb']), ('\ufbdf', &['\u06cb']), ('\ufbe0',
+        &['\u06c5']), ('\ufbe1', &['\u06c5']), ('\ufbe2', &['\u06c9']), ('\ufbe3', &['\u06c9']),
+        ('\ufbe4', &['\u06d0']), ('\ufbe5', &['\u06d0']), ('\ufbe6', &['\u06d0']), ('\ufbe7',
+        &['\u06d0']), ('\ufbe8', &['\u0649']), ('\ufbe9', &['\u0649']), ('\ufbea', &['\u0626',
+        '\u0627']), ('\ufbeb', &['\u0626', '\u0627']), ('\ufbec', &['\u0626', '\u06d5']), ('\ufbed',
+        &['\u0626', '\u06d5']), ('\ufbee', &['\u0626', '\u0648']), ('\ufbef', &['\u0626',
+        '\u0648']), ('\ufbf0', &['\u0626', '\u06c7']), ('\ufbf1', &['\u0626', '\u06c7']), ('\ufbf2',
+        &['\u0626', '\u06c6']), ('\ufbf3', &['\u0626', '\u06c6']), ('\ufbf4', &['\u0626',
+        '\u06c8']), ('\ufbf5', &['\u0626', '\u06c8']), ('\ufbf6', &['\u0626', '\u06d0']), ('\ufbf7',
+        &['\u0626', '\u06d0']), ('\ufbf8', &['\u0626', '\u06d0']), ('\ufbf9', &['\u0626',
+        '\u0649']), ('\ufbfa', &['\u0626', '\u0649']), ('\ufbfb', &['\u0626', '\u0649']), ('\ufbfc',
+        &['\u06cc']), ('\ufbfd', &['\u06cc']), ('\ufbfe', &['\u06cc']), ('\ufbff', &['\u06cc']),
+        ('\ufc00', &['\u0626', '\u062c']), ('\ufc01', &['\u0626', '\u062d']), ('\ufc02', &['\u0626',
+        '\u0645']), ('\ufc03', &['\u0626', '\u0649']), ('\ufc04', &['\u0626', '\u064a']), ('\ufc05',
+        &['\u0628', '\u062c']), ('\ufc06', &['\u0628', '\u062d']), ('\ufc07', &['\u0628',
+        '\u062e']), ('\ufc08', &['\u0628', '\u0645']), ('\ufc09', &['\u0628', '\u0649']), ('\ufc0a',
+        &['\u0628', '\u064a']), ('\ufc0b', &['\u062a', '\u062c']), ('\ufc0c', &['\u062a',
+        '\u062d']), ('\ufc0d', &['\u062a', '\u062e']), ('\ufc0e', &['\u062a', '\u0645']), ('\ufc0f',
+        &['\u062a', '\u0649']), ('\ufc10', &['\u062a', '\u064a']), ('\ufc11', &['\u062b',
+        '\u062c']), ('\ufc12', &['\u062b', '\u0645']), ('\ufc13', &['\u062b', '\u0649']), ('\ufc14',
+        &['\u062b', '\u064a']), ('\ufc15', &['\u062c', '\u062d']), ('\ufc16', &['\u062c',
+        '\u0645']), ('\ufc17', &['\u062d', '\u062c']), ('\ufc18', &['\u062d', '\u0645']), ('\ufc19',
+        &['\u062e', '\u062c']), ('\ufc1a', &['\u062e', '\u062d']), ('\ufc1b', &['\u062e',
+        '\u0645']), ('\ufc1c', &['\u0633', '\u062c']), ('\ufc1d', &['\u0633', '\u062d']), ('\ufc1e',
+        &['\u0633', '\u062e']), ('\ufc1f', &['\u0633', '\u0645']), ('\ufc20', &['\u0635',
+        '\u062d']), ('\ufc21', &['\u0635', '\u0645']), ('\ufc22', &['\u0636', '\u062c']), ('\ufc23',
+        &['\u0636', '\u062d']), ('\ufc24', &['\u0636', '\u062e']), ('\ufc25', &['\u0636',
+        '\u0645']), ('\ufc26', &['\u0637', '\u062d']), ('\ufc27', &['\u0637', '\u0645']), ('\ufc28',
+        &['\u0638', '\u0645']), ('\ufc29', &['\u0639', '\u062c']), ('\ufc2a', &['\u0639',
+        '\u0645']), ('\ufc2b', &['\u063a', '\u062c']), ('\ufc2c', &['\u063a', '\u0645']), ('\ufc2d',
+        &['\u0641', '\u062c']), ('\ufc2e', &['\u0641', '\u062d']), ('\ufc2f', &['\u0641',
+        '\u062e']), ('\ufc30', &['\u0641', '\u0645']), ('\ufc31', &['\u0641', '\u0649']), ('\ufc32',
+        &['\u0641', '\u064a']), ('\ufc33', &['\u0642', '\u062d']), ('\ufc34', &['\u0642',
+        '\u0645']), ('\ufc35', &['\u0642', '\u0649']), ('\ufc36', &['\u0642', '\u064a']), ('\ufc37',
+        &['\u0643', '\u0627']), ('\ufc38', &['\u0643', '\u062c']), ('\ufc39', &['\u0643',
+        '\u062d']), ('\ufc3a', &['\u0643', '\u062e']), ('\ufc3b', &['\u0643', '\u0644']), ('\ufc3c',
+        &['\u0643', '\u0645']), ('\ufc3d', &['\u0643', '\u0649']), ('\ufc3e', &['\u0643',
+        '\u064a']), ('\ufc3f', &['\u0644', '\u062c']), ('\ufc40', &['\u0644', '\u062d']), ('\ufc41',
+        &['\u0644', '\u062e']), ('\ufc42', &['\u0644', '\u0645']), ('\ufc43', &['\u0644',
+        '\u0649']), ('\ufc44', &['\u0644', '\u064a']), ('\ufc45', &['\u0645', '\u062c']), ('\ufc46',
+        &['\u0645', '\u062d']), ('\ufc47', &['\u0645', '\u062e']), ('\ufc48', &['\u0645',
+        '\u0645']), ('\ufc49', &['\u0645', '\u0649']), ('\ufc4a', &['\u0645', '\u064a']), ('\ufc4b',
+        &['\u0646', '\u062c']), ('\ufc4c', &['\u0646', '\u062d']), ('\ufc4d', &['\u0646',
+        '\u062e']), ('\ufc4e', &['\u0646', '\u0645']), ('\ufc4f', &['\u0646', '\u0649']), ('\ufc50',
+        &['\u0646', '\u064a']), ('\ufc51', &['\u0647', '\u062c']), ('\ufc52', &['\u0647',
+        '\u0645']), ('\ufc53', &['\u0647', '\u0649']), ('\ufc54', &['\u0647', '\u064a']), ('\ufc55',
+        &['\u064a', '\u062c']), ('\ufc56', &['\u064a', '\u062d']), ('\ufc57', &['\u064a',
+        '\u062e']), ('\ufc58', &['\u064a', '\u0645']), ('\ufc59', &['\u064a', '\u0649']), ('\ufc5a',
+        &['\u064a', '\u064a']), ('\ufc5b', &['\u0630', '\u0670']), ('\ufc5c', &['\u0631',
+        '\u0670']), ('\ufc5d', &['\u0649', '\u0670']), ('\ufc5e', &['\x20', '\u064c', '\u0651']),
+        ('\ufc5f', &['\x20', '\u064d', '\u0651']), ('\ufc60', &['\x20', '\u064e', '\u0651']),
+        ('\ufc61', &['\x20', '\u064f', '\u0651']), ('\ufc62', &['\x20', '\u0650', '\u0651']),
+        ('\ufc63', &['\x20', '\u0651', '\u0670']), ('\ufc64', &['\u0626', '\u0631']), ('\ufc65',
+        &['\u0626', '\u0632']), ('\ufc66', &['\u0626', '\u0645']), ('\ufc67', &['\u0626',
+        '\u0646']), ('\ufc68', &['\u0626', '\u0649']), ('\ufc69', &['\u0626', '\u064a']), ('\ufc6a',
+        &['\u0628', '\u0631']), ('\ufc6b', &['\u0628', '\u0632']), ('\ufc6c', &['\u0628',
+        '\u0645']), ('\ufc6d', &['\u0628', '\u0646']), ('\ufc6e', &['\u0628', '\u0649']), ('\ufc6f',
+        &['\u0628', '\u064a']), ('\ufc70', &['\u062a', '\u0631']), ('\ufc71', &['\u062a',
+        '\u0632']), ('\ufc72', &['\u062a', '\u0645']), ('\ufc73', &['\u062a', '\u0646']), ('\ufc74',
+        &['\u062a', '\u0649']), ('\ufc75', &['\u062a', '\u064a']), ('\ufc76', &['\u062b',
+        '\u0631']), ('\ufc77', &['\u062b', '\u0632']), ('\ufc78', &['\u062b', '\u0645']), ('\ufc79',
+        &['\u062b', '\u0646']), ('\ufc7a', &['\u062b', '\u0649']), ('\ufc7b', &['\u062b',
+        '\u064a']), ('\ufc7c', &['\u0641', '\u0649']), ('\ufc7d', &['\u0641', '\u064a']), ('\ufc7e',
+        &['\u0642', '\u0649']), ('\ufc7f', &['\u0642', '\u064a']), ('\ufc80', &['\u0643',
+        '\u0627']), ('\ufc81', &['\u0643', '\u0644']), ('\ufc82', &['\u0643', '\u0645']), ('\ufc83',
+        &['\u0643', '\u0649']), ('\ufc84', &['\u0643', '\u064a']), ('\ufc85', &['\u0644',
+        '\u0645']), ('\ufc86', &['\u0644', '\u0649']), ('\ufc87', &['\u0644', '\u064a']), ('\ufc88',
+        &['\u0645', '\u0627']), ('\ufc89', &['\u0645', '\u0645']), ('\ufc8a', &['\u0646',
+        '\u0631']), ('\ufc8b', &['\u0646', '\u0632']), ('\ufc8c', &['\u0646', '\u0645']), ('\ufc8d',
+        &['\u0646', '\u0646']), ('\ufc8e', &['\u0646', '\u0649']), ('\ufc8f', &['\u0646',
+        '\u064a']), ('\ufc90', &['\u0649', '\u0670']), ('\ufc91', &['\u064a', '\u0631']), ('\ufc92',
+        &['\u064a', '\u0632']), ('\ufc93', &['\u064a', '\u0645']), ('\ufc94', &['\u064a',
+        '\u0646']), ('\ufc95', &['\u064a', '\u0649']), ('\ufc96', &['\u064a', '\u064a']), ('\ufc97',
+        &['\u0626', '\u062c']), ('\ufc98', &['\u0626', '\u062d']), ('\ufc99', &['\u0626',
+        '\u062e']), ('\ufc9a', &['\u0626', '\u0645']), ('\ufc9b', &['\u0626', '\u0647']), ('\ufc9c',
+        &['\u0628', '\u062c']), ('\ufc9d', &['\u0628', '\u062d']), ('\ufc9e', &['\u0628',
+        '\u062e']), ('\ufc9f', &['\u0628', '\u0645']), ('\ufca0', &['\u0628', '\u0647']), ('\ufca1',
+        &['\u062a', '\u062c']), ('\ufca2', &['\u062a', '\u062d']), ('\ufca3', &['\u062a',
+        '\u062e']), ('\ufca4', &['\u062a', '\u0645']), ('\ufca5', &['\u062a', '\u0647']), ('\ufca6',
+        &['\u062b', '\u0645']), ('\ufca7', &['\u062c', '\u062d']), ('\ufca8', &['\u062c',
+        '\u0645']), ('\ufca9', &['\u062d', '\u062c']), ('\ufcaa', &['\u062d', '\u0645']), ('\ufcab',
+        &['\u062e', '\u062c']), ('\ufcac', &['\u062e', '\u0645']), ('\ufcad', &['\u0633',
+        '\u062c']), ('\ufcae', &['\u0633', '\u062d']), ('\ufcaf', &['\u0633', '\u062e']), ('\ufcb0',
+        &['\u0633', '\u0645']), ('\ufcb1', &['\u0635', '\u062d']), ('\ufcb2', &['\u0635',
+        '\u062e']), ('\ufcb3', &['\u0635', '\u0645']), ('\ufcb4', &['\u0636', '\u062c']), ('\ufcb5',
+        &['\u0636', '\u062d']), ('\ufcb6', &['\u0636', '\u062e']), ('\ufcb7', &['\u0636',
+        '\u0645']), ('\ufcb8', &['\u0637', '\u062d']), ('\ufcb9', &['\u0638', '\u0645']), ('\ufcba',
+        &['\u0639', '\u062c']), ('\ufcbb', &['\u0639', '\u0645']), ('\ufcbc', &['\u063a',
+        '\u062c']), ('\ufcbd', &['\u063a', '\u0645']), ('\ufcbe', &['\u0641', '\u062c']), ('\ufcbf',
+        &['\u0641', '\u062d']), ('\ufcc0', &['\u0641', '\u062e']), ('\ufcc1', &['\u0641',
+        '\u0645']), ('\ufcc2', &['\u0642', '\u062d']), ('\ufcc3', &['\u0642', '\u0645']), ('\ufcc4',
+        &['\u0643', '\u062c']), ('\ufcc5', &['\u0643', '\u062d']), ('\ufcc6', &['\u0643',
+        '\u062e']), ('\ufcc7', &['\u0643', '\u0644']), ('\ufcc8', &['\u0643', '\u0645']), ('\ufcc9',
+        &['\u0644', '\u062c']), ('\ufcca', &['\u0644', '\u062d']), ('\ufccb', &['\u0644',
+        '\u062e']), ('\ufccc', &['\u0644', '\u0645']), ('\ufccd', &['\u0644', '\u0647']), ('\ufcce',
+        &['\u0645', '\u062c']), ('\ufccf', &['\u0645', '\u062d']), ('\ufcd0', &['\u0645',
+        '\u062e']), ('\ufcd1', &['\u0645', '\u0645']), ('\ufcd2', &['\u0646', '\u062c']), ('\ufcd3',
+        &['\u0646', '\u062d']), ('\ufcd4', &['\u0646', '\u062e']), ('\ufcd5', &['\u0646',
+        '\u0645']), ('\ufcd6', &['\u0646', '\u0647']), ('\ufcd7', &['\u0647', '\u062c']), ('\ufcd8',
+        &['\u0647', '\u0645']), ('\ufcd9', &['\u0647', '\u0670']), ('\ufcda', &['\u064a',
+        '\u062c']), ('\ufcdb', &['\u064a', '\u062d']), ('\ufcdc', &['\u064a', '\u062e']), ('\ufcdd',
+        &['\u064a', '\u0645']), ('\ufcde', &['\u064a', '\u0647']), ('\ufcdf', &['\u0626',
+        '\u0645']), ('\ufce0', &['\u0626', '\u0647']), ('\ufce1', &['\u0628', '\u0645']), ('\ufce2',
+        &['\u0628', '\u0647']), ('\ufce3', &['\u062a', '\u0645']), ('\ufce4', &['\u062a',
+        '\u0647']), ('\ufce5', &['\u062b', '\u0645']), ('\ufce6', &['\u062b', '\u0647']), ('\ufce7',
+        &['\u0633', '\u0645']), ('\ufce8', &['\u0633', '\u0647']), ('\ufce9', &['\u0634',
+        '\u0645']), ('\ufcea', &['\u0634', '\u0647']), ('\ufceb', &['\u0643', '\u0644']), ('\ufcec',
+        &['\u0643', '\u0645']), ('\ufced', &['\u0644', '\u0645']), ('\ufcee', &['\u0646',
+        '\u0645']), ('\ufcef', &['\u0646', '\u0647']), ('\ufcf0', &['\u064a', '\u0645']), ('\ufcf1',
+        &['\u064a', '\u0647']), ('\ufcf2', &['\u0640', '\u064e', '\u0651']), ('\ufcf3', &['\u0640',
+        '\u064f', '\u0651']), ('\ufcf4', &['\u0640', '\u0650', '\u0651']), ('\ufcf5', &['\u0637',
+        '\u0649']), ('\ufcf6', &['\u0637', '\u064a']), ('\ufcf7', &['\u0639', '\u0649']), ('\ufcf8',
+        &['\u0639', '\u064a']), ('\ufcf9', &['\u063a', '\u0649']), ('\ufcfa', &['\u063a',
+        '\u064a']), ('\ufcfb', &['\u0633', '\u0649']), ('\ufcfc', &['\u0633', '\u064a']), ('\ufcfd',
+        &['\u0634', '\u0649']), ('\ufcfe', &['\u0634', '\u064a']), ('\ufcff', &['\u062d',
+        '\u0649']), ('\ufd00', &['\u062d', '\u064a']), ('\ufd01', &['\u062c', '\u0649']), ('\ufd02',
+        &['\u062c', '\u064a']), ('\ufd03', &['\u062e', '\u0649']), ('\ufd04', &['\u062e',
+        '\u064a']), ('\ufd05', &['\u0635', '\u0649']), ('\ufd06', &['\u0635', '\u064a']), ('\ufd07',
+        &['\u0636', '\u0649']), ('\ufd08', &['\u0636', '\u064a']), ('\ufd09', &['\u0634',
+        '\u062c']), ('\ufd0a', &['\u0634', '\u062d']), ('\ufd0b', &['\u0634', '\u062e']), ('\ufd0c',
+        &['\u0634', '\u0645']), ('\ufd0d', &['\u0634', '\u0631']), ('\ufd0e', &['\u0633',
+        '\u0631']), ('\ufd0f', &['\u0635', '\u0631']), ('\ufd10', &['\u0636', '\u0631']), ('\ufd11',
+        &['\u0637', '\u0649']), ('\ufd12', &['\u0637', '\u064a']), ('\ufd13', &['\u0639',
+        '\u0649']), ('\ufd14', &['\u0639', '\u064a']), ('\ufd15', &['\u063a', '\u0649']), ('\ufd16',
+        &['\u063a', '\u064a']), ('\ufd17', &['\u0633', '\u0649']), ('\ufd18', &['\u0633',
+        '\u064a']), ('\ufd19', &['\u0634', '\u0649']), ('\ufd1a', &['\u0634', '\u064a']), ('\ufd1b',
+        &['\u062d', '\u0649']), ('\ufd1c', &['\u062d', '\u064a']), ('\ufd1d', &['\u062c',
+        '\u0649']), ('\ufd1e', &['\u062c', '\u064a']), ('\ufd1f', &['\u062e', '\u0649']), ('\ufd20',
+        &['\u062e', '\u064a']), ('\ufd21', &['\u0635', '\u0649']), ('\ufd22', &['\u0635',
+        '\u064a']), ('\ufd23', &['\u0636', '\u0649']), ('\ufd24', &['\u0636', '\u064a']), ('\ufd25',
+        &['\u0634', '\u062c']), ('\ufd26', &['\u0634', '\u062d']), ('\ufd27', &['\u0634',
+        '\u062e']), ('\ufd28', &['\u0634', '\u0645']), ('\ufd29', &['\u0634', '\u0631']), ('\ufd2a',
+        &['\u0633', '\u0631']), ('\ufd2b', &['\u0635', '\u0631']), ('\ufd2c', &['\u0636',
+        '\u0631']), ('\ufd2d', &['\u0634', '\u062c']), ('\ufd2e', &['\u0634', '\u062d']), ('\ufd2f',
+        &['\u0634', '\u062e']), ('\ufd30', &['\u0634', '\u0645']), ('\ufd31', &['\u0633',
+        '\u0647']), ('\ufd32', &['\u0634', '\u0647']), ('\ufd33', &['\u0637', '\u0645']), ('\ufd34',
+        &['\u0633', '\u062c']), ('\ufd35', &['\u0633', '\u062d']), ('\ufd36', &['\u0633',
+        '\u062e']), ('\ufd37', &['\u0634', '\u062c']), ('\ufd38', &['\u0634', '\u062d']), ('\ufd39',
+        &['\u0634', '\u062e']), ('\ufd3a', &['\u0637', '\u0645']), ('\ufd3b', &['\u0638',
+        '\u0645']), ('\ufd3c', &['\u0627', '\u064b']), ('\ufd3d', &['\u0627', '\u064b']), ('\ufd50',
+        &['\u062a', '\u062c', '\u0645']), ('\ufd51', &['\u062a', '\u062d', '\u062c']), ('\ufd52',
+        &['\u062a', '\u062d', '\u062c']), ('\ufd53', &['\u062a', '\u062d', '\u0645']), ('\ufd54',
+        &['\u062a', '\u062e', '\u0645']), ('\ufd55', &['\u062a', '\u0645', '\u062c']), ('\ufd56',
+        &['\u062a', '\u0645', '\u062d']), ('\ufd57', &['\u062a', '\u0645', '\u062e']), ('\ufd58',
+        &['\u062c', '\u0645', '\u062d']), ('\ufd59', &['\u062c', '\u0645', '\u062d']), ('\ufd5a',
+        &['\u062d', '\u0645', '\u064a']), ('\ufd5b', &['\u062d', '\u0645', '\u0649']), ('\ufd5c',
+        &['\u0633', '\u062d', '\u062c']), ('\ufd5d', &['\u0633', '\u062c', '\u062d']), ('\ufd5e',
+        &['\u0633', '\u062c', '\u0649']), ('\ufd5f', &['\u0633', '\u0645', '\u062d']), ('\ufd60',
+        &['\u0633', '\u0645', '\u062d']), ('\ufd61', &['\u0633', '\u0645', '\u062c']), ('\ufd62',
+        &['\u0633', '\u0645', '\u0645']), ('\ufd63', &['\u0633', '\u0645', '\u0645']), ('\ufd64',
+        &['\u0635', '\u062d', '\u062d']), ('\ufd65', &['\u0635', '\u062d', '\u062d']), ('\ufd66',
+        &['\u0635', '\u0645', '\u0645']), ('\ufd67', &['\u0634', '\u062d', '\u0645']), ('\ufd68',
+        &['\u0634', '\u062d', '\u0645']), ('\ufd69', &['\u0634', '\u062c', '\u064a']), ('\ufd6a',
+        &['\u0634', '\u0645', '\u062e']), ('\ufd6b', &['\u0634', '\u0645', '\u062e']), ('\ufd6c',
+        &['\u0634', '\u0645', '\u0645']), ('\ufd6d', &['\u0634', '\u0645', '\u0645']), ('\ufd6e',
+        &['\u0636', '\u062d', '\u0649']), ('\ufd6f', &['\u0636', '\u062e', '\u0645']), ('\ufd70',
+        &['\u0636', '\u062e', '\u0645']), ('\ufd71', &['\u0637', '\u0645', '\u062d']), ('\ufd72',
+        &['\u0637', '\u0645', '\u062d']), ('\ufd73', &['\u0637', '\u0645', '\u0645']), ('\ufd74',
+        &['\u0637', '\u0645', '\u064a']), ('\ufd75', &['\u0639', '\u062c', '\u0645']), ('\ufd76',
+        &['\u0639', '\u0645', '\u0645']), ('\ufd77', &['\u0639', '\u0645', '\u0645']), ('\ufd78',
+        &['\u0639', '\u0645', '\u0649']), ('\ufd79', &['\u063a', '\u0645', '\u0645']), ('\ufd7a',
+        &['\u063a', '\u0645', '\u064a']), ('\ufd7b', &['\u063a', '\u0645', '\u0649']), ('\ufd7c',
+        &['\u0641', '\u062e', '\u0645']), ('\ufd7d', &['\u0641', '\u062e', '\u0645']), ('\ufd7e',
+        &['\u0642', '\u0645', '\u062d']), ('\ufd7f', &['\u0642', '\u0645', '\u0645']), ('\ufd80',
+        &['\u0644', '\u062d', '\u0645']), ('\ufd81', &['\u0644', '\u062d', '\u064a']), ('\ufd82',
+        &['\u0644', '\u062d', '\u0649']), ('\ufd83', &['\u0644', '\u062c', '\u062c']), ('\ufd84',
+        &['\u0644', '\u062c', '\u062c']), ('\ufd85', &['\u0644', '\u062e', '\u0645']), ('\ufd86',
+        &['\u0644', '\u062e', '\u0645']), ('\ufd87', &['\u0644', '\u0645', '\u062d']), ('\ufd88',
+        &['\u0644', '\u0645', '\u062d']), ('\ufd89', &['\u0645', '\u062d', '\u062c']), ('\ufd8a',
+        &['\u0645', '\u062d', '\u0645']), ('\ufd8b', &['\u0645', '\u062d', '\u064a']), ('\ufd8c',
+        &['\u0645', '\u062c', '\u062d']), ('\ufd8d', &['\u0645', '\u062c', '\u0645']), ('\ufd8e',
+        &['\u0645', '\u062e', '\u062c']), ('\ufd8f', &['\u0645', '\u062e', '\u0645']), ('\ufd92',
+        &['\u0645', '\u062c', '\u062e']), ('\ufd93', &['\u0647', '\u0645', '\u062c']), ('\ufd94',
+        &['\u0647', '\u0645', '\u0645']), ('\ufd95', &['\u0646', '\u062d', '\u0645']), ('\ufd96',
+        &['\u0646', '\u062d', '\u0649']), ('\ufd97', &['\u0646', '\u062c', '\u0645']), ('\ufd98',
+        &['\u0646', '\u062c', '\u0645']), ('\ufd99', &['\u0646', '\u062c', '\u0649']), ('\ufd9a',
+        &['\u0646', '\u0645', '\u064a']), ('\ufd9b', &['\u0646', '\u0645', '\u0649']), ('\ufd9c',
+        &['\u064a', '\u0645', '\u0645']), ('\ufd9d', &['\u064a', '\u0645', '\u0645']), ('\ufd9e',
+        &['\u0628', '\u062e', '\u064a']), ('\ufd9f', &['\u062a', '\u062c', '\u064a']), ('\ufda0',
+        &['\u062a', '\u062c', '\u0649']), ('\ufda1', &['\u062a', '\u062e', '\u064a']), ('\ufda2',
+        &['\u062a', '\u062e', '\u0649']), ('\ufda3', &['\u062a', '\u0645', '\u064a']), ('\ufda4',
+        &['\u062a', '\u0645', '\u0649']), ('\ufda5', &['\u062c', '\u0645', '\u064a']), ('\ufda6',
+        &['\u062c', '\u062d', '\u0649']), ('\ufda7', &['\u062c', '\u0645', '\u0649']), ('\ufda8',
+        &['\u0633', '\u062e', '\u0649']), ('\ufda9', &['\u0635', '\u062d', '\u064a']), ('\ufdaa',
+        &['\u0634', '\u062d', '\u064a']), ('\ufdab', &['\u0636', '\u062d', '\u064a']), ('\ufdac',
+        &['\u0644', '\u062c', '\u064a']), ('\ufdad', &['\u0644', '\u0645', '\u064a']), ('\ufdae',
+        &['\u064a', '\u062d', '\u064a']), ('\ufdaf', &['\u064a', '\u062c', '\u064a']), ('\ufdb0',
+        &['\u064a', '\u0645', '\u064a']), ('\ufdb1', &['\u0645', '\u0645', '\u064a']), ('\ufdb2',
+        &['\u0642', '\u0645', '\u064a']), ('\ufdb3', &['\u0646', '\u062d', '\u064a']), ('\ufdb4',
+        &['\u0642', '\u0645', '\u062d']), ('\ufdb5', &['\u0644', '\u062d', '\u0645']), ('\ufdb6',
+        &['\u0639', '\u0645', '\u064a']), ('\ufdb7', &['\u0643', '\u0645', '\u064a']), ('\ufdb8',
+        &['\u0646', '\u062c', '\u062d']), ('\ufdb9', &['\u0645', '\u062e', '\u064a']), ('\ufdba',
+        &['\u0644', '\u062c', '\u0645']), ('\ufdbb', &['\u0643', '\u0645', '\u0645']), ('\ufdbc',
+        &['\u0644', '\u062c', '\u0645']), ('\ufdbd', &['\u0646', '\u062c', '\u062d']), ('\ufdbe',
+        &['\u062c', '\u062d', '\u064a']), ('\ufdbf', &['\u062d', '\u062c', '\u064a']), ('\ufdc0',
+        &['\u0645', '\u062c', '\u064a']), ('\ufdc1', &['\u0641', '\u0645', '\u064a']), ('\ufdc2',
+        &['\u0628', '\u062d', '\u064a']), ('\ufdc3', &['\u0643', '\u0645', '\u0645']), ('\ufdc4',
+        &['\u0639', '\u062c', '\u0645']), ('\ufdc5', &['\u0635', '\u0645', '\u0645']), ('\ufdc6',
+        &['\u0633', '\u062e', '\u064a']), ('\ufdc7', &['\u0646', '\u062c', '\u064a']), ('\ufdf0',
+        &['\u0635', '\u0644', '\u06d2']), ('\ufdf1', &['\u0642', '\u0644', '\u06d2']), ('\ufdf2',
+        &['\u0627', '\u0644', '\u0644', '\u0647']), ('\ufdf3', &['\u0627', '\u0643', '\u0628',
+        '\u0631']), ('\ufdf4', &['\u0645', '\u062d', '\u0645', '\u062f']), ('\ufdf5', &['\u0635',
+        '\u0644', '\u0639', '\u0645']), ('\ufdf6', &['\u0631', '\u0633', '\u0648', '\u0644']),
+        ('\ufdf7', &['\u0639', '\u0644', '\u064a', '\u0647']), ('\ufdf8', &['\u0648', '\u0633',
+        '\u0644', '\u0645']), ('\ufdf9', &['\u0635', '\u0644', '\u0649']), ('\ufdfa', &['\u0635',
+        '\u0644', '\u0649', '\x20', '\u0627', '\u0644', '\u0644', '\u0647', '\x20', '\u0639',
+        '\u0644', '\u064a', '\u0647', '\x20', '\u0648', '\u0633', '\u0644', '\u0645']), ('\ufdfb',
+        &['\u062c', '\u0644', '\x20', '\u062c', '\u0644', '\u0627', '\u0644', '\u0647']), ('\ufdfc',
+        &['\u0631', '\u06cc', '\u0627', '\u0644']), ('\ufe10', &['\x2c']), ('\ufe11', &['\u3001']),
+        ('\ufe12', &['\u3002']), ('\ufe13', &['\x3a']), ('\ufe14', &['\x3b']), ('\ufe15',
+        &['\x21']), ('\ufe16', &['\x3f']), ('\ufe17', &['\u3016']), ('\ufe18', &['\u3017']),
+        ('\ufe19', &['\u2026']), ('\ufe30', &['\u2025']), ('\ufe31', &['\u2014']), ('\ufe32',
+        &['\u2013']), ('\ufe33', &['\x5f']), ('\ufe34', &['\x5f']), ('\ufe35', &['\x28']),
+        ('\ufe36', &['\x29']), ('\ufe37', &['\x7b']), ('\ufe38', &['\x7d']), ('\ufe39',
+        &['\u3014']), ('\ufe3a', &['\u3015']), ('\ufe3b', &['\u3010']), ('\ufe3c', &['\u3011']),
+        ('\ufe3d', &['\u300a']), ('\ufe3e', &['\u300b']), ('\ufe3f', &['\u3008']), ('\ufe40',
+        &['\u3009']), ('\ufe41', &['\u300c']), ('\ufe42', &['\u300d']), ('\ufe43', &['\u300e']),
+        ('\ufe44', &['\u300f']), ('\ufe47', &['\x5b']), ('\ufe48', &['\x5d']), ('\ufe49',
+        &['\u203e']), ('\ufe4a', &['\u203e']), ('\ufe4b', &['\u203e']), ('\ufe4c', &['\u203e']),
+        ('\ufe4d', &['\x5f']), ('\ufe4e', &['\x5f']), ('\ufe4f', &['\x5f']), ('\ufe50', &['\x2c']),
+        ('\ufe51', &['\u3001']), ('\ufe52', &['\x2e']), ('\ufe54', &['\x3b']), ('\ufe55',
+        &['\x3a']), ('\ufe56', &['\x3f']), ('\ufe57', &['\x21']), ('\ufe58', &['\u2014']),
+        ('\ufe59', &['\x28']), ('\ufe5a', &['\x29']), ('\ufe5b', &['\x7b']), ('\ufe5c', &['\x7d']),
+        ('\ufe5d', &['\u3014']), ('\ufe5e', &['\u3015']), ('\ufe5f', &['\x23']), ('\ufe60',
+        &['\x26']), ('\ufe61', &['\x2a']), ('\ufe62', &['\x2b']), ('\ufe63', &['\x2d']), ('\ufe64',
+        &['\x3c']), ('\ufe65', &['\x3e']), ('\ufe66', &['\x3d']), ('\ufe68', &['\x5c']), ('\ufe69',
+        &['\x24']), ('\ufe6a', &['\x25']), ('\ufe6b', &['\x40']), ('\ufe70', &['\x20', '\u064b']),
+        ('\ufe71', &['\u0640', '\u064b']), ('\ufe72', &['\x20', '\u064c']), ('\ufe74', &['\x20',
+        '\u064d']), ('\ufe76', &['\x20', '\u064e']), ('\ufe77', &['\u0640', '\u064e']), ('\ufe78',
+        &['\x20', '\u064f']), ('\ufe79', &['\u0640', '\u064f']), ('\ufe7a', &['\x20', '\u0650']),
+        ('\ufe7b', &['\u0640', '\u0650']), ('\ufe7c', &['\x20', '\u0651']), ('\ufe7d', &['\u0640',
+        '\u0651']), ('\ufe7e', &['\x20', '\u0652']), ('\ufe7f', &['\u0640', '\u0652']), ('\ufe80',
+        &['\u0621']), ('\ufe81', &['\u0622']), ('\ufe82', &['\u0622']), ('\ufe83', &['\u0623']),
+        ('\ufe84', &['\u0623']), ('\ufe85', &['\u0624']), ('\ufe86', &['\u0624']), ('\ufe87',
+        &['\u0625']), ('\ufe88', &['\u0625']), ('\ufe89', &['\u0626']), ('\ufe8a', &['\u0626']),
+        ('\ufe8b', &['\u0626']), ('\ufe8c', &['\u0626']), ('\ufe8d', &['\u0627']), ('\ufe8e',
+        &['\u0627']), ('\ufe8f', &['\u0628']), ('\ufe90', &['\u0628']), ('\ufe91', &['\u0628']),
+        ('\ufe92', &['\u0628']), ('\ufe93', &['\u0629']), ('\ufe94', &['\u0629']), ('\ufe95',
+        &['\u062a']), ('\ufe96', &['\u062a']), ('\ufe97', &['\u062a']), ('\ufe98', &['\u062a']),
+        ('\ufe99', &['\u062b']), ('\ufe9a', &['\u062b']), ('\ufe9b', &['\u062b']), ('\ufe9c',
+        &['\u062b']), ('\ufe9d', &['\u062c']), ('\ufe9e', &['\u062c']), ('\ufe9f', &['\u062c']),
+        ('\ufea0', &['\u062c']), ('\ufea1', &['\u062d']), ('\ufea2', &['\u062d']), ('\ufea3',
+        &['\u062d']), ('\ufea4', &['\u062d']), ('\ufea5', &['\u062e']), ('\ufea6', &['\u062e']),
+        ('\ufea7', &['\u062e']), ('\ufea8', &['\u062e']), ('\ufea9', &['\u062f']), ('\ufeaa',
+        &['\u062f']), ('\ufeab', &['\u0630']), ('\ufeac', &['\u0630']), ('\ufead', &['\u0631']),
+        ('\ufeae', &['\u0631']), ('\ufeaf', &['\u0632']), ('\ufeb0', &['\u0632']), ('\ufeb1',
+        &['\u0633']), ('\ufeb2', &['\u0633']), ('\ufeb3', &['\u0633']), ('\ufeb4', &['\u0633']),
+        ('\ufeb5', &['\u0634']), ('\ufeb6', &['\u0634']), ('\ufeb7', &['\u0634']), ('\ufeb8',
+        &['\u0634']), ('\ufeb9', &['\u0635']), ('\ufeba', &['\u0635']), ('\ufebb', &['\u0635']),
+        ('\ufebc', &['\u0635']), ('\ufebd', &['\u0636']), ('\ufebe', &['\u0636']), ('\ufebf',
+        &['\u0636']), ('\ufec0', &['\u0636']), ('\ufec1', &['\u0637']), ('\ufec2', &['\u0637']),
+        ('\ufec3', &['\u0637']), ('\ufec4', &['\u0637']), ('\ufec5', &['\u0638']), ('\ufec6',
+        &['\u0638']), ('\ufec7', &['\u0638']), ('\ufec8', &['\u0638']), ('\ufec9', &['\u0639']),
+        ('\ufeca', &['\u0639']), ('\ufecb', &['\u0639']), ('\ufecc', &['\u0639']), ('\ufecd',
+        &['\u063a']), ('\ufece', &['\u063a']), ('\ufecf', &['\u063a']), ('\ufed0', &['\u063a']),
+        ('\ufed1', &['\u0641']), ('\ufed2', &['\u0641']), ('\ufed3', &['\u0641']), ('\ufed4',
+        &['\u0641']), ('\ufed5', &['\u0642']), ('\ufed6', &['\u0642']), ('\ufed7', &['\u0642']),
+        ('\ufed8', &['\u0642']), ('\ufed9', &['\u0643']), ('\ufeda', &['\u0643']), ('\ufedb',
+        &['\u0643']), ('\ufedc', &['\u0643']), ('\ufedd', &['\u0644']), ('\ufede', &['\u0644']),
+        ('\ufedf', &['\u0644']), ('\ufee0', &['\u0644']), ('\ufee1', &['\u0645']), ('\ufee2',
+        &['\u0645']), ('\ufee3', &['\u0645']), ('\ufee4', &['\u0645']), ('\ufee5', &['\u0646']),
+        ('\ufee6', &['\u0646']), ('\ufee7', &['\u0646']), ('\ufee8', &['\u0646']), ('\ufee9',
+        &['\u0647']), ('\ufeea', &['\u0647']), ('\ufeeb', &['\u0647']), ('\ufeec', &['\u0647']),
+        ('\ufeed', &['\u0648']), ('\ufeee', &['\u0648']), ('\ufeef', &['\u0649']), ('\ufef0',
+        &['\u0649']), ('\ufef1', &['\u064a']), ('\ufef2', &['\u064a']), ('\ufef3', &['\u064a']),
+        ('\ufef4', &['\u064a']), ('\ufef5', &['\u0644', '\u0622']), ('\ufef6', &['\u0644',
+        '\u0622']), ('\ufef7', &['\u0644', '\u0623']), ('\ufef8', &['\u0644', '\u0623']), ('\ufef9',
+        &['\u0644', '\u0625']), ('\ufefa', &['\u0644', '\u0625']), ('\ufefb', &['\u0644',
+        '\u0627']), ('\ufefc', &['\u0644', '\u0627']), ('\uff01', &['\x21']), ('\uff02', &['\x22']),
+        ('\uff03', &['\x23']), ('\uff04', &['\x24']), ('\uff05', &['\x25']), ('\uff06', &['\x26']),
+        ('\uff07', &['\x27']), ('\uff08', &['\x28']), ('\uff09', &['\x29']), ('\uff0a', &['\x2a']),
+        ('\uff0b', &['\x2b']), ('\uff0c', &['\x2c']), ('\uff0d', &['\x2d']), ('\uff0e', &['\x2e']),
+        ('\uff0f', &['\x2f']), ('\uff10', &['\x30']), ('\uff11', &['\x31']), ('\uff12', &['\x32']),
+        ('\uff13', &['\x33']), ('\uff14', &['\x34']), ('\uff15', &['\x35']), ('\uff16', &['\x36']),
+        ('\uff17', &['\x37']), ('\uff18', &['\x38']), ('\uff19', &['\x39']), ('\uff1a', &['\x3a']),
+        ('\uff1b', &['\x3b']), ('\uff1c', &['\x3c']), ('\uff1d', &['\x3d']), ('\uff1e', &['\x3e']),
+        ('\uff1f', &['\x3f']), ('\uff20', &['\x40']), ('\uff21', &['\x41']), ('\uff22', &['\x42']),
+        ('\uff23', &['\x43']), ('\uff24', &['\x44']), ('\uff25', &['\x45']), ('\uff26', &['\x46']),
+        ('\uff27', &['\x47']), ('\uff28', &['\x48']), ('\uff29', &['\x49']), ('\uff2a', &['\x4a']),
+        ('\uff2b', &['\x4b']), ('\uff2c', &['\x4c']), ('\uff2d', &['\x4d']), ('\uff2e', &['\x4e']),
+        ('\uff2f', &['\x4f']), ('\uff30', &['\x50']), ('\uff31', &['\x51']), ('\uff32', &['\x52']),
+        ('\uff33', &['\x53']), ('\uff34', &['\x54']), ('\uff35', &['\x55']), ('\uff36', &['\x56']),
+        ('\uff37', &['\x57']), ('\uff38', &['\x58']), ('\uff39', &['\x59']), ('\uff3a', &['\x5a']),
+        ('\uff3b', &['\x5b']), ('\uff3c', &['\x5c']), ('\uff3d', &['\x5d']), ('\uff3e', &['\x5e']),
+        ('\uff3f', &['\x5f']), ('\uff40', &['\x60']), ('\uff41', &['\x61']), ('\uff42', &['\x62']),
+        ('\uff43', &['\x63']), ('\uff44', &['\x64']), ('\uff45', &['\x65']), ('\uff46', &['\x66']),
+        ('\uff47', &['\x67']), ('\uff48', &['\x68']), ('\uff49', &['\x69']), ('\uff4a', &['\x6a']),
+        ('\uff4b', &['\x6b']), ('\uff4c', &['\x6c']), ('\uff4d', &['\x6d']), ('\uff4e', &['\x6e']),
+        ('\uff4f', &['\x6f']), ('\uff50', &['\x70']), ('\uff51', &['\x71']), ('\uff52', &['\x72']),
+        ('\uff53', &['\x73']), ('\uff54', &['\x74']), ('\uff55', &['\x75']), ('\uff56', &['\x76']),
+        ('\uff57', &['\x77']), ('\uff58', &['\x78']), ('\uff59', &['\x79']), ('\uff5a', &['\x7a']),
+        ('\uff5b', &['\x7b']), ('\uff5c', &['\x7c']), ('\uff5d', &['\x7d']), ('\uff5e', &['\x7e']),
+        ('\uff5f', &['\u2985']), ('\uff60', &['\u2986']), ('\uff61', &['\u3002']), ('\uff62',
+        &['\u300c']), ('\uff63', &['\u300d']), ('\uff64', &['\u3001']), ('\uff65', &['\u30fb']),
+        ('\uff66', &['\u30f2']), ('\uff67', &['\u30a1']), ('\uff68', &['\u30a3']), ('\uff69',
+        &['\u30a5']), ('\uff6a', &['\u30a7']), ('\uff6b', &['\u30a9']), ('\uff6c', &['\u30e3']),
+        ('\uff6d', &['\u30e5']), ('\uff6e', &['\u30e7']), ('\uff6f', &['\u30c3']), ('\uff70',
+        &['\u30fc']), ('\uff71', &['\u30a2']), ('\uff72', &['\u30a4']), ('\uff73', &['\u30a6']),
+        ('\uff74', &['\u30a8']), ('\uff75', &['\u30aa']), ('\uff76', &['\u30ab']), ('\uff77',
+        &['\u30ad']), ('\uff78', &['\u30af']), ('\uff79', &['\u30b1']), ('\uff7a', &['\u30b3']),
+        ('\uff7b', &['\u30b5']), ('\uff7c', &['\u30b7']), ('\uff7d', &['\u30b9']), ('\uff7e',
+        &['\u30bb']), ('\uff7f', &['\u30bd']), ('\uff80', &['\u30bf']), ('\uff81', &['\u30c1']),
+        ('\uff82', &['\u30c4']), ('\uff83', &['\u30c6']), ('\uff84', &['\u30c8']), ('\uff85',
+        &['\u30ca']), ('\uff86', &['\u30cb']), ('\uff87', &['\u30cc']), ('\uff88', &['\u30cd']),
+        ('\uff89', &['\u30ce']), ('\uff8a', &['\u30cf']), ('\uff8b', &['\u30d2']), ('\uff8c',
+        &['\u30d5']), ('\uff8d', &['\u30d8']), ('\uff8e', &['\u30db']), ('\uff8f', &['\u30de']),
+        ('\uff90', &['\u30df']), ('\uff91', &['\u30e0']), ('\uff92', &['\u30e1']), ('\uff93',
+        &['\u30e2']), ('\uff94', &['\u30e4']), ('\uff95', &['\u30e6']), ('\uff96', &['\u30e8']),
+        ('\uff97', &['\u30e9']), ('\uff98', &['\u30ea']), ('\uff99', &['\u30eb']), ('\uff9a',
+        &['\u30ec']), ('\uff9b', &['\u30ed']), ('\uff9c', &['\u30ef']), ('\uff9d', &['\u30f3']),
+        ('\uff9e', &['\u3099']), ('\uff9f', &['\u309a']), ('\uffa0', &['\u3164']), ('\uffa1',
+        &['\u3131']), ('\uffa2', &['\u3132']), ('\uffa3', &['\u3133']), ('\uffa4', &['\u3134']),
+        ('\uffa5', &['\u3135']), ('\uffa6', &['\u3136']), ('\uffa7', &['\u3137']), ('\uffa8',
+        &['\u3138']), ('\uffa9', &['\u3139']), ('\uffaa', &['\u313a']), ('\uffab', &['\u313b']),
+        ('\uffac', &['\u313c']), ('\uffad', &['\u313d']), ('\uffae', &['\u313e']), ('\uffaf',
+        &['\u313f']), ('\uffb0', &['\u3140']), ('\uffb1', &['\u3141']), ('\uffb2', &['\u3142']),
+        ('\uffb3', &['\u3143']), ('\uffb4', &['\u3144']), ('\uffb5', &['\u3145']), ('\uffb6',
+        &['\u3146']), ('\uffb7', &['\u3147']), ('\uffb8', &['\u3148']), ('\uffb9', &['\u3149']),
+        ('\uffba', &['\u314a']), ('\uffbb', &['\u314b']), ('\uffbc', &['\u314c']), ('\uffbd',
+        &['\u314d']), ('\uffbe', &['\u314e']), ('\uffc2', &['\u314f']), ('\uffc3', &['\u3150']),
+        ('\uffc4', &['\u3151']), ('\uffc5', &['\u3152']), ('\uffc6', &['\u3153']), ('\uffc7',
+        &['\u3154']), ('\uffca', &['\u3155']), ('\uffcb', &['\u3156']), ('\uffcc', &['\u3157']),
+        ('\uffcd', &['\u3158']), ('\uffce', &['\u3159']), ('\uffcf', &['\u315a']), ('\uffd2',
+        &['\u315b']), ('\uffd3', &['\u315c']), ('\uffd4', &['\u315d']), ('\uffd5', &['\u315e']),
+        ('\uffd6', &['\u315f']), ('\uffd7', &['\u3160']), ('\uffda', &['\u3161']), ('\uffdb',
+        &['\u3162']), ('\uffdc', &['\u3163']), ('\uffe0', &['\xa2']), ('\uffe1', &['\xa3']),
+        ('\uffe2', &['\xac']), ('\uffe3', &['\xaf']), ('\uffe4', &['\xa6']), ('\uffe5', &['\xa5']),
+        ('\uffe6', &['\u20a9']), ('\uffe8', &['\u2502']), ('\uffe9', &['\u2190']), ('\uffea',
+        &['\u2191']), ('\uffeb', &['\u2192']), ('\uffec', &['\u2193']), ('\uffed', &['\u25a0']),
+        ('\uffee', &['\u25cb']), ('\U0001d400', &['\x41']), ('\U0001d401', &['\x42']),
+        ('\U0001d402', &['\x43']), ('\U0001d403', &['\x44']), ('\U0001d404', &['\x45']),
+        ('\U0001d405', &['\x46']), ('\U0001d406', &['\x47']), ('\U0001d407', &['\x48']),
+        ('\U0001d408', &['\x49']), ('\U0001d409', &['\x4a']), ('\U0001d40a', &['\x4b']),
+        ('\U0001d40b', &['\x4c']), ('\U0001d40c', &['\x4d']), ('\U0001d40d', &['\x4e']),
+        ('\U0001d40e', &['\x4f']), ('\U0001d40f', &['\x50']), ('\U0001d410', &['\x51']),
+        ('\U0001d411', &['\x52']), ('\U0001d412', &['\x53']), ('\U0001d413', &['\x54']),
+        ('\U0001d414', &['\x55']), ('\U0001d415', &['\x56']), ('\U0001d416', &['\x57']),
+        ('\U0001d417', &['\x58']), ('\U0001d418', &['\x59']), ('\U0001d419', &['\x5a']),
+        ('\U0001d41a', &['\x61']), ('\U0001d41b', &['\x62']), ('\U0001d41c', &['\x63']),
+        ('\U0001d41d', &['\x64']), ('\U0001d41e', &['\x65']), ('\U0001d41f', &['\x66']),
+        ('\U0001d420', &['\x67']), ('\U0001d421', &['\x68']), ('\U0001d422', &['\x69']),
+        ('\U0001d423', &['\x6a']), ('\U0001d424', &['\x6b']), ('\U0001d425', &['\x6c']),
+        ('\U0001d426', &['\x6d']), ('\U0001d427', &['\x6e']), ('\U0001d428', &['\x6f']),
+        ('\U0001d429', &['\x70']), ('\U0001d42a', &['\x71']), ('\U0001d42b', &['\x72']),
+        ('\U0001d42c', &['\x73']), ('\U0001d42d', &['\x74']), ('\U0001d42e', &['\x75']),
+        ('\U0001d42f', &['\x76']), ('\U0001d430', &['\x77']), ('\U0001d431', &['\x78']),
+        ('\U0001d432', &['\x79']), ('\U0001d433', &['\x7a']), ('\U0001d434', &['\x41']),
+        ('\U0001d435', &['\x42']), ('\U0001d436', &['\x43']), ('\U0001d437', &['\x44']),
+        ('\U0001d438', &['\x45']), ('\U0001d439', &['\x46']), ('\U0001d43a', &['\x47']),
+        ('\U0001d43b', &['\x48']), ('\U0001d43c', &['\x49']), ('\U0001d43d', &['\x4a']),
+        ('\U0001d43e', &['\x4b']), ('\U0001d43f', &['\x4c']), ('\U0001d440', &['\x4d']),
+        ('\U0001d441', &['\x4e']), ('\U0001d442', &['\x4f']), ('\U0001d443', &['\x50']),
+        ('\U0001d444', &['\x51']), ('\U0001d445', &['\x52']), ('\U0001d446', &['\x53']),
+        ('\U0001d447', &['\x54']), ('\U0001d448', &['\x55']), ('\U0001d449', &['\x56']),
+        ('\U0001d44a', &['\x57']), ('\U0001d44b', &['\x58']), ('\U0001d44c', &['\x59']),
+        ('\U0001d44d', &['\x5a']), ('\U0001d44e', &['\x61']), ('\U0001d44f', &['\x62']),
+        ('\U0001d450', &['\x63']), ('\U0001d451', &['\x64']), ('\U0001d452', &['\x65']),
+        ('\U0001d453', &['\x66']), ('\U0001d454', &['\x67']), ('\U0001d456', &['\x69']),
+        ('\U0001d457', &['\x6a']), ('\U0001d458', &['\x6b']), ('\U0001d459', &['\x6c']),
+        ('\U0001d45a', &['\x6d']), ('\U0001d45b', &['\x6e']), ('\U0001d45c', &['\x6f']),
+        ('\U0001d45d', &['\x70']), ('\U0001d45e', &['\x71']), ('\U0001d45f', &['\x72']),
+        ('\U0001d460', &['\x73']), ('\U0001d461', &['\x74']), ('\U0001d462', &['\x75']),
+        ('\U0001d463', &['\x76']), ('\U0001d464', &['\x77']), ('\U0001d465', &['\x78']),
+        ('\U0001d466', &['\x79']), ('\U0001d467', &['\x7a']), ('\U0001d468', &['\x41']),
+        ('\U0001d469', &['\x42']), ('\U0001d46a', &['\x43']), ('\U0001d46b', &['\x44']),
+        ('\U0001d46c', &['\x45']), ('\U0001d46d', &['\x46']), ('\U0001d46e', &['\x47']),
+        ('\U0001d46f', &['\x48']), ('\U0001d470', &['\x49']), ('\U0001d471', &['\x4a']),
+        ('\U0001d472', &['\x4b']), ('\U0001d473', &['\x4c']), ('\U0001d474', &['\x4d']),
+        ('\U0001d475', &['\x4e']), ('\U0001d476', &['\x4f']), ('\U0001d477', &['\x50']),
+        ('\U0001d478', &['\x51']), ('\U0001d479', &['\x52']), ('\U0001d47a', &['\x53']),
+        ('\U0001d47b', &['\x54']), ('\U0001d47c', &['\x55']), ('\U0001d47d', &['\x56']),
+        ('\U0001d47e', &['\x57']), ('\U0001d47f', &['\x58']), ('\U0001d480', &['\x59']),
+        ('\U0001d481', &['\x5a']), ('\U0001d482', &['\x61']), ('\U0001d483', &['\x62']),
+        ('\U0001d484', &['\x63']), ('\U0001d485', &['\x64']), ('\U0001d486', &['\x65']),
+        ('\U0001d487', &['\x66']), ('\U0001d488', &['\x67']), ('\U0001d489', &['\x68']),
+        ('\U0001d48a', &['\x69']), ('\U0001d48b', &['\x6a']), ('\U0001d48c', &['\x6b']),
+        ('\U0001d48d', &['\x6c']), ('\U0001d48e', &['\x6d']), ('\U0001d48f', &['\x6e']),
+        ('\U0001d490', &['\x6f']), ('\U0001d491', &['\x70']), ('\U0001d492', &['\x71']),
+        ('\U0001d493', &['\x72']), ('\U0001d494', &['\x73']), ('\U0001d495', &['\x74']),
+        ('\U0001d496', &['\x75']), ('\U0001d497', &['\x76']), ('\U0001d498', &['\x77']),
+        ('\U0001d499', &['\x78']), ('\U0001d49a', &['\x79']), ('\U0001d49b', &['\x7a']),
+        ('\U0001d49c', &['\x41']), ('\U0001d49e', &['\x43']), ('\U0001d49f', &['\x44']),
+        ('\U0001d4a2', &['\x47']), ('\U0001d4a5', &['\x4a']), ('\U0001d4a6', &['\x4b']),
+        ('\U0001d4a9', &['\x4e']), ('\U0001d4aa', &['\x4f']), ('\U0001d4ab', &['\x50']),
+        ('\U0001d4ac', &['\x51']), ('\U0001d4ae', &['\x53']), ('\U0001d4af', &['\x54']),
+        ('\U0001d4b0', &['\x55']), ('\U0001d4b1', &['\x56']), ('\U0001d4b2', &['\x57']),
+        ('\U0001d4b3', &['\x58']), ('\U0001d4b4', &['\x59']), ('\U0001d4b5', &['\x5a']),
+        ('\U0001d4b6', &['\x61']), ('\U0001d4b7', &['\x62']), ('\U0001d4b8', &['\x63']),
+        ('\U0001d4b9', &['\x64']), ('\U0001d4bb', &['\x66']), ('\U0001d4bd', &['\x68']),
+        ('\U0001d4be', &['\x69']), ('\U0001d4bf', &['\x6a']), ('\U0001d4c0', &['\x6b']),
+        ('\U0001d4c1', &['\x6c']), ('\U0001d4c2', &['\x6d']), ('\U0001d4c3', &['\x6e']),
+        ('\U0001d4c5', &['\x70']), ('\U0001d4c6', &['\x71']), ('\U0001d4c7', &['\x72']),
+        ('\U0001d4c8', &['\x73']), ('\U0001d4c9', &['\x74']), ('\U0001d4ca', &['\x75']),
+        ('\U0001d4cb', &['\x76']), ('\U0001d4cc', &['\x77']), ('\U0001d4cd', &['\x78']),
+        ('\U0001d4ce', &['\x79']), ('\U0001d4cf', &['\x7a']), ('\U0001d4d0', &['\x41']),
+        ('\U0001d4d1', &['\x42']), ('\U0001d4d2', &['\x43']), ('\U0001d4d3', &['\x44']),
+        ('\U0001d4d4', &['\x45']), ('\U0001d4d5', &['\x46']), ('\U0001d4d6', &['\x47']),
+        ('\U0001d4d7', &['\x48']), ('\U0001d4d8', &['\x49']), ('\U0001d4d9', &['\x4a']),
+        ('\U0001d4da', &['\x4b']), ('\U0001d4db', &['\x4c']), ('\U0001d4dc', &['\x4d']),
+        ('\U0001d4dd', &['\x4e']), ('\U0001d4de', &['\x4f']), ('\U0001d4df', &['\x50']),
+        ('\U0001d4e0', &['\x51']), ('\U0001d4e1', &['\x52']), ('\U0001d4e2', &['\x53']),
+        ('\U0001d4e3', &['\x54']), ('\U0001d4e4', &['\x55']), ('\U0001d4e5', &['\x56']),
+        ('\U0001d4e6', &['\x57']), ('\U0001d4e7', &['\x58']), ('\U0001d4e8', &['\x59']),
+        ('\U0001d4e9', &['\x5a']), ('\U0001d4ea', &['\x61']), ('\U0001d4eb', &['\x62']),
+        ('\U0001d4ec', &['\x63']), ('\U0001d4ed', &['\x64']), ('\U0001d4ee', &['\x65']),
+        ('\U0001d4ef', &['\x66']), ('\U0001d4f0', &['\x67']), ('\U0001d4f1', &['\x68']),
+        ('\U0001d4f2', &['\x69']), ('\U0001d4f3', &['\x6a']), ('\U0001d4f4', &['\x6b']),
+        ('\U0001d4f5', &['\x6c']), ('\U0001d4f6', &['\x6d']), ('\U0001d4f7', &['\x6e']),
+        ('\U0001d4f8', &['\x6f']), ('\U0001d4f9', &['\x70']), ('\U0001d4fa', &['\x71']),
+        ('\U0001d4fb', &['\x72']), ('\U0001d4fc', &['\x73']), ('\U0001d4fd', &['\x74']),
+        ('\U0001d4fe', &['\x75']), ('\U0001d4ff', &['\x76']), ('\U0001d500', &['\x77']),
+        ('\U0001d501', &['\x78']), ('\U0001d502', &['\x79']), ('\U0001d503', &['\x7a']),
+        ('\U0001d504', &['\x41']), ('\U0001d505', &['\x42']), ('\U0001d507', &['\x44']),
+        ('\U0001d508', &['\x45']), ('\U0001d509', &['\x46']), ('\U0001d50a', &['\x47']),
+        ('\U0001d50d', &['\x4a']), ('\U0001d50e', &['\x4b']), ('\U0001d50f', &['\x4c']),
+        ('\U0001d510', &['\x4d']), ('\U0001d511', &['\x4e']), ('\U0001d512', &['\x4f']),
+        ('\U0001d513', &['\x50']), ('\U0001d514', &['\x51']), ('\U0001d516', &['\x53']),
+        ('\U0001d517', &['\x54']), ('\U0001d518', &['\x55']), ('\U0001d519', &['\x56']),
+        ('\U0001d51a', &['\x57']), ('\U0001d51b', &['\x58']), ('\U0001d51c', &['\x59']),
+        ('\U0001d51e', &['\x61']), ('\U0001d51f', &['\x62']), ('\U0001d520', &['\x63']),
+        ('\U0001d521', &['\x64']), ('\U0001d522', &['\x65']), ('\U0001d523', &['\x66']),
+        ('\U0001d524', &['\x67']), ('\U0001d525', &['\x68']), ('\U0001d526', &['\x69']),
+        ('\U0001d527', &['\x6a']), ('\U0001d528', &['\x6b']), ('\U0001d529', &['\x6c']),
+        ('\U0001d52a', &['\x6d']), ('\U0001d52b', &['\x6e']), ('\U0001d52c', &['\x6f']),
+        ('\U0001d52d', &['\x70']), ('\U0001d52e', &['\x71']), ('\U0001d52f', &['\x72']),
+        ('\U0001d530', &['\x73']), ('\U0001d531', &['\x74']), ('\U0001d532', &['\x75']),
+        ('\U0001d533', &['\x76']), ('\U0001d534', &['\x77']), ('\U0001d535', &['\x78']),
+        ('\U0001d536', &['\x79']), ('\U0001d537', &['\x7a']), ('\U0001d538', &['\x41']),
+        ('\U0001d539', &['\x42']), ('\U0001d53b', &['\x44']), ('\U0001d53c', &['\x45']),
+        ('\U0001d53d', &['\x46']), ('\U0001d53e', &['\x47']), ('\U0001d540', &['\x49']),
+        ('\U0001d541', &['\x4a']), ('\U0001d542', &['\x4b']), ('\U0001d543', &['\x4c']),
+        ('\U0001d544', &['\x4d']), ('\U0001d546', &['\x4f']), ('\U0001d54a', &['\x53']),
+        ('\U0001d54b', &['\x54']), ('\U0001d54c', &['\x55']), ('\U0001d54d', &['\x56']),
+        ('\U0001d54e', &['\x57']), ('\U0001d54f', &['\x58']), ('\U0001d550', &['\x59']),
+        ('\U0001d552', &['\x61']), ('\U0001d553', &['\x62']), ('\U0001d554', &['\x63']),
+        ('\U0001d555', &['\x64']), ('\U0001d556', &['\x65']), ('\U0001d557', &['\x66']),
+        ('\U0001d558', &['\x67']), ('\U0001d559', &['\x68']), ('\U0001d55a', &['\x69']),
+        ('\U0001d55b', &['\x6a']), ('\U0001d55c', &['\x6b']), ('\U0001d55d', &['\x6c']),
+        ('\U0001d55e', &['\x6d']), ('\U0001d55f', &['\x6e']), ('\U0001d560', &['\x6f']),
+        ('\U0001d561', &['\x70']), ('\U0001d562', &['\x71']), ('\U0001d563', &['\x72']),
+        ('\U0001d564', &['\x73']), ('\U0001d565', &['\x74']), ('\U0001d566', &['\x75']),
+        ('\U0001d567', &['\x76']), ('\U0001d568', &['\x77']), ('\U0001d569', &['\x78']),
+        ('\U0001d56a', &['\x79']), ('\U0001d56b', &['\x7a']), ('\U0001d56c', &['\x41']),
+        ('\U0001d56d', &['\x42']), ('\U0001d56e', &['\x43']), ('\U0001d56f', &['\x44']),
+        ('\U0001d570', &['\x45']), ('\U0001d571', &['\x46']), ('\U0001d572', &['\x47']),
+        ('\U0001d573', &['\x48']), ('\U0001d574', &['\x49']), ('\U0001d575', &['\x4a']),
+        ('\U0001d576', &['\x4b']), ('\U0001d577', &['\x4c']), ('\U0001d578', &['\x4d']),
+        ('\U0001d579', &['\x4e']), ('\U0001d57a', &['\x4f']), ('\U0001d57b', &['\x50']),
+        ('\U0001d57c', &['\x51']), ('\U0001d57d', &['\x52']), ('\U0001d57e', &['\x53']),
+        ('\U0001d57f', &['\x54']), ('\U0001d580', &['\x55']), ('\U0001d581', &['\x56']),
+        ('\U0001d582', &['\x57']), ('\U0001d583', &['\x58']), ('\U0001d584', &['\x59']),
+        ('\U0001d585', &['\x5a']), ('\U0001d586', &['\x61']), ('\U0001d587', &['\x62']),
+        ('\U0001d588', &['\x63']), ('\U0001d589', &['\x64']), ('\U0001d58a', &['\x65']),
+        ('\U0001d58b', &['\x66']), ('\U0001d58c', &['\x67']), ('\U0001d58d', &['\x68']),
+        ('\U0001d58e', &['\x69']), ('\U0001d58f', &['\x6a']), ('\U0001d590', &['\x6b']),
+        ('\U0001d591', &['\x6c']), ('\U0001d592', &['\x6d']), ('\U0001d593', &['\x6e']),
+        ('\U0001d594', &['\x6f']), ('\U0001d595', &['\x70']), ('\U0001d596', &['\x71']),
+        ('\U0001d597', &['\x72']), ('\U0001d598', &['\x73']), ('\U0001d599', &['\x74']),
+        ('\U0001d59a', &['\x75']), ('\U0001d59b', &['\x76']), ('\U0001d59c', &['\x77']),
+        ('\U0001d59d', &['\x78']), ('\U0001d59e', &['\x79']), ('\U0001d59f', &['\x7a']),
+        ('\U0001d5a0', &['\x41']), ('\U0001d5a1', &['\x42']), ('\U0001d5a2', &['\x43']),
+        ('\U0001d5a3', &['\x44']), ('\U0001d5a4', &['\x45']), ('\U0001d5a5', &['\x46']),
+        ('\U0001d5a6', &['\x47']), ('\U0001d5a7', &['\x48']), ('\U0001d5a8', &['\x49']),
+        ('\U0001d5a9', &['\x4a']), ('\U0001d5aa', &['\x4b']), ('\U0001d5ab', &['\x4c']),
+        ('\U0001d5ac', &['\x4d']), ('\U0001d5ad', &['\x4e']), ('\U0001d5ae', &['\x4f']),
+        ('\U0001d5af', &['\x50']), ('\U0001d5b0', &['\x51']), ('\U0001d5b1', &['\x52']),
+        ('\U0001d5b2', &['\x53']), ('\U0001d5b3', &['\x54']), ('\U0001d5b4', &['\x55']),
+        ('\U0001d5b5', &['\x56']), ('\U0001d5b6', &['\x57']), ('\U0001d5b7', &['\x58']),
+        ('\U0001d5b8', &['\x59']), ('\U0001d5b9', &['\x5a']), ('\U0001d5ba', &['\x61']),
+        ('\U0001d5bb', &['\x62']), ('\U0001d5bc', &['\x63']), ('\U0001d5bd', &['\x64']),
+        ('\U0001d5be', &['\x65']), ('\U0001d5bf', &['\x66']), ('\U0001d5c0', &['\x67']),
+        ('\U0001d5c1', &['\x68']), ('\U0001d5c2', &['\x69']), ('\U0001d5c3', &['\x6a']),
+        ('\U0001d5c4', &['\x6b']), ('\U0001d5c5', &['\x6c']), ('\U0001d5c6', &['\x6d']),
+        ('\U0001d5c7', &['\x6e']), ('\U0001d5c8', &['\x6f']), ('\U0001d5c9', &['\x70']),
+        ('\U0001d5ca', &['\x71']), ('\U0001d5cb', &['\x72']), ('\U0001d5cc', &['\x73']),
+        ('\U0001d5cd', &['\x74']), ('\U0001d5ce', &['\x75']), ('\U0001d5cf', &['\x76']),
+        ('\U0001d5d0', &['\x77']), ('\U0001d5d1', &['\x78']), ('\U0001d5d2', &['\x79']),
+        ('\U0001d5d3', &['\x7a']), ('\U0001d5d4', &['\x41']), ('\U0001d5d5', &['\x42']),
+        ('\U0001d5d6', &['\x43']), ('\U0001d5d7', &['\x44']), ('\U0001d5d8', &['\x45']),
+        ('\U0001d5d9', &['\x46']), ('\U0001d5da', &['\x47']), ('\U0001d5db', &['\x48']),
+        ('\U0001d5dc', &['\x49']), ('\U0001d5dd', &['\x4a']), ('\U0001d5de', &['\x4b']),
+        ('\U0001d5df', &['\x4c']), ('\U0001d5e0', &['\x4d']), ('\U0001d5e1', &['\x4e']),
+        ('\U0001d5e2', &['\x4f']), ('\U0001d5e3', &['\x50']), ('\U0001d5e4', &['\x51']),
+        ('\U0001d5e5', &['\x52']), ('\U0001d5e6', &['\x53']), ('\U0001d5e7', &['\x54']),
+        ('\U0001d5e8', &['\x55']), ('\U0001d5e9', &['\x56']), ('\U0001d5ea', &['\x57']),
+        ('\U0001d5eb', &['\x58']), ('\U0001d5ec', &['\x59']), ('\U0001d5ed', &['\x5a']),
+        ('\U0001d5ee', &['\x61']), ('\U0001d5ef', &['\x62']), ('\U0001d5f0', &['\x63']),
+        ('\U0001d5f1', &['\x64']), ('\U0001d5f2', &['\x65']), ('\U0001d5f3', &['\x66']),
+        ('\U0001d5f4', &['\x67']), ('\U0001d5f5', &['\x68']), ('\U0001d5f6', &['\x69']),
+        ('\U0001d5f7', &['\x6a']), ('\U0001d5f8', &['\x6b']), ('\U0001d5f9', &['\x6c']),
+        ('\U0001d5fa', &['\x6d']), ('\U0001d5fb', &['\x6e']), ('\U0001d5fc', &['\x6f']),
+        ('\U0001d5fd', &['\x70']), ('\U0001d5fe', &['\x71']), ('\U0001d5ff', &['\x72']),
+        ('\U0001d600', &['\x73']), ('\U0001d601', &['\x74']), ('\U0001d602', &['\x75']),
+        ('\U0001d603', &['\x76']), ('\U0001d604', &['\x77']), ('\U0001d605', &['\x78']),
+        ('\U0001d606', &['\x79']), ('\U0001d607', &['\x7a']), ('\U0001d608', &['\x41']),
+        ('\U0001d609', &['\x42']), ('\U0001d60a', &['\x43']), ('\U0001d60b', &['\x44']),
+        ('\U0001d60c', &['\x45']), ('\U0001d60d', &['\x46']), ('\U0001d60e', &['\x47']),
+        ('\U0001d60f', &['\x48']), ('\U0001d610', &['\x49']), ('\U0001d611', &['\x4a']),
+        ('\U0001d612', &['\x4b']), ('\U0001d613', &['\x4c']), ('\U0001d614', &['\x4d']),
+        ('\U0001d615', &['\x4e']), ('\U0001d616', &['\x4f']), ('\U0001d617', &['\x50']),
+        ('\U0001d618', &['\x51']), ('\U0001d619', &['\x52']), ('\U0001d61a', &['\x53']),
+        ('\U0001d61b', &['\x54']), ('\U0001d61c', &['\x55']), ('\U0001d61d', &['\x56']),
+        ('\U0001d61e', &['\x57']), ('\U0001d61f', &['\x58']), ('\U0001d620', &['\x59']),
+        ('\U0001d621', &['\x5a']), ('\U0001d622', &['\x61']), ('\U0001d623', &['\x62']),
+        ('\U0001d624', &['\x63']), ('\U0001d625', &['\x64']), ('\U0001d626', &['\x65']),
+        ('\U0001d627', &['\x66']), ('\U0001d628', &['\x67']), ('\U0001d629', &['\x68']),
+        ('\U0001d62a', &['\x69']), ('\U0001d62b', &['\x6a']), ('\U0001d62c', &['\x6b']),
+        ('\U0001d62d', &['\x6c']), ('\U0001d62e', &['\x6d']), ('\U0001d62f', &['\x6e']),
+        ('\U0001d630', &['\x6f']), ('\U0001d631', &['\x70']), ('\U0001d632', &['\x71']),
+        ('\U0001d633', &['\x72']), ('\U0001d634', &['\x73']), ('\U0001d635', &['\x74']),
+        ('\U0001d636', &['\x75']), ('\U0001d637', &['\x76']), ('\U0001d638', &['\x77']),
+        ('\U0001d639', &['\x78']), ('\U0001d63a', &['\x79']), ('\U0001d63b', &['\x7a']),
+        ('\U0001d63c', &['\x41']), ('\U0001d63d', &['\x42']), ('\U0001d63e', &['\x43']),
+        ('\U0001d63f', &['\x44']), ('\U0001d640', &['\x45']), ('\U0001d641', &['\x46']),
+        ('\U0001d642', &['\x47']), ('\U0001d643', &['\x48']), ('\U0001d644', &['\x49']),
+        ('\U0001d645', &['\x4a']), ('\U0001d646', &['\x4b']), ('\U0001d647', &['\x4c']),
+        ('\U0001d648', &['\x4d']), ('\U0001d649', &['\x4e']), ('\U0001d64a', &['\x4f']),
+        ('\U0001d64b', &['\x50']), ('\U0001d64c', &['\x51']), ('\U0001d64d', &['\x52']),
+        ('\U0001d64e', &['\x53']), ('\U0001d64f', &['\x54']), ('\U0001d650', &['\x55']),
+        ('\U0001d651', &['\x56']), ('\U0001d652', &['\x57']), ('\U0001d653', &['\x58']),
+        ('\U0001d654', &['\x59']), ('\U0001d655', &['\x5a']), ('\U0001d656', &['\x61']),
+        ('\U0001d657', &['\x62']), ('\U0001d658', &['\x63']), ('\U0001d659', &['\x64']),
+        ('\U0001d65a', &['\x65']), ('\U0001d65b', &['\x66']), ('\U0001d65c', &['\x67']),
+        ('\U0001d65d', &['\x68']), ('\U0001d65e', &['\x69']), ('\U0001d65f', &['\x6a']),
+        ('\U0001d660', &['\x6b']), ('\U0001d661', &['\x6c']), ('\U0001d662', &['\x6d']),
+        ('\U0001d663', &['\x6e']), ('\U0001d664', &['\x6f']), ('\U0001d665', &['\x70']),
+        ('\U0001d666', &['\x71']), ('\U0001d667', &['\x72']), ('\U0001d668', &['\x73']),
+        ('\U0001d669', &['\x74']), ('\U0001d66a', &['\x75']), ('\U0001d66b', &['\x76']),
+        ('\U0001d66c', &['\x77']), ('\U0001d66d', &['\x78']), ('\U0001d66e', &['\x79']),
+        ('\U0001d66f', &['\x7a']), ('\U0001d670', &['\x41']), ('\U0001d671', &['\x42']),
+        ('\U0001d672', &['\x43']), ('\U0001d673', &['\x44']), ('\U0001d674', &['\x45']),
+        ('\U0001d675', &['\x46']), ('\U0001d676', &['\x47']), ('\U0001d677', &['\x48']),
+        ('\U0001d678', &['\x49']), ('\U0001d679', &['\x4a']), ('\U0001d67a', &['\x4b']),
+        ('\U0001d67b', &['\x4c']), ('\U0001d67c', &['\x4d']), ('\U0001d67d', &['\x4e']),
+        ('\U0001d67e', &['\x4f']), ('\U0001d67f', &['\x50']), ('\U0001d680', &['\x51']),
+        ('\U0001d681', &['\x52']), ('\U0001d682', &['\x53']), ('\U0001d683', &['\x54']),
+        ('\U0001d684', &['\x55']), ('\U0001d685', &['\x56']), ('\U0001d686', &['\x57']),
+        ('\U0001d687', &['\x58']), ('\U0001d688', &['\x59']), ('\U0001d689', &['\x5a']),
+        ('\U0001d68a', &['\x61']), ('\U0001d68b', &['\x62']), ('\U0001d68c', &['\x63']),
+        ('\U0001d68d', &['\x64']), ('\U0001d68e', &['\x65']), ('\U0001d68f', &['\x66']),
+        ('\U0001d690', &['\x67']), ('\U0001d691', &['\x68']), ('\U0001d692', &['\x69']),
+        ('\U0001d693', &['\x6a']), ('\U0001d694', &['\x6b']), ('\U0001d695', &['\x6c']),
+        ('\U0001d696', &['\x6d']), ('\U0001d697', &['\x6e']), ('\U0001d698', &['\x6f']),
+        ('\U0001d699', &['\x70']), ('\U0001d69a', &['\x71']), ('\U0001d69b', &['\x72']),
+        ('\U0001d69c', &['\x73']), ('\U0001d69d', &['\x74']), ('\U0001d69e', &['\x75']),
+        ('\U0001d69f', &['\x76']), ('\U0001d6a0', &['\x77']), ('\U0001d6a1', &['\x78']),
+        ('\U0001d6a2', &['\x79']), ('\U0001d6a3', &['\x7a']), ('\U0001d6a4', &['\u0131']),
+        ('\U0001d6a5', &['\u0237']), ('\U0001d6a8', &['\u0391']), ('\U0001d6a9', &['\u0392']),
+        ('\U0001d6aa', &['\u0393']), ('\U0001d6ab', &['\u0394']), ('\U0001d6ac', &['\u0395']),
+        ('\U0001d6ad', &['\u0396']), ('\U0001d6ae', &['\u0397']), ('\U0001d6af', &['\u0398']),
+        ('\U0001d6b0', &['\u0399']), ('\U0001d6b1', &['\u039a']), ('\U0001d6b2', &['\u039b']),
+        ('\U0001d6b3', &['\u039c']), ('\U0001d6b4', &['\u039d']), ('\U0001d6b5', &['\u039e']),
+        ('\U0001d6b6', &['\u039f']), ('\U0001d6b7', &['\u03a0']), ('\U0001d6b8', &['\u03a1']),
+        ('\U0001d6b9', &['\u03f4']), ('\U0001d6ba', &['\u03a3']), ('\U0001d6bb', &['\u03a4']),
+        ('\U0001d6bc', &['\u03a5']), ('\U0001d6bd', &['\u03a6']), ('\U0001d6be', &['\u03a7']),
+        ('\U0001d6bf', &['\u03a8']), ('\U0001d6c0', &['\u03a9']), ('\U0001d6c1', &['\u2207']),
+        ('\U0001d6c2', &['\u03b1']), ('\U0001d6c3', &['\u03b2']), ('\U0001d6c4', &['\u03b3']),
+        ('\U0001d6c5', &['\u03b4']), ('\U0001d6c6', &['\u03b5']), ('\U0001d6c7', &['\u03b6']),
+        ('\U0001d6c8', &['\u03b7']), ('\U0001d6c9', &['\u03b8']), ('\U0001d6ca', &['\u03b9']),
+        ('\U0001d6cb', &['\u03ba']), ('\U0001d6cc', &['\u03bb']), ('\U0001d6cd', &['\u03bc']),
+        ('\U0001d6ce', &['\u03bd']), ('\U0001d6cf', &['\u03be']), ('\U0001d6d0', &['\u03bf']),
+        ('\U0001d6d1', &['\u03c0']), ('\U0001d6d2', &['\u03c1']), ('\U0001d6d3', &['\u03c2']),
+        ('\U0001d6d4', &['\u03c3']), ('\U0001d6d5', &['\u03c4']), ('\U0001d6d6', &['\u03c5']),
+        ('\U0001d6d7', &['\u03c6']), ('\U0001d6d8', &['\u03c7']), ('\U0001d6d9', &['\u03c8']),
+        ('\U0001d6da', &['\u03c9']), ('\U0001d6db', &['\u2202']), ('\U0001d6dc', &['\u03f5']),
+        ('\U0001d6dd', &['\u03d1']), ('\U0001d6de', &['\u03f0']), ('\U0001d6df', &['\u03d5']),
+        ('\U0001d6e0', &['\u03f1']), ('\U0001d6e1', &['\u03d6']), ('\U0001d6e2', &['\u0391']),
+        ('\U0001d6e3', &['\u0392']), ('\U0001d6e4', &['\u0393']), ('\U0001d6e5', &['\u0394']),
+        ('\U0001d6e6', &['\u0395']), ('\U0001d6e7', &['\u0396']), ('\U0001d6e8', &['\u0397']),
+        ('\U0001d6e9', &['\u0398']), ('\U0001d6ea', &['\u0399']), ('\U0001d6eb', &['\u039a']),
+        ('\U0001d6ec', &['\u039b']), ('\U0001d6ed', &['\u039c']), ('\U0001d6ee', &['\u039d']),
+        ('\U0001d6ef', &['\u039e']), ('\U0001d6f0', &['\u039f']), ('\U0001d6f1', &['\u03a0']),
+        ('\U0001d6f2', &['\u03a1']), ('\U0001d6f3', &['\u03f4']), ('\U0001d6f4', &['\u03a3']),
+        ('\U0001d6f5', &['\u03a4']), ('\U0001d6f6', &['\u03a5']), ('\U0001d6f7', &['\u03a6']),
+        ('\U0001d6f8', &['\u03a7']), ('\U0001d6f9', &['\u03a8']), ('\U0001d6fa', &['\u03a9']),
+        ('\U0001d6fb', &['\u2207']), ('\U0001d6fc', &['\u03b1']), ('\U0001d6fd', &['\u03b2']),
+        ('\U0001d6fe', &['\u03b3']), ('\U0001d6ff', &['\u03b4']), ('\U0001d700', &['\u03b5']),
+        ('\U0001d701', &['\u03b6']), ('\U0001d702', &['\u03b7']), ('\U0001d703', &['\u03b8']),
+        ('\U0001d704', &['\u03b9']), ('\U0001d705', &['\u03ba']), ('\U0001d706', &['\u03bb']),
+        ('\U0001d707', &['\u03bc']), ('\U0001d708', &['\u03bd']), ('\U0001d709', &['\u03be']),
+        ('\U0001d70a', &['\u03bf']), ('\U0001d70b', &['\u03c0']), ('\U0001d70c', &['\u03c1']),
+        ('\U0001d70d', &['\u03c2']), ('\U0001d70e', &['\u03c3']), ('\U0001d70f', &['\u03c4']),
+        ('\U0001d710', &['\u03c5']), ('\U0001d711', &['\u03c6']), ('\U0001d712', &['\u03c7']),
+        ('\U0001d713', &['\u03c8']), ('\U0001d714', &['\u03c9']), ('\U0001d715', &['\u2202']),
+        ('\U0001d716', &['\u03f5']), ('\U0001d717', &['\u03d1']), ('\U0001d718', &['\u03f0']),
+        ('\U0001d719', &['\u03d5']), ('\U0001d71a', &['\u03f1']), ('\U0001d71b', &['\u03d6']),
+        ('\U0001d71c', &['\u0391']), ('\U0001d71d', &['\u0392']), ('\U0001d71e', &['\u0393']),
+        ('\U0001d71f', &['\u0394']), ('\U0001d720', &['\u0395']), ('\U0001d721', &['\u0396']),
+        ('\U0001d722', &['\u0397']), ('\U0001d723', &['\u0398']), ('\U0001d724', &['\u0399']),
+        ('\U0001d725', &['\u039a']), ('\U0001d726', &['\u039b']), ('\U0001d727', &['\u039c']),
+        ('\U0001d728', &['\u039d']), ('\U0001d729', &['\u039e']), ('\U0001d72a', &['\u039f']),
+        ('\U0001d72b', &['\u03a0']), ('\U0001d72c', &['\u03a1']), ('\U0001d72d', &['\u03f4']),
+        ('\U0001d72e', &['\u03a3']), ('\U0001d72f', &['\u03a4']), ('\U0001d730', &['\u03a5']),
+        ('\U0001d731', &['\u03a6']), ('\U0001d732', &['\u03a7']), ('\U0001d733', &['\u03a8']),
+        ('\U0001d734', &['\u03a9']), ('\U0001d735', &['\u2207']), ('\U0001d736', &['\u03b1']),
+        ('\U0001d737', &['\u03b2']), ('\U0001d738', &['\u03b3']), ('\U0001d739', &['\u03b4']),
+        ('\U0001d73a', &['\u03b5']), ('\U0001d73b', &['\u03b6']), ('\U0001d73c', &['\u03b7']),
+        ('\U0001d73d', &['\u03b8']), ('\U0001d73e', &['\u03b9']), ('\U0001d73f', &['\u03ba']),
+        ('\U0001d740', &['\u03bb']), ('\U0001d741', &['\u03bc']), ('\U0001d742', &['\u03bd']),
+        ('\U0001d743', &['\u03be']), ('\U0001d744', &['\u03bf']), ('\U0001d745', &['\u03c0']),
+        ('\U0001d746', &['\u03c1']), ('\U0001d747', &['\u03c2']), ('\U0001d748', &['\u03c3']),
+        ('\U0001d749', &['\u03c4']), ('\U0001d74a', &['\u03c5']), ('\U0001d74b', &['\u03c6']),
+        ('\U0001d74c', &['\u03c7']), ('\U0001d74d', &['\u03c8']), ('\U0001d74e', &['\u03c9']),
+        ('\U0001d74f', &['\u2202']), ('\U0001d750', &['\u03f5']), ('\U0001d751', &['\u03d1']),
+        ('\U0001d752', &['\u03f0']), ('\U0001d753', &['\u03d5']), ('\U0001d754', &['\u03f1']),
+        ('\U0001d755', &['\u03d6']), ('\U0001d756', &['\u0391']), ('\U0001d757', &['\u0392']),
+        ('\U0001d758', &['\u0393']), ('\U0001d759', &['\u0394']), ('\U0001d75a', &['\u0395']),
+        ('\U0001d75b', &['\u0396']), ('\U0001d75c', &['\u0397']), ('\U0001d75d', &['\u0398']),
+        ('\U0001d75e', &['\u0399']), ('\U0001d75f', &['\u039a']), ('\U0001d760', &['\u039b']),
+        ('\U0001d761', &['\u039c']), ('\U0001d762', &['\u039d']), ('\U0001d763', &['\u039e']),
+        ('\U0001d764', &['\u039f']), ('\U0001d765', &['\u03a0']), ('\U0001d766', &['\u03a1']),
+        ('\U0001d767', &['\u03f4']), ('\U0001d768', &['\u03a3']), ('\U0001d769', &['\u03a4']),
+        ('\U0001d76a', &['\u03a5']), ('\U0001d76b', &['\u03a6']), ('\U0001d76c', &['\u03a7']),
+        ('\U0001d76d', &['\u03a8']), ('\U0001d76e', &['\u03a9']), ('\U0001d76f', &['\u2207']),
+        ('\U0001d770', &['\u03b1']), ('\U0001d771', &['\u03b2']), ('\U0001d772', &['\u03b3']),
+        ('\U0001d773', &['\u03b4']), ('\U0001d774', &['\u03b5']), ('\U0001d775', &['\u03b6']),
+        ('\U0001d776', &['\u03b7']), ('\U0001d777', &['\u03b8']), ('\U0001d778', &['\u03b9']),
+        ('\U0001d779', &['\u03ba']), ('\U0001d77a', &['\u03bb']), ('\U0001d77b', &['\u03bc']),
+        ('\U0001d77c', &['\u03bd']), ('\U0001d77d', &['\u03be']), ('\U0001d77e', &['\u03bf']),
+        ('\U0001d77f', &['\u03c0']), ('\U0001d780', &['\u03c1']), ('\U0001d781', &['\u03c2']),
+        ('\U0001d782', &['\u03c3']), ('\U0001d783', &['\u03c4']), ('\U0001d784', &['\u03c5']),
+        ('\U0001d785', &['\u03c6']), ('\U0001d786', &['\u03c7']), ('\U0001d787', &['\u03c8']),
+        ('\U0001d788', &['\u03c9']), ('\U0001d789', &['\u2202']), ('\U0001d78a', &['\u03f5']),
+        ('\U0001d78b', &['\u03d1']), ('\U0001d78c', &['\u03f0']), ('\U0001d78d', &['\u03d5']),
+        ('\U0001d78e', &['\u03f1']), ('\U0001d78f', &['\u03d6']), ('\U0001d790', &['\u0391']),
+        ('\U0001d791', &['\u0392']), ('\U0001d792', &['\u0393']), ('\U0001d793', &['\u0394']),
+        ('\U0001d794', &['\u0395']), ('\U0001d795', &['\u0396']), ('\U0001d796', &['\u0397']),
+        ('\U0001d797', &['\u0398']), ('\U0001d798', &['\u0399']), ('\U0001d799', &['\u039a']),
+        ('\U0001d79a', &['\u039b']), ('\U0001d79b', &['\u039c']), ('\U0001d79c', &['\u039d']),
+        ('\U0001d79d', &['\u039e']), ('\U0001d79e', &['\u039f']), ('\U0001d79f', &['\u03a0']),
+        ('\U0001d7a0', &['\u03a1']), ('\U0001d7a1', &['\u03f4']), ('\U0001d7a2', &['\u03a3']),
+        ('\U0001d7a3', &['\u03a4']), ('\U0001d7a4', &['\u03a5']), ('\U0001d7a5', &['\u03a6']),
+        ('\U0001d7a6', &['\u03a7']), ('\U0001d7a7', &['\u03a8']), ('\U0001d7a8', &['\u03a9']),
+        ('\U0001d7a9', &['\u2207']), ('\U0001d7aa', &['\u03b1']), ('\U0001d7ab', &['\u03b2']),
+        ('\U0001d7ac', &['\u03b3']), ('\U0001d7ad', &['\u03b4']), ('\U0001d7ae', &['\u03b5']),
+        ('\U0001d7af', &['\u03b6']), ('\U0001d7b0', &['\u03b7']), ('\U0001d7b1', &['\u03b8']),
+        ('\U0001d7b2', &['\u03b9']), ('\U0001d7b3', &['\u03ba']), ('\U0001d7b4', &['\u03bb']),
+        ('\U0001d7b5', &['\u03bc']), ('\U0001d7b6', &['\u03bd']), ('\U0001d7b7', &['\u03be']),
+        ('\U0001d7b8', &['\u03bf']), ('\U0001d7b9', &['\u03c0']), ('\U0001d7ba', &['\u03c1']),
+        ('\U0001d7bb', &['\u03c2']), ('\U0001d7bc', &['\u03c3']), ('\U0001d7bd', &['\u03c4']),
+        ('\U0001d7be', &['\u03c5']), ('\U0001d7bf', &['\u03c6']), ('\U0001d7c0', &['\u03c7']),
+        ('\U0001d7c1', &['\u03c8']), ('\U0001d7c2', &['\u03c9']), ('\U0001d7c3', &['\u2202']),
+        ('\U0001d7c4', &['\u03f5']), ('\U0001d7c5', &['\u03d1']), ('\U0001d7c6', &['\u03f0']),
+        ('\U0001d7c7', &['\u03d5']), ('\U0001d7c8', &['\u03f1']), ('\U0001d7c9', &['\u03d6']),
+        ('\U0001d7ca', &['\u03dc']), ('\U0001d7cb', &['\u03dd']), ('\U0001d7ce', &['\x30']),
+        ('\U0001d7cf', &['\x31']), ('\U0001d7d0', &['\x32']), ('\U0001d7d1', &['\x33']),
+        ('\U0001d7d2', &['\x34']), ('\U0001d7d3', &['\x35']), ('\U0001d7d4', &['\x36']),
+        ('\U0001d7d5', &['\x37']), ('\U0001d7d6', &['\x38']), ('\U0001d7d7', &['\x39']),
+        ('\U0001d7d8', &['\x30']), ('\U0001d7d9', &['\x31']), ('\U0001d7da', &['\x32']),
+        ('\U0001d7db', &['\x33']), ('\U0001d7dc', &['\x34']), ('\U0001d7dd', &['\x35']),
+        ('\U0001d7de', &['\x36']), ('\U0001d7df', &['\x37']), ('\U0001d7e0', &['\x38']),
+        ('\U0001d7e1', &['\x39']), ('\U0001d7e2', &['\x30']), ('\U0001d7e3', &['\x31']),
+        ('\U0001d7e4', &['\x32']), ('\U0001d7e5', &['\x33']), ('\U0001d7e6', &['\x34']),
+        ('\U0001d7e7', &['\x35']), ('\U0001d7e8', &['\x36']), ('\U0001d7e9', &['\x37']),
+        ('\U0001d7ea', &['\x38']), ('\U0001d7eb', &['\x39']), ('\U0001d7ec', &['\x30']),
+        ('\U0001d7ed', &['\x31']), ('\U0001d7ee', &['\x32']), ('\U0001d7ef', &['\x33']),
+        ('\U0001d7f0', &['\x34']), ('\U0001d7f1', &['\x35']), ('\U0001d7f2', &['\x36']),
+        ('\U0001d7f3', &['\x37']), ('\U0001d7f4', &['\x38']), ('\U0001d7f5', &['\x39']),
+        ('\U0001d7f6', &['\x30']), ('\U0001d7f7', &['\x31']), ('\U0001d7f8', &['\x32']),
+        ('\U0001d7f9', &['\x33']), ('\U0001d7fa', &['\x34']), ('\U0001d7fb', &['\x35']),
+        ('\U0001d7fc', &['\x36']), ('\U0001d7fd', &['\x37']), ('\U0001d7fe', &['\x38']),
+        ('\U0001d7ff', &['\x39']), ('\U0001ee00', &['\u0627']), ('\U0001ee01', &['\u0628']),
+        ('\U0001ee02', &['\u062c']), ('\U0001ee03', &['\u062f']), ('\U0001ee05', &['\u0648']),
+        ('\U0001ee06', &['\u0632']), ('\U0001ee07', &['\u062d']), ('\U0001ee08', &['\u0637']),
+        ('\U0001ee09', &['\u064a']), ('\U0001ee0a', &['\u0643']), ('\U0001ee0b', &['\u0644']),
+        ('\U0001ee0c', &['\u0645']), ('\U0001ee0d', &['\u0646']), ('\U0001ee0e', &['\u0633']),
+        ('\U0001ee0f', &['\u0639']), ('\U0001ee10', &['\u0641']), ('\U0001ee11', &['\u0635']),
+        ('\U0001ee12', &['\u0642']), ('\U0001ee13', &['\u0631']), ('\U0001ee14', &['\u0634']),
+        ('\U0001ee15', &['\u062a']), ('\U0001ee16', &['\u062b']), ('\U0001ee17', &['\u062e']),
+        ('\U0001ee18', &['\u0630']), ('\U0001ee19', &['\u0636']), ('\U0001ee1a', &['\u0638']),
+        ('\U0001ee1b', &['\u063a']), ('\U0001ee1c', &['\u066e']), ('\U0001ee1d', &['\u06ba']),
+        ('\U0001ee1e', &['\u06a1']), ('\U0001ee1f', &['\u066f']), ('\U0001ee21', &['\u0628']),
+        ('\U0001ee22', &['\u062c']), ('\U0001ee24', &['\u0647']), ('\U0001ee27', &['\u062d']),
+        ('\U0001ee29', &['\u064a']), ('\U0001ee2a', &['\u0643']), ('\U0001ee2b', &['\u0644']),
+        ('\U0001ee2c', &['\u0645']), ('\U0001ee2d', &['\u0646']), ('\U0001ee2e', &['\u0633']),
+        ('\U0001ee2f', &['\u0639']), ('\U0001ee30', &['\u0641']), ('\U0001ee31', &['\u0635']),
+        ('\U0001ee32', &['\u0642']), ('\U0001ee34', &['\u0634']), ('\U0001ee35', &['\u062a']),
+        ('\U0001ee36', &['\u062b']), ('\U0001ee37', &['\u062e']), ('\U0001ee39', &['\u0636']),
+        ('\U0001ee3b', &['\u063a']), ('\U0001ee42', &['\u062c']), ('\U0001ee47', &['\u062d']),
+        ('\U0001ee49', &['\u064a']), ('\U0001ee4b', &['\u0644']), ('\U0001ee4d', &['\u0646']),
+        ('\U0001ee4e', &['\u0633']), ('\U0001ee4f', &['\u0639']), ('\U0001ee51', &['\u0635']),
+        ('\U0001ee52', &['\u0642']), ('\U0001ee54', &['\u0634']), ('\U0001ee57', &['\u062e']),
+        ('\U0001ee59', &['\u0636']), ('\U0001ee5b', &['\u063a']), ('\U0001ee5d', &['\u06ba']),
+        ('\U0001ee5f', &['\u066f']), ('\U0001ee61', &['\u0628']), ('\U0001ee62', &['\u062c']),
+        ('\U0001ee64', &['\u0647']), ('\U0001ee67', &['\u062d']), ('\U0001ee68', &['\u0637']),
+        ('\U0001ee69', &['\u064a']), ('\U0001ee6a', &['\u0643']), ('\U0001ee6c', &['\u0645']),
+        ('\U0001ee6d', &['\u0646']), ('\U0001ee6e', &['\u0633']), ('\U0001ee6f', &['\u0639']),
+        ('\U0001ee70', &['\u0641']), ('\U0001ee71', &['\u0635']), ('\U0001ee72', &['\u0642']),
+        ('\U0001ee74', &['\u0634']), ('\U0001ee75', &['\u062a']), ('\U0001ee76', &['\u062b']),
+        ('\U0001ee77', &['\u062e']), ('\U0001ee79', &['\u0636']), ('\U0001ee7a', &['\u0638']),
+        ('\U0001ee7b', &['\u063a']), ('\U0001ee7c', &['\u066e']), ('\U0001ee7e', &['\u06a1']),
+        ('\U0001ee80', &['\u0627']), ('\U0001ee81', &['\u0628']), ('\U0001ee82', &['\u062c']),
+        ('\U0001ee83', &['\u062f']), ('\U0001ee84', &['\u0647']), ('\U0001ee85', &['\u0648']),
+        ('\U0001ee86', &['\u0632']), ('\U0001ee87', &['\u062d']), ('\U0001ee88', &['\u0637']),
+        ('\U0001ee89', &['\u064a']), ('\U0001ee8b', &['\u0644']), ('\U0001ee8c', &['\u0645']),
+        ('\U0001ee8d', &['\u0646']), ('\U0001ee8e', &['\u0633']), ('\U0001ee8f', &['\u0639']),
+        ('\U0001ee90', &['\u0641']), ('\U0001ee91', &['\u0635']), ('\U0001ee92', &['\u0642']),
+        ('\U0001ee93', &['\u0631']), ('\U0001ee94', &['\u0634']), ('\U0001ee95', &['\u062a']),
+        ('\U0001ee96', &['\u062b']), ('\U0001ee97', &['\u062e']), ('\U0001ee98', &['\u0630']),
+        ('\U0001ee99', &['\u0636']), ('\U0001ee9a', &['\u0638']), ('\U0001ee9b', &['\u063a']),
+        ('\U0001eea1', &['\u0628']), ('\U0001eea2', &['\u062c']), ('\U0001eea3', &['\u062f']),
+        ('\U0001eea5', &['\u0648']), ('\U0001eea6', &['\u0632']), ('\U0001eea7', &['\u062d']),
+        ('\U0001eea8', &['\u0637']), ('\U0001eea9', &['\u064a']), ('\U0001eeab', &['\u0644']),
+        ('\U0001eeac', &['\u0645']), ('\U0001eead', &['\u0646']), ('\U0001eeae', &['\u0633']),
+        ('\U0001eeaf', &['\u0639']), ('\U0001eeb0', &['\u0641']), ('\U0001eeb1', &['\u0635']),
+        ('\U0001eeb2', &['\u0642']), ('\U0001eeb3', &['\u0631']), ('\U0001eeb4', &['\u0634']),
+        ('\U0001eeb5', &['\u062a']), ('\U0001eeb6', &['\u062b']), ('\U0001eeb7', &['\u062e']),
+        ('\U0001eeb8', &['\u0630']), ('\U0001eeb9', &['\u0636']), ('\U0001eeba', &['\u0638']),
+        ('\U0001eebb', &['\u063a']), ('\U0001f100', &['\x30', '\x2e']), ('\U0001f101', &['\x30',
+        '\x2c']), ('\U0001f102', &['\x31', '\x2c']), ('\U0001f103', &['\x32', '\x2c']),
+        ('\U0001f104', &['\x33', '\x2c']), ('\U0001f105', &['\x34', '\x2c']), ('\U0001f106',
+        &['\x35', '\x2c']), ('\U0001f107', &['\x36', '\x2c']), ('\U0001f108', &['\x37', '\x2c']),
+        ('\U0001f109', &['\x38', '\x2c']), ('\U0001f10a', &['\x39', '\x2c']), ('\U0001f110',
+        &['\x28', '\x41', '\x29']), ('\U0001f111', &['\x28', '\x42', '\x29']), ('\U0001f112',
+        &['\x28', '\x43', '\x29']), ('\U0001f113', &['\x28', '\x44', '\x29']), ('\U0001f114',
+        &['\x28', '\x45', '\x29']), ('\U0001f115', &['\x28', '\x46', '\x29']), ('\U0001f116',
+        &['\x28', '\x47', '\x29']), ('\U0001f117', &['\x28', '\x48', '\x29']), ('\U0001f118',
+        &['\x28', '\x49', '\x29']), ('\U0001f119', &['\x28', '\x4a', '\x29']), ('\U0001f11a',
+        &['\x28', '\x4b', '\x29']), ('\U0001f11b', &['\x28', '\x4c', '\x29']), ('\U0001f11c',
+        &['\x28', '\x4d', '\x29']), ('\U0001f11d', &['\x28', '\x4e', '\x29']), ('\U0001f11e',
+        &['\x28', '\x4f', '\x29']), ('\U0001f11f', &['\x28', '\x50', '\x29']), ('\U0001f120',
+        &['\x28', '\x51', '\x29']), ('\U0001f121', &['\x28', '\x52', '\x29']), ('\U0001f122',
+        &['\x28', '\x53', '\x29']), ('\U0001f123', &['\x28', '\x54', '\x29']), ('\U0001f124',
+        &['\x28', '\x55', '\x29']), ('\U0001f125', &['\x28', '\x56', '\x29']), ('\U0001f126',
+        &['\x28', '\x57', '\x29']), ('\U0001f127', &['\x28', '\x58', '\x29']), ('\U0001f128',
+        &['\x28', '\x59', '\x29']), ('\U0001f129', &['\x28', '\x5a', '\x29']), ('\U0001f12a',
+        &['\u3014', '\x53', '\u3015']), ('\U0001f12b', &['\x43']), ('\U0001f12c', &['\x52']),
+        ('\U0001f12d', &['\x43', '\x44']), ('\U0001f12e', &['\x57', '\x5a']), ('\U0001f130',
+        &['\x41']), ('\U0001f131', &['\x42']), ('\U0001f132', &['\x43']), ('\U0001f133', &['\x44']),
+        ('\U0001f134', &['\x45']), ('\U0001f135', &['\x46']), ('\U0001f136', &['\x47']),
+        ('\U0001f137', &['\x48']), ('\U0001f138', &['\x49']), ('\U0001f139', &['\x4a']),
+        ('\U0001f13a', &['\x4b']), ('\U0001f13b', &['\x4c']), ('\U0001f13c', &['\x4d']),
+        ('\U0001f13d', &['\x4e']), ('\U0001f13e', &['\x4f']), ('\U0001f13f', &['\x50']),
+        ('\U0001f140', &['\x51']), ('\U0001f141', &['\x52']), ('\U0001f142', &['\x53']),
+        ('\U0001f143', &['\x54']), ('\U0001f144', &['\x55']), ('\U0001f145', &['\x56']),
+        ('\U0001f146', &['\x57']), ('\U0001f147', &['\x58']), ('\U0001f148', &['\x59']),
+        ('\U0001f149', &['\x5a']), ('\U0001f14a', &['\x48', '\x56']), ('\U0001f14b', &['\x4d',
+        '\x56']), ('\U0001f14c', &['\x53', '\x44']), ('\U0001f14d', &['\x53', '\x53']),
+        ('\U0001f14e', &['\x50', '\x50', '\x56']), ('\U0001f14f', &['\x57', '\x43']), ('\U0001f16a',
+        &['\x4d', '\x43']), ('\U0001f16b', &['\x4d', '\x44']), ('\U0001f190', &['\x44', '\x4a']),
+        ('\U0001f200', &['\u307b', '\u304b']), ('\U0001f201', &['\u30b3', '\u30b3']), ('\U0001f202',
+        &['\u30b5']), ('\U0001f210', &['\u624b']), ('\U0001f211', &['\u5b57']), ('\U0001f212',
+        &['\u53cc']), ('\U0001f213', &['\u30c7']), ('\U0001f214', &['\u4e8c']), ('\U0001f215',
+        &['\u591a']), ('\U0001f216', &['\u89e3']), ('\U0001f217', &['\u5929']), ('\U0001f218',
+        &['\u4ea4']), ('\U0001f219', &['\u6620']), ('\U0001f21a', &['\u7121']), ('\U0001f21b',
+        &['\u6599']), ('\U0001f21c', &['\u524d']), ('\U0001f21d', &['\u5f8c']), ('\U0001f21e',
+        &['\u518d']), ('\U0001f21f', &['\u65b0']), ('\U0001f220', &['\u521d']), ('\U0001f221',
+        &['\u7d42']), ('\U0001f222', &['\u751f']), ('\U0001f223', &['\u8ca9']), ('\U0001f224',
+        &['\u58f0']), ('\U0001f225', &['\u5439']), ('\U0001f226', &['\u6f14']), ('\U0001f227',
+        &['\u6295']), ('\U0001f228', &['\u6355']), ('\U0001f229', &['\u4e00']), ('\U0001f22a',
+        &['\u4e09']), ('\U0001f22b', &['\u904a']), ('\U0001f22c', &['\u5de6']), ('\U0001f22d',
+        &['\u4e2d']), ('\U0001f22e', &['\u53f3']), ('\U0001f22f', &['\u6307']), ('\U0001f230',
+        &['\u8d70']), ('\U0001f231', &['\u6253']), ('\U0001f232', &['\u7981']), ('\U0001f233',
+        &['\u7a7a']), ('\U0001f234', &['\u5408']), ('\U0001f235', &['\u6e80']), ('\U0001f236',
+        &['\u6709']), ('\U0001f237', &['\u6708']), ('\U0001f238', &['\u7533']), ('\U0001f239',
+        &['\u5272']), ('\U0001f23a', &['\u55b6']), ('\U0001f240', &['\u3014', '\u672c', '\u3015']),
+        ('\U0001f241', &['\u3014', '\u4e09', '\u3015']), ('\U0001f242', &['\u3014', '\u4e8c',
+        '\u3015']), ('\U0001f243', &['\u3014', '\u5b89', '\u3015']), ('\U0001f244', &['\u3014',
+        '\u70b9', '\u3015']), ('\U0001f245', &['\u3014', '\u6253', '\u3015']), ('\U0001f246',
+        &['\u3014', '\u76d7', '\u3015']), ('\U0001f247', &['\u3014', '\u52dd', '\u3015']),
+        ('\U0001f248', &['\u3014', '\u6557', '\u3015']), ('\U0001f250', &['\u5f97']), ('\U0001f251',
+        &['\u53ef'])
+    ];
+
+
+    fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
+        use core::option::{Some, None};
+        use core::cmp::{Equal, Less, Greater};
+        use core::slice::ImmutableVector;
+        match r.bsearch(|&(lo, hi, _)| {
+            if lo <= c && c <= hi { Equal }
+            else if hi < c { Less }
+            else { Greater }
+        }) {
+            Some(idx) => {
+                let (_, _, result) = r[idx];
+                result
+            }
+            None => 0
+        }
+    }
+
+    static combining_class_table: &'static [(char, char, u8)] = &[
+        ('\u0300', '\u0314', 230), ('\u0315', '\u0315', 232), ('\u0316', '\u0319', 220), ('\u031a',
+        '\u031a', 232), ('\u031b', '\u031b', 216), ('\u031c', '\u0320', 220), ('\u0321', '\u0322',
+        202), ('\u0323', '\u0326', 220), ('\u0327', '\u0328', 202), ('\u0329', '\u0333', 220),
+        ('\u0334', '\u0338', 1), ('\u0339', '\u033c', 220), ('\u033d', '\u0344', 230), ('\u0345',
+        '\u0345', 240), ('\u0346', '\u0346', 230), ('\u0347', '\u0349', 220), ('\u034a', '\u034c',
+        230), ('\u034d', '\u034e', 220), ('\u0350', '\u0352', 230), ('\u0353', '\u0356', 220),
+        ('\u0357', '\u0357', 230), ('\u0358', '\u0358', 232), ('\u0359', '\u035a', 220), ('\u035b',
+        '\u035b', 230), ('\u035c', '\u035c', 233), ('\u035d', '\u035e', 234), ('\u035f', '\u035f',
+        233), ('\u0360', '\u0361', 234), ('\u0362', '\u0362', 233), ('\u0363', '\u036f', 230),
+        ('\u0483', '\u0487', 230), ('\u0591', '\u0591', 220), ('\u0592', '\u0595', 230), ('\u0596',
+        '\u0596', 220), ('\u0597', '\u0599', 230), ('\u059a', '\u059a', 222), ('\u059b', '\u059b',
+        220), ('\u059c', '\u05a1', 230), ('\u05a2', '\u05a7', 220), ('\u05a8', '\u05a9', 230),
+        ('\u05aa', '\u05aa', 220), ('\u05ab', '\u05ac', 230), ('\u05ad', '\u05ad', 222), ('\u05ae',
+        '\u05ae', 228), ('\u05af', '\u05af', 230), ('\u05b0', '\u05b0', 10), ('\u05b1', '\u05b1',
+        11), ('\u05b2', '\u05b2', 12), ('\u05b3', '\u05b3', 13), ('\u05b4', '\u05b4', 14),
+        ('\u05b5', '\u05b5', 15), ('\u05b6', '\u05b6', 16), ('\u05b7', '\u05b7', 17), ('\u05b8',
+        '\u05b8', 18), ('\u05b9', '\u05ba', 19), ('\u05bb', '\u05bb', 20), ('\u05bc', '\u05bc', 21),
+        ('\u05bd', '\u05bd', 22), ('\u05bf', '\u05bf', 23), ('\u05c1', '\u05c1', 24), ('\u05c2',
+        '\u05c2', 25), ('\u05c4', '\u05c4', 230), ('\u05c5', '\u05c5', 220), ('\u05c7', '\u05c7',
+        18), ('\u0610', '\u0617', 230), ('\u0618', '\u0618', 30), ('\u0619', '\u0619', 31),
+        ('\u061a', '\u061a', 32), ('\u064b', '\u064b', 27), ('\u064c', '\u064c', 28), ('\u064d',
+        '\u064d', 29), ('\u064e', '\u064e', 30), ('\u064f', '\u064f', 31), ('\u0650', '\u0650', 32),
+        ('\u0651', '\u0651', 33), ('\u0652', '\u0652', 34), ('\u0653', '\u0654', 230), ('\u0655',
+        '\u0656', 220), ('\u0657', '\u065b', 230), ('\u065c', '\u065c', 220), ('\u065d', '\u065e',
+        230), ('\u065f', '\u065f', 220), ('\u0670', '\u0670', 35), ('\u06d6', '\u06dc', 230),
+        ('\u06df', '\u06e2', 230), ('\u06e3', '\u06e3', 220), ('\u06e4', '\u06e4', 230), ('\u06e7',
+        '\u06e8', 230), ('\u06ea', '\u06ea', 220), ('\u06eb', '\u06ec', 230), ('\u06ed', '\u06ed',
+        220), ('\u0711', '\u0711', 36), ('\u0730', '\u0730', 230), ('\u0731', '\u0731', 220),
+        ('\u0732', '\u0733', 230), ('\u0734', '\u0734', 220), ('\u0735', '\u0736', 230), ('\u0737',
+        '\u0739', 220), ('\u073a', '\u073a', 230), ('\u073b', '\u073c', 220), ('\u073d', '\u073d',
+        230), ('\u073e', '\u073e', 220), ('\u073f', '\u0741', 230), ('\u0742', '\u0742', 220),
+        ('\u0743', '\u0743', 230), ('\u0744', '\u0744', 220), ('\u0745', '\u0745', 230), ('\u0746',
+        '\u0746', 220), ('\u0747', '\u0747', 230), ('\u0748', '\u0748', 220), ('\u0749', '\u074a',
+        230), ('\u07eb', '\u07f1', 230), ('\u07f2', '\u07f2', 220), ('\u07f3', '\u07f3', 230),
+        ('\u0816', '\u0819', 230), ('\u081b', '\u0823', 230), ('\u0825', '\u0827', 230), ('\u0829',
+        '\u082d', 230), ('\u0859', '\u085b', 220), ('\u08e4', '\u08e5', 230), ('\u08e6', '\u08e6',
+        220), ('\u08e7', '\u08e8', 230), ('\u08e9', '\u08e9', 220), ('\u08ea', '\u08ec', 230),
+        ('\u08ed', '\u08ef', 220), ('\u08f0', '\u08f0', 27), ('\u08f1', '\u08f1', 28), ('\u08f2',
+        '\u08f2', 29), ('\u08f3', '\u08f5', 230), ('\u08f6', '\u08f6', 220), ('\u08f7', '\u08f8',
+        230), ('\u08f9', '\u08fa', 220), ('\u08fb', '\u08ff', 230), ('\u093c', '\u093c', 7),
+        ('\u094d', '\u094d', 9), ('\u0951', '\u0951', 230), ('\u0952', '\u0952', 220), ('\u0953',
+        '\u0954', 230), ('\u09bc', '\u09bc', 7), ('\u09cd', '\u09cd', 9), ('\u0a3c', '\u0a3c', 7),
+        ('\u0a4d', '\u0a4d', 9), ('\u0abc', '\u0abc', 7), ('\u0acd', '\u0acd', 9), ('\u0b3c',
+        '\u0b3c', 7), ('\u0b4d', '\u0b4d', 9), ('\u0bcd', '\u0bcd', 9), ('\u0c4d', '\u0c4d', 9),
+        ('\u0c55', '\u0c55', 84), ('\u0c56', '\u0c56', 91), ('\u0cbc', '\u0cbc', 7), ('\u0ccd',
+        '\u0ccd', 9), ('\u0d4d', '\u0d4d', 9), ('\u0dca', '\u0dca', 9), ('\u0e38', '\u0e39', 103),
+        ('\u0e3a', '\u0e3a', 9), ('\u0e48', '\u0e4b', 107), ('\u0eb8', '\u0eb9', 118), ('\u0ec8',
+        '\u0ecb', 122), ('\u0f18', '\u0f19', 220), ('\u0f35', '\u0f35', 220), ('\u0f37', '\u0f37',
+        220), ('\u0f39', '\u0f39', 216), ('\u0f71', '\u0f71', 129), ('\u0f72', '\u0f72', 130),
+        ('\u0f74', '\u0f74', 132), ('\u0f7a', '\u0f7d', 130), ('\u0f80', '\u0f80', 130), ('\u0f82',
+        '\u0f83', 230), ('\u0f84', '\u0f84', 9), ('\u0f86', '\u0f87', 230), ('\u0fc6', '\u0fc6',
+        220), ('\u1037', '\u1037', 7), ('\u1039', '\u103a', 9), ('\u108d', '\u108d', 220),
+        ('\u135d', '\u135f', 230), ('\u1714', '\u1714', 9), ('\u1734', '\u1734', 9), ('\u17d2',
+        '\u17d2', 9), ('\u17dd', '\u17dd', 230), ('\u18a9', '\u18a9', 228), ('\u1939', '\u1939',
+        222), ('\u193a', '\u193a', 230), ('\u193b', '\u193b', 220), ('\u1a17', '\u1a17', 230),
+        ('\u1a18', '\u1a18', 220), ('\u1a60', '\u1a60', 9), ('\u1a75', '\u1a7c', 230), ('\u1a7f',
+        '\u1a7f', 220), ('\u1ab0', '\u1ab4', 230), ('\u1ab5', '\u1aba', 220), ('\u1abb', '\u1abc',
+        230), ('\u1abd', '\u1abd', 220), ('\u1b34', '\u1b34', 7), ('\u1b44', '\u1b44', 9),
+        ('\u1b6b', '\u1b6b', 230), ('\u1b6c', '\u1b6c', 220), ('\u1b6d', '\u1b73', 230), ('\u1baa',
+        '\u1bab', 9), ('\u1be6', '\u1be6', 7), ('\u1bf2', '\u1bf3', 9), ('\u1c37', '\u1c37', 7),
+        ('\u1cd0', '\u1cd2', 230), ('\u1cd4', '\u1cd4', 1), ('\u1cd5', '\u1cd9', 220), ('\u1cda',
+        '\u1cdb', 230), ('\u1cdc', '\u1cdf', 220), ('\u1ce0', '\u1ce0', 230), ('\u1ce2', '\u1ce8',
+        1), ('\u1ced', '\u1ced', 220), ('\u1cf4', '\u1cf4', 230), ('\u1cf8', '\u1cf9', 230),
+        ('\u1dc0', '\u1dc1', 230), ('\u1dc2', '\u1dc2', 220), ('\u1dc3', '\u1dc9', 230), ('\u1dca',
+        '\u1dca', 220), ('\u1dcb', '\u1dcc', 230), ('\u1dcd', '\u1dcd', 234), ('\u1dce', '\u1dce',
+        214), ('\u1dcf', '\u1dcf', 220), ('\u1dd0', '\u1dd0', 202), ('\u1dd1', '\u1df5', 230),
+        ('\u1dfc', '\u1dfc', 233), ('\u1dfd', '\u1dfd', 220), ('\u1dfe', '\u1dfe', 230), ('\u1dff',
+        '\u1dff', 220), ('\u20d0', '\u20d1', 230), ('\u20d2', '\u20d3', 1), ('\u20d4', '\u20d7',
+        230), ('\u20d8', '\u20da', 1), ('\u20db', '\u20dc', 230), ('\u20e1', '\u20e1', 230),
+        ('\u20e5', '\u20e6', 1), ('\u20e7', '\u20e7', 230), ('\u20e8', '\u20e8', 220), ('\u20e9',
+        '\u20e9', 230), ('\u20ea', '\u20eb', 1), ('\u20ec', '\u20ef', 220), ('\u20f0', '\u20f0',
+        230), ('\u2cef', '\u2cf1', 230), ('\u2d7f', '\u2d7f', 9), ('\u2de0', '\u2dff', 230),
+        ('\u302a', '\u302a', 218), ('\u302b', '\u302b', 228), ('\u302c', '\u302c', 232), ('\u302d',
+        '\u302d', 222), ('\u302e', '\u302f', 224), ('\u3099', '\u309a', 8), ('\ua66f', '\ua66f',
+        230), ('\ua674', '\ua67d', 230), ('\ua69f', '\ua69f', 230), ('\ua6f0', '\ua6f1', 230),
+        ('\ua806', '\ua806', 9), ('\ua8c4', '\ua8c4', 9), ('\ua8e0', '\ua8f1', 230), ('\ua92b',
+        '\ua92d', 220), ('\ua953', '\ua953', 9), ('\ua9b3', '\ua9b3', 7), ('\ua9c0', '\ua9c0', 9),
+        ('\uaab0', '\uaab0', 230), ('\uaab2', '\uaab3', 230), ('\uaab4', '\uaab4', 220), ('\uaab7',
+        '\uaab8', 230), ('\uaabe', '\uaabf', 230), ('\uaac1', '\uaac1', 230), ('\uaaf6', '\uaaf6',
+        9), ('\uabed', '\uabed', 9), ('\ufb1e', '\ufb1e', 26), ('\ufe20', '\ufe26', 230), ('\ufe27',
+        '\ufe2d', 220), ('\U000101fd', '\U000101fd', 220), ('\U000102e0', '\U000102e0', 220),
+        ('\U00010376', '\U0001037a', 230), ('\U00010a0d', '\U00010a0d', 220), ('\U00010a0f',
+        '\U00010a0f', 230), ('\U00010a38', '\U00010a38', 230), ('\U00010a39', '\U00010a39', 1),
+        ('\U00010a3a', '\U00010a3a', 220), ('\U00010a3f', '\U00010a3f', 9), ('\U00010ae5',
+        '\U00010ae5', 230), ('\U00010ae6', '\U00010ae6', 220), ('\U00011046', '\U00011046', 9),
+        ('\U0001107f', '\U0001107f', 9), ('\U000110b9', '\U000110b9', 9), ('\U000110ba',
+        '\U000110ba', 7), ('\U00011100', '\U00011102', 230), ('\U00011133', '\U00011134', 9),
+        ('\U00011173', '\U00011173', 7), ('\U000111c0', '\U000111c0', 9), ('\U00011235',
+        '\U00011235', 9), ('\U00011236', '\U00011236', 7), ('\U000112e9', '\U000112e9', 7),
+        ('\U000112ea', '\U000112ea', 9), ('\U0001133c', '\U0001133c', 7), ('\U0001134d',
+        '\U0001134d', 9), ('\U00011366', '\U0001136c', 230), ('\U00011370', '\U00011374', 230),
+        ('\U000114c2', '\U000114c2', 9), ('\U000114c3', '\U000114c3', 7), ('\U000115bf',
+        '\U000115bf', 9), ('\U000115c0', '\U000115c0', 7), ('\U0001163f', '\U0001163f', 9),
+        ('\U000116b6', '\U000116b6', 9), ('\U000116b7', '\U000116b7', 7), ('\U00016af0',
+        '\U00016af4', 1), ('\U00016b30', '\U00016b36', 230), ('\U0001bc9e', '\U0001bc9e', 1),
+        ('\U0001d165', '\U0001d166', 216), ('\U0001d167', '\U0001d169', 1), ('\U0001d16d',
+        '\U0001d16d', 226), ('\U0001d16e', '\U0001d172', 216), ('\U0001d17b', '\U0001d182', 220),
+        ('\U0001d185', '\U0001d189', 230), ('\U0001d18a', '\U0001d18b', 220), ('\U0001d1aa',
+        '\U0001d1ad', 230), ('\U0001d242', '\U0001d244', 230), ('\U0001e8d0', '\U0001e8d6', 220)
+    ];
+
+    pub fn canonical_combining_class(c: char) -> u8 {
+        bsearch_range_value_table(c, combining_class_table)
+    }
+
+}
+
+pub mod conversions {
+    use core::cmp::{Equal, Less, Greater};
+    use core::slice::ImmutableVector;
+    use core::tuple::Tuple2;
+    use core::option::{Option, Some, None};
+
+    pub fn to_lower(c: char) -> char {
+        match bsearch_case_table(c, LuLl_table) {
+          None        => c,
+          Some(index) => LuLl_table[index].val1()
+        }
+    }
+
+    pub fn to_upper(c: char) -> char {
+        match bsearch_case_table(c, LlLu_table) {
+            None        => c,
+            Some(index) => LlLu_table[index].val1()
+        }
+    }
+
+    fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<uint> {
+        table.bsearch(|&(key, _)| {
+            if c == key { Equal }
+            else if key < c { Less }
+            else { Greater }
+        })
+    }
+
+    static LuLl_table: &'static [(char, char)] = &[
+        ('\x41', '\x61'), ('\x42', '\x62'), ('\x43', '\x63'), ('\x44', '\x64'), ('\x45', '\x65'),
+        ('\x46', '\x66'), ('\x47', '\x67'), ('\x48', '\x68'), ('\x49', '\x69'), ('\x4a', '\x6a'),
+        ('\x4b', '\x6b'), ('\x4c', '\x6c'), ('\x4d', '\x6d'), ('\x4e', '\x6e'), ('\x4f', '\x6f'),
+        ('\x50', '\x70'), ('\x51', '\x71'), ('\x52', '\x72'), ('\x53', '\x73'), ('\x54', '\x74'),
+        ('\x55', '\x75'), ('\x56', '\x76'), ('\x57', '\x77'), ('\x58', '\x78'), ('\x59', '\x79'),
+        ('\x5a', '\x7a'), ('\xc0', '\xe0'), ('\xc1', '\xe1'), ('\xc2', '\xe2'), ('\xc3', '\xe3'),
+        ('\xc4', '\xe4'), ('\xc5', '\xe5'), ('\xc6', '\xe6'), ('\xc7', '\xe7'), ('\xc8', '\xe8'),
+        ('\xc9', '\xe9'), ('\xca', '\xea'), ('\xcb', '\xeb'), ('\xcc', '\xec'), ('\xcd', '\xed'),
+        ('\xce', '\xee'), ('\xcf', '\xef'), ('\xd0', '\xf0'), ('\xd1', '\xf1'), ('\xd2', '\xf2'),
+        ('\xd3', '\xf3'), ('\xd4', '\xf4'), ('\xd5', '\xf5'), ('\xd6', '\xf6'), ('\xd8', '\xf8'),
+        ('\xd9', '\xf9'), ('\xda', '\xfa'), ('\xdb', '\xfb'), ('\xdc', '\xfc'), ('\xdd', '\xfd'),
+        ('\xde', '\xfe'), ('\u0100', '\u0101'), ('\u0102', '\u0103'), ('\u0104', '\u0105'),
+        ('\u0106', '\u0107'), ('\u0108', '\u0109'), ('\u010a', '\u010b'), ('\u010c', '\u010d'),
+        ('\u010e', '\u010f'), ('\u0110', '\u0111'), ('\u0112', '\u0113'), ('\u0114', '\u0115'),
+        ('\u0116', '\u0117'), ('\u0118', '\u0119'), ('\u011a', '\u011b'), ('\u011c', '\u011d'),
+        ('\u011e', '\u011f'), ('\u0120', '\u0121'), ('\u0122', '\u0123'), ('\u0124', '\u0125'),
+        ('\u0126', '\u0127'), ('\u0128', '\u0129'), ('\u012a', '\u012b'), ('\u012c', '\u012d'),
+        ('\u012e', '\u012f'), ('\u0130', '\x69'), ('\u0132', '\u0133'), ('\u0134', '\u0135'),
+        ('\u0136', '\u0137'), ('\u0139', '\u013a'), ('\u013b', '\u013c'), ('\u013d', '\u013e'),
+        ('\u013f', '\u0140'), ('\u0141', '\u0142'), ('\u0143', '\u0144'), ('\u0145', '\u0146'),
+        ('\u0147', '\u0148'), ('\u014a', '\u014b'), ('\u014c', '\u014d'), ('\u014e', '\u014f'),
+        ('\u0150', '\u0151'), ('\u0152', '\u0153'), ('\u0154', '\u0155'), ('\u0156', '\u0157'),
+        ('\u0158', '\u0159'), ('\u015a', '\u015b'), ('\u015c', '\u015d'), ('\u015e', '\u015f'),
+        ('\u0160', '\u0161'), ('\u0162', '\u0163'), ('\u0164', '\u0165'), ('\u0166', '\u0167'),
+        ('\u0168', '\u0169'), ('\u016a', '\u016b'), ('\u016c', '\u016d'), ('\u016e', '\u016f'),
+        ('\u0170', '\u0171'), ('\u0172', '\u0173'), ('\u0174', '\u0175'), ('\u0176', '\u0177'),
+        ('\u0178', '\xff'), ('\u0179', '\u017a'), ('\u017b', '\u017c'), ('\u017d', '\u017e'),
+        ('\u0181', '\u0253'), ('\u0182', '\u0183'), ('\u0184', '\u0185'), ('\u0186', '\u0254'),
+        ('\u0187', '\u0188'), ('\u0189', '\u0256'), ('\u018a', '\u0257'), ('\u018b', '\u018c'),
+        ('\u018e', '\u01dd'), ('\u018f', '\u0259'), ('\u0190', '\u025b'), ('\u0191', '\u0192'),
+        ('\u0193', '\u0260'), ('\u0194', '\u0263'), ('\u0196', '\u0269'), ('\u0197', '\u0268'),
+        ('\u0198', '\u0199'), ('\u019c', '\u026f'), ('\u019d', '\u0272'), ('\u019f', '\u0275'),
+        ('\u01a0', '\u01a1'), ('\u01a2', '\u01a3'), ('\u01a4', '\u01a5'), ('\u01a6', '\u0280'),
+        ('\u01a7', '\u01a8'), ('\u01a9', '\u0283'), ('\u01ac', '\u01ad'), ('\u01ae', '\u0288'),
+        ('\u01af', '\u01b0'), ('\u01b1', '\u028a'), ('\u01b2', '\u028b'), ('\u01b3', '\u01b4'),
+        ('\u01b5', '\u01b6'), ('\u01b7', '\u0292'), ('\u01b8', '\u01b9'), ('\u01bc', '\u01bd'),
+        ('\u01c4', '\u01c6'), ('\u01c7', '\u01c9'), ('\u01ca', '\u01cc'), ('\u01cd', '\u01ce'),
+        ('\u01cf', '\u01d0'), ('\u01d1', '\u01d2'), ('\u01d3', '\u01d4'), ('\u01d5', '\u01d6'),
+        ('\u01d7', '\u01d8'), ('\u01d9', '\u01da'), ('\u01db', '\u01dc'), ('\u01de', '\u01df'),
+        ('\u01e0', '\u01e1'), ('\u01e2', '\u01e3'), ('\u01e4', '\u01e5'), ('\u01e6', '\u01e7'),
+        ('\u01e8', '\u01e9'), ('\u01ea', '\u01eb'), ('\u01ec', '\u01ed'), ('\u01ee', '\u01ef'),
+        ('\u01f1', '\u01f3'), ('\u01f4', '\u01f5'), ('\u01f6', '\u0195'), ('\u01f7', '\u01bf'),
+        ('\u01f8', '\u01f9'), ('\u01fa', '\u01fb'), ('\u01fc', '\u01fd'), ('\u01fe', '\u01ff'),
+        ('\u0200', '\u0201'), ('\u0202', '\u0203'), ('\u0204', '\u0205'), ('\u0206', '\u0207'),
+        ('\u0208', '\u0209'), ('\u020a', '\u020b'), ('\u020c', '\u020d'), ('\u020e', '\u020f'),
+        ('\u0210', '\u0211'), ('\u0212', '\u0213'), ('\u0214', '\u0215'), ('\u0216', '\u0217'),
+        ('\u0218', '\u0219'), ('\u021a', '\u021b'), ('\u021c', '\u021d'), ('\u021e', '\u021f'),
+        ('\u0220', '\u019e'), ('\u0222', '\u0223'), ('\u0224', '\u0225'), ('\u0226', '\u0227'),
+        ('\u0228', '\u0229'), ('\u022a', '\u022b'), ('\u022c', '\u022d'), ('\u022e', '\u022f'),
+        ('\u0230', '\u0231'), ('\u0232', '\u0233'), ('\u023a', '\u2c65'), ('\u023b', '\u023c'),
+        ('\u023d', '\u019a'), ('\u023e', '\u2c66'), ('\u0241', '\u0242'), ('\u0243', '\u0180'),
+        ('\u0244', '\u0289'), ('\u0245', '\u028c'), ('\u0246', '\u0247'), ('\u0248', '\u0249'),
+        ('\u024a', '\u024b'), ('\u024c', '\u024d'), ('\u024e', '\u024f'), ('\u0370', '\u0371'),
+        ('\u0372', '\u0373'), ('\u0376', '\u0377'), ('\u037f', '\u03f3'), ('\u0386', '\u03ac'),
+        ('\u0388', '\u03ad'), ('\u0389', '\u03ae'), ('\u038a', '\u03af'), ('\u038c', '\u03cc'),
+        ('\u038e', '\u03cd'), ('\u038f', '\u03ce'), ('\u0391', '\u03b1'), ('\u0392', '\u03b2'),
+        ('\u0393', '\u03b3'), ('\u0394', '\u03b4'), ('\u0395', '\u03b5'), ('\u0396', '\u03b6'),
+        ('\u0397', '\u03b7'), ('\u0398', '\u03b8'), ('\u0399', '\u03b9'), ('\u039a', '\u03ba'),
+        ('\u039b', '\u03bb'), ('\u039c', '\u03bc'), ('\u039d', '\u03bd'), ('\u039e', '\u03be'),
+        ('\u039f', '\u03bf'), ('\u03a0', '\u03c0'), ('\u03a1', '\u03c1'), ('\u03a3', '\u03c3'),
+        ('\u03a4', '\u03c4'), ('\u03a5', '\u03c5'), ('\u03a6', '\u03c6'), ('\u03a7', '\u03c7'),
+        ('\u03a8', '\u03c8'), ('\u03a9', '\u03c9'), ('\u03aa', '\u03ca'), ('\u03ab', '\u03cb'),
+        ('\u03cf', '\u03d7'), ('\u03d8', '\u03d9'), ('\u03da', '\u03db'), ('\u03dc', '\u03dd'),
+        ('\u03de', '\u03df'), ('\u03e0', '\u03e1'), ('\u03e2', '\u03e3'), ('\u03e4', '\u03e5'),
+        ('\u03e6', '\u03e7'), ('\u03e8', '\u03e9'), ('\u03ea', '\u03eb'), ('\u03ec', '\u03ed'),
+        ('\u03ee', '\u03ef'), ('\u03f4', '\u03b8'), ('\u03f7', '\u03f8'), ('\u03f9', '\u03f2'),
+        ('\u03fa', '\u03fb'), ('\u03fd', '\u037b'), ('\u03fe', '\u037c'), ('\u03ff', '\u037d'),
+        ('\u0400', '\u0450'), ('\u0401', '\u0451'), ('\u0402', '\u0452'), ('\u0403', '\u0453'),
+        ('\u0404', '\u0454'), ('\u0405', '\u0455'), ('\u0406', '\u0456'), ('\u0407', '\u0457'),
+        ('\u0408', '\u0458'), ('\u0409', '\u0459'), ('\u040a', '\u045a'), ('\u040b', '\u045b'),
+        ('\u040c', '\u045c'), ('\u040d', '\u045d'), ('\u040e', '\u045e'), ('\u040f', '\u045f'),
+        ('\u0410', '\u0430'), ('\u0411', '\u0431'), ('\u0412', '\u0432'), ('\u0413', '\u0433'),
+        ('\u0414', '\u0434'), ('\u0415', '\u0435'), ('\u0416', '\u0436'), ('\u0417', '\u0437'),
+        ('\u0418', '\u0438'), ('\u0419', '\u0439'), ('\u041a', '\u043a'), ('\u041b', '\u043b'),
+        ('\u041c', '\u043c'), ('\u041d', '\u043d'), ('\u041e', '\u043e'), ('\u041f', '\u043f'),
+        ('\u0420', '\u0440'), ('\u0421', '\u0441'), ('\u0422', '\u0442'), ('\u0423', '\u0443'),
+        ('\u0424', '\u0444'), ('\u0425', '\u0445'), ('\u0426', '\u0446'), ('\u0427', '\u0447'),
+        ('\u0428', '\u0448'), ('\u0429', '\u0449'), ('\u042a', '\u044a'), ('\u042b', '\u044b'),
+        ('\u042c', '\u044c'), ('\u042d', '\u044d'), ('\u042e', '\u044e'), ('\u042f', '\u044f'),
+        ('\u0460', '\u0461'), ('\u0462', '\u0463'), ('\u0464', '\u0465'), ('\u0466', '\u0467'),
+        ('\u0468', '\u0469'), ('\u046a', '\u046b'), ('\u046c', '\u046d'), ('\u046e', '\u046f'),
+        ('\u0470', '\u0471'), ('\u0472', '\u0473'), ('\u0474', '\u0475'), ('\u0476', '\u0477'),
+        ('\u0478', '\u0479'), ('\u047a', '\u047b'), ('\u047c', '\u047d'), ('\u047e', '\u047f'),
+        ('\u0480', '\u0481'), ('\u048a', '\u048b'), ('\u048c', '\u048d'), ('\u048e', '\u048f'),
+        ('\u0490', '\u0491'), ('\u0492', '\u0493'), ('\u0494', '\u0495'), ('\u0496', '\u0497'),
+        ('\u0498', '\u0499'), ('\u049a', '\u049b'), ('\u049c', '\u049d'), ('\u049e', '\u049f'),
+        ('\u04a0', '\u04a1'), ('\u04a2', '\u04a3'), ('\u04a4', '\u04a5'), ('\u04a6', '\u04a7'),
+        ('\u04a8', '\u04a9'), ('\u04aa', '\u04ab'), ('\u04ac', '\u04ad'), ('\u04ae', '\u04af'),
+        ('\u04b0', '\u04b1'), ('\u04b2', '\u04b3'), ('\u04b4', '\u04b5'), ('\u04b6', '\u04b7'),
+        ('\u04b8', '\u04b9'), ('\u04ba', '\u04bb'), ('\u04bc', '\u04bd'), ('\u04be', '\u04bf'),
+        ('\u04c0', '\u04cf'), ('\u04c1', '\u04c2'), ('\u04c3', '\u04c4'), ('\u04c5', '\u04c6'),
+        ('\u04c7', '\u04c8'), ('\u04c9', '\u04ca'), ('\u04cb', '\u04cc'), ('\u04cd', '\u04ce'),
+        ('\u04d0', '\u04d1'), ('\u04d2', '\u04d3'), ('\u04d4', '\u04d5'), ('\u04d6', '\u04d7'),
+        ('\u04d8', '\u04d9'), ('\u04da', '\u04db'), ('\u04dc', '\u04dd'), ('\u04de', '\u04df'),
+        ('\u04e0', '\u04e1'), ('\u04e2', '\u04e3'), ('\u04e4', '\u04e5'), ('\u04e6', '\u04e7'),
+        ('\u04e8', '\u04e9'), ('\u04ea', '\u04eb'), ('\u04ec', '\u04ed'), ('\u04ee', '\u04ef'),
+        ('\u04f0', '\u04f1'), ('\u04f2', '\u04f3'), ('\u04f4', '\u04f5'), ('\u04f6', '\u04f7'),
+        ('\u04f8', '\u04f9'), ('\u04fa', '\u04fb'), ('\u04fc', '\u04fd'), ('\u04fe', '\u04ff'),
+        ('\u0500', '\u0501'), ('\u0502', '\u0503'), ('\u0504', '\u0505'), ('\u0506', '\u0507'),
+        ('\u0508', '\u0509'), ('\u050a', '\u050b'), ('\u050c', '\u050d'), ('\u050e', '\u050f'),
+        ('\u0510', '\u0511'), ('\u0512', '\u0513'), ('\u0514', '\u0515'), ('\u0516', '\u0517'),
+        ('\u0518', '\u0519'), ('\u051a', '\u051b'), ('\u051c', '\u051d'), ('\u051e', '\u051f'),
+        ('\u0520', '\u0521'), ('\u0522', '\u0523'), ('\u0524', '\u0525'), ('\u0526', '\u0527'),
+        ('\u0528', '\u0529'), ('\u052a', '\u052b'), ('\u052c', '\u052d'), ('\u052e', '\u052f'),
+        ('\u0531', '\u0561'), ('\u0532', '\u0562'), ('\u0533', '\u0563'), ('\u0534', '\u0564'),
+        ('\u0535', '\u0565'), ('\u0536', '\u0566'), ('\u0537', '\u0567'), ('\u0538', '\u0568'),
+        ('\u0539', '\u0569'), ('\u053a', '\u056a'), ('\u053b', '\u056b'), ('\u053c', '\u056c'),
+        ('\u053d', '\u056d'), ('\u053e', '\u056e'), ('\u053f', '\u056f'), ('\u0540', '\u0570'),
+        ('\u0541', '\u0571'), ('\u0542', '\u0572'), ('\u0543', '\u0573'), ('\u0544', '\u0574'),
+        ('\u0545', '\u0575'), ('\u0546', '\u0576'), ('\u0547', '\u0577'), ('\u0548', '\u0578'),
+        ('\u0549', '\u0579'), ('\u054a', '\u057a'), ('\u054b', '\u057b'), ('\u054c', '\u057c'),
+        ('\u054d', '\u057d'), ('\u054e', '\u057e'), ('\u054f', '\u057f'), ('\u0550', '\u0580'),
+        ('\u0551', '\u0581'), ('\u0552', '\u0582'), ('\u0553', '\u0583'), ('\u0554', '\u0584'),
+        ('\u0555', '\u0585'), ('\u0556', '\u0586'), ('\u10a0', '\u2d00'), ('\u10a1', '\u2d01'),
+        ('\u10a2', '\u2d02'), ('\u10a3', '\u2d03'), ('\u10a4', '\u2d04'), ('\u10a5', '\u2d05'),
+        ('\u10a6', '\u2d06'), ('\u10a7', '\u2d07'), ('\u10a8', '\u2d08'), ('\u10a9', '\u2d09'),
+        ('\u10aa', '\u2d0a'), ('\u10ab', '\u2d0b'), ('\u10ac', '\u2d0c'), ('\u10ad', '\u2d0d'),
+        ('\u10ae', '\u2d0e'), ('\u10af', '\u2d0f'), ('\u10b0', '\u2d10'), ('\u10b1', '\u2d11'),
+        ('\u10b2', '\u2d12'), ('\u10b3', '\u2d13'), ('\u10b4', '\u2d14'), ('\u10b5', '\u2d15'),
+        ('\u10b6', '\u2d16'), ('\u10b7', '\u2d17'), ('\u10b8', '\u2d18'), ('\u10b9', '\u2d19'),
+        ('\u10ba', '\u2d1a'), ('\u10bb', '\u2d1b'), ('\u10bc', '\u2d1c'), ('\u10bd', '\u2d1d'),
+        ('\u10be', '\u2d1e'), ('\u10bf', '\u2d1f'), ('\u10c0', '\u2d20'), ('\u10c1', '\u2d21'),
+        ('\u10c2', '\u2d22'), ('\u10c3', '\u2d23'), ('\u10c4', '\u2d24'), ('\u10c5', '\u2d25'),
+        ('\u10c7', '\u2d27'), ('\u10cd', '\u2d2d'), ('\u1e00', '\u1e01'), ('\u1e02', '\u1e03'),
+        ('\u1e04', '\u1e05'), ('\u1e06', '\u1e07'), ('\u1e08', '\u1e09'), ('\u1e0a', '\u1e0b'),
+        ('\u1e0c', '\u1e0d'), ('\u1e0e', '\u1e0f'), ('\u1e10', '\u1e11'), ('\u1e12', '\u1e13'),
+        ('\u1e14', '\u1e15'), ('\u1e16', '\u1e17'), ('\u1e18', '\u1e19'), ('\u1e1a', '\u1e1b'),
+        ('\u1e1c', '\u1e1d'), ('\u1e1e', '\u1e1f'), ('\u1e20', '\u1e21'), ('\u1e22', '\u1e23'),
+        ('\u1e24', '\u1e25'), ('\u1e26', '\u1e27'), ('\u1e28', '\u1e29'), ('\u1e2a', '\u1e2b'),
+        ('\u1e2c', '\u1e2d'), ('\u1e2e', '\u1e2f'), ('\u1e30', '\u1e31'), ('\u1e32', '\u1e33'),
+        ('\u1e34', '\u1e35'), ('\u1e36', '\u1e37'), ('\u1e38', '\u1e39'), ('\u1e3a', '\u1e3b'),
+        ('\u1e3c', '\u1e3d'), ('\u1e3e', '\u1e3f'), ('\u1e40', '\u1e41'), ('\u1e42', '\u1e43'),
+        ('\u1e44', '\u1e45'), ('\u1e46', '\u1e47'), ('\u1e48', '\u1e49'), ('\u1e4a', '\u1e4b'),
+        ('\u1e4c', '\u1e4d'), ('\u1e4e', '\u1e4f'), ('\u1e50', '\u1e51'), ('\u1e52', '\u1e53'),
+        ('\u1e54', '\u1e55'), ('\u1e56', '\u1e57'), ('\u1e58', '\u1e59'), ('\u1e5a', '\u1e5b'),
+        ('\u1e5c', '\u1e5d'), ('\u1e5e', '\u1e5f'), ('\u1e60', '\u1e61'), ('\u1e62', '\u1e63'),
+        ('\u1e64', '\u1e65'), ('\u1e66', '\u1e67'), ('\u1e68', '\u1e69'), ('\u1e6a', '\u1e6b'),
+        ('\u1e6c', '\u1e6d'), ('\u1e6e', '\u1e6f'), ('\u1e70', '\u1e71'), ('\u1e72', '\u1e73'),
+        ('\u1e74', '\u1e75'), ('\u1e76', '\u1e77'), ('\u1e78', '\u1e79'), ('\u1e7a', '\u1e7b'),
+        ('\u1e7c', '\u1e7d'), ('\u1e7e', '\u1e7f'), ('\u1e80', '\u1e81'), ('\u1e82', '\u1e83'),
+        ('\u1e84', '\u1e85'), ('\u1e86', '\u1e87'), ('\u1e88', '\u1e89'), ('\u1e8a', '\u1e8b'),
+        ('\u1e8c', '\u1e8d'), ('\u1e8e', '\u1e8f'), ('\u1e90', '\u1e91'), ('\u1e92', '\u1e93'),
+        ('\u1e94', '\u1e95'), ('\u1e9e', '\xdf'), ('\u1ea0', '\u1ea1'), ('\u1ea2', '\u1ea3'),
+        ('\u1ea4', '\u1ea5'), ('\u1ea6', '\u1ea7'), ('\u1ea8', '\u1ea9'), ('\u1eaa', '\u1eab'),
+        ('\u1eac', '\u1ead'), ('\u1eae', '\u1eaf'), ('\u1eb0', '\u1eb1'), ('\u1eb2', '\u1eb3'),
+        ('\u1eb4', '\u1eb5'), ('\u1eb6', '\u1eb7'), ('\u1eb8', '\u1eb9'), ('\u1eba', '\u1ebb'),
+        ('\u1ebc', '\u1ebd'), ('\u1ebe', '\u1ebf'), ('\u1ec0', '\u1ec1'), ('\u1ec2', '\u1ec3'),
+        ('\u1ec4', '\u1ec5'), ('\u1ec6', '\u1ec7'), ('\u1ec8', '\u1ec9'), ('\u1eca', '\u1ecb'),
+        ('\u1ecc', '\u1ecd'), ('\u1ece', '\u1ecf'), ('\u1ed0', '\u1ed1'), ('\u1ed2', '\u1ed3'),
+        ('\u1ed4', '\u1ed5'), ('\u1ed6', '\u1ed7'), ('\u1ed8', '\u1ed9'), ('\u1eda', '\u1edb'),
+        ('\u1edc', '\u1edd'), ('\u1ede', '\u1edf'), ('\u1ee0', '\u1ee1'), ('\u1ee2', '\u1ee3'),
+        ('\u1ee4', '\u1ee5'), ('\u1ee6', '\u1ee7'), ('\u1ee8', '\u1ee9'), ('\u1eea', '\u1eeb'),
+        ('\u1eec', '\u1eed'), ('\u1eee', '\u1eef'), ('\u1ef0', '\u1ef1'), ('\u1ef2', '\u1ef3'),
+        ('\u1ef4', '\u1ef5'), ('\u1ef6', '\u1ef7'), ('\u1ef8', '\u1ef9'), ('\u1efa', '\u1efb'),
+        ('\u1efc', '\u1efd'), ('\u1efe', '\u1eff'), ('\u1f08', '\u1f00'), ('\u1f09', '\u1f01'),
+        ('\u1f0a', '\u1f02'), ('\u1f0b', '\u1f03'), ('\u1f0c', '\u1f04'), ('\u1f0d', '\u1f05'),
+        ('\u1f0e', '\u1f06'), ('\u1f0f', '\u1f07'), ('\u1f18', '\u1f10'), ('\u1f19', '\u1f11'),
+        ('\u1f1a', '\u1f12'), ('\u1f1b', '\u1f13'), ('\u1f1c', '\u1f14'), ('\u1f1d', '\u1f15'),
+        ('\u1f28', '\u1f20'), ('\u1f29', '\u1f21'), ('\u1f2a', '\u1f22'), ('\u1f2b', '\u1f23'),
+        ('\u1f2c', '\u1f24'), ('\u1f2d', '\u1f25'), ('\u1f2e', '\u1f26'), ('\u1f2f', '\u1f27'),
+        ('\u1f38', '\u1f30'), ('\u1f39', '\u1f31'), ('\u1f3a', '\u1f32'), ('\u1f3b', '\u1f33'),
+        ('\u1f3c', '\u1f34'), ('\u1f3d', '\u1f35'), ('\u1f3e', '\u1f36'), ('\u1f3f', '\u1f37'),
+        ('\u1f48', '\u1f40'), ('\u1f49', '\u1f41'), ('\u1f4a', '\u1f42'), ('\u1f4b', '\u1f43'),
+        ('\u1f4c', '\u1f44'), ('\u1f4d', '\u1f45'), ('\u1f59', '\u1f51'), ('\u1f5b', '\u1f53'),
+        ('\u1f5d', '\u1f55'), ('\u1f5f', '\u1f57'), ('\u1f68', '\u1f60'), ('\u1f69', '\u1f61'),
+        ('\u1f6a', '\u1f62'), ('\u1f6b', '\u1f63'), ('\u1f6c', '\u1f64'), ('\u1f6d', '\u1f65'),
+        ('\u1f6e', '\u1f66'), ('\u1f6f', '\u1f67'), ('\u1fb8', '\u1fb0'), ('\u1fb9', '\u1fb1'),
+        ('\u1fba', '\u1f70'), ('\u1fbb', '\u1f71'), ('\u1fc8', '\u1f72'), ('\u1fc9', '\u1f73'),
+        ('\u1fca', '\u1f74'), ('\u1fcb', '\u1f75'), ('\u1fd8', '\u1fd0'), ('\u1fd9', '\u1fd1'),
+        ('\u1fda', '\u1f76'), ('\u1fdb', '\u1f77'), ('\u1fe8', '\u1fe0'), ('\u1fe9', '\u1fe1'),
+        ('\u1fea', '\u1f7a'), ('\u1feb', '\u1f7b'), ('\u1fec', '\u1fe5'), ('\u1ff8', '\u1f78'),
+        ('\u1ff9', '\u1f79'), ('\u1ffa', '\u1f7c'), ('\u1ffb', '\u1f7d'), ('\u2126', '\u03c9'),
+        ('\u212a', '\x6b'), ('\u212b', '\xe5'), ('\u2132', '\u214e'), ('\u2183', '\u2184'),
+        ('\u2c00', '\u2c30'), ('\u2c01', '\u2c31'), ('\u2c02', '\u2c32'), ('\u2c03', '\u2c33'),
+        ('\u2c04', '\u2c34'), ('\u2c05', '\u2c35'), ('\u2c06', '\u2c36'), ('\u2c07', '\u2c37'),
+        ('\u2c08', '\u2c38'), ('\u2c09', '\u2c39'), ('\u2c0a', '\u2c3a'), ('\u2c0b', '\u2c3b'),
+        ('\u2c0c', '\u2c3c'), ('\u2c0d', '\u2c3d'), ('\u2c0e', '\u2c3e'), ('\u2c0f', '\u2c3f'),
+        ('\u2c10', '\u2c40'), ('\u2c11', '\u2c41'), ('\u2c12', '\u2c42'), ('\u2c13', '\u2c43'),
+        ('\u2c14', '\u2c44'), ('\u2c15', '\u2c45'), ('\u2c16', '\u2c46'), ('\u2c17', '\u2c47'),
+        ('\u2c18', '\u2c48'), ('\u2c19', '\u2c49'), ('\u2c1a', '\u2c4a'), ('\u2c1b', '\u2c4b'),
+        ('\u2c1c', '\u2c4c'), ('\u2c1d', '\u2c4d'), ('\u2c1e', '\u2c4e'), ('\u2c1f', '\u2c4f'),
+        ('\u2c20', '\u2c50'), ('\u2c21', '\u2c51'), ('\u2c22', '\u2c52'), ('\u2c23', '\u2c53'),
+        ('\u2c24', '\u2c54'), ('\u2c25', '\u2c55'), ('\u2c26', '\u2c56'), ('\u2c27', '\u2c57'),
+        ('\u2c28', '\u2c58'), ('\u2c29', '\u2c59'), ('\u2c2a', '\u2c5a'), ('\u2c2b', '\u2c5b'),
+        ('\u2c2c', '\u2c5c'), ('\u2c2d', '\u2c5d'), ('\u2c2e', '\u2c5e'), ('\u2c60', '\u2c61'),
+        ('\u2c62', '\u026b'), ('\u2c63', '\u1d7d'), ('\u2c64', '\u027d'), ('\u2c67', '\u2c68'),
+        ('\u2c69', '\u2c6a'), ('\u2c6b', '\u2c6c'), ('\u2c6d', '\u0251'), ('\u2c6e', '\u0271'),
+        ('\u2c6f', '\u0250'), ('\u2c70', '\u0252'), ('\u2c72', '\u2c73'), ('\u2c75', '\u2c76'),
+        ('\u2c7e', '\u023f'), ('\u2c7f', '\u0240'), ('\u2c80', '\u2c81'), ('\u2c82', '\u2c83'),
+        ('\u2c84', '\u2c85'), ('\u2c86', '\u2c87'), ('\u2c88', '\u2c89'), ('\u2c8a', '\u2c8b'),
+        ('\u2c8c', '\u2c8d'), ('\u2c8e', '\u2c8f'), ('\u2c90', '\u2c91'), ('\u2c92', '\u2c93'),
+        ('\u2c94', '\u2c95'), ('\u2c96', '\u2c97'), ('\u2c98', '\u2c99'), ('\u2c9a', '\u2c9b'),
+        ('\u2c9c', '\u2c9d'), ('\u2c9e', '\u2c9f'), ('\u2ca0', '\u2ca1'), ('\u2ca2', '\u2ca3'),
+        ('\u2ca4', '\u2ca5'), ('\u2ca6', '\u2ca7'), ('\u2ca8', '\u2ca9'), ('\u2caa', '\u2cab'),
+        ('\u2cac', '\u2cad'), ('\u2cae', '\u2caf'), ('\u2cb0', '\u2cb1'), ('\u2cb2', '\u2cb3'),
+        ('\u2cb4', '\u2cb5'), ('\u2cb6', '\u2cb7'), ('\u2cb8', '\u2cb9'), ('\u2cba', '\u2cbb'),
+        ('\u2cbc', '\u2cbd'), ('\u2cbe', '\u2cbf'), ('\u2cc0', '\u2cc1'), ('\u2cc2', '\u2cc3'),
+        ('\u2cc4', '\u2cc5'), ('\u2cc6', '\u2cc7'), ('\u2cc8', '\u2cc9'), ('\u2cca', '\u2ccb'),
+        ('\u2ccc', '\u2ccd'), ('\u2cce', '\u2ccf'), ('\u2cd0', '\u2cd1'), ('\u2cd2', '\u2cd3'),
+        ('\u2cd4', '\u2cd5'), ('\u2cd6', '\u2cd7'), ('\u2cd8', '\u2cd9'), ('\u2cda', '\u2cdb'),
+        ('\u2cdc', '\u2cdd'), ('\u2cde', '\u2cdf'), ('\u2ce0', '\u2ce1'), ('\u2ce2', '\u2ce3'),
+        ('\u2ceb', '\u2cec'), ('\u2ced', '\u2cee'), ('\u2cf2', '\u2cf3'), ('\ua640', '\ua641'),
+        ('\ua642', '\ua643'), ('\ua644', '\ua645'), ('\ua646', '\ua647'), ('\ua648', '\ua649'),
+        ('\ua64a', '\ua64b'), ('\ua64c', '\ua64d'), ('\ua64e', '\ua64f'), ('\ua650', '\ua651'),
+        ('\ua652', '\ua653'), ('\ua654', '\ua655'), ('\ua656', '\ua657'), ('\ua658', '\ua659'),
+        ('\ua65a', '\ua65b'), ('\ua65c', '\ua65d'), ('\ua65e', '\ua65f'), ('\ua660', '\ua661'),
+        ('\ua662', '\ua663'), ('\ua664', '\ua665'), ('\ua666', '\ua667'), ('\ua668', '\ua669'),
+        ('\ua66a', '\ua66b'), ('\ua66c', '\ua66d'), ('\ua680', '\ua681'), ('\ua682', '\ua683'),
+        ('\ua684', '\ua685'), ('\ua686', '\ua687'), ('\ua688', '\ua689'), ('\ua68a', '\ua68b'),
+        ('\ua68c', '\ua68d'), ('\ua68e', '\ua68f'), ('\ua690', '\ua691'), ('\ua692', '\ua693'),
+        ('\ua694', '\ua695'), ('\ua696', '\ua697'), ('\ua698', '\ua699'), ('\ua69a', '\ua69b'),
+        ('\ua722', '\ua723'), ('\ua724', '\ua725'), ('\ua726', '\ua727'), ('\ua728', '\ua729'),
+        ('\ua72a', '\ua72b'), ('\ua72c', '\ua72d'), ('\ua72e', '\ua72f'), ('\ua732', '\ua733'),
+        ('\ua734', '\ua735'), ('\ua736', '\ua737'), ('\ua738', '\ua739'), ('\ua73a', '\ua73b'),
+        ('\ua73c', '\ua73d'), ('\ua73e', '\ua73f'), ('\ua740', '\ua741'), ('\ua742', '\ua743'),
+        ('\ua744', '\ua745'), ('\ua746', '\ua747'), ('\ua748', '\ua749'), ('\ua74a', '\ua74b'),
+        ('\ua74c', '\ua74d'), ('\ua74e', '\ua74f'), ('\ua750', '\ua751'), ('\ua752', '\ua753'),
+        ('\ua754', '\ua755'), ('\ua756', '\ua757'), ('\ua758', '\ua759'), ('\ua75a', '\ua75b'),
+        ('\ua75c', '\ua75d'), ('\ua75e', '\ua75f'), ('\ua760', '\ua761'), ('\ua762', '\ua763'),
+        ('\ua764', '\ua765'), ('\ua766', '\ua767'), ('\ua768', '\ua769'), ('\ua76a', '\ua76b'),
+        ('\ua76c', '\ua76d'), ('\ua76e', '\ua76f'), ('\ua779', '\ua77a'), ('\ua77b', '\ua77c'),
+        ('\ua77d', '\u1d79'), ('\ua77e', '\ua77f'), ('\ua780', '\ua781'), ('\ua782', '\ua783'),
+        ('\ua784', '\ua785'), ('\ua786', '\ua787'), ('\ua78b', '\ua78c'), ('\ua78d', '\u0265'),
+        ('\ua790', '\ua791'), ('\ua792', '\ua793'), ('\ua796', '\ua797'), ('\ua798', '\ua799'),
+        ('\ua79a', '\ua79b'), ('\ua79c', '\ua79d'), ('\ua79e', '\ua79f'), ('\ua7a0', '\ua7a1'),
+        ('\ua7a2', '\ua7a3'), ('\ua7a4', '\ua7a5'), ('\ua7a6', '\ua7a7'), ('\ua7a8', '\ua7a9'),
+        ('\ua7aa', '\u0266'), ('\ua7ab', '\u025c'), ('\ua7ac', '\u0261'), ('\ua7ad', '\u026c'),
+        ('\ua7b0', '\u029e'), ('\ua7b1', '\u0287'), ('\uff21', '\uff41'), ('\uff22', '\uff42'),
+        ('\uff23', '\uff43'), ('\uff24', '\uff44'), ('\uff25', '\uff45'), ('\uff26', '\uff46'),
+        ('\uff27', '\uff47'), ('\uff28', '\uff48'), ('\uff29', '\uff49'), ('\uff2a', '\uff4a'),
+        ('\uff2b', '\uff4b'), ('\uff2c', '\uff4c'), ('\uff2d', '\uff4d'), ('\uff2e', '\uff4e'),
+        ('\uff2f', '\uff4f'), ('\uff30', '\uff50'), ('\uff31', '\uff51'), ('\uff32', '\uff52'),
+        ('\uff33', '\uff53'), ('\uff34', '\uff54'), ('\uff35', '\uff55'), ('\uff36', '\uff56'),
+        ('\uff37', '\uff57'), ('\uff38', '\uff58'), ('\uff39', '\uff59'), ('\uff3a', '\uff5a'),
+        ('\U00010400', '\U00010428'), ('\U00010401', '\U00010429'), ('\U00010402', '\U0001042a'),
+        ('\U00010403', '\U0001042b'), ('\U00010404', '\U0001042c'), ('\U00010405', '\U0001042d'),
+        ('\U00010406', '\U0001042e'), ('\U00010407', '\U0001042f'), ('\U00010408', '\U00010430'),
+        ('\U00010409', '\U00010431'), ('\U0001040a', '\U00010432'), ('\U0001040b', '\U00010433'),
+        ('\U0001040c', '\U00010434'), ('\U0001040d', '\U00010435'), ('\U0001040e', '\U00010436'),
+        ('\U0001040f', '\U00010437'), ('\U00010410', '\U00010438'), ('\U00010411', '\U00010439'),
+        ('\U00010412', '\U0001043a'), ('\U00010413', '\U0001043b'), ('\U00010414', '\U0001043c'),
+        ('\U00010415', '\U0001043d'), ('\U00010416', '\U0001043e'), ('\U00010417', '\U0001043f'),
+        ('\U00010418', '\U00010440'), ('\U00010419', '\U00010441'), ('\U0001041a', '\U00010442'),
+        ('\U0001041b', '\U00010443'), ('\U0001041c', '\U00010444'), ('\U0001041d', '\U00010445'),
+        ('\U0001041e', '\U00010446'), ('\U0001041f', '\U00010447'), ('\U00010420', '\U00010448'),
+        ('\U00010421', '\U00010449'), ('\U00010422', '\U0001044a'), ('\U00010423', '\U0001044b'),
+        ('\U00010424', '\U0001044c'), ('\U00010425', '\U0001044d'), ('\U00010426', '\U0001044e'),
+        ('\U00010427', '\U0001044f'), ('\U000118a0', '\U000118c0'), ('\U000118a1', '\U000118c1'),
+        ('\U000118a2', '\U000118c2'), ('\U000118a3', '\U000118c3'), ('\U000118a4', '\U000118c4'),
+        ('\U000118a5', '\U000118c5'), ('\U000118a6', '\U000118c6'), ('\U000118a7', '\U000118c7'),
+        ('\U000118a8', '\U000118c8'), ('\U000118a9', '\U000118c9'), ('\U000118aa', '\U000118ca'),
+        ('\U000118ab', '\U000118cb'), ('\U000118ac', '\U000118cc'), ('\U000118ad', '\U000118cd'),
+        ('\U000118ae', '\U000118ce'), ('\U000118af', '\U000118cf'), ('\U000118b0', '\U000118d0'),
+        ('\U000118b1', '\U000118d1'), ('\U000118b2', '\U000118d2'), ('\U000118b3', '\U000118d3'),
+        ('\U000118b4', '\U000118d4'), ('\U000118b5', '\U000118d5'), ('\U000118b6', '\U000118d6'),
+        ('\U000118b7', '\U000118d7'), ('\U000118b8', '\U000118d8'), ('\U000118b9', '\U000118d9'),
+        ('\U000118ba', '\U000118da'), ('\U000118bb', '\U000118db'), ('\U000118bc', '\U000118dc'),
+        ('\U000118bd', '\U000118dd'), ('\U000118be', '\U000118de'), ('\U000118bf', '\U000118df')
+    ];
+
+    static LlLu_table: &'static [(char, char)] = &[
+        ('\x61', '\x41'), ('\x62', '\x42'), ('\x63', '\x43'), ('\x64', '\x44'), ('\x65', '\x45'),
+        ('\x66', '\x46'), ('\x67', '\x47'), ('\x68', '\x48'), ('\x69', '\x49'), ('\x6a', '\x4a'),
+        ('\x6b', '\x4b'), ('\x6c', '\x4c'), ('\x6d', '\x4d'), ('\x6e', '\x4e'), ('\x6f', '\x4f'),
+        ('\x70', '\x50'), ('\x71', '\x51'), ('\x72', '\x52'), ('\x73', '\x53'), ('\x74', '\x54'),
+        ('\x75', '\x55'), ('\x76', '\x56'), ('\x77', '\x57'), ('\x78', '\x58'), ('\x79', '\x59'),
+        ('\x7a', '\x5a'), ('\xb5', '\u039c'), ('\xe0', '\xc0'), ('\xe1', '\xc1'), ('\xe2', '\xc2'),
+        ('\xe3', '\xc3'), ('\xe4', '\xc4'), ('\xe5', '\xc5'), ('\xe6', '\xc6'), ('\xe7', '\xc7'),
+        ('\xe8', '\xc8'), ('\xe9', '\xc9'), ('\xea', '\xca'), ('\xeb', '\xcb'), ('\xec', '\xcc'),
+        ('\xed', '\xcd'), ('\xee', '\xce'), ('\xef', '\xcf'), ('\xf0', '\xd0'), ('\xf1', '\xd1'),
+        ('\xf2', '\xd2'), ('\xf3', '\xd3'), ('\xf4', '\xd4'), ('\xf5', '\xd5'), ('\xf6', '\xd6'),
+        ('\xf8', '\xd8'), ('\xf9', '\xd9'), ('\xfa', '\xda'), ('\xfb', '\xdb'), ('\xfc', '\xdc'),
+        ('\xfd', '\xdd'), ('\xfe', '\xde'), ('\xff', '\u0178'), ('\u0101', '\u0100'), ('\u0103',
+        '\u0102'), ('\u0105', '\u0104'), ('\u0107', '\u0106'), ('\u0109', '\u0108'), ('\u010b',
+        '\u010a'), ('\u010d', '\u010c'), ('\u010f', '\u010e'), ('\u0111', '\u0110'), ('\u0113',
+        '\u0112'), ('\u0115', '\u0114'), ('\u0117', '\u0116'), ('\u0119', '\u0118'), ('\u011b',
+        '\u011a'), ('\u011d', '\u011c'), ('\u011f', '\u011e'), ('\u0121', '\u0120'), ('\u0123',
+        '\u0122'), ('\u0125', '\u0124'), ('\u0127', '\u0126'), ('\u0129', '\u0128'), ('\u012b',
+        '\u012a'), ('\u012d', '\u012c'), ('\u012f', '\u012e'), ('\u0131', '\x49'), ('\u0133',
+        '\u0132'), ('\u0135', '\u0134'), ('\u0137', '\u0136'), ('\u013a', '\u0139'), ('\u013c',
+        '\u013b'), ('\u013e', '\u013d'), ('\u0140', '\u013f'), ('\u0142', '\u0141'), ('\u0144',
+        '\u0143'), ('\u0146', '\u0145'), ('\u0148', '\u0147'), ('\u014b', '\u014a'), ('\u014d',
+        '\u014c'), ('\u014f', '\u014e'), ('\u0151', '\u0150'), ('\u0153', '\u0152'), ('\u0155',
+        '\u0154'), ('\u0157', '\u0156'), ('\u0159', '\u0158'), ('\u015b', '\u015a'), ('\u015d',
+        '\u015c'), ('\u015f', '\u015e'), ('\u0161', '\u0160'), ('\u0163', '\u0162'), ('\u0165',
+        '\u0164'), ('\u0167', '\u0166'), ('\u0169', '\u0168'), ('\u016b', '\u016a'), ('\u016d',
+        '\u016c'), ('\u016f', '\u016e'), ('\u0171', '\u0170'), ('\u0173', '\u0172'), ('\u0175',
+        '\u0174'), ('\u0177', '\u0176'), ('\u017a', '\u0179'), ('\u017c', '\u017b'), ('\u017e',
+        '\u017d'), ('\u017f', '\x53'), ('\u0180', '\u0243'), ('\u0183', '\u0182'), ('\u0185',
+        '\u0184'), ('\u0188', '\u0187'), ('\u018c', '\u018b'), ('\u0192', '\u0191'), ('\u0195',
+        '\u01f6'), ('\u0199', '\u0198'), ('\u019a', '\u023d'), ('\u019e', '\u0220'), ('\u01a1',
+        '\u01a0'), ('\u01a3', '\u01a2'), ('\u01a5', '\u01a4'), ('\u01a8', '\u01a7'), ('\u01ad',
+        '\u01ac'), ('\u01b0', '\u01af'), ('\u01b4', '\u01b3'), ('\u01b6', '\u01b5'), ('\u01b9',
+        '\u01b8'), ('\u01bd', '\u01bc'), ('\u01bf', '\u01f7'), ('\u01c6', '\u01c4'), ('\u01c9',
+        '\u01c7'), ('\u01cc', '\u01ca'), ('\u01ce', '\u01cd'), ('\u01d0', '\u01cf'), ('\u01d2',
+        '\u01d1'), ('\u01d4', '\u01d3'), ('\u01d6', '\u01d5'), ('\u01d8', '\u01d7'), ('\u01da',
+        '\u01d9'), ('\u01dc', '\u01db'), ('\u01dd', '\u018e'), ('\u01df', '\u01de'), ('\u01e1',
+        '\u01e0'), ('\u01e3', '\u01e2'), ('\u01e5', '\u01e4'), ('\u01e7', '\u01e6'), ('\u01e9',
+        '\u01e8'), ('\u01eb', '\u01ea'), ('\u01ed', '\u01ec'), ('\u01ef', '\u01ee'), ('\u01f3',
+        '\u01f1'), ('\u01f5', '\u01f4'), ('\u01f9', '\u01f8'), ('\u01fb', '\u01fa'), ('\u01fd',
+        '\u01fc'), ('\u01ff', '\u01fe'), ('\u0201', '\u0200'), ('\u0203', '\u0202'), ('\u0205',
+        '\u0204'), ('\u0207', '\u0206'), ('\u0209', '\u0208'), ('\u020b', '\u020a'), ('\u020d',
+        '\u020c'), ('\u020f', '\u020e'), ('\u0211', '\u0210'), ('\u0213', '\u0212'), ('\u0215',
+        '\u0214'), ('\u0217', '\u0216'), ('\u0219', '\u0218'), ('\u021b', '\u021a'), ('\u021d',
+        '\u021c'), ('\u021f', '\u021e'), ('\u0223', '\u0222'), ('\u0225', '\u0224'), ('\u0227',
+        '\u0226'), ('\u0229', '\u0228'), ('\u022b', '\u022a'), ('\u022d', '\u022c'), ('\u022f',
+        '\u022e'), ('\u0231', '\u0230'), ('\u0233', '\u0232'), ('\u023c', '\u023b'), ('\u023f',
+        '\u2c7e'), ('\u0240', '\u2c7f'), ('\u0242', '\u0241'), ('\u0247', '\u0246'), ('\u0249',
+        '\u0248'), ('\u024b', '\u024a'), ('\u024d', '\u024c'), ('\u024f', '\u024e'), ('\u0250',
+        '\u2c6f'), ('\u0251', '\u2c6d'), ('\u0252', '\u2c70'), ('\u0253', '\u0181'), ('\u0254',
+        '\u0186'), ('\u0256', '\u0189'), ('\u0257', '\u018a'), ('\u0259', '\u018f'), ('\u025b',
+        '\u0190'), ('\u025c', '\ua7ab'), ('\u0260', '\u0193'), ('\u0261', '\ua7ac'), ('\u0263',
+        '\u0194'), ('\u0265', '\ua78d'), ('\u0266', '\ua7aa'), ('\u0268', '\u0197'), ('\u0269',
+        '\u0196'), ('\u026b', '\u2c62'), ('\u026c', '\ua7ad'), ('\u026f', '\u019c'), ('\u0271',
+        '\u2c6e'), ('\u0272', '\u019d'), ('\u0275', '\u019f'), ('\u027d', '\u2c64'), ('\u0280',
+        '\u01a6'), ('\u0283', '\u01a9'), ('\u0287', '\ua7b1'), ('\u0288', '\u01ae'), ('\u0289',
+        '\u0244'), ('\u028a', '\u01b1'), ('\u028b', '\u01b2'), ('\u028c', '\u0245'), ('\u0292',
+        '\u01b7'), ('\u029e', '\ua7b0'), ('\u0371', '\u0370'), ('\u0373', '\u0372'), ('\u0377',
+        '\u0376'), ('\u037b', '\u03fd'), ('\u037c', '\u03fe'), ('\u037d', '\u03ff'), ('\u03ac',
+        '\u0386'), ('\u03ad', '\u0388'), ('\u03ae', '\u0389'), ('\u03af', '\u038a'), ('\u03b1',
+        '\u0391'), ('\u03b2', '\u0392'), ('\u03b3', '\u0393'), ('\u03b4', '\u0394'), ('\u03b5',
+        '\u0395'), ('\u03b6', '\u0396'), ('\u03b7', '\u0397'), ('\u03b8', '\u0398'), ('\u03b9',
+        '\u0399'), ('\u03ba', '\u039a'), ('\u03bb', '\u039b'), ('\u03bc', '\u039c'), ('\u03bd',
+        '\u039d'), ('\u03be', '\u039e'), ('\u03bf', '\u039f'), ('\u03c0', '\u03a0'), ('\u03c1',
+        '\u03a1'), ('\u03c2', '\u03a3'), ('\u03c3', '\u03a3'), ('\u03c4', '\u03a4'), ('\u03c5',
+        '\u03a5'), ('\u03c6', '\u03a6'), ('\u03c7', '\u03a7'), ('\u03c8', '\u03a8'), ('\u03c9',
+        '\u03a9'), ('\u03ca', '\u03aa'), ('\u03cb', '\u03ab'), ('\u03cc', '\u038c'), ('\u03cd',
+        '\u038e'), ('\u03ce', '\u038f'), ('\u03d0', '\u0392'), ('\u03d1', '\u0398'), ('\u03d5',
+        '\u03a6'), ('\u03d6', '\u03a0'), ('\u03d7', '\u03cf'), ('\u03d9', '\u03d8'), ('\u03db',
+        '\u03da'), ('\u03dd', '\u03dc'), ('\u03df', '\u03de'), ('\u03e1', '\u03e0'), ('\u03e3',
+        '\u03e2'), ('\u03e5', '\u03e4'), ('\u03e7', '\u03e6'), ('\u03e9', '\u03e8'), ('\u03eb',
+        '\u03ea'), ('\u03ed', '\u03ec'), ('\u03ef', '\u03ee'), ('\u03f0', '\u039a'), ('\u03f1',
+        '\u03a1'), ('\u03f2', '\u03f9'), ('\u03f3', '\u037f'), ('\u03f5', '\u0395'), ('\u03f8',
+        '\u03f7'), ('\u03fb', '\u03fa'), ('\u0430', '\u0410'), ('\u0431', '\u0411'), ('\u0432',
+        '\u0412'), ('\u0433', '\u0413'), ('\u0434', '\u0414'), ('\u0435', '\u0415'), ('\u0436',
+        '\u0416'), ('\u0437', '\u0417'), ('\u0438', '\u0418'), ('\u0439', '\u0419'), ('\u043a',
+        '\u041a'), ('\u043b', '\u041b'), ('\u043c', '\u041c'), ('\u043d', '\u041d'), ('\u043e',
+        '\u041e'), ('\u043f', '\u041f'), ('\u0440', '\u0420'), ('\u0441', '\u0421'), ('\u0442',
+        '\u0422'), ('\u0443', '\u0423'), ('\u0444', '\u0424'), ('\u0445', '\u0425'), ('\u0446',
+        '\u0426'), ('\u0447', '\u0427'), ('\u0448', '\u0428'), ('\u0449', '\u0429'), ('\u044a',
+        '\u042a'), ('\u044b', '\u042b'), ('\u044c', '\u042c'), ('\u044d', '\u042d'), ('\u044e',
+        '\u042e'), ('\u044f', '\u042f'), ('\u0450', '\u0400'), ('\u0451', '\u0401'), ('\u0452',
+        '\u0402'), ('\u0453', '\u0403'), ('\u0454', '\u0404'), ('\u0455', '\u0405'), ('\u0456',
+        '\u0406'), ('\u0457', '\u0407'), ('\u0458', '\u0408'), ('\u0459', '\u0409'), ('\u045a',
+        '\u040a'), ('\u045b', '\u040b'), ('\u045c', '\u040c'), ('\u045d', '\u040d'), ('\u045e',
+        '\u040e'), ('\u045f', '\u040f'), ('\u0461', '\u0460'), ('\u0463', '\u0462'), ('\u0465',
+        '\u0464'), ('\u0467', '\u0466'), ('\u0469', '\u0468'), ('\u046b', '\u046a'), ('\u046d',
+        '\u046c'), ('\u046f', '\u046e'), ('\u0471', '\u0470'), ('\u0473', '\u0472'), ('\u0475',
+        '\u0474'), ('\u0477', '\u0476'), ('\u0479', '\u0478'), ('\u047b', '\u047a'), ('\u047d',
+        '\u047c'), ('\u047f', '\u047e'), ('\u0481', '\u0480'), ('\u048b', '\u048a'), ('\u048d',
+        '\u048c'), ('\u048f', '\u048e'), ('\u0491', '\u0490'), ('\u0493', '\u0492'), ('\u0495',
+        '\u0494'), ('\u0497', '\u0496'), ('\u0499', '\u0498'), ('\u049b', '\u049a'), ('\u049d',
+        '\u049c'), ('\u049f', '\u049e'), ('\u04a1', '\u04a0'), ('\u04a3', '\u04a2'), ('\u04a5',
+        '\u04a4'), ('\u04a7', '\u04a6'), ('\u04a9', '\u04a8'), ('\u04ab', '\u04aa'), ('\u04ad',
+        '\u04ac'), ('\u04af', '\u04ae'), ('\u04b1', '\u04b0'), ('\u04b3', '\u04b2'), ('\u04b5',
+        '\u04b4'), ('\u04b7', '\u04b6'), ('\u04b9', '\u04b8'), ('\u04bb', '\u04ba'), ('\u04bd',
+        '\u04bc'), ('\u04bf', '\u04be'), ('\u04c2', '\u04c1'), ('\u04c4', '\u04c3'), ('\u04c6',
+        '\u04c5'), ('\u04c8', '\u04c7'), ('\u04ca', '\u04c9'), ('\u04cc', '\u04cb'), ('\u04ce',
+        '\u04cd'), ('\u04cf', '\u04c0'), ('\u04d1', '\u04d0'), ('\u04d3', '\u04d2'), ('\u04d5',
+        '\u04d4'), ('\u04d7', '\u04d6'), ('\u04d9', '\u04d8'), ('\u04db', '\u04da'), ('\u04dd',
+        '\u04dc'), ('\u04df', '\u04de'), ('\u04e1', '\u04e0'), ('\u04e3', '\u04e2'), ('\u04e5',
+        '\u04e4'), ('\u04e7', '\u04e6'), ('\u04e9', '\u04e8'), ('\u04eb', '\u04ea'), ('\u04ed',
+        '\u04ec'), ('\u04ef', '\u04ee'), ('\u04f1', '\u04f0'), ('\u04f3', '\u04f2'), ('\u04f5',
+        '\u04f4'), ('\u04f7', '\u04f6'), ('\u04f9', '\u04f8'), ('\u04fb', '\u04fa'), ('\u04fd',
+        '\u04fc'), ('\u04ff', '\u04fe'), ('\u0501', '\u0500'), ('\u0503', '\u0502'), ('\u0505',
+        '\u0504'), ('\u0507', '\u0506'), ('\u0509', '\u0508'), ('\u050b', '\u050a'), ('\u050d',
+        '\u050c'), ('\u050f', '\u050e'), ('\u0511', '\u0510'), ('\u0513', '\u0512'), ('\u0515',
+        '\u0514'), ('\u0517', '\u0516'), ('\u0519', '\u0518'), ('\u051b', '\u051a'), ('\u051d',
+        '\u051c'), ('\u051f', '\u051e'), ('\u0521', '\u0520'), ('\u0523', '\u0522'), ('\u0525',
+        '\u0524'), ('\u0527', '\u0526'), ('\u0529', '\u0528'), ('\u052b', '\u052a'), ('\u052d',
+        '\u052c'), ('\u052f', '\u052e'), ('\u0561', '\u0531'), ('\u0562', '\u0532'), ('\u0563',
+        '\u0533'), ('\u0564', '\u0534'), ('\u0565', '\u0535'), ('\u0566', '\u0536'), ('\u0567',
+        '\u0537'), ('\u0568', '\u0538'), ('\u0569', '\u0539'), ('\u056a', '\u053a'), ('\u056b',
+        '\u053b'), ('\u056c', '\u053c'), ('\u056d', '\u053d'), ('\u056e', '\u053e'), ('\u056f',
+        '\u053f'), ('\u0570', '\u0540'), ('\u0571', '\u0541'), ('\u0572', '\u0542'), ('\u0573',
+        '\u0543'), ('\u0574', '\u0544'), ('\u0575', '\u0545'), ('\u0576', '\u0546'), ('\u0577',
+        '\u0547'), ('\u0578', '\u0548'), ('\u0579', '\u0549'), ('\u057a', '\u054a'), ('\u057b',
+        '\u054b'), ('\u057c', '\u054c'), ('\u057d', '\u054d'), ('\u057e', '\u054e'), ('\u057f',
+        '\u054f'), ('\u0580', '\u0550'), ('\u0581', '\u0551'), ('\u0582', '\u0552'), ('\u0583',
+        '\u0553'), ('\u0584', '\u0554'), ('\u0585', '\u0555'), ('\u0586', '\u0556'), ('\u1d79',
+        '\ua77d'), ('\u1d7d', '\u2c63'), ('\u1e01', '\u1e00'), ('\u1e03', '\u1e02'), ('\u1e05',
+        '\u1e04'), ('\u1e07', '\u1e06'), ('\u1e09', '\u1e08'), ('\u1e0b', '\u1e0a'), ('\u1e0d',
+        '\u1e0c'), ('\u1e0f', '\u1e0e'), ('\u1e11', '\u1e10'), ('\u1e13', '\u1e12'), ('\u1e15',
+        '\u1e14'), ('\u1e17', '\u1e16'), ('\u1e19', '\u1e18'), ('\u1e1b', '\u1e1a'), ('\u1e1d',
+        '\u1e1c'), ('\u1e1f', '\u1e1e'), ('\u1e21', '\u1e20'), ('\u1e23', '\u1e22'), ('\u1e25',
+        '\u1e24'), ('\u1e27', '\u1e26'), ('\u1e29', '\u1e28'), ('\u1e2b', '\u1e2a'), ('\u1e2d',
+        '\u1e2c'), ('\u1e2f', '\u1e2e'), ('\u1e31', '\u1e30'), ('\u1e33', '\u1e32'), ('\u1e35',
+        '\u1e34'), ('\u1e37', '\u1e36'), ('\u1e39', '\u1e38'), ('\u1e3b', '\u1e3a'), ('\u1e3d',
+        '\u1e3c'), ('\u1e3f', '\u1e3e'), ('\u1e41', '\u1e40'), ('\u1e43', '\u1e42'), ('\u1e45',
+        '\u1e44'), ('\u1e47', '\u1e46'), ('\u1e49', '\u1e48'), ('\u1e4b', '\u1e4a'), ('\u1e4d',
+        '\u1e4c'), ('\u1e4f', '\u1e4e'), ('\u1e51', '\u1e50'), ('\u1e53', '\u1e52'), ('\u1e55',
+        '\u1e54'), ('\u1e57', '\u1e56'), ('\u1e59', '\u1e58'), ('\u1e5b', '\u1e5a'), ('\u1e5d',
+        '\u1e5c'), ('\u1e5f', '\u1e5e'), ('\u1e61', '\u1e60'), ('\u1e63', '\u1e62'), ('\u1e65',
+        '\u1e64'), ('\u1e67', '\u1e66'), ('\u1e69', '\u1e68'), ('\u1e6b', '\u1e6a'), ('\u1e6d',
+        '\u1e6c'), ('\u1e6f', '\u1e6e'), ('\u1e71', '\u1e70'), ('\u1e73', '\u1e72'), ('\u1e75',
+        '\u1e74'), ('\u1e77', '\u1e76'), ('\u1e79', '\u1e78'), ('\u1e7b', '\u1e7a'), ('\u1e7d',
+        '\u1e7c'), ('\u1e7f', '\u1e7e'), ('\u1e81', '\u1e80'), ('\u1e83', '\u1e82'), ('\u1e85',
+        '\u1e84'), ('\u1e87', '\u1e86'), ('\u1e89', '\u1e88'), ('\u1e8b', '\u1e8a'), ('\u1e8d',
+        '\u1e8c'), ('\u1e8f', '\u1e8e'), ('\u1e91', '\u1e90'), ('\u1e93', '\u1e92'), ('\u1e95',
+        '\u1e94'), ('\u1e9b', '\u1e60'), ('\u1ea1', '\u1ea0'), ('\u1ea3', '\u1ea2'), ('\u1ea5',
+        '\u1ea4'), ('\u1ea7', '\u1ea6'), ('\u1ea9', '\u1ea8'), ('\u1eab', '\u1eaa'), ('\u1ead',
+        '\u1eac'), ('\u1eaf', '\u1eae'), ('\u1eb1', '\u1eb0'), ('\u1eb3', '\u1eb2'), ('\u1eb5',
+        '\u1eb4'), ('\u1eb7', '\u1eb6'), ('\u1eb9', '\u1eb8'), ('\u1ebb', '\u1eba'), ('\u1ebd',
+        '\u1ebc'), ('\u1ebf', '\u1ebe'), ('\u1ec1', '\u1ec0'), ('\u1ec3', '\u1ec2'), ('\u1ec5',
+        '\u1ec4'), ('\u1ec7', '\u1ec6'), ('\u1ec9', '\u1ec8'), ('\u1ecb', '\u1eca'), ('\u1ecd',
+        '\u1ecc'), ('\u1ecf', '\u1ece'), ('\u1ed1', '\u1ed0'), ('\u1ed3', '\u1ed2'), ('\u1ed5',
+        '\u1ed4'), ('\u1ed7', '\u1ed6'), ('\u1ed9', '\u1ed8'), ('\u1edb', '\u1eda'), ('\u1edd',
+        '\u1edc'), ('\u1edf', '\u1ede'), ('\u1ee1', '\u1ee0'), ('\u1ee3', '\u1ee2'), ('\u1ee5',
+        '\u1ee4'), ('\u1ee7', '\u1ee6'), ('\u1ee9', '\u1ee8'), ('\u1eeb', '\u1eea'), ('\u1eed',
+        '\u1eec'), ('\u1eef', '\u1eee'), ('\u1ef1', '\u1ef0'), ('\u1ef3', '\u1ef2'), ('\u1ef5',
+        '\u1ef4'), ('\u1ef7', '\u1ef6'), ('\u1ef9', '\u1ef8'), ('\u1efb', '\u1efa'), ('\u1efd',
+        '\u1efc'), ('\u1eff', '\u1efe'), ('\u1f00', '\u1f08'), ('\u1f01', '\u1f09'), ('\u1f02',
+        '\u1f0a'), ('\u1f03', '\u1f0b'), ('\u1f04', '\u1f0c'), ('\u1f05', '\u1f0d'), ('\u1f06',
+        '\u1f0e'), ('\u1f07', '\u1f0f'), ('\u1f10', '\u1f18'), ('\u1f11', '\u1f19'), ('\u1f12',
+        '\u1f1a'), ('\u1f13', '\u1f1b'), ('\u1f14', '\u1f1c'), ('\u1f15', '\u1f1d'), ('\u1f20',
+        '\u1f28'), ('\u1f21', '\u1f29'), ('\u1f22', '\u1f2a'), ('\u1f23', '\u1f2b'), ('\u1f24',
+        '\u1f2c'), ('\u1f25', '\u1f2d'), ('\u1f26', '\u1f2e'), ('\u1f27', '\u1f2f'), ('\u1f30',
+        '\u1f38'), ('\u1f31', '\u1f39'), ('\u1f32', '\u1f3a'), ('\u1f33', '\u1f3b'), ('\u1f34',
+        '\u1f3c'), ('\u1f35', '\u1f3d'), ('\u1f36', '\u1f3e'), ('\u1f37', '\u1f3f'), ('\u1f40',
+        '\u1f48'), ('\u1f41', '\u1f49'), ('\u1f42', '\u1f4a'), ('\u1f43', '\u1f4b'), ('\u1f44',
+        '\u1f4c'), ('\u1f45', '\u1f4d'), ('\u1f51', '\u1f59'), ('\u1f53', '\u1f5b'), ('\u1f55',
+        '\u1f5d'), ('\u1f57', '\u1f5f'), ('\u1f60', '\u1f68'), ('\u1f61', '\u1f69'), ('\u1f62',
+        '\u1f6a'), ('\u1f63', '\u1f6b'), ('\u1f64', '\u1f6c'), ('\u1f65', '\u1f6d'), ('\u1f66',
+        '\u1f6e'), ('\u1f67', '\u1f6f'), ('\u1f70', '\u1fba'), ('\u1f71', '\u1fbb'), ('\u1f72',
+        '\u1fc8'), ('\u1f73', '\u1fc9'), ('\u1f74', '\u1fca'), ('\u1f75', '\u1fcb'), ('\u1f76',
+        '\u1fda'), ('\u1f77', '\u1fdb'), ('\u1f78', '\u1ff8'), ('\u1f79', '\u1ff9'), ('\u1f7a',
+        '\u1fea'), ('\u1f7b', '\u1feb'), ('\u1f7c', '\u1ffa'), ('\u1f7d', '\u1ffb'), ('\u1f80',
+        '\u1f88'), ('\u1f81', '\u1f89'), ('\u1f82', '\u1f8a'), ('\u1f83', '\u1f8b'), ('\u1f84',
+        '\u1f8c'), ('\u1f85', '\u1f8d'), ('\u1f86', '\u1f8e'), ('\u1f87', '\u1f8f'), ('\u1f90',
+        '\u1f98'), ('\u1f91', '\u1f99'), ('\u1f92', '\u1f9a'), ('\u1f93', '\u1f9b'), ('\u1f94',
+        '\u1f9c'), ('\u1f95', '\u1f9d'), ('\u1f96', '\u1f9e'), ('\u1f97', '\u1f9f'), ('\u1fa0',
+        '\u1fa8'), ('\u1fa1', '\u1fa9'), ('\u1fa2', '\u1faa'), ('\u1fa3', '\u1fab'), ('\u1fa4',
+        '\u1fac'), ('\u1fa5', '\u1fad'), ('\u1fa6', '\u1fae'), ('\u1fa7', '\u1faf'), ('\u1fb0',
+        '\u1fb8'), ('\u1fb1', '\u1fb9'), ('\u1fb3', '\u1fbc'), ('\u1fbe', '\u0399'), ('\u1fc3',
+        '\u1fcc'), ('\u1fd0', '\u1fd8'), ('\u1fd1', '\u1fd9'), ('\u1fe0', '\u1fe8'), ('\u1fe1',
+        '\u1fe9'), ('\u1fe5', '\u1fec'), ('\u1ff3', '\u1ffc'), ('\u214e', '\u2132'), ('\u2184',
+        '\u2183'), ('\u2c30', '\u2c00'), ('\u2c31', '\u2c01'), ('\u2c32', '\u2c02'), ('\u2c33',
+        '\u2c03'), ('\u2c34', '\u2c04'), ('\u2c35', '\u2c05'), ('\u2c36', '\u2c06'), ('\u2c37',
+        '\u2c07'), ('\u2c38', '\u2c08'), ('\u2c39', '\u2c09'), ('\u2c3a', '\u2c0a'), ('\u2c3b',
+        '\u2c0b'), ('\u2c3c', '\u2c0c'), ('\u2c3d', '\u2c0d'), ('\u2c3e', '\u2c0e'), ('\u2c3f',
+        '\u2c0f'), ('\u2c40', '\u2c10'), ('\u2c41', '\u2c11'), ('\u2c42', '\u2c12'), ('\u2c43',
+        '\u2c13'), ('\u2c44', '\u2c14'), ('\u2c45', '\u2c15'), ('\u2c46', '\u2c16'), ('\u2c47',
+        '\u2c17'), ('\u2c48', '\u2c18'), ('\u2c49', '\u2c19'), ('\u2c4a', '\u2c1a'), ('\u2c4b',
+        '\u2c1b'), ('\u2c4c', '\u2c1c'), ('\u2c4d', '\u2c1d'), ('\u2c4e', '\u2c1e'), ('\u2c4f',
+        '\u2c1f'), ('\u2c50', '\u2c20'), ('\u2c51', '\u2c21'), ('\u2c52', '\u2c22'), ('\u2c53',
+        '\u2c23'), ('\u2c54', '\u2c24'), ('\u2c55', '\u2c25'), ('\u2c56', '\u2c26'), ('\u2c57',
+        '\u2c27'), ('\u2c58', '\u2c28'), ('\u2c59', '\u2c29'), ('\u2c5a', '\u2c2a'), ('\u2c5b',
+        '\u2c2b'), ('\u2c5c', '\u2c2c'), ('\u2c5d', '\u2c2d'), ('\u2c5e', '\u2c2e'), ('\u2c61',
+        '\u2c60'), ('\u2c65', '\u023a'), ('\u2c66', '\u023e'), ('\u2c68', '\u2c67'), ('\u2c6a',
+        '\u2c69'), ('\u2c6c', '\u2c6b'), ('\u2c73', '\u2c72'), ('\u2c76', '\u2c75'), ('\u2c81',
+        '\u2c80'), ('\u2c83', '\u2c82'), ('\u2c85', '\u2c84'), ('\u2c87', '\u2c86'), ('\u2c89',
+        '\u2c88'), ('\u2c8b', '\u2c8a'), ('\u2c8d', '\u2c8c'), ('\u2c8f', '\u2c8e'), ('\u2c91',
+        '\u2c90'), ('\u2c93', '\u2c92'), ('\u2c95', '\u2c94'), ('\u2c97', '\u2c96'), ('\u2c99',
+        '\u2c98'), ('\u2c9b', '\u2c9a'), ('\u2c9d', '\u2c9c'), ('\u2c9f', '\u2c9e'), ('\u2ca1',
+        '\u2ca0'), ('\u2ca3', '\u2ca2'), ('\u2ca5', '\u2ca4'), ('\u2ca7', '\u2ca6'), ('\u2ca9',
+        '\u2ca8'), ('\u2cab', '\u2caa'), ('\u2cad', '\u2cac'), ('\u2caf', '\u2cae'), ('\u2cb1',
+        '\u2cb0'), ('\u2cb3', '\u2cb2'), ('\u2cb5', '\u2cb4'), ('\u2cb7', '\u2cb6'), ('\u2cb9',
+        '\u2cb8'), ('\u2cbb', '\u2cba'), ('\u2cbd', '\u2cbc'), ('\u2cbf', '\u2cbe'), ('\u2cc1',
+        '\u2cc0'), ('\u2cc3', '\u2cc2'), ('\u2cc5', '\u2cc4'), ('\u2cc7', '\u2cc6'), ('\u2cc9',
+        '\u2cc8'), ('\u2ccb', '\u2cca'), ('\u2ccd', '\u2ccc'), ('\u2ccf', '\u2cce'), ('\u2cd1',
+        '\u2cd0'), ('\u2cd3', '\u2cd2'), ('\u2cd5', '\u2cd4'), ('\u2cd7', '\u2cd6'), ('\u2cd9',
+        '\u2cd8'), ('\u2cdb', '\u2cda'), ('\u2cdd', '\u2cdc'), ('\u2cdf', '\u2cde'), ('\u2ce1',
+        '\u2ce0'), ('\u2ce3', '\u2ce2'), ('\u2cec', '\u2ceb'), ('\u2cee', '\u2ced'), ('\u2cf3',
+        '\u2cf2'), ('\u2d00', '\u10a0'), ('\u2d01', '\u10a1'), ('\u2d02', '\u10a2'), ('\u2d03',
+        '\u10a3'), ('\u2d04', '\u10a4'), ('\u2d05', '\u10a5'), ('\u2d06', '\u10a6'), ('\u2d07',
+        '\u10a7'), ('\u2d08', '\u10a8'), ('\u2d09', '\u10a9'), ('\u2d0a', '\u10aa'), ('\u2d0b',
+        '\u10ab'), ('\u2d0c', '\u10ac'), ('\u2d0d', '\u10ad'), ('\u2d0e', '\u10ae'), ('\u2d0f',
+        '\u10af'), ('\u2d10', '\u10b0'), ('\u2d11', '\u10b1'), ('\u2d12', '\u10b2'), ('\u2d13',
+        '\u10b3'), ('\u2d14', '\u10b4'), ('\u2d15', '\u10b5'), ('\u2d16', '\u10b6'), ('\u2d17',
+        '\u10b7'), ('\u2d18', '\u10b8'), ('\u2d19', '\u10b9'), ('\u2d1a', '\u10ba'), ('\u2d1b',
+        '\u10bb'), ('\u2d1c', '\u10bc'), ('\u2d1d', '\u10bd'), ('\u2d1e', '\u10be'), ('\u2d1f',
+        '\u10bf'), ('\u2d20', '\u10c0'), ('\u2d21', '\u10c1'), ('\u2d22', '\u10c2'), ('\u2d23',
+        '\u10c3'), ('\u2d24', '\u10c4'), ('\u2d25', '\u10c5'), ('\u2d27', '\u10c7'), ('\u2d2d',
+        '\u10cd'), ('\ua641', '\ua640'), ('\ua643', '\ua642'), ('\ua645', '\ua644'), ('\ua647',
+        '\ua646'), ('\ua649', '\ua648'), ('\ua64b', '\ua64a'), ('\ua64d', '\ua64c'), ('\ua64f',
+        '\ua64e'), ('\ua651', '\ua650'), ('\ua653', '\ua652'), ('\ua655', '\ua654'), ('\ua657',
+        '\ua656'), ('\ua659', '\ua658'), ('\ua65b', '\ua65a'), ('\ua65d', '\ua65c'), ('\ua65f',
+        '\ua65e'), ('\ua661', '\ua660'), ('\ua663', '\ua662'), ('\ua665', '\ua664'), ('\ua667',
+        '\ua666'), ('\ua669', '\ua668'), ('\ua66b', '\ua66a'), ('\ua66d', '\ua66c'), ('\ua681',
+        '\ua680'), ('\ua683', '\ua682'), ('\ua685', '\ua684'), ('\ua687', '\ua686'), ('\ua689',
+        '\ua688'), ('\ua68b', '\ua68a'), ('\ua68d', '\ua68c'), ('\ua68f', '\ua68e'), ('\ua691',
+        '\ua690'), ('\ua693', '\ua692'), ('\ua695', '\ua694'), ('\ua697', '\ua696'), ('\ua699',
+        '\ua698'), ('\ua69b', '\ua69a'), ('\ua723', '\ua722'), ('\ua725', '\ua724'), ('\ua727',
+        '\ua726'), ('\ua729', '\ua728'), ('\ua72b', '\ua72a'), ('\ua72d', '\ua72c'), ('\ua72f',
+        '\ua72e'), ('\ua733', '\ua732'), ('\ua735', '\ua734'), ('\ua737', '\ua736'), ('\ua739',
+        '\ua738'), ('\ua73b', '\ua73a'), ('\ua73d', '\ua73c'), ('\ua73f', '\ua73e'), ('\ua741',
+        '\ua740'), ('\ua743', '\ua742'), ('\ua745', '\ua744'), ('\ua747', '\ua746'), ('\ua749',
+        '\ua748'), ('\ua74b', '\ua74a'), ('\ua74d', '\ua74c'), ('\ua74f', '\ua74e'), ('\ua751',
+        '\ua750'), ('\ua753', '\ua752'), ('\ua755', '\ua754'), ('\ua757', '\ua756'), ('\ua759',
+        '\ua758'), ('\ua75b', '\ua75a'), ('\ua75d', '\ua75c'), ('\ua75f', '\ua75e'), ('\ua761',
+        '\ua760'), ('\ua763', '\ua762'), ('\ua765', '\ua764'), ('\ua767', '\ua766'), ('\ua769',
+        '\ua768'), ('\ua76b', '\ua76a'), ('\ua76d', '\ua76c'), ('\ua76f', '\ua76e'), ('\ua77a',
+        '\ua779'), ('\ua77c', '\ua77b'), ('\ua77f', '\ua77e'), ('\ua781', '\ua780'), ('\ua783',
+        '\ua782'), ('\ua785', '\ua784'), ('\ua787', '\ua786'), ('\ua78c', '\ua78b'), ('\ua791',
+        '\ua790'), ('\ua793', '\ua792'), ('\ua797', '\ua796'), ('\ua799', '\ua798'), ('\ua79b',
+        '\ua79a'), ('\ua79d', '\ua79c'), ('\ua79f', '\ua79e'), ('\ua7a1', '\ua7a0'), ('\ua7a3',
+        '\ua7a2'), ('\ua7a5', '\ua7a4'), ('\ua7a7', '\ua7a6'), ('\ua7a9', '\ua7a8'), ('\uff41',
+        '\uff21'), ('\uff42', '\uff22'), ('\uff43', '\uff23'), ('\uff44', '\uff24'), ('\uff45',
+        '\uff25'), ('\uff46', '\uff26'), ('\uff47', '\uff27'), ('\uff48', '\uff28'), ('\uff49',
+        '\uff29'), ('\uff4a', '\uff2a'), ('\uff4b', '\uff2b'), ('\uff4c', '\uff2c'), ('\uff4d',
+        '\uff2d'), ('\uff4e', '\uff2e'), ('\uff4f', '\uff2f'), ('\uff50', '\uff30'), ('\uff51',
+        '\uff31'), ('\uff52', '\uff32'), ('\uff53', '\uff33'), ('\uff54', '\uff34'), ('\uff55',
+        '\uff35'), ('\uff56', '\uff36'), ('\uff57', '\uff37'), ('\uff58', '\uff38'), ('\uff59',
+        '\uff39'), ('\uff5a', '\uff3a'), ('\U00010428', '\U00010400'), ('\U00010429', '\U00010401'),
+        ('\U0001042a', '\U00010402'), ('\U0001042b', '\U00010403'), ('\U0001042c', '\U00010404'),
+        ('\U0001042d', '\U00010405'), ('\U0001042e', '\U00010406'), ('\U0001042f', '\U00010407'),
+        ('\U00010430', '\U00010408'), ('\U00010431', '\U00010409'), ('\U00010432', '\U0001040a'),
+        ('\U00010433', '\U0001040b'), ('\U00010434', '\U0001040c'), ('\U00010435', '\U0001040d'),
+        ('\U00010436', '\U0001040e'), ('\U00010437', '\U0001040f'), ('\U00010438', '\U00010410'),
+        ('\U00010439', '\U00010411'), ('\U0001043a', '\U00010412'), ('\U0001043b', '\U00010413'),
+        ('\U0001043c', '\U00010414'), ('\U0001043d', '\U00010415'), ('\U0001043e', '\U00010416'),
+        ('\U0001043f', '\U00010417'), ('\U00010440', '\U00010418'), ('\U00010441', '\U00010419'),
+        ('\U00010442', '\U0001041a'), ('\U00010443', '\U0001041b'), ('\U00010444', '\U0001041c'),
+        ('\U00010445', '\U0001041d'), ('\U00010446', '\U0001041e'), ('\U00010447', '\U0001041f'),
+        ('\U00010448', '\U00010420'), ('\U00010449', '\U00010421'), ('\U0001044a', '\U00010422'),
+        ('\U0001044b', '\U00010423'), ('\U0001044c', '\U00010424'), ('\U0001044d', '\U00010425'),
+        ('\U0001044e', '\U00010426'), ('\U0001044f', '\U00010427'), ('\U000118c0', '\U000118a0'),
+        ('\U000118c1', '\U000118a1'), ('\U000118c2', '\U000118a2'), ('\U000118c3', '\U000118a3'),
+        ('\U000118c4', '\U000118a4'), ('\U000118c5', '\U000118a5'), ('\U000118c6', '\U000118a6'),
+        ('\U000118c7', '\U000118a7'), ('\U000118c8', '\U000118a8'), ('\U000118c9', '\U000118a9'),
+        ('\U000118ca', '\U000118aa'), ('\U000118cb', '\U000118ab'), ('\U000118cc', '\U000118ac'),
+        ('\U000118cd', '\U000118ad'), ('\U000118ce', '\U000118ae'), ('\U000118cf', '\U000118af'),
+        ('\U000118d0', '\U000118b0'), ('\U000118d1', '\U000118b1'), ('\U000118d2', '\U000118b2'),
+        ('\U000118d3', '\U000118b3'), ('\U000118d4', '\U000118b4'), ('\U000118d5', '\U000118b5'),
+        ('\U000118d6', '\U000118b6'), ('\U000118d7', '\U000118b7'), ('\U000118d8', '\U000118b8'),
+        ('\U000118d9', '\U000118b9'), ('\U000118da', '\U000118ba'), ('\U000118db', '\U000118bb'),
+        ('\U000118dc', '\U000118bc'), ('\U000118dd', '\U000118bd'), ('\U000118de', '\U000118be'),
+        ('\U000118df', '\U000118bf')
+    ];
+
+}
+
+pub mod charwidth {
+    use core::option::{Option, Some, None};
+    use core::slice::ImmutableVector;
+
+    fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
+        use core::cmp::{Equal, Less, Greater};
+        match r.bsearch(|&(lo, hi, _, _)| {
+            if lo <= c && c <= hi { Equal }
+            else if hi < c { Less }
+            else { Greater }
+        }) {
+            Some(idx) => {
+                let (_, _, r_ncjk, r_cjk) = r[idx];
+                if is_cjk { r_cjk } else { r_ncjk }
+            }
+            None => 1
+        }
+    }
+
+    pub fn width(c: char, is_cjk: bool) -> Option<uint> {
+        match c as uint {
+            _c @ 0 => Some(0),          // null is zero width
+            cu if cu < 0x20 => None,    // control sequences have no width
+            cu if cu < 0x7F => Some(1), // ASCII
+            cu if cu < 0xA0 => None,    // more control sequences
+            _ => Some(bsearch_range_value_table(c, is_cjk, charwidth_table) as uint)
+        }
+    }
+
+    // character width table. Based on Markus Kuhn's free wcwidth() implementation,
+    //     http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+    static charwidth_table: &'static [(char, char, u8, u8)] = &[
+        ('\xa1', '\xa1', 1, 2), ('\xa4', '\xa4', 1, 2), ('\xa7', '\xa8', 1, 2), ('\xaa', '\xaa', 1,
+        2), ('\xae', '\xae', 1, 2), ('\xb0', '\xb4', 1, 2), ('\xb6', '\xba', 1, 2), ('\xbc', '\xbf',
+        1, 2), ('\xc6', '\xc6', 1, 2), ('\xd0', '\xd0', 1, 2), ('\xd7', '\xd8', 1, 2), ('\xde',
+        '\xe1', 1, 2), ('\xe6', '\xe6', 1, 2), ('\xe8', '\xea', 1, 2), ('\xec', '\xed', 1, 2),
+        ('\xf0', '\xf0', 1, 2), ('\xf2', '\xf3', 1, 2), ('\xf7', '\xfa', 1, 2), ('\xfc', '\xfc', 1,
+        2), ('\xfe', '\xfe', 1, 2), ('\u0101', '\u0101', 1, 2), ('\u0111', '\u0111', 1, 2),
+        ('\u0113', '\u0113', 1, 2), ('\u011b', '\u011b', 1, 2), ('\u0126', '\u0127', 1, 2),
+        ('\u012b', '\u012b', 1, 2), ('\u0131', '\u0133', 1, 2), ('\u0138', '\u0138', 1, 2),
+        ('\u013f', '\u0142', 1, 2), ('\u0144', '\u0144', 1, 2), ('\u0148', '\u014b', 1, 2),
+        ('\u014d', '\u014d', 1, 2), ('\u0152', '\u0153', 1, 2), ('\u0166', '\u0167', 1, 2),
+        ('\u016b', '\u016b', 1, 2), ('\u01ce', '\u01ce', 1, 2), ('\u01d0', '\u01d0', 1, 2),
+        ('\u01d2', '\u01d2', 1, 2), ('\u01d4', '\u01d4', 1, 2), ('\u01d6', '\u01d6', 1, 2),
+        ('\u01d8', '\u01d8', 1, 2), ('\u01da', '\u01da', 1, 2), ('\u01dc', '\u01dc', 1, 2),
+        ('\u0251', '\u0251', 1, 2), ('\u0261', '\u0261', 1, 2), ('\u02c4', '\u02c4', 1, 2),
+        ('\u02c7', '\u02c7', 1, 2), ('\u02c9', '\u02cb', 1, 2), ('\u02cd', '\u02cd', 1, 2),
+        ('\u02d0', '\u02d0', 1, 2), ('\u02d8', '\u02db', 1, 2), ('\u02dd', '\u02dd', 1, 2),
+        ('\u02df', '\u02df', 1, 2), ('\u0300', '\u036f', 0, 0), ('\u0391', '\u03a1', 1, 2),
+        ('\u03a3', '\u03a9', 1, 2), ('\u03b1', '\u03c1', 1, 2), ('\u03c3', '\u03c9', 1, 2),
+        ('\u0401', '\u0401', 1, 2), ('\u0410', '\u044f', 1, 2), ('\u0451', '\u0451', 1, 2),
+        ('\u0483', '\u0489', 0, 0), ('\u0591', '\u05bd', 0, 0), ('\u05bf', '\u05bf', 0, 0),
+        ('\u05c1', '\u05c2', 0, 0), ('\u05c4', '\u05c5', 0, 0), ('\u05c7', '\u05c7', 0, 0),
+        ('\u0600', '\u0605', 0, 0), ('\u0610', '\u061a', 0, 0), ('\u061c', '\u061c', 0, 0),
+        ('\u064b', '\u065f', 0, 0), ('\u0670', '\u0670', 0, 0), ('\u06d6', '\u06dd', 0, 0),
+        ('\u06df', '\u06e4', 0, 0), ('\u06e7', '\u06e8', 0, 0), ('\u06ea', '\u06ed', 0, 0),
+        ('\u070f', '\u070f', 0, 0), ('\u0711', '\u0711', 0, 0), ('\u0730', '\u074a', 0, 0),
+        ('\u07a6', '\u07b0', 0, 0), ('\u07eb', '\u07f3', 0, 0), ('\u0816', '\u0819', 0, 0),
+        ('\u081b', '\u0823', 0, 0), ('\u0825', '\u0827', 0, 0), ('\u0829', '\u082d', 0, 0),
+        ('\u0859', '\u085b', 0, 0), ('\u08e4', '\u0902', 0, 0), ('\u093a', '\u093a', 0, 0),
+        ('\u093c', '\u093c', 0, 0), ('\u0941', '\u0948', 0, 0), ('\u094d', '\u094d', 0, 0),
+        ('\u0951', '\u0957', 0, 0), ('\u0962', '\u0963', 0, 0), ('\u0981', '\u0981', 0, 0),
+        ('\u09bc', '\u09bc', 0, 0), ('\u09c1', '\u09c4', 0, 0), ('\u09cd', '\u09cd', 0, 0),
+        ('\u09e2', '\u09e3', 0, 0), ('\u0a01', '\u0a02', 0, 0), ('\u0a3c', '\u0a3c', 0, 0),
+        ('\u0a41', '\u0a42', 0, 0), ('\u0a47', '\u0a48', 0, 0), ('\u0a4b', '\u0a4d', 0, 0),
+        ('\u0a51', '\u0a51', 0, 0), ('\u0a70', '\u0a71', 0, 0), ('\u0a75', '\u0a75', 0, 0),
+        ('\u0a81', '\u0a82', 0, 0), ('\u0abc', '\u0abc', 0, 0), ('\u0ac1', '\u0ac5', 0, 0),
+        ('\u0ac7', '\u0ac8', 0, 0), ('\u0acd', '\u0acd', 0, 0), ('\u0ae2', '\u0ae3', 0, 0),
+        ('\u0b01', '\u0b01', 0, 0), ('\u0b3c', '\u0b3c', 0, 0), ('\u0b3f', '\u0b3f', 0, 0),
+        ('\u0b41', '\u0b44', 0, 0), ('\u0b4d', '\u0b4d', 0, 0), ('\u0b56', '\u0b56', 0, 0),
+        ('\u0b62', '\u0b63', 0, 0), ('\u0b82', '\u0b82', 0, 0), ('\u0bc0', '\u0bc0', 0, 0),
+        ('\u0bcd', '\u0bcd', 0, 0), ('\u0c00', '\u0c00', 0, 0), ('\u0c3e', '\u0c40', 0, 0),
+        ('\u0c46', '\u0c48', 0, 0), ('\u0c4a', '\u0c4d', 0, 0), ('\u0c55', '\u0c56', 0, 0),
+        ('\u0c62', '\u0c63', 0, 0), ('\u0c81', '\u0c81', 0, 0), ('\u0cbc', '\u0cbc', 0, 0),
+        ('\u0cbf', '\u0cbf', 0, 0), ('\u0cc6', '\u0cc6', 0, 0), ('\u0ccc', '\u0ccd', 0, 0),
+        ('\u0ce2', '\u0ce3', 0, 0), ('\u0d01', '\u0d01', 0, 0), ('\u0d41', '\u0d44', 0, 0),
+        ('\u0d4d', '\u0d4d', 0, 0), ('\u0d62', '\u0d63', 0, 0), ('\u0dca', '\u0dca', 0, 0),
+        ('\u0dd2', '\u0dd4', 0, 0), ('\u0dd6', '\u0dd6', 0, 0), ('\u0e31', '\u0e31', 0, 0),
+        ('\u0e34', '\u0e3a', 0, 0), ('\u0e47', '\u0e4e', 0, 0), ('\u0eb1', '\u0eb1', 0, 0),
+        ('\u0eb4', '\u0eb9', 0, 0), ('\u0ebb', '\u0ebc', 0, 0), ('\u0ec8', '\u0ecd', 0, 0),
+        ('\u0f18', '\u0f19', 0, 0), ('\u0f35', '\u0f35', 0, 0), ('\u0f37', '\u0f37', 0, 0),
+        ('\u0f39', '\u0f39', 0, 0), ('\u0f71', '\u0f7e', 0, 0), ('\u0f80', '\u0f84', 0, 0),
+        ('\u0f86', '\u0f87', 0, 0), ('\u0f8d', '\u0f97', 0, 0), ('\u0f99', '\u0fbc', 0, 0),
+        ('\u0fc6', '\u0fc6', 0, 0), ('\u102d', '\u1030', 0, 0), ('\u1032', '\u1037', 0, 0),
+        ('\u1039', '\u103a', 0, 0), ('\u103d', '\u103e', 0, 0), ('\u1058', '\u1059', 0, 0),
+        ('\u105e', '\u1060', 0, 0), ('\u1071', '\u1074', 0, 0), ('\u1082', '\u1082', 0, 0),
+        ('\u1085', '\u1086', 0, 0), ('\u108d', '\u108d', 0, 0), ('\u109d', '\u109d', 0, 0),
+        ('\u1100', '\u115f', 2, 2), ('\u1160', '\u11ff', 0, 0), ('\u135d', '\u135f', 0, 0),
+        ('\u1712', '\u1714', 0, 0), ('\u1732', '\u1734', 0, 0), ('\u1752', '\u1753', 0, 0),
+        ('\u1772', '\u1773', 0, 0), ('\u17b4', '\u17b5', 0, 0), ('\u17b7', '\u17bd', 0, 0),
+        ('\u17c6', '\u17c6', 0, 0), ('\u17c9', '\u17d3', 0, 0), ('\u17dd', '\u17dd', 0, 0),
+        ('\u180b', '\u180e', 0, 0), ('\u18a9', '\u18a9', 0, 0), ('\u1920', '\u1922', 0, 0),
+        ('\u1927', '\u1928', 0, 0), ('\u1932', '\u1932', 0, 0), ('\u1939', '\u193b', 0, 0),
+        ('\u1a17', '\u1a18', 0, 0), ('\u1a1b', '\u1a1b', 0, 0), ('\u1a56', '\u1a56', 0, 0),
+        ('\u1a58', '\u1a5e', 0, 0), ('\u1a60', '\u1a60', 0, 0), ('\u1a62', '\u1a62', 0, 0),
+        ('\u1a65', '\u1a6c', 0, 0), ('\u1a73', '\u1a7c', 0, 0), ('\u1a7f', '\u1a7f', 0, 0),
+        ('\u1ab0', '\u1abe', 0, 0), ('\u1b00', '\u1b03', 0, 0), ('\u1b34', '\u1b34', 0, 0),
+        ('\u1b36', '\u1b3a', 0, 0), ('\u1b3c', '\u1b3c', 0, 0), ('\u1b42', '\u1b42', 0, 0),
+        ('\u1b6b', '\u1b73', 0, 0), ('\u1b80', '\u1b81', 0, 0), ('\u1ba2', '\u1ba5', 0, 0),
+        ('\u1ba8', '\u1ba9', 0, 0), ('\u1bab', '\u1bad', 0, 0), ('\u1be6', '\u1be6', 0, 0),
+        ('\u1be8', '\u1be9', 0, 0), ('\u1bed', '\u1bed', 0, 0), ('\u1bef', '\u1bf1', 0, 0),
+        ('\u1c2c', '\u1c33', 0, 0), ('\u1c36', '\u1c37', 0, 0), ('\u1cd0', '\u1cd2', 0, 0),
+        ('\u1cd4', '\u1ce0', 0, 0), ('\u1ce2', '\u1ce8', 0, 0), ('\u1ced', '\u1ced', 0, 0),
+        ('\u1cf4', '\u1cf4', 0, 0), ('\u1cf8', '\u1cf9', 0, 0), ('\u1dc0', '\u1df5', 0, 0),
+        ('\u1dfc', '\u1dff', 0, 0), ('\u200b', '\u200f', 0, 0), ('\u2010', '\u2010', 1, 2),
+        ('\u2013', '\u2016', 1, 2), ('\u2018', '\u2019', 1, 2), ('\u201c', '\u201d', 1, 2),
+        ('\u2020', '\u2022', 1, 2), ('\u2024', '\u2027', 1, 2), ('\u202a', '\u202e', 0, 0),
+        ('\u2030', '\u2030', 1, 2), ('\u2032', '\u2033', 1, 2), ('\u2035', '\u2035', 1, 2),
+        ('\u203b', '\u203b', 1, 2), ('\u203e', '\u203e', 1, 2), ('\u2060', '\u2064', 0, 0),
+        ('\u2066', '\u206f', 0, 0), ('\u2074', '\u2074', 1, 2), ('\u207f', '\u207f', 1, 2),
+        ('\u2081', '\u2084', 1, 2), ('\u20ac', '\u20ac', 1, 2), ('\u20d0', '\u20f0', 0, 0),
+        ('\u2103', '\u2103', 1, 2), ('\u2105', '\u2105', 1, 2), ('\u2109', '\u2109', 1, 2),
+        ('\u2113', '\u2113', 1, 2), ('\u2116', '\u2116', 1, 2), ('\u2121', '\u2122', 1, 2),
+        ('\u2126', '\u2126', 1, 2), ('\u212b', '\u212b', 1, 2), ('\u2153', '\u2154', 1, 2),
+        ('\u215b', '\u215e', 1, 2), ('\u2160', '\u216b', 1, 2), ('\u2170', '\u2179', 1, 2),
+        ('\u2189', '\u2189', 1, 2), ('\u2190', '\u2199', 1, 2), ('\u21b8', '\u21b9', 1, 2),
+        ('\u21d2', '\u21d2', 1, 2), ('\u21d4', '\u21d4', 1, 2), ('\u21e7', '\u21e7', 1, 2),
+        ('\u2200', '\u2200', 1, 2), ('\u2202', '\u2203', 1, 2), ('\u2207', '\u2208', 1, 2),
+        ('\u220b', '\u220b', 1, 2), ('\u220f', '\u220f', 1, 2), ('\u2211', '\u2211', 1, 2),
+        ('\u2215', '\u2215', 1, 2), ('\u221a', '\u221a', 1, 2), ('\u221d', '\u2220', 1, 2),
+        ('\u2223', '\u2223', 1, 2), ('\u2225', '\u2225', 1, 2), ('\u2227', '\u222c', 1, 2),
+        ('\u222e', '\u222e', 1, 2), ('\u2234', '\u2237', 1, 2), ('\u223c', '\u223d', 1, 2),
+        ('\u2248', '\u2248', 1, 2), ('\u224c', '\u224c', 1, 2), ('\u2252', '\u2252', 1, 2),
+        ('\u2260', '\u2261', 1, 2), ('\u2264', '\u2267', 1, 2), ('\u226a', '\u226b', 1, 2),
+        ('\u226e', '\u226f', 1, 2), ('\u2282', '\u2283', 1, 2), ('\u2286', '\u2287', 1, 2),
+        ('\u2295', '\u2295', 1, 2), ('\u2299', '\u2299', 1, 2), ('\u22a5', '\u22a5', 1, 2),
+        ('\u22bf', '\u22bf', 1, 2), ('\u2312', '\u2312', 1, 2), ('\u2329', '\u232a', 2, 2),
+        ('\u2460', '\u24e9', 1, 2), ('\u24eb', '\u254b', 1, 2), ('\u2550', '\u2573', 1, 2),
+        ('\u2580', '\u258f', 1, 2), ('\u2592', '\u2595', 1, 2), ('\u25a0', '\u25a1', 1, 2),
+        ('\u25a3', '\u25a9', 1, 2), ('\u25b2', '\u25b3', 1, 2), ('\u25b6', '\u25b7', 1, 2),
+        ('\u25bc', '\u25bd', 1, 2), ('\u25c0', '\u25c1', 1, 2), ('\u25c6', '\u25c8', 1, 2),
+        ('\u25cb', '\u25cb', 1, 2), ('\u25ce', '\u25d1', 1, 2), ('\u25e2', '\u25e5', 1, 2),
+        ('\u25ef', '\u25ef', 1, 2), ('\u2605', '\u2606', 1, 2), ('\u2609', '\u2609', 1, 2),
+        ('\u260e', '\u260f', 1, 2), ('\u2614', '\u2615', 1, 2), ('\u261c', '\u261c', 1, 2),
+        ('\u261e', '\u261e', 1, 2), ('\u2640', '\u2640', 1, 2), ('\u2642', '\u2642', 1, 2),
+        ('\u2660', '\u2661', 1, 2), ('\u2663', '\u2665', 1, 2), ('\u2667', '\u266a', 1, 2),
+        ('\u266c', '\u266d', 1, 2), ('\u266f', '\u266f', 1, 2), ('\u269e', '\u269f', 1, 2),
+        ('\u26be', '\u26bf', 1, 2), ('\u26c4', '\u26cd', 1, 2), ('\u26cf', '\u26e1', 1, 2),
+        ('\u26e3', '\u26e3', 1, 2), ('\u26e8', '\u26ff', 1, 2), ('\u273d', '\u273d', 1, 2),
+        ('\u2757', '\u2757', 1, 2), ('\u2776', '\u277f', 1, 2), ('\u2b55', '\u2b59', 1, 2),
+        ('\u2cef', '\u2cf1', 0, 0), ('\u2d7f', '\u2d7f', 0, 0), ('\u2de0', '\u2dff', 0, 0),
+        ('\u2e80', '\u2e99', 2, 2), ('\u2e9b', '\u2ef3', 2, 2), ('\u2f00', '\u2fd5', 2, 2),
+        ('\u2ff0', '\u2ffb', 2, 2), ('\u3000', '\u3029', 2, 2), ('\u302a', '\u302d', 0, 0),
+        ('\u302e', '\u303e', 2, 2), ('\u3041', '\u3096', 2, 2), ('\u3099', '\u309a', 0, 0),
+        ('\u309b', '\u30ff', 2, 2), ('\u3105', '\u312d', 2, 2), ('\u3131', '\u318e', 2, 2),
+        ('\u3190', '\u31ba', 2, 2), ('\u31c0', '\u31e3', 2, 2), ('\u31f0', '\u321e', 2, 2),
+        ('\u3220', '\u3247', 2, 2), ('\u3248', '\u324f', 1, 2), ('\u3250', '\u32fe', 2, 2),
+        ('\u3300', '\u4dbf', 2, 2), ('\u4e00', '\ua48c', 2, 2), ('\ua490', '\ua4c6', 2, 2),
+        ('\ua66f', '\ua672', 0, 0), ('\ua674', '\ua67d', 0, 0), ('\ua69f', '\ua69f', 0, 0),
+        ('\ua6f0', '\ua6f1', 0, 0), ('\ua802', '\ua802', 0, 0), ('\ua806', '\ua806', 0, 0),
+        ('\ua80b', '\ua80b', 0, 0), ('\ua825', '\ua826', 0, 0), ('\ua8c4', '\ua8c4', 0, 0),
+        ('\ua8e0', '\ua8f1', 0, 0), ('\ua926', '\ua92d', 0, 0), ('\ua947', '\ua951', 0, 0),
+        ('\ua960', '\ua97c', 2, 2), ('\ua980', '\ua982', 0, 0), ('\ua9b3', '\ua9b3', 0, 0),
+        ('\ua9b6', '\ua9b9', 0, 0), ('\ua9bc', '\ua9bc', 0, 0), ('\ua9e5', '\ua9e5', 0, 0),
+        ('\uaa29', '\uaa2e', 0, 0), ('\uaa31', '\uaa32', 0, 0), ('\uaa35', '\uaa36', 0, 0),
+        ('\uaa43', '\uaa43', 0, 0), ('\uaa4c', '\uaa4c', 0, 0), ('\uaa7c', '\uaa7c', 0, 0),
+        ('\uaab0', '\uaab0', 0, 0), ('\uaab2', '\uaab4', 0, 0), ('\uaab7', '\uaab8', 0, 0),
+        ('\uaabe', '\uaabf', 0, 0), ('\uaac1', '\uaac1', 0, 0), ('\uaaec', '\uaaed', 0, 0),
+        ('\uaaf6', '\uaaf6', 0, 0), ('\uabe5', '\uabe5', 0, 0), ('\uabe8', '\uabe8', 0, 0),
+        ('\uabed', '\uabed', 0, 0), ('\uac00', '\ud7a3', 2, 2), ('\ue000', '\uf8ff', 1, 2),
+        ('\uf900', '\ufaff', 2, 2), ('\ufb1e', '\ufb1e', 0, 0), ('\ufe00', '\ufe0f', 0, 0),
+        ('\ufe10', '\ufe19', 2, 2), ('\ufe20', '\ufe2d', 0, 0), ('\ufe30', '\ufe52', 2, 2),
+        ('\ufe54', '\ufe66', 2, 2), ('\ufe68', '\ufe6b', 2, 2), ('\ufeff', '\ufeff', 0, 0),
+        ('\uff01', '\uff60', 2, 2), ('\uffe0', '\uffe6', 2, 2), ('\ufff9', '\ufffb', 0, 0),
+        ('\ufffd', '\ufffd', 1, 2), ('\U000101fd', '\U000101fd', 0, 0), ('\U000102e0', '\U000102e0',
+        0, 0), ('\U00010376', '\U0001037a', 0, 0), ('\U00010a01', '\U00010a03', 0, 0),
+        ('\U00010a05', '\U00010a06', 0, 0), ('\U00010a0c', '\U00010a0f', 0, 0), ('\U00010a38',
+        '\U00010a3a', 0, 0), ('\U00010a3f', '\U00010a3f', 0, 0), ('\U00010ae5', '\U00010ae6', 0, 0),
+        ('\U00011001', '\U00011001', 0, 0), ('\U00011038', '\U00011046', 0, 0), ('\U0001107f',
+        '\U00011081', 0, 0), ('\U000110b3', '\U000110b6', 0, 0), ('\U000110b9', '\U000110ba', 0, 0),
+        ('\U000110bd', '\U000110bd', 0, 0), ('\U00011100', '\U00011102', 0, 0), ('\U00011127',
+        '\U0001112b', 0, 0), ('\U0001112d', '\U00011134', 0, 0), ('\U00011173', '\U00011173', 0, 0),
+        ('\U00011180', '\U00011181', 0, 0), ('\U000111b6', '\U000111be', 0, 0), ('\U0001122f',
+        '\U00011231', 0, 0), ('\U00011234', '\U00011234', 0, 0), ('\U00011236', '\U00011237', 0, 0),
+        ('\U000112df', '\U000112df', 0, 0), ('\U000112e3', '\U000112ea', 0, 0), ('\U00011301',
+        '\U00011301', 0, 0), ('\U0001133c', '\U0001133c', 0, 0), ('\U00011340', '\U00011340', 0, 0),
+        ('\U00011366', '\U0001136c', 0, 0), ('\U00011370', '\U00011374', 0, 0), ('\U000114b3',
+        '\U000114b8', 0, 0), ('\U000114ba', '\U000114ba', 0, 0), ('\U000114bf', '\U000114c0', 0, 0),
+        ('\U000114c2', '\U000114c3', 0, 0), ('\U000115b2', '\U000115b5', 0, 0), ('\U000115bc',
+        '\U000115bd', 0, 0), ('\U000115bf', '\U000115c0', 0, 0), ('\U00011633', '\U0001163a', 0, 0),
+        ('\U0001163d', '\U0001163d', 0, 0), ('\U0001163f', '\U00011640', 0, 0), ('\U000116ab',
+        '\U000116ab', 0, 0), ('\U000116ad', '\U000116ad', 0, 0), ('\U000116b0', '\U000116b5', 0, 0),
+        ('\U000116b7', '\U000116b7', 0, 0), ('\U00016af0', '\U00016af4', 0, 0), ('\U00016b30',
+        '\U00016b36', 0, 0), ('\U00016f8f', '\U00016f92', 0, 0), ('\U0001b000', '\U0001b001', 2, 2),
+        ('\U0001bc9d', '\U0001bc9e', 0, 0), ('\U0001bca0', '\U0001bca3', 0, 0), ('\U0001d167',
+        '\U0001d169', 0, 0), ('\U0001d173', '\U0001d182', 0, 0), ('\U0001d185', '\U0001d18b', 0, 0),
+        ('\U0001d1aa', '\U0001d1ad', 0, 0), ('\U0001d242', '\U0001d244', 0, 0), ('\U0001e8d0',
+        '\U0001e8d6', 0, 0), ('\U0001f100', '\U0001f10a', 1, 2), ('\U0001f110', '\U0001f12d', 1, 2),
+        ('\U0001f130', '\U0001f169', 1, 2), ('\U0001f170', '\U0001f19a', 1, 2), ('\U0001f200',
+        '\U0001f202', 2, 2), ('\U0001f210', '\U0001f23a', 2, 2), ('\U0001f240', '\U0001f248', 2, 2),
+        ('\U0001f250', '\U0001f251', 2, 2), ('\U00020000', '\U0002fffd', 2, 2), ('\U00030000',
+        '\U0003fffd', 2, 2), ('\U000e0001', '\U000e0001', 0, 0), ('\U000e0020', '\U000e007f', 0, 0),
+        ('\U000e0100', '\U000e01ef', 0, 0), ('\U000f0000', '\U000ffffd', 1, 2), ('\U00100000',
+        '\U0010fffd', 1, 2)
+    ];
+
+}
diff --git a/src/libunicode/u_char.rs b/src/libunicode/u_char.rs
new file mode 100644 (file)
index 0000000..a927c36
--- /dev/null
@@ -0,0 +1,266 @@
+// Copyright 2012-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.
+
+/*!
+ * Unicode-intensive `char` methods.
+ *
+ * These methods implement functionality for `char` that requires knowledge of
+ * Unicode definitions, including normalization, categorization, and display information.
+ */
+
+use core::option::Option;
+use tables::{derived_property, property, general_category, conversions, charwidth};
+
+/// Returns whether the specified `char` is considered a Unicode alphabetic
+/// code point
+pub fn is_alphabetic(c: char) -> bool   { derived_property::Alphabetic(c) }
+
+/// Returns whether the specified `char` satisfies the 'XID_Start' Unicode property
+///
+/// 'XID_Start' is a Unicode Derived Property specified in
+/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+/// mostly similar to ID_Start but modified for closure under NFKx.
+#[allow(non_snake_case_functions)]
+pub fn is_XID_start(c: char) -> bool    { derived_property::XID_Start(c) }
+
+/// Returns whether the specified `char` satisfies the 'XID_Continue' Unicode property
+///
+/// 'XID_Continue' is a Unicode Derived Property specified in
+/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+/// mostly similar to 'ID_Continue' but modified for closure under NFKx.
+#[allow(non_snake_case_functions)]
+pub fn is_XID_continue(c: char) -> bool { derived_property::XID_Continue(c) }
+
+///
+/// Indicates whether a `char` is in lower case
+///
+/// This is defined according to the terms of the Unicode Derived Core Property 'Lowercase'.
+///
+#[inline]
+pub fn is_lowercase(c: char) -> bool { derived_property::Lowercase(c) }
+
+///
+/// Indicates whether a `char` is in upper case
+///
+/// This is defined according to the terms of the Unicode Derived Core Property 'Uppercase'.
+///
+#[inline]
+pub fn is_uppercase(c: char) -> bool { derived_property::Uppercase(c) }
+
+///
+/// Indicates whether a `char` is whitespace
+///
+/// Whitespace is defined in terms of the Unicode Property 'White_Space'.
+///
+#[inline]
+pub fn is_whitespace(c: char) -> bool {
+    // As an optimization ASCII whitespace characters are checked separately
+    c == ' '
+        || ('\x09' <= c && c <= '\x0d')
+        || property::White_Space(c)
+}
+
+///
+/// Indicates whether a `char` is alphanumeric
+///
+/// Alphanumericness is defined in terms of the Unicode General Categories
+/// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+///
+#[inline]
+pub fn is_alphanumeric(c: char) -> bool {
+    derived_property::Alphabetic(c)
+        || general_category::N(c)
+}
+
+///
+/// Indicates whether a `char` is a control code point
+///
+/// Control code points are defined in terms of the Unicode General Category
+/// 'Cc'.
+///
+#[inline]
+pub fn is_control(c: char) -> bool { general_category::Cc(c) }
+
+/// Indicates whether the `char` is numeric (Nd, Nl, or No)
+#[inline]
+pub fn is_digit(c: char) -> bool {
+    general_category::N(c)
+}
+
+/// Convert a char to its uppercase equivalent
+///
+/// The case-folding performed is the common or simple mapping:
+/// it maps one unicode codepoint (one char in Rust) to its uppercase equivalent according
+/// to the Unicode database at ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+/// The additional SpecialCasing.txt is not considered here, as it expands to multiple
+/// codepoints in some cases.
+///
+/// A full reference can be found here
+/// http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
+///
+/// # Return value
+///
+/// Returns the char itself if no conversion was made
+#[inline]
+pub fn to_uppercase(c: char) -> char {
+    conversions::to_upper(c)
+}
+
+/// Convert a char to its lowercase equivalent
+///
+/// The case-folding performed is the common or simple mapping
+/// see `to_uppercase` for references and more information
+///
+/// # Return value
+///
+/// Returns the char itself if no conversion if possible
+#[inline]
+pub fn to_lowercase(c: char) -> char {
+    conversions::to_lower(c)
+}
+
+/// Returns this character's displayed width in columns, or `None` if it is a
+/// control character other than `'\x00'`.
+///
+/// `is_cjk` determines behavior for characters in the Ambiguous category:
+/// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+/// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
+/// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+/// recommends that these characters be treated as 1 column (i.e.,
+/// `is_cjk` = `false`) if the context cannot be reliably determined.
+pub fn width(c: char, is_cjk: bool) -> Option<uint> {
+    charwidth::width(c, is_cjk)
+}
+
+/// Useful functions for Unicode characters.
+pub trait UnicodeChar {
+    /// Returns whether the specified character is considered a Unicode
+    /// alphabetic code point.
+    fn is_alphabetic(&self) -> bool;
+
+    /// Returns whether the specified character satisfies the 'XID_Start'
+    /// Unicode property.
+    ///
+    /// 'XID_Start' is a Unicode Derived Property specified in
+    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+    /// mostly similar to ID_Start but modified for closure under NFKx.
+    #[allow(non_snake_case_functions)]
+    fn is_XID_start(&self) -> bool;
+
+    /// Returns whether the specified `char` satisfies the 'XID_Continue'
+    /// Unicode property.
+    ///
+    /// 'XID_Continue' is a Unicode Derived Property specified in
+    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+    /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
+    #[allow(non_snake_case_functions)]
+    fn is_XID_continue(&self) -> bool;
+
+
+    /// Indicates whether a character is in lowercase.
+    ///
+    /// This is defined according to the terms of the Unicode Derived Core
+    /// Property `Lowercase`.
+    fn is_lowercase(&self) -> bool;
+
+    /// Indicates whether a character is in uppercase.
+    ///
+    /// This is defined according to the terms of the Unicode Derived Core
+    /// Property `Uppercase`.
+    fn is_uppercase(&self) -> bool;
+
+    /// Indicates whether a character is whitespace.
+    ///
+    /// Whitespace is defined in terms of the Unicode Property `White_Space`.
+    fn is_whitespace(&self) -> bool;
+
+    /// Indicates whether a character is alphanumeric.
+    ///
+    /// Alphanumericness is defined in terms of the Unicode General Categories
+    /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+    fn is_alphanumeric(&self) -> bool;
+
+    /// Indicates whether a character is a control code point.
+    ///
+    /// Control code points are defined in terms of the Unicode General
+    /// Category `Cc`.
+    fn is_control(&self) -> bool;
+
+    /// Indicates whether the character is numeric (Nd, Nl, or No).
+    fn is_digit(&self) -> bool;
+
+    /// Converts a character to its lowercase equivalent.
+    ///
+    /// The case-folding performed is the common or simple mapping. See
+    /// `to_uppercase()` for references and more information.
+    ///
+    /// # Return value
+    ///
+    /// Returns the lowercase equivalent of the character, or the character
+    /// itself if no conversion is possible.
+    fn to_lowercase(&self) -> char;
+
+    /// Converts a character to its uppercase equivalent.
+    ///
+    /// The case-folding performed is the common or simple mapping: it maps
+    /// one unicode codepoint (one character in Rust) to its uppercase
+    /// equivalent according to the Unicode database [1]. The additional
+    /// `SpecialCasing.txt` is not considered here, as it expands to multiple
+    /// codepoints in some cases.
+    ///
+    /// A full reference can be found here [2].
+    ///
+    /// # Return value
+    ///
+    /// Returns the uppercase equivalent of the character, or the character
+    /// itself if no conversion was made.
+    ///
+    /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+    ///
+    /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
+    fn to_uppercase(&self) -> char;
+
+    /// Returns this character's displayed width in columns, or `None` if it is a
+    /// control character other than `'\x00'`.
+    ///
+    /// `is_cjk` determines behavior for characters in the Ambiguous category:
+    /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+    /// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
+    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+    /// recommends that these characters be treated as 1 column (i.e.,
+    /// `is_cjk` = `false`) if the context cannot be reliably determined.
+    fn width(&self, is_cjk: bool) -> Option<uint>;
+}
+
+impl UnicodeChar for char {
+    fn is_alphabetic(&self) -> bool { is_alphabetic(*self) }
+
+    fn is_XID_start(&self) -> bool { is_XID_start(*self) }
+
+    fn is_XID_continue(&self) -> bool { is_XID_continue(*self) }
+
+    fn is_lowercase(&self) -> bool { is_lowercase(*self) }
+
+    fn is_uppercase(&self) -> bool { is_uppercase(*self) }
+
+    fn is_whitespace(&self) -> bool { is_whitespace(*self) }
+
+    fn is_alphanumeric(&self) -> bool { is_alphanumeric(*self) }
+
+    fn is_control(&self) -> bool { is_control(*self) }
+
+    fn is_digit(&self) -> bool { is_digit(*self) }
+
+    fn to_lowercase(&self) -> char { to_lowercase(*self) }
+
+    fn to_uppercase(&self) -> char { to_uppercase(*self) }
+
+    fn width(&self, is_cjk: bool) -> Option<uint> { width(*self, is_cjk) }
+}
diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs
new file mode 100644 (file)
index 0000000..84a2eab
--- /dev/null
@@ -0,0 +1,119 @@
+// Copyright 2012-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.
+
+/*!
+ * Unicode-intensive string manipulations.
+ *
+ * This module provides functionality to `str` that requires the Unicode
+ * methods provided by the UnicodeChar trait.
+ */
+
+use core::collections::Collection;
+use core::iter::{Filter};
+use core::str::{CharSplits, StrSlice};
+use core::iter::Iterator;
+use u_char;
+
+/// An iterator over the words of a string, separated by a sequence of whitespace
+pub type Words<'a> =
+    Filter<'a, &'a str, CharSplits<'a, extern "Rust" fn(char) -> bool>>;
+
+/// Methods for Unicode string slices
+pub trait UnicodeStrSlice<'a> {
+    /// An iterator over the words of a string (subsequences separated
+    /// by any sequence of whitespace). Sequences of whitespace are
+    /// collapsed, so empty "words" are not included.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let some_words = " Mary   had\ta little  \n\t lamb";
+    /// let v: Vec<&str> = some_words.words().collect();
+    /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
+    /// ```
+    fn words(&self) -> Words<'a>;
+
+    /// Returns true if the string contains only whitespace.
+    ///
+    /// Whitespace characters are determined by `char::is_whitespace`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// assert!(" \t\n".is_whitespace());
+    /// assert!("".is_whitespace());
+    ///
+    /// assert!( !"abc".is_whitespace());
+    /// ```
+    fn is_whitespace(&self) -> bool;
+
+    /// Returns true if the string contains only alphanumeric code
+    /// points.
+    ///
+    /// Alphanumeric characters are determined by `char::is_alphanumeric`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// assert!("Löwe老虎Léopard123".is_alphanumeric());
+    /// assert!("".is_alphanumeric());
+    ///
+    /// assert!( !" &*~".is_alphanumeric());
+    /// ```
+    fn is_alphanumeric(&self) -> bool;
+
+    /// Returns a string's displayed width in columns, treating control
+    /// characters as zero-width.
+    ///
+    /// `is_cjk` determines behavior for characters in the Ambiguous category:
+    /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+    /// In CJK locales, `is_cjk` should be `true`, else it should be `false`.
+    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+    /// recommends that these characters be treated as 1 column (i.e.,
+    /// `is_cjk` = `false`) if the locale is unknown.
+    //fn width(&self, is_cjk: bool) -> uint;
+
+    /// Returns a string with leading and trailing whitespace removed.
+    fn trim(&self) -> &'a str;
+
+    /// Returns a string with leading whitespace removed.
+    fn trim_left(&self) -> &'a str;
+
+    /// Returns a string with trailing whitespace removed.
+    fn trim_right(&self) -> &'a str;
+}
+
+impl<'a> UnicodeStrSlice<'a> for &'a str {
+    #[inline]
+    fn words(&self) -> Words<'a> {
+        self.split(u_char::is_whitespace).filter(|s| !s.is_empty())
+    }
+
+    #[inline]
+    fn is_whitespace(&self) -> bool { self.chars().all(u_char::is_whitespace) }
+
+    #[inline]
+    fn is_alphanumeric(&self) -> bool { self.chars().all(u_char::is_alphanumeric) }
+
+    #[inline]
+    fn trim(&self) -> &'a str {
+        self.trim_left().trim_right()
+    }
+
+    #[inline]
+    fn trim_left(&self) -> &'a str {
+        self.trim_left_chars(u_char::is_whitespace)
+    }
+
+    #[inline]
+    fn trim_right(&self) -> &'a str {
+        self.trim_right_chars(u_char::is_whitespace)
+    }
+}
index a60cc8e992b4d58592ee11818f5a4ee84b90e207..b95fc3c495eed1a994e3d0cd7f4423d30c5d5520 100644 (file)
 
 //! Types/fns concerning URLs (see RFC 3986)
 
-#![crate_id = "url#0.11.0"]
+#![crate_name = "url"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(default_type_params)]
 
@@ -25,9 +25,8 @@
 use std::fmt;
 use std::from_str::FromStr;
 use std::hash;
-use std::io::BufReader;
-use std::string::String;
 use std::uint;
+use std::path::BytesContainer;
 
 /// A Uniform Resource Locator (URL).  A URL is a form of URI (Uniform Resource
 /// Identifier) that includes network location information, such as hostname or
 /// # Example
 ///
 /// ```rust
-/// use url::{Url, UserInfo};
+/// use url::Url;
 ///
-/// let url = Url { scheme: "https".to_string(),
-///                 user: Some(UserInfo { user: "username".to_string(), pass: None }),
-///                 host: "example.com".to_string(),
-///                 port: Some("8080".to_string()),
-///                 path: "/foo/bar".to_string(),
-///                 query: vec!(("baz".to_string(), "qux".to_string())),
-///                 fragment: Some("quz".to_string()) };
-/// // https://username@example.com:8080/foo/bar?baz=qux#quz
+/// let raw = "https://username@example.com:8080/foo/bar?baz=qux#quz";
+/// match Url::parse(raw) {
+///     Ok(u) => println!("Parsed '{}'", u),
+///     Err(e) => println!("Couldn't parse '{}': {}", raw, e),
+/// }
 /// ```
 #[deriving(Clone, PartialEq, Eq)]
 pub struct Url {
@@ -56,26 +52,20 @@ pub struct Url {
     /// A domain name or IP address.  For example, `example.com`.
     pub host: String,
     /// A TCP port number, for example `8080`.
-    pub port: Option<String>,
-    /// The path component of a URL, for example `/foo/bar`.
-    pub path: String,
-    /// The query component of a URL.
-    /// `vec!(("baz".to_string(), "qux".to_string()))` represents the fragment
-    /// `baz=qux` in the above example.
-    pub query: Query,
-    /// The fragment component, such as `quz`.  Doesn't include the leading `#` character.
-    pub fragment: Option<String>
+    pub port: Option<u16>,
+    /// The path component of a URL, for example `/foo/bar?baz=qux#quz`.
+    pub path: Path,
 }
 
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Eq)]
 pub struct Path {
     /// The path component of a URL, for example `/foo/bar`.
     pub path: String,
     /// The query component of a URL.
-    /// `vec!(("baz".to_string(), "qux".to_string()))` represents the fragment
+    /// `vec![("baz".to_string(), "qux".to_string())]` represents the fragment
     /// `baz=qux` in the above example.
     pub query: Query,
-    /// The fragment component, such as `quz`.  Doesn't include the leading `#` character.
+    /// The fragment component, such as `quz`. Not including the leading `#` character.
     pub fragment: Option<String>
 }
 
@@ -95,7 +85,7 @@ impl Url {
     pub fn new(scheme: String,
                user: Option<UserInfo>,
                host: String,
-               port: Option<String>,
+               port: Option<u16>,
                path: String,
                query: Query,
                fragment: Option<String>)
@@ -105,11 +95,48 @@ pub fn new(scheme: String,
             user: user,
             host: host,
             port: port,
-            path: path,
-            query: query,
-            fragment: fragment,
+            path: Path::new(path, query, fragment)
         }
     }
+
+    /// Parses a URL, converting it from a string to a `Url` representation.
+    ///
+    /// # Arguments
+    /// * rawurl - a string representing the full URL, including scheme.
+    ///
+    /// # Return value
+    ///
+    /// `Err(e)` if the string did not represent a valid URL, where `e` is a
+    /// `String` error message. Otherwise, `Ok(u)` where `u` is a `Url` struct
+    /// representing the URL.
+    pub fn parse(rawurl: &str) -> DecodeResult<Url> {
+        // scheme
+        let (scheme, rest) = try!(get_scheme(rawurl));
+
+        // authority
+        let (userinfo, host, port, rest) = try!(get_authority(rest));
+
+        // path
+        let has_authority = host.len() > 0;
+        let (path, rest) = try!(get_path(rest, has_authority));
+
+        // query and fragment
+        let (query, fragment) = try!(get_query_fragment(rest));
+
+        let url = Url::new(scheme.to_string(),
+                            userinfo,
+                            host.to_string(),
+                            port,
+                            path,
+                            query,
+                            fragment);
+        Ok(url)
+    }
+}
+
+#[deprecated="use `Url::parse`"]
+pub fn from_str(s: &str) -> Result<Url, String> {
+    Url::parse(s)
 }
 
 impl Path {
@@ -123,6 +150,30 @@ pub fn new(path: String,
             fragment: fragment,
         }
     }
+
+    /// Parses a URL path, converting it from a string to a `Path` representation.
+    ///
+    /// # Arguments
+    /// * rawpath - a string representing the path component of a URL.
+    ///
+    /// # Return value
+    ///
+    /// `Err(e)` if the string did not represent a valid URL path, where `e` is a
+    /// `String` error message. Otherwise, `Ok(p)` where `p` is a `Path` struct
+    /// representing the URL path.
+    pub fn parse(rawpath: &str) -> DecodeResult<Path> {
+        let (path, rest) = try!(get_path(rawpath, false));
+
+        // query and fragment
+        let (query, fragment) = try!(get_query_fragment(rest.as_slice()));
+
+        Ok(Path{ path: path, query: query, fragment: fragment })
+    }
+}
+
+#[deprecated="use `Path::parse`"]
+pub fn path_from_str(s: &str) -> Result<Path, String> {
+    Path::parse(s)
 }
 
 impl UserInfo {
@@ -132,294 +183,221 @@ pub fn new(user: String, pass: Option<String>) -> UserInfo {
     }
 }
 
-fn encode_inner(s: &str, full_url: bool) -> String {
-    let mut rdr = BufReader::new(s.as_bytes());
-    let mut out = String::new();
-
-    loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Err(..) => break,
-            Ok(..) => buf[0] as char,
+fn encode_inner<T: BytesContainer>(c: T, full_url: bool) -> String {
+    c.container_as_bytes().iter().fold(String::new(), |mut out, &b| {
+        match b as char {
+            // unreserved:
+            'A' .. 'Z'
+            | 'a' .. 'z'
+            | '0' .. '9'
+            | '-' | '.' | '_' | '~' => out.push_char(b as char),
+
+            // gen-delims:
+            ':' | '/' | '?' | '#' | '[' | ']' | '@' |
+            // sub-delims:
+            '!' | '$' | '&' | '"' | '(' | ')' | '*' |
+            '+' | ',' | ';' | '='
+                if full_url => out.push_char(b as char),
+
+            ch => out.push_str(format!("%{:02X}", ch as uint).as_slice()),
         };
 
-        match ch {
-          // unreserved:
-          'A' .. 'Z' |
-          'a' .. 'z' |
-          '0' .. '9' |
-          '-' | '.' | '_' | '~' => {
-            out.push_char(ch);
-          }
-          _ => {
-              if full_url {
-                match ch {
-                  // gen-delims:
-                  ':' | '/' | '?' | '#' | '[' | ']' | '@' |
-
-                  // sub-delims:
-                  '!' | '$' | '&' | '"' | '(' | ')' | '*' |
-                  '+' | ',' | ';' | '=' => {
-                    out.push_char(ch);
-                  }
-
-                  _ => out.push_str(format!("%{:02X}", ch as uint).as_slice())
-                }
-            } else {
-                out.push_str(format!("%{:02X}", ch as uint).as_slice());
-            }
-          }
-        }
-    }
-
-    out
+        out
+    })
 }
 
-/**
- * Encodes a URI by replacing reserved characters with percent-encoded
- * character sequences.
- *
- * This function is compliant with RFC 3986.
- *
- * # Example
- *
- * ```rust
- * use url::encode;
- *
- * let url = encode("https://example.com/Rust (programming language)");
- * println!("{}", url); // https://example.com/Rust%20(programming%20language)
- * ```
- */
-pub fn encode(s: &str) -> String {
-    encode_inner(s, true)
+/// Encodes a URI by replacing reserved characters with percent-encoded
+/// character sequences.
+///
+/// This function is compliant with RFC 3986.
+///
+/// # Example
+///
+/// ```rust
+/// use url::encode;
+///
+/// let url = encode("https://example.com/Rust (programming language)");
+/// println!("{}", url); // https://example.com/Rust%20(programming%20language)
+/// ```
+pub fn encode<T: BytesContainer>(container: T) -> String {
+    encode_inner(container, true)
 }
 
-/**
- * Encodes a URI component by replacing reserved characters with percent-
- * encoded character sequences.
- *
- * This function is compliant with RFC 3986.
- */
 
-pub fn encode_component(s: &str) -> String {
-    encode_inner(s, false)
+/// Encodes a URI component by replacing reserved characters with percent-
+/// encoded character sequences.
+///
+/// This function is compliant with RFC 3986.
+pub fn encode_component<T: BytesContainer>(container: T) -> String {
+    encode_inner(container, false)
 }
 
-fn decode_inner(s: &str, full_url: bool) -> String {
-    let mut rdr = BufReader::new(s.as_bytes());
-    let mut out = String::new();
+pub type DecodeResult<T> = Result<T, String>;
 
-    loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Err(..) => break,
-            Ok(..) => buf[0] as char
-        };
-        match ch {
-          '%' => {
-            let mut bytes = [0, 0];
-            match rdr.read(bytes) {
-                Ok(2) => {}
-                _ => fail!() // FIXME: malformed url?
-            }
-            let ch = uint::parse_bytes(bytes, 16u).unwrap() as u8 as char;
-
-            if full_url {
-                // Only decode some characters:
-                match ch {
-                  // gen-delims:
-                  ':' | '/' | '?' | '#' | '[' | ']' | '@' |
-
-                  // sub-delims:
-                  '!' | '$' | '&' | '"' | '(' | ')' | '*' |
-                  '+' | ',' | ';' | '=' => {
-                    out.push_char('%');
-                    out.push_char(bytes[0u] as char);
-                    out.push_char(bytes[1u] as char);
-                  }
-
-                  ch => out.push_char(ch)
-                }
-            } else {
-                  out.push_char(ch);
-            }
-          }
-          ch => out.push_char(ch)
-        }
-    }
-
-    out
-}
-
-/**
- * Decodes a percent-encoded string representing a URI.
- *
- * This will only decode escape sequences generated by `encode`.
- *
- * # Example
- *
- * ```rust
- * use url::decode;
- *
- * let url = decode("https://example.com/Rust%20(programming%20language)");
- * println!("{}", url); // https://example.com/Rust (programming language)
- * ```
- */
-pub fn decode(s: &str) -> String {
-    decode_inner(s, true)
+/// Decodes a percent-encoded string representing a URI.
+///
+/// This will only decode escape sequences generated by `encode`.
+///
+/// # Example
+///
+/// ```rust
+/// use url::decode;
+///
+/// let url = decode("https://example.com/Rust%20(programming%20language)");
+/// println!("{}", url); // https://example.com/Rust (programming language)
+/// ```
+pub fn decode<T: BytesContainer>(container: T) -> DecodeResult<String> {
+    decode_inner(container, true)
 }
 
-/**
- * Decode a string encoded with percent encoding.
- */
-pub fn decode_component(s: &str) -> String {
-    decode_inner(s, false)
+/// Decode a string encoded with percent encoding.
+pub fn decode_component<T: BytesContainer>(container: T) -> DecodeResult<String> {
+    decode_inner(container, false)
 }
 
-fn encode_plus(s: &str) -> String {
-    let mut rdr = BufReader::new(s.as_bytes());
+fn decode_inner<T: BytesContainer>(c: T, full_url: bool) -> DecodeResult<String> {
     let mut out = String::new();
+    let mut iter = c.container_as_bytes().iter().map(|&b| b);
 
     loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Ok(..) => buf[0] as char,
-            Err(..) => break,
-        };
-        match ch {
-          'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '.' | '-' => {
-            out.push_char(ch);
-          }
-          ' ' => out.push_char('+'),
-          _ => out.push_str(format!("%{:X}", ch as uint).as_slice())
+        match iter.next() {
+            Some(b) => match b as char {
+                '%' => {
+                    let bytes = match (iter.next(), iter.next()) {
+                        (Some(one), Some(two)) => [one as u8, two as u8],
+                        _ => return Err(format!("Malformed input: found '%' \
+                                                without two trailing bytes")),
+                    };
+
+                    // Only decode some characters if full_url:
+                    match uint::parse_bytes(bytes, 16u).unwrap() as u8 as char {
+                        // gen-delims:
+                        ':' | '/' | '?' | '#' | '[' | ']' | '@' |
+
+                        // sub-delims:
+                        '!' | '$' | '&' | '"' | '(' | ')' | '*' |
+                        '+' | ',' | ';' | '='
+                            if full_url => {
+                            out.push_char('%');
+                            out.push_char(bytes[0u] as char);
+                            out.push_char(bytes[1u] as char);
+                        }
+
+                        ch => out.push_char(ch)
+                    }
+                }
+                ch => out.push_char(ch)
+            },
+            None => return Ok(out),
         }
     }
-
-    out
 }
 
-/**
- * Encode a hashmap to the 'application/x-www-form-urlencoded' media type.
- */
+/// Encode a hashmap to the 'application/x-www-form-urlencoded' media type.
 pub fn encode_form_urlencoded(m: &HashMap<String, Vec<String>>) -> String {
-    let mut out = String::new();
-    let mut first = true;
+    fn encode_plus<T: Str>(s: &T) -> String {
+        s.as_slice().bytes().fold(String::new(), |mut out, b| {
+            match b as char {
+              'A' .. 'Z'
+              | 'a' .. 'z'
+              | '0' .. '9'
+              | '_' | '.' | '-' => out.push_char(b as char),
+              ' ' => out.push_char('+'),
+              ch => out.push_str(format!("%{:X}", ch as uint).as_slice())
+            }
+
+            out
+        })
+    }
 
-    for (key, values) in m.iter() {
-        let key = encode_plus(key.as_slice());
+    let mut first = true;
+    m.iter().fold(String::new(), |mut out, (key, values)| {
+        let key = encode_plus(key);
 
         for value in values.iter() {
             if first {
                 first = false;
             } else {
                 out.push_char('&');
-                first = false;
             }
 
-            out.push_str(format!("{}={}",
-                                 key,
-                                 encode_plus(value.as_slice())).as_slice());
+            out.push_str(key.as_slice());
+            out.push_char('=');
+            out.push_str(encode_plus(value).as_slice());
         }
-    }
 
-    out
+        out
+    })
 }
 
-/**
- * Decode a string encoded with the 'application/x-www-form-urlencoded' media
- * type into a hashmap.
- */
-#[allow(experimental)]
-pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<String, Vec<String>> {
-    let mut rdr = BufReader::new(s);
-    let mut m: HashMap<String,Vec<String>> = HashMap::new();
+/// Decode a string encoded with the 'application/x-www-form-urlencoded' media
+/// type into a hashmap.
+pub fn decode_form_urlencoded(s: &[u8])
+                            -> DecodeResult<HashMap<String, Vec<String>>> {
+    fn maybe_push_value(map: &mut HashMap<String, Vec<String>>,
+                        key: String,
+                        value: String) {
+        if key.len() > 0 && value.len() > 0 {
+            let values = map.find_or_insert_with(key, |_| vec!());
+            values.push(value);
+        }
+    }
+
+    let mut out = HashMap::new();
+    let mut iter = s.iter().map(|&x| x);
+
     let mut key = String::new();
     let mut value = String::new();
     let mut parsing_key = true;
 
     loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Ok(..) => buf[0] as char,
-            Err(..) => break,
-        };
-        match ch {
-            '&' | ';' => {
-                if key.len() > 0 && value.len() > 0 {
-                    let mut values = match m.pop_equiv(&key.as_slice()) {
-                        Some(values) => values,
-                        None => vec!(),
-                    };
-
-                    values.push(value);
-                    m.insert(key, values);
+        match iter.next() {
+            Some(b) => match b as char {
+                '&' | ';' => {
+                    maybe_push_value(&mut out, key, value);
+
+                    parsing_key = true;
+                    key = String::new();
+                    value = String::new();
                 }
-
-                parsing_key = true;
-                key = String::new();
-                value = String::new();
-            }
-            '=' => parsing_key = false,
-            ch => {
-                let ch = match ch {
-                    '%' => {
-                        let mut bytes = [0, 0];
-                        match rdr.read(bytes) {
-                            Ok(2) => {}
-                            _ => fail!() // FIXME: malformed?
+                '=' => parsing_key = false,
+                ch => {
+                    let ch = match ch {
+                        '%' => {
+                            let bytes = match (iter.next(), iter.next()) {
+                                (Some(one), Some(two)) => [one as u8, two as u8],
+                                _ => return Err(format!("Malformed input: found \
+                                                '%' without two trailing bytes"))
+                            };
+
+                            uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
                         }
-                        uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
-                    }
-                    '+' => ' ',
-                    ch => ch
-                };
+                        '+' => ' ',
+                        ch => ch
+                    };
 
-                if parsing_key {
-                    key.push_char(ch)
-                } else {
-                    value.push_char(ch)
+                    if parsing_key {
+                        key.push_char(ch)
+                    } else {
+                        value.push_char(ch)
+                    }
                 }
+            },
+            None => {
+                maybe_push_value(&mut out, key, value);
+                return Ok(out)
             }
         }
     }
-
-    if key.len() > 0 && value.len() > 0 {
-        let mut values = match m.pop_equiv(&key.as_slice()) {
-            Some(values) => values,
-            None => vec!(),
-        };
-
-        values.push(value);
-        m.insert(key, values);
-    }
-
-    m
 }
 
+fn split_char_first<'a>(s: &'a str, c: char) -> (&'a str, &'a str) {
+    let mut iter = s.splitn(c, 1);
 
-fn split_char_first(s: &str, c: char) -> (String, String) {
-    let len = s.len();
-    let mut index = len;
-    let mut mat = 0;
-    let mut rdr = BufReader::new(s.as_bytes());
-    loop {
-        let mut buf = [0];
-        let ch = match rdr.read(buf) {
-            Ok(..) => buf[0] as char,
-            Err(..) => break,
-        };
-        if ch == c {
-            // found a match, adjust markers
-            index = (rdr.tell().unwrap() as uint) - 1;
-            mat = 1;
-            break;
-        }
-    }
-    if index+mat == len {
-        return (s.slice(0, index).to_string(), "".to_string());
-    } else {
-        return (s.slice(0, index).to_string(),
-                s.slice(index + mat, s.len()).to_string());
+    match (iter.next(), iter.next()) {
+        (Some(a), Some(b)) => (a, b),
+        (Some(a), None) => (a, ""),
+        (None, _) => unreachable!(),
     }
 }
 
@@ -432,103 +410,86 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-fn query_from_str(rawquery: &str) -> Query {
+fn query_from_str(rawquery: &str) -> DecodeResult<Query> {
     let mut query: Query = vec!();
     if !rawquery.is_empty() {
         for p in rawquery.split('&') {
             let (k, v) = split_char_first(p, '=');
-            query.push((decode_component(k.as_slice()),
-                        decode_component(v.as_slice())));
-        };
+            query.push((try!(decode_component(k)),
+                        try!(decode_component(v))));
+        }
     }
-    return query;
+
+    Ok(query)
 }
 
-/**
- * Converts an instance of a URI `Query` type to a string.
- *
- * # Example
- *
- * ```rust
- * let query = vec!(("title".to_string(), "The Village".to_string()),
- *                  ("north".to_string(), "52.91".to_string()),
- *                  ("west".to_string(), "4.10".to_string()));
- * println!("{}", url::query_to_str(&query));  // title=The%20Village&north=52.91&west=4.10
- * ```
- */
-#[allow(unused_must_use)]
+/// Converts an instance of a URI `Query` type to a string.
+///
+/// # Example
+///
+/// ```rust
+/// let query = vec![("title".to_string(), "The Village".to_string()),
+///                  ("north".to_string(), "52.91".to_string()),
+///                  ("west".to_string(), "4.10".to_string())];
+/// println!("{}", url::query_to_str(&query));  // title=The%20Village&north=52.91&west=4.10
+/// ```
 pub fn query_to_str(query: &Query) -> String {
-    use std::io::MemWriter;
-    use std::str;
-
-    let mut writer = MemWriter::new();
-    for (i, &(ref k, ref v)) in query.iter().enumerate() {
-        if i != 0 { write!(&mut writer, "&"); }
-        write!(&mut writer, "{}={}", encode_component(k.as_slice()),
-               encode_component(v.as_slice()));
-    }
-    str::from_utf8_lossy(writer.unwrap().as_slice()).to_string()
+    query.iter().enumerate().fold(String::new(), |mut out, (i, &(ref k, ref v))| {
+        if i != 0 {
+            out.push_char('&');
+        }
+
+        out.push_str(encode_component(k.as_slice()).as_slice());
+        out.push_char('=');
+        out.push_str(encode_component(v.as_slice()).as_slice());
+        out
+    })
 }
 
-/**
- * Returns a tuple of the URI scheme and the rest of the URI, or a parsing error.
- *
- * Does not include the separating `:` character.
- *
- * # Example
- *
- * ```rust
- * use url::get_scheme;
- *
- * let scheme = match get_scheme("https://example.com/") {
- *     Ok((sch, _)) => sch,
- *     Err(_) => "(None)".to_string(),
- * };
- * println!("Scheme in use: {}.", scheme); // Scheme in use: https.
- * ```
- */
-pub fn get_scheme(rawurl: &str) -> Result<(String, String), String> {
+/// Returns a tuple of the URI scheme and the rest of the URI, or a parsing error.
+///
+/// Does not include the separating `:` character.
+///
+/// # Example
+///
+/// ```rust
+/// use url::get_scheme;
+///
+/// let scheme = match get_scheme("https://example.com/") {
+///     Ok((sch, _)) => sch,
+///     Err(_) => "(None)",
+/// };
+/// println!("Scheme in use: {}.", scheme); // Scheme in use: https.
+/// ```
+pub fn get_scheme<'a>(rawurl: &'a str) -> DecodeResult<(&'a str, &'a str)> {
     for (i,c) in rawurl.chars().enumerate() {
-        match c {
-          'A' .. 'Z' | 'a' .. 'z' => continue,
-          '0' .. '9' | '+' | '-' | '.' => {
-            if i == 0 {
-                return Err("url: Scheme must begin with a \
-                            letter.".to_string());
+        let result = match c {
+            'A' .. 'Z'
+            | 'a' .. 'z' => continue,
+            '0' .. '9' | '+' | '-' | '.' => {
+                if i != 0 { continue }
+
+                Err("url: Scheme must begin with a letter.".to_string())
             }
-            continue;
-          }
-          ':' => {
-            if i == 0 {
-                return Err("url: Scheme cannot be empty.".to_string());
-            } else {
-                return Ok((rawurl.slice(0,i).to_string(),
-                           rawurl.slice(i+1,rawurl.len()).to_string()));
+            ':' => {
+                if i == 0 {
+                    Err("url: Scheme cannot be empty.".to_string())
+                } else {
+                    Ok((rawurl.slice(0,i), rawurl.slice(i+1,rawurl.len())))
+                }
             }
-          }
-          _ => {
-            return Err("url: Invalid character in scheme.".to_string());
-          }
-        }
-    };
-    return Err("url: Scheme must be terminated with a colon.".to_string());
-}
+            _ => Err("url: Invalid character in scheme.".to_string()),
+        };
 
-#[deriving(Clone, PartialEq)]
-enum Input {
-    Digit, // all digits
-    Hex, // digits and letters a-f
-    Unreserved // all other legal characters
+        return result;
+    }
+
+    Err("url: Scheme must be terminated with a colon.".to_string())
 }
 
 // returns userinfo, host, port, and unparsed part, or an error
-fn get_authority(rawurl: &str) ->
-    Result<(Option<UserInfo>, String, Option<String>, String), String> {
-    if !rawurl.starts_with("//") {
-        // there is no authority.
-        return Ok((None, "".to_string(), None, rawurl.to_str()));
-    }
-
+fn get_authority<'a>(rawurl: &'a str) ->
+    DecodeResult<(Option<UserInfo>, &'a str, Option<u16>, &'a str)> {
     enum State {
         Start, // starting state
         PassHostPort, // could be in user or port
@@ -538,12 +499,24 @@ enum State {
         InPort // are in port
     }
 
+    #[deriving(Clone, PartialEq)]
+    enum Input {
+        Digit, // all digits
+        Hex, // digits and letters a-f
+        Unreserved // all other legal characters
+    }
+
+    if !rawurl.starts_with("//") {
+        // there is no authority.
+        return Ok((None, "", None, rawurl));
+    }
+
     let len = rawurl.len();
     let mut st = Start;
     let mut input = Digit; // most restricted, start here.
 
     let mut userinfo = None;
-    let mut host = "".to_string();
+    let mut host = "";
     let mut port = None;
 
     let mut colon_count = 0u;
@@ -551,27 +524,27 @@ enum State {
     let mut begin = 2;
     let mut end = len;
 
-    for (i,c) in rawurl.chars().enumerate() {
-        if i < 2 { continue; } // ignore the leading //
-
+    for (i,c) in rawurl.chars().enumerate()
+                               // ignore the leading '//' handled by early return
+                               .skip(2) {
         // deal with input class first
         match c {
-          '0' .. '9' => (),
-          'A' .. 'F' | 'a' .. 'f' => {
-            if input == Digit {
-                input = Hex;
+            '0' .. '9' => (),
+            'A' .. 'F'
+            | 'a' .. 'f' => {
+                if input == Digit {
+                    input = Hex;
+                }
             }
-          }
-          'G' .. 'Z' | 'g' .. 'z' | '-' | '.' | '_' | '~' | '%' |
-          '&' |'\'' | '(' | ')' | '+' | '!' | '*' | ',' | ';' | '=' => {
-            input = Unreserved;
-          }
-          ':' | '@' | '?' | '#' | '/' => {
-            // separators, don't change anything
-          }
-          _ => {
-            return Err("Illegal character in authority".to_string());
-          }
+            'G' .. 'Z'
+            | 'g' .. 'z'
+            | '-' | '.' | '_' | '~' | '%'
+            | '&' |'\'' | '(' | ')' | '+'
+            | '!' | '*' | ',' | ';' | '=' => input = Unreserved,
+            ':' | '@' | '?' | '#' | '/' => {
+                // separators, don't change anything
+            }
+            _ => return Err("Illegal character in authority".to_string()),
         }
 
         // now process states
@@ -595,7 +568,7 @@ enum State {
                 pos = i;
                 if input == Unreserved {
                     // must be port
-                    host = rawurl.slice(begin, i).to_string();
+                    host = rawurl.slice(begin, i);
                     st = InPort;
                 } else {
                     // can't be sure whether this is an ipv6 address or a port
@@ -604,21 +577,18 @@ enum State {
               }
               Ip6Port => {
                 if input == Unreserved {
-                    return Err("Illegal characters in \
-                                authority.".to_string());
+                    return Err("Illegal characters in authority.".to_string());
                 }
                 st = Ip6Host;
               }
               Ip6Host => {
                 if colon_count > 7 {
-                    host = rawurl.slice(begin, i).to_string();
+                    host = rawurl.slice(begin, i);
                     pos = i;
                     st = InPort;
                 }
               }
-              _ => {
-                return Err("Invalid ':' in authority.".to_string());
-              }
+              _ => return Err("Invalid ':' in authority.".to_string()),
             }
             input = Digit; // reset input class
           }
@@ -638,9 +608,7 @@ enum State {
                 userinfo = Some(UserInfo::new(user, Some(pass)));
                 st = InHost;
               }
-              _ => {
-                return Err("Invalid '@' in authority.".to_string());
-              }
+              _ => return Err("Invalid '@' in authority.".to_string()),
             }
             begin = i+1;
           }
@@ -655,44 +623,53 @@ enum State {
 
     // finish up
     match st {
-      Start => {
-        host = rawurl.slice(begin, end).to_string();
-      }
-      PassHostPort | Ip6Port => {
+      Start => host = rawurl.slice(begin, end),
+      PassHostPort
+      | Ip6Port => {
         if input != Digit {
             return Err("Non-digit characters in port.".to_string());
         }
-        host = rawurl.slice(begin, pos).to_string();
-        port = Some(rawurl.slice(pos+1, end).to_string());
-      }
-      Ip6Host | InHost => {
-        host = rawurl.slice(begin, end).to_string();
+        host = rawurl.slice(begin, pos);
+        port = Some(rawurl.slice(pos+1, end));
       }
+      Ip6Host
+      | InHost => host = rawurl.slice(begin, end),
       InPort => {
         if input != Digit {
             return Err("Non-digit characters in port.".to_string());
         }
-        port = Some(rawurl.slice(pos+1, end).to_string());
+        port = Some(rawurl.slice(pos+1, end));
       }
     }
 
-    let rest = rawurl.slice(end, len).to_string();
-    return Ok((userinfo, host, port, rest));
+    let rest = rawurl.slice(end, len);
+    // If we have a port string, ensure it parses to u16.
+    let port = match port {
+        None => None,
+        opt => match opt.and_then(|p| FromStr::from_str(p)) {
+            None => return Err(format!("Failed to parse port: {}", port)),
+            opt => opt
+        }
+    };
+
+    Ok((userinfo, host, port, rest))
 }
 
 
 // returns the path and unparsed part of url, or an error
-fn get_path(rawurl: &str, authority: bool) ->
-    Result<(String, String), String> {
+fn get_path<'a>(rawurl: &'a str, is_authority: bool)
+                                            -> DecodeResult<(String, &'a str)> {
     let len = rawurl.len();
     let mut end = len;
     for (i,c) in rawurl.chars().enumerate() {
         match c {
-          'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '&' |'\'' | '(' | ')' | '.'
-          | '@' | ':' | '%' | '/' | '+' | '!' | '*' | ',' | ';' | '='
-          | '_' | '-' | '~' => {
-            continue;
-          }
+          'A' .. 'Z'
+          | 'a' .. 'z'
+          | '0' .. '9'
+          | '&' |'\'' | '(' | ')' | '.'
+          | '@' | ':' | '%' | '/' | '+'
+          | '!' | '*' | ',' | ';' | '='
+          | '_' | '-' | '~' => continue,
           '?' | '#' => {
             end = i;
             break;
@@ -701,127 +678,53 @@ fn get_path(rawurl: &str, authority: bool) ->
         }
     }
 
-    if authority {
-        if end != 0 && !rawurl.starts_with("/") {
-            return Err("Non-empty path must begin with\
-                              '/' in presence of authority.".to_string());
-        }
+    if is_authority && end != 0 && !rawurl.starts_with("/") {
+        Err("Non-empty path must begin with \
+            '/' in presence of authority.".to_string())
+    } else {
+        Ok((try!(decode_component(rawurl.slice(0, end))),
+            rawurl.slice(end, len)))
     }
-
-    return Ok((decode_component(rawurl.slice(0, end)),
-                    rawurl.slice(end, len).to_string()));
 }
 
 // returns the parsed query and the fragment, if present
-fn get_query_fragment(rawurl: &str) ->
-    Result<(Query, Option<String>), String> {
-    if !rawurl.starts_with("?") {
-        if rawurl.starts_with("#") {
-            let f = decode_component(rawurl.slice(
-                                                1,
-                                                rawurl.len()));
-            return Ok((vec!(), Some(f)));
-        } else {
-            return Ok((vec!(), None));
-        }
-    }
-    let (q, r) = split_char_first(rawurl.slice(1, rawurl.len()), '#');
-    let f = if r.len() != 0 {
-        Some(decode_component(r.as_slice()))
-    } else {
-        None
-    };
-    return Ok((query_from_str(q.as_slice()), f));
-}
-
-/**
- * Parses a URL, converting it from a string to `Url` representation.
- *
- * # Arguments
- *
- * `rawurl` - a string representing the full URL, including scheme.
- *
- * # Returns
- *
- * A `Url` struct type representing the URL.
- */
-pub fn from_str(rawurl: &str) -> Result<Url, String> {
-    // scheme
-    let (scheme, rest) = match get_scheme(rawurl) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
-    };
-
-    // authority
-    let (userinfo, host, port, rest) = match get_authority(rest.as_slice()) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
-    };
-
-    // path
-    let has_authority = host.len() > 0;
-    let (path, rest) = match get_path(rest.as_slice(), has_authority) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
-    };
-
-    // query and fragment
-    let (query, fragment) = match get_query_fragment(rest.as_slice()) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
-    };
-
-    Ok(Url::new(scheme, userinfo, host, port, path, query, fragment))
-}
-
-pub fn path_from_str(rawpath: &str) -> Result<Path, String> {
-    let (path, rest) = match get_path(rawpath, false) {
-        Ok(val) => val,
-        Err(e) => return Err(e)
-    };
+fn get_query_fragment(rawurl: &str) -> DecodeResult<(Query, Option<String>)> {
+    let (before_fragment, raw_fragment) = split_char_first(rawurl, '#');
 
-    // query and fragment
-    let (query, fragment) = match get_query_fragment(rest.as_slice()) {
-        Ok(val) => val,
-        Err(e) => return Err(e),
+    // Parse the fragment if available
+    let fragment = match raw_fragment {
+        "" => None,
+        raw => Some(try!(decode_component(raw)))
     };
 
-    Ok(Path{ path: path, query: query, fragment: fragment })
+    match before_fragment.slice_shift_char() {
+        (Some('?'), rest) => Ok((try!(query_from_str(rest)), fragment)),
+        (None, "") => Ok((vec!(), fragment)),
+        _ => Err(format!("Query didn't start with '?': '{}..'", before_fragment)),
+    }
 }
 
 impl FromStr for Url {
     fn from_str(s: &str) -> Option<Url> {
-        match from_str(s) {
-            Ok(url) => Some(url),
-            Err(_) => None
-        }
+        Url::parse(s).ok()
     }
 }
 
 impl FromStr for Path {
     fn from_str(s: &str) -> Option<Path> {
-        match path_from_str(s) {
-            Ok(path) => Some(path),
-            Err(_) => None
-        }
+        Path::parse(s).ok()
     }
 }
 
 impl fmt::Show for Url {
-    /**
-     * Converts a URL from `Url` to string representation.
-     *
-     * # Arguments
-     *
-     * `url` - a URL.
-     *
-     * # Returns
-     *
-     * A string that contains the formatted URL. Note that this will usually
-     * be an inverse of `from_str` but might strip out unneeded separators;
-     * for example, "http://somehost.com?", when parsed and formatted, will
-     * result in just "http://somehost.com".
-     */
+    /// Converts a URL from `Url` to string representation.
+    ///
+    /// # Returns
+    ///
+    /// A string that contains the formatted URL. Note that this will usually
+    /// be an inverse of `from_str` but might strip out unneeded separators;
+    /// for example, "http://somehost.com?", when parsed and formatted, will
+    /// result in just "http://somehost.com".
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "{}:", self.scheme));
 
@@ -838,18 +741,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             }
         }
 
-        try!(write!(f, "{}", self.path));
-
-        if !self.query.is_empty() {
-            try!(write!(f, "?{}", query_to_str(&self.query)));
-        }
-
-        match self.fragment {
-            Some(ref fragment) => {
-                write!(f, "#{}", encode_component(fragment.as_slice()))
-            }
-            None => Ok(()),
-        }
+        write!(f, "{}", self.path)
     }
 }
 
@@ -857,7 +749,7 @@ impl fmt::Show for Path {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "{}", self.path));
         if !self.query.is_empty() {
-            try!(write!(f, "?{}", self.query))
+            try!(write!(f, "?{}", query_to_str(&self.query)))
         }
 
         match self.fragment {
@@ -871,13 +763,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl<S: hash::Writer> hash::Hash<S> for Url {
     fn hash(&self, state: &mut S) {
-        self.to_str().hash(state)
+        self.to_string().hash(state)
     }
 }
 
 impl<S: hash::Writer> hash::Hash<S> for Path {
     fn hash(&self, state: &mut S) {
-        self.to_str().hash(state)
+        self.to_string().hash(state)
     }
 }
 
@@ -887,12 +779,12 @@ fn hash(&self, state: &mut S) {
 #[test]
 fn test_split_char_first() {
     let (u,v) = split_char_first("hello, sweet world", ',');
-    assert_eq!(u, "hello".to_string());
-    assert_eq!(v, " sweet world".to_string());
+    assert_eq!(u, "hello");
+    assert_eq!(v, " sweet world");
 
     let (u,v) = split_char_first("hello sweet world", ',');
-    assert_eq!(u, "hello sweet world".to_string());
-    assert_eq!(v, "".to_string());
+    assert_eq!(u, "hello sweet world");
+    assert_eq!(v, "");
 }
 
 #[test]
@@ -900,40 +792,39 @@ fn test_get_authority() {
     let (u, h, p, r) = get_authority(
         "//user:pass@rust-lang.org/something").unwrap();
     assert_eq!(u, Some(UserInfo::new("user".to_string(), Some("pass".to_string()))));
-    assert_eq!(h, "rust-lang.org".to_string());
+    assert_eq!(h, "rust-lang.org");
     assert!(p.is_none());
-    assert_eq!(r, "/something".to_string());
+    assert_eq!(r, "/something");
 
     let (u, h, p, r) = get_authority(
         "//rust-lang.org:8000?something").unwrap();
     assert!(u.is_none());
-    assert_eq!(h, "rust-lang.org".to_string());
-    assert_eq!(p, Some("8000".to_string()));
-    assert_eq!(r, "?something".to_string());
+    assert_eq!(h, "rust-lang.org");
+    assert_eq!(p, Some(8000));
+    assert_eq!(r, "?something");
 
-    let (u, h, p, r) = get_authority(
-        "//rust-lang.org#blah").unwrap();
+    let (u, h, p, r) = get_authority("//rust-lang.org#blah").unwrap();
     assert!(u.is_none());
-    assert_eq!(h, "rust-lang.org".to_string());
+    assert_eq!(h, "rust-lang.org");
     assert!(p.is_none());
-    assert_eq!(r, "#blah".to_string());
+    assert_eq!(r, "#blah");
 
     // ipv6 tests
     let (_, h, _, _) = get_authority(
         "//2001:0db8:85a3:0042:0000:8a2e:0370:7334#blah").unwrap();
-    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334".to_string());
+    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334");
 
     let (_, h, p, _) = get_authority(
         "//2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000#blah").unwrap();
-    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334".to_string());
-    assert_eq!(p, Some("8000".to_string()));
+    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334");
+    assert_eq!(p, Some(8000));
 
     let (u, h, p, _) = get_authority(
         "//us:p@2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000#blah"
     ).unwrap();
     assert_eq!(u, Some(UserInfo::new("us".to_string(), Some("p".to_string()))));
-    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334".to_string());
-    assert_eq!(p, Some("8000".to_string()));
+    assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334");
+    assert_eq!(p, Some(8000));
 
     // invalid authorities;
     assert!(get_authority("//user:pass@rust-lang:something").is_err());
@@ -942,25 +833,27 @@ fn test_get_authority() {
         "//2001:0db8:85a3:0042:0000:8a2e:0370:7334:800a").is_err());
     assert!(get_authority(
         "//2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000:00").is_err());
+    // outside u16 range
+    assert!(get_authority("//user:pass@rust-lang:65536").is_err());
 
     // these parse as empty, because they don't start with '//'
     let (_, h, _, _) = get_authority("user:pass@rust-lang").unwrap();
-    assert_eq!(h, "".to_string());
+    assert_eq!(h, "");
     let (_, h, _, _) = get_authority("rust-lang.org").unwrap();
-    assert_eq!(h, "".to_string());
+    assert_eq!(h, "");
 }
 
 #[test]
 fn test_get_path() {
     let (p, r) = get_path("/something+%20orother", true).unwrap();
     assert_eq!(p, "/something+ orother".to_string());
-    assert_eq!(r, "".to_string());
+    assert_eq!(r, "");
     let (p, r) = get_path("test@email.com#fragment", false).unwrap();
     assert_eq!(p, "test@email.com".to_string());
-    assert_eq!(r, "#fragment".to_string());
+    assert_eq!(r, "#fragment");
     let (p, r) = get_path("/gen/:addr=?q=v", false).unwrap();
     assert_eq!(p, "/gen/:addr=".to_string());
-    assert_eq!(r, "?q=v".to_string());
+    assert_eq!(r, "?q=v");
 
     //failure cases
     assert!(get_path("something?q", true).is_err());
@@ -968,96 +861,95 @@ fn test_get_path() {
 
 #[cfg(test)]
 mod tests {
-    use {encode_form_urlencoded, decode_form_urlencoded,
-         decode, encode, from_str, encode_component, decode_component,
-         path_from_str, UserInfo, get_scheme};
+    use {encode_form_urlencoded, decode_form_urlencoded, decode, encode,
+        encode_component, decode_component, UserInfo, get_scheme, Url, Path};
 
     use std::collections::HashMap;
+    use std::path::BytesContainer;
 
     #[test]
     fn test_url_parse() {
         let url = "http://user:pass@rust-lang.org:8080/doc/~u?s=v#something";
-
-        let up = from_str(url);
-        let u = up.unwrap();
-        assert_eq!(&u.scheme, &"http".to_string());
-        assert_eq!(&u.user, &Some(UserInfo::new("user".to_string(), Some("pass".to_string()))));
-        assert_eq!(&u.host, &"rust-lang.org".to_string());
-        assert_eq!(&u.port, &Some("8080".to_string()));
-        assert_eq!(&u.path, &"/doc/~u".to_string());
-        assert_eq!(&u.query, &vec!(("s".to_string(), "v".to_string())));
-        assert_eq!(&u.fragment, &Some("something".to_string()));
+        let u = from_str::<Url>(url).unwrap();
+
+        assert_eq!(u.scheme, "http".to_string());
+        assert_eq!(u.user, Some(UserInfo::new("user".to_string(), Some("pass".to_string()))));
+        assert_eq!(u.host, "rust-lang.org".to_string());
+        assert_eq!(u.port, Some(8080));
+        assert_eq!(u.path.path, "/doc/~u".to_string());
+        assert_eq!(u.path.query, vec!(("s".to_string(), "v".to_string())));
+        assert_eq!(u.path.fragment, Some("something".to_string()));
     }
 
     #[test]
     fn test_path_parse() {
         let path = "/doc/~u?s=v#something";
+        let u = from_str::<Path>(path).unwrap();
 
-        let up = path_from_str(path);
-        let u = up.unwrap();
-        assert_eq!(&u.path, &"/doc/~u".to_string());
-        assert_eq!(&u.query, &vec!(("s".to_string(), "v".to_string())));
-        assert_eq!(&u.fragment, &Some("something".to_string()));
+        assert_eq!(u.path, "/doc/~u".to_string());
+        assert_eq!(u.query, vec!(("s".to_string(), "v".to_string())));
+        assert_eq!(u.fragment, Some("something".to_string()));
     }
 
     #[test]
     fn test_url_parse_host_slash() {
         let urlstr = "http://0.42.42.42/";
-        let url = from_str(urlstr).unwrap();
-        assert!(url.host == "0.42.42.42".to_string());
-        assert!(url.path == "/".to_string());
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.host, "0.42.42.42".to_string());
+        assert_eq!(url.path.path, "/".to_string());
     }
 
     #[test]
     fn test_path_parse_host_slash() {
         let pathstr = "/";
-        let path = path_from_str(pathstr).unwrap();
-        assert!(path.path == "/".to_string());
+        let path = from_str::<Path>(pathstr).unwrap();
+        assert_eq!(path.path, "/".to_string());
     }
 
     #[test]
     fn test_url_host_with_port() {
         let urlstr = "scheme://host:1234";
-        let url = from_str(urlstr).unwrap();
-        assert_eq!(&url.scheme, &"scheme".to_string());
-        assert_eq!(&url.host, &"host".to_string());
-        assert_eq!(&url.port, &Some("1234".to_string()));
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.scheme, "scheme".to_string());
+        assert_eq!(url.host, "host".to_string());
+        assert_eq!(url.port, Some(1234));
         // is empty path really correct? Other tests think so
-        assert_eq!(&url.path, &"".to_string());
+        assert_eq!(url.path.path, "".to_string());
+
         let urlstr = "scheme://host:1234/";
-        let url = from_str(urlstr).unwrap();
-        assert_eq!(&url.scheme, &"scheme".to_string());
-        assert_eq!(&url.host, &"host".to_string());
-        assert_eq!(&url.port, &Some("1234".to_string()));
-        assert_eq!(&url.path, &"/".to_string());
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.scheme, "scheme".to_string());
+        assert_eq!(url.host, "host".to_string());
+        assert_eq!(url.port, Some(1234));
+        assert_eq!(url.path.path, "/".to_string());
     }
 
     #[test]
     fn test_url_with_underscores() {
         let urlstr = "http://dotcom.com/file_name.html";
-        let url = from_str(urlstr).unwrap();
-        assert!(url.path == "/file_name.html".to_string());
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.path.path, "/file_name.html".to_string());
     }
 
     #[test]
     fn test_path_with_underscores() {
         let pathstr = "/file_name.html";
-        let path = path_from_str(pathstr).unwrap();
-        assert!(path.path == "/file_name.html".to_string());
+        let path = from_str::<Path>(pathstr).unwrap();
+        assert_eq!(path.path, "/file_name.html".to_string());
     }
 
     #[test]
     fn test_url_with_dashes() {
         let urlstr = "http://dotcom.com/file-name.html";
-        let url = from_str(urlstr).unwrap();
-        assert!(url.path == "/file-name.html".to_string());
+        let url = from_str::<Url>(urlstr).unwrap();
+        assert_eq!(url.path.path, "/file-name.html".to_string());
     }
 
     #[test]
     fn test_path_with_dashes() {
         let pathstr = "/file-name.html";
-        let path = path_from_str(pathstr).unwrap();
-        assert!(path.path == "/file-name.html".to_string());
+        let path = from_str::<Path>(pathstr).unwrap();
+        assert_eq!(path.path, "/file-name.html".to_string());
     }
 
     #[test]
@@ -1067,83 +959,93 @@ fn test_no_scheme() {
 
     #[test]
     fn test_invalid_scheme_errors() {
-        assert!(from_str("99://something").is_err());
-        assert!(from_str("://something").is_err());
+        assert!(Url::parse("99://something").is_err());
+        assert!(Url::parse("://something").is_err());
     }
 
     #[test]
     fn test_full_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org/doc?s=v#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_userless_url_parse_and_format() {
         let url = "http://rust-lang.org/doc?s=v#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_queryless_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org/doc#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_empty_query_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org/doc?#something";
         let should_be = "http://user:pass@rust-lang.org/doc#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), should_be);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), should_be);
     }
 
     #[test]
     fn test_fragmentless_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org/doc?q=v";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_minimal_url_parse_and_format() {
         let url = "http://rust-lang.org/doc";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_url_with_port_parse_and_format() {
         let url = "http://rust-lang.org:80/doc";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_scheme_host_only_url_parse_and_format() {
         let url = "http://rust-lang.org";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_pathless_url_parse_and_format() {
         let url = "http://user:pass@rust-lang.org?q=v#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_scheme_host_fragment_only_url_parse_and_format() {
         let url = "http://rust-lang.org#something";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_url_component_encoding() {
         let url = "http://rust-lang.org/doc%20uments?ba%25d%20=%23%26%2B";
-        let u = from_str(url).unwrap();
-        assert!(u.path == "/doc uments".to_string());
-        assert!(u.query == vec!(("ba%d ".to_string(), "#&+".to_string())));
+        let u = from_str::<Url>(url).unwrap();
+        assert!(u.path.path == "/doc uments".to_string());
+        assert!(u.path.query == vec!(("ba%d ".to_string(), "#&+".to_string())));
     }
 
     #[test]
     fn test_path_component_encoding() {
         let path = "/doc%20uments?ba%25d%20=%23%26%2B";
-        let p = path_from_str(path).unwrap();
+        let p = from_str::<Path>(path).unwrap();
         assert!(p.path == "/doc uments".to_string());
         assert!(p.query == vec!(("ba%d ".to_string(), "#&+".to_string())));
     }
@@ -1151,124 +1053,151 @@ fn test_path_component_encoding() {
     #[test]
     fn test_url_without_authority() {
         let url = "mailto:test@email.com";
-        assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+        let u = from_str::<Url>(url).unwrap();
+        assert_eq!(format!("{}", u).as_slice(), url);
     }
 
     #[test]
     fn test_encode() {
-        assert_eq!(encode(""), "".to_string());
-        assert_eq!(encode("http://example.com"), "http://example.com".to_string());
-        assert_eq!(encode("foo bar% baz"), "foo%20bar%25%20baz".to_string());
-        assert_eq!(encode(" "), "%20".to_string());
-        assert_eq!(encode("!"), "!".to_string());
-        assert_eq!(encode("\""), "\"".to_string());
-        assert_eq!(encode("#"), "#".to_string());
-        assert_eq!(encode("$"), "$".to_string());
-        assert_eq!(encode("%"), "%25".to_string());
-        assert_eq!(encode("&"), "&".to_string());
-        assert_eq!(encode("'"), "%27".to_string());
-        assert_eq!(encode("("), "(".to_string());
-        assert_eq!(encode(")"), ")".to_string());
-        assert_eq!(encode("*"), "*".to_string());
-        assert_eq!(encode("+"), "+".to_string());
-        assert_eq!(encode(","), ",".to_string());
-        assert_eq!(encode("/"), "/".to_string());
-        assert_eq!(encode(":"), ":".to_string());
-        assert_eq!(encode(";"), ";".to_string());
-        assert_eq!(encode("="), "=".to_string());
-        assert_eq!(encode("?"), "?".to_string());
-        assert_eq!(encode("@"), "@".to_string());
-        assert_eq!(encode("["), "[".to_string());
-        assert_eq!(encode("]"), "]".to_string());
-        assert_eq!(encode("\0"), "%00".to_string());
-        assert_eq!(encode("\n"), "%0A".to_string());
+        fn t<T: BytesContainer>(input: T, expected: &str) {
+            assert_eq!(encode(input), expected.to_string())
+        }
+
+        t("", "");
+        t("http://example.com", "http://example.com");
+        t("foo bar% baz", "foo%20bar%25%20baz");
+        t(" ", "%20");
+        t("!", "!");
+        t("\"", "\"");
+        t("#", "#");
+        t("$", "$");
+        t("%", "%25");
+        t("&", "&");
+        t("'", "%27");
+        t("(", "(");
+        t(")", ")");
+        t("*", "*");
+        t("+", "+");
+        t(",", ",");
+        t("/", "/");
+        t(":", ":");
+        t(";", ";");
+        t("=", "=");
+        t("?", "?");
+        t("@", "@");
+        t("[", "[");
+        t("]", "]");
+        t("\0", "%00");
+        t("\n", "%0A");
+
+        t(&[0u8, 10, 37], "%00%0A%25");
     }
 
     #[test]
     fn test_encode_component() {
-        assert_eq!(encode_component(""), "".to_string());
-        assert!(encode_component("http://example.com") ==
-            "http%3A%2F%2Fexample.com".to_string());
-        assert!(encode_component("foo bar% baz") ==
-            "foo%20bar%25%20baz".to_string());
-        assert_eq!(encode_component(" "), "%20".to_string());
-        assert_eq!(encode_component("!"), "%21".to_string());
-        assert_eq!(encode_component("#"), "%23".to_string());
-        assert_eq!(encode_component("$"), "%24".to_string());
-        assert_eq!(encode_component("%"), "%25".to_string());
-        assert_eq!(encode_component("&"), "%26".to_string());
-        assert_eq!(encode_component("'"), "%27".to_string());
-        assert_eq!(encode_component("("), "%28".to_string());
-        assert_eq!(encode_component(")"), "%29".to_string());
-        assert_eq!(encode_component("*"), "%2A".to_string());
-        assert_eq!(encode_component("+"), "%2B".to_string());
-        assert_eq!(encode_component(","), "%2C".to_string());
-        assert_eq!(encode_component("/"), "%2F".to_string());
-        assert_eq!(encode_component(":"), "%3A".to_string());
-        assert_eq!(encode_component(";"), "%3B".to_string());
-        assert_eq!(encode_component("="), "%3D".to_string());
-        assert_eq!(encode_component("?"), "%3F".to_string());
-        assert_eq!(encode_component("@"), "%40".to_string());
-        assert_eq!(encode_component("["), "%5B".to_string());
-        assert_eq!(encode_component("]"), "%5D".to_string());
-        assert_eq!(encode_component("\0"), "%00".to_string());
-        assert_eq!(encode_component("\n"), "%0A".to_string());
+        fn t<T: BytesContainer>(input: T, expected: &str) {
+            assert_eq!(encode_component(input), expected.to_string())
+        }
+
+        t("", "");
+        t("http://example.com", "http%3A%2F%2Fexample.com");
+        t("foo bar% baz", "foo%20bar%25%20baz");
+        t(" ", "%20");
+        t("!", "%21");
+        t("#", "%23");
+        t("$", "%24");
+        t("%", "%25");
+        t("&", "%26");
+        t("'", "%27");
+        t("(", "%28");
+        t(")", "%29");
+        t("*", "%2A");
+        t("+", "%2B");
+        t(",", "%2C");
+        t("/", "%2F");
+        t(":", "%3A");
+        t(";", "%3B");
+        t("=", "%3D");
+        t("?", "%3F");
+        t("@", "%40");
+        t("[", "%5B");
+        t("]", "%5D");
+        t("\0", "%00");
+        t("\n", "%0A");
+
+        t(&[0u8, 10, 37], "%00%0A%25");
     }
 
     #[test]
     fn test_decode() {
-        assert_eq!(decode(""), "".to_string());
-        assert_eq!(decode("abc/def 123"), "abc/def 123".to_string());
-        assert_eq!(decode("abc%2Fdef%20123"), "abc%2Fdef 123".to_string());
-        assert_eq!(decode("%20"), " ".to_string());
-        assert_eq!(decode("%21"), "%21".to_string());
-        assert_eq!(decode("%22"), "%22".to_string());
-        assert_eq!(decode("%23"), "%23".to_string());
-        assert_eq!(decode("%24"), "%24".to_string());
-        assert_eq!(decode("%25"), "%".to_string());
-        assert_eq!(decode("%26"), "%26".to_string());
-        assert_eq!(decode("%27"), "'".to_string());
-        assert_eq!(decode("%28"), "%28".to_string());
-        assert_eq!(decode("%29"), "%29".to_string());
-        assert_eq!(decode("%2A"), "%2A".to_string());
-        assert_eq!(decode("%2B"), "%2B".to_string());
-        assert_eq!(decode("%2C"), "%2C".to_string());
-        assert_eq!(decode("%2F"), "%2F".to_string());
-        assert_eq!(decode("%3A"), "%3A".to_string());
-        assert_eq!(decode("%3B"), "%3B".to_string());
-        assert_eq!(decode("%3D"), "%3D".to_string());
-        assert_eq!(decode("%3F"), "%3F".to_string());
-        assert_eq!(decode("%40"), "%40".to_string());
-        assert_eq!(decode("%5B"), "%5B".to_string());
-        assert_eq!(decode("%5D"), "%5D".to_string());
+        fn t<T: BytesContainer>(input: T, expected: &str) {
+            assert_eq!(decode(input), Ok(expected.to_string()))
+        }
+
+        assert!(decode("sadsadsda%").is_err());
+        assert!(decode("waeasd%4").is_err());
+        t("", "");
+        t("abc/def 123", "abc/def 123");
+        t("abc%2Fdef%20123", "abc%2Fdef 123");
+        t("%20", " ");
+        t("%21", "%21");
+        t("%22", "%22");
+        t("%23", "%23");
+        t("%24", "%24");
+        t("%25", "%");
+        t("%26", "%26");
+        t("%27", "'");
+        t("%28", "%28");
+        t("%29", "%29");
+        t("%2A", "%2A");
+        t("%2B", "%2B");
+        t("%2C", "%2C");
+        t("%2F", "%2F");
+        t("%3A", "%3A");
+        t("%3B", "%3B");
+        t("%3D", "%3D");
+        t("%3F", "%3F");
+        t("%40", "%40");
+        t("%5B", "%5B");
+        t("%5D", "%5D");
+
+        t("%00%0A%25".as_bytes(), "\0\n%");
     }
 
     #[test]
     fn test_decode_component() {
-        assert_eq!(decode_component(""), "".to_string());
-        assert_eq!(decode_component("abc/def 123"), "abc/def 123".to_string());
-        assert_eq!(decode_component("abc%2Fdef%20123"), "abc/def 123".to_string());
-        assert_eq!(decode_component("%20"), " ".to_string());
-        assert_eq!(decode_component("%21"), "!".to_string());
-        assert_eq!(decode_component("%22"), "\"".to_string());
-        assert_eq!(decode_component("%23"), "#".to_string());
-        assert_eq!(decode_component("%24"), "$".to_string());
-        assert_eq!(decode_component("%25"), "%".to_string());
-        assert_eq!(decode_component("%26"), "&".to_string());
-        assert_eq!(decode_component("%27"), "'".to_string());
-        assert_eq!(decode_component("%28"), "(".to_string());
-        assert_eq!(decode_component("%29"), ")".to_string());
-        assert_eq!(decode_component("%2A"), "*".to_string());
-        assert_eq!(decode_component("%2B"), "+".to_string());
-        assert_eq!(decode_component("%2C"), ",".to_string());
-        assert_eq!(decode_component("%2F"), "/".to_string());
-        assert_eq!(decode_component("%3A"), ":".to_string());
-        assert_eq!(decode_component("%3B"), ";".to_string());
-        assert_eq!(decode_component("%3D"), "=".to_string());
-        assert_eq!(decode_component("%3F"), "?".to_string());
-        assert_eq!(decode_component("%40"), "@".to_string());
-        assert_eq!(decode_component("%5B"), "[".to_string());
-        assert_eq!(decode_component("%5D"), "]".to_string());
+        fn t<T: BytesContainer>(input: T, expected: &str) {
+            assert_eq!(decode_component(input), Ok(expected.to_string()))
+        }
+
+        assert!(decode_component("asacsa%").is_err());
+        assert!(decode_component("acsas%4").is_err());
+        t("", "");
+        t("abc/def 123", "abc/def 123");
+        t("abc%2Fdef%20123", "abc/def 123");
+        t("%20", " ");
+        t("%21", "!");
+        t("%22", "\"");
+        t("%23", "#");
+        t("%24", "$");
+        t("%25", "%");
+        t("%26", "&");
+        t("%27", "'");
+        t("%28", "(");
+        t("%29", ")");
+        t("%2A", "*");
+        t("%2B", "+");
+        t("%2C", ",");
+        t("%2F", "/");
+        t("%3A", ":");
+        t("%3B", ";");
+        t("%3D", "=");
+        t("%3F", "?");
+        t("%40", "@");
+        t("%5B", "[");
+        t("%5D", "]");
+
+        t("%00%0A%25".as_bytes(), "\0\n%");
     }
 
     #[test]
@@ -1286,16 +1215,16 @@ fn test_encode_form_urlencoded() {
 
         let mut m = HashMap::new();
         m.insert("foo bar".to_string(), vec!("abc".to_string(), "12 = 34".to_string()));
-        assert!(encode_form_urlencoded(&m) ==
-            "foo+bar=abc&foo+bar=12+%3D+34".to_string());
+        assert_eq!(encode_form_urlencoded(&m),
+                    "foo+bar=abc&foo+bar=12+%3D+34".to_string());
     }
 
     #[test]
     fn test_decode_form_urlencoded() {
-        assert_eq!(decode_form_urlencoded([]).len(), 0);
+        assert_eq!(decode_form_urlencoded([]).unwrap().len(), 0);
 
         let s = "a=1&foo+bar=abc&foo+bar=12+%3D+34".as_bytes();
-        let form = decode_form_urlencoded(s);
+        let form = decode_form_urlencoded(s).unwrap();
         assert_eq!(form.len(), 2);
         assert_eq!(form.get(&"a".to_string()), &vec!("1".to_string()));
         assert_eq!(form.get(&"foo bar".to_string()),
index 297afe4aa598e4b21ac30e5c7a55331b1fb6daa5..1f84306f9ccc9274bfc5bb84ee6c6b7fbf7a3d97 100644 (file)
@@ -33,7 +33,7 @@
 
 fn main() {
     let uuid1 = Uuid::new_v4();
-    println!("{}", uuid1.to_str());
+    println!("{}", uuid1.to_string());
 }
 ```
 
@@ -54,14 +54,14 @@ fn main() {
 
 */
 
-#![crate_id = "uuid#0.11.0"]
+#![crate_name = "uuid"]
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/0.11.0/",
+       html_root_url = "http://doc.rust-lang.org/master/",
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(default_type_params)]
@@ -620,7 +620,7 @@ fn test_parse_uuid_v4() {
 
         // Round-trip
         let uuid_orig = Uuid::new_v4();
-        let orig_str = uuid_orig.to_str();
+        let orig_str = uuid_orig.to_string();
         let uuid_out = Uuid::parse_string(orig_str.as_slice()).unwrap();
         assert!(uuid_orig == uuid_out);
 
@@ -648,9 +648,9 @@ fn test_to_simple_str() {
     }
 
     #[test]
-    fn test_to_str() {
+    fn test_to_string() {
         let uuid1 = Uuid::new_v4();
-        let s = uuid1.to_str();
+        let s = uuid1.to_string();
 
         assert!(s.len() == 32);
         assert!(s.as_slice().chars().all(|c| c.is_digit_radix(16)));
@@ -683,7 +683,7 @@ fn test_to_str_matching() {
         let uuid1 = Uuid::new_v4();
 
         let hs = uuid1.to_hyphenated_str();
-        let ss = uuid1.to_str();
+        let ss = uuid1.to_string();
 
         let hsn = str::from_chars(hs.as_slice()
                                     .chars()
@@ -702,7 +702,7 @@ fn test_string_roundtrip() {
         let uuid_hs = Uuid::parse_string(hs.as_slice()).unwrap();
         assert!(uuid_hs == uuid);
 
-        let ss = uuid.to_str();
+        let ss = uuid.to_string();
         let uuid_ss = Uuid::parse_string(ss.as_slice()).unwrap();
         assert!(uuid_ss == uuid);
     }
@@ -831,10 +831,10 @@ pub fn create_uuids(b: &mut Bencher) {
     }
 
     #[bench]
-    pub fn uuid_to_str(b: &mut Bencher) {
+    pub fn uuid_to_string(b: &mut Bencher) {
         let u = Uuid::new_v4();
         b.iter(|| {
-            u.to_str();
+            u.to_string();
         })
     }
 
index 5c694b34193ef981489759aba1b064e90c9fd34d..c0c7015e31a77840815841aca47aae8238e70bce 100644 (file)
@@ -1,3 +1,19 @@
+S 2014-07-09 8ddd286
+  freebsd-x86_64 de0c39057f409b69e5ddb888ba3e20b90d63f5db
+  linux-i386 28bef31f2a017e1998256d0c2b2e0a0c9221451b
+  linux-x86_64 853bd73501a10d49cafdf823110c61f13a3392d6
+  macos-i386 b89540ae54f9e565565d36147a586bb4bfbd861b
+  macos-x86_64 58709eb936e7fd66a28a1bb82aaf43a4d8260dea
+  winnt-i386 64a32dcb008d4590a6c6a9efaffbe1d22a334d34
+
+S 2014-07-05 aaff4e0
+  freebsd-x86_64 10272ca9eb17e1be4a4b172aacfb4b33fffcc8fb
+  linux-i386 72ba9f6e0d096c30f128cb3736ffac0b57530a20
+  linux-x86_64 e5621f84934a7d76002ab95a354fbbb9ae6ebbb1
+  macos-i386 a88fd84ee959e59265de12b8f551ed56c0e943df
+  macos-x86_64 f19d479e5a0d2a6067a05b1910e4a6a544836b0a
+  winnt-i386 0c5a91e422409b89ac22f8c265af66f759d476c8
+
 S 2014-06-25 bab614f
   freebsd-x86_64 14cb361c8fdefa2534bb6776a04815c08680ecd6
   linux-i386 8fec4845626c557431a4aa7bfb2b5cfc65ad9eda
index eddedfa36bb301657b77b5b91a4a6a9053eaeead..e26ea7c4fa6d0b73b79e49c83722512ccd5549fa 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="crateresolve1#0.1"]
-
+// compile-flags:-C extra-filename=-1
+#![crate_name = "crateresolve1"]
 #![crate_type = "lib"]
 
 pub fn f() -> int { 10 }
index 48042de0bad45830c9bad3e554e266c09c990fbf..715171b143a4a46686e59ad3ab168f2a52a6a272 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="crateresolve1#0.2"]
-
+// compile-flags:-C extra-filename=-2
+#![crate_name = "crateresolve1"]
 #![crate_type = "lib"]
 
 pub fn f() -> int { 20 }
index c126560fe3eb2cbec9ffbe01433625ecaa4afa40..f733b5b908ab49aff407753905edf2a33317e185 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="crateresolve1#0.3"]
-
+// compile-flags:-C extra-filename=-3
+#![crate_name = "crateresolve1"]
 #![crate_type = "lib"]
 
 pub fn f() -> int { 30 }
diff --git a/src/test/auxiliary/crateresolve2-1.rs b/src/test/auxiliary/crateresolve2-1.rs
deleted file mode 100644 (file)
index f436e7c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_id="crateresolve2#0.1"]
-
-#![crate_type = "lib"]
-
-pub fn f() -> int { 10 }
diff --git a/src/test/auxiliary/crateresolve2-2.rs b/src/test/auxiliary/crateresolve2-2.rs
deleted file mode 100644 (file)
index 1f92ce5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_id="crateresolve2#0.2"]
-
-#![crate_type = "lib"]
-
-pub fn f() -> int { 20 }
diff --git a/src/test/auxiliary/crateresolve2-3.rs b/src/test/auxiliary/crateresolve2-3.rs
deleted file mode 100644 (file)
index fe064b7..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_id="crateresolve2#0.3"]
-
-#![crate_type = "lib"]
-
-pub fn f() -> int { 30 }
index e26f8effb47fc85f852d1d878a7a8d7c0875d0d4..5c83b327912270e6a15c9a7f6b89e154df86a19a 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="externcallback#0.1"]
+#![crate_name="externcallback"]
 #![crate_type = "lib"]
 
 extern crate libc;
diff --git a/src/test/auxiliary/issue-11908-1.rs b/src/test/auxiliary/issue-11908-1.rs
deleted file mode 100644 (file)
index 8a48e48..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// no-prefer-dynamic
-
-#![crate_id = "url#0.11.0"]
-#![crate_type = "dylib"]
diff --git a/src/test/auxiliary/issue-11908-2.rs b/src/test/auxiliary/issue-11908-2.rs
deleted file mode 100644 (file)
index 0deece5..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// no-prefer-dynamic
-
-#![crate_id = "url#0.11.0"]
-#![crate_type = "rlib"]
diff --git a/src/test/auxiliary/issue2378a.rs b/src/test/auxiliary/issue2378a.rs
deleted file mode 100644 (file)
index 934c4f5..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "lib"]
-
-pub enum maybe<T> { just(T), nothing }
-
-impl <T:Clone> Index<uint,T> for maybe<T> {
-    fn index(&self, _idx: &uint) -> T {
-        match self {
-            &just(ref t) => (*t).clone(),
-            &nothing => { fail!(); }
-        }
-    }
-}
diff --git a/src/test/auxiliary/issue2378b.rs b/src/test/auxiliary/issue2378b.rs
deleted file mode 100644 (file)
index 03f685c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "lib"]
-
-extern crate issue2378a;
-
-use issue2378a::maybe;
-
-pub struct two_maybes<T> {pub a: maybe<T>, pub b: maybe<T>}
-
-impl<T:Clone> Index<uint,(T,T)> for two_maybes<T> {
-    fn index(&self, idx: &uint) -> (T, T) {
-        (self.a[*idx], self.b[*idx])
-    }
-}
diff --git a/src/test/auxiliary/rlib_crate_test.rs b/src/test/auxiliary/rlib_crate_test.rs
new file mode 100644 (file)
index 0000000..be03a36
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2013-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.
+
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+#![feature(plugin_registrar)]
+
+extern crate rustc;
+
+use rustc::plugin::Registry;
+
+#[plugin_registrar]
+pub fn plugin_registrar(_: &mut Registry) {}
diff --git a/src/test/auxiliary/xcrate_struct_aliases.rs b/src/test/auxiliary/xcrate_struct_aliases.rs
new file mode 100644 (file)
index 0000000..a0ec727
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct S {
+    pub x: int,
+    pub y: int,
+}
+
+pub type S2 = S;
+
index c3e877f80817658efea54fe3618ee6687b80d9e3..1d2d02d7d592689de2661c6d4b79b0e877d887a4 100644 (file)
@@ -90,11 +90,11 @@ pub fn bench_str<T:MutableSet<String>,
             let mut set = f();
             timed(&mut self.sequential_strings, || {
                 for i in range(0u, num_keys) {
-                    set.insert(i.to_str());
+                    set.insert(i.to_string());
                 }
 
                 for i in range(0u, num_keys) {
-                    assert!(set.contains(&i.to_str()));
+                    assert!(set.contains(&i.to_string()));
                 }
             })
         }
@@ -103,7 +103,7 @@ pub fn bench_str<T:MutableSet<String>,
             let mut set = f();
             timed(&mut self.random_strings, || {
                 for _ in range(0, num_keys) {
-                    let s = rng.gen::<uint>().to_str();
+                    let s = rng.gen::<uint>().to_string();
                     set.insert(s);
                 }
             })
@@ -112,11 +112,11 @@ pub fn bench_str<T:MutableSet<String>,
         {
             let mut set = f();
             for i in range(0u, num_keys) {
-                set.insert(i.to_str());
+                set.insert(i.to_string());
             }
             timed(&mut self.delete_strings, || {
                 for i in range(0u, num_keys) {
-                    assert!(set.remove(&i.to_str()));
+                    assert!(set.remove(&i.to_string()));
                 }
             })
         }
index 1c51ea055d04e3ab30a09831eee315dd7511fcac..f38517515660970d7b33dbc525567c6449cefae0 100644 (file)
@@ -24,7 +24,7 @@ fn main() {
     let n = from_str::<uint>(args.get(1).as_slice()).unwrap();
 
     for i in range(0u, n) {
-        let x = i.to_str();
+        let x = i.to_string();
         println!("{}", x);
     }
 }
index 8095037662bccf4e95edfe1eac7ecff0ed1a4112..0c76d14852e08695cf9ebc83272b1c2979741080 100644 (file)
@@ -48,7 +48,7 @@ fn show_color_list(set: Vec<Color>) -> String {
     let mut out = String::new();
     for col in set.iter() {
         out.push_char(' ');
-        out.push_str(col.to_str().as_slice());
+        out.push_str(col.to_string().as_slice());
     }
     out
 }
index 195c146c12fe719f26927bef8016837b91852345..b3deb88543ed46bdec52e56732c69bc2d20886fe 100644 (file)
@@ -64,7 +64,7 @@ fn sortKV(mut orig: Vec<(Vec<u8> ,f64)> ) -> Vec<(Vec<u8> ,f64)> {
                                k.as_slice()
                                .to_ascii()
                                .to_upper()
-                               .into_str(), v).as_slice());
+                               .into_string(), v).as_slice());
    }
 
    return buffer
@@ -72,7 +72,7 @@ fn sortKV(mut orig: Vec<(Vec<u8> ,f64)> ) -> Vec<(Vec<u8> ,f64)> {
 
 // given a map, search for the frequency of a pattern
 fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
-   let key = key.to_owned().into_ascii().as_slice().to_lower().into_str();
+   let key = key.to_owned().into_ascii().as_slice().to_lower().into_string();
    match mm.find_equiv(&key.as_bytes()) {
       option::None      => { return 0u; }
       option::Some(&num) => { return num; }
index 85f035b60cbbe23567357b0207ba71badecc6349..0e0b0b518d587efc815ddadf375e76588cc3a349 100644 (file)
@@ -115,7 +115,7 @@ fn main() {
 
                 let elapsed = stop - start;
 
-                println!("{}\t{}\t{}", n, fibn, elapsed.to_str());
+                println!("{}\t{}\t{}", n, fibn, elapsed.to_string());
             }
         }
     }
index 19b9d5638d0d8f3f034586958591b6322ebacd26..bdf6862d0b133ffa1150b60874e13ba0f14e0952 100644 (file)
@@ -67,7 +67,7 @@ fn main() {
     } else {
         box io::stdin() as Box<io::Reader>
     };
-    let mut seq = rdr.read_to_str().unwrap();
+    let mut seq = rdr.read_to_string().unwrap();
     let ilen = seq.len();
 
     seq = regex!(">[^\n]*\n|\n").replace_all(seq.as_slice(), NoExpand(""));
@@ -109,7 +109,7 @@ fn main() {
     let (mut variant_strs, mut counts) = (vec!(), vec!());
     for variant in variants.move_iter() {
         let seq_arc_copy = seq_arc.clone();
-        variant_strs.push(variant.to_str().to_owned());
+        variant_strs.push(variant.to_string().to_owned());
         counts.push(Future::spawn(proc() {
             count_matches(seq_arc_copy.as_slice(), &variant)
         }));
diff --git a/src/test/compile-fail-fulldeps/macro-crate-rlib.rs b/src/test/compile-fail-fulldeps/macro-crate-rlib.rs
new file mode 100644 (file)
index 0000000..625245d
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2013-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.
+
+// aux-build:rlib_crate_test.rs
+// ignore-stage1
+// ignore-tidy-linelength
+// ignore-android
+
+#![feature(phase)]
+#[phase(plugin)] extern crate rlib_crate_test;
+//~^ ERROR: plugin crate `rlib_crate_test` only found in rlib format, but must be available in dylib format
+
+fn main() {}
index 39c2accaddf3327dd0259ac7b5344720b4ab4ad6..6a3b0b91ffe297ed9d24f03a8d685f687c0c344e 100644 (file)
@@ -18,5 +18,5 @@
 extern crate macro_crate_test;
 
 fn main() {
-    assert_eq!(3, unexported_macro!()); //~ ERROR macro undefined: 'unexported_macro'
+    assert_eq!(3, unexported_macro!()); //~ ERROR macro undefined: 'unexported_macro!'
 }
index 43956752cd9b343fc72ee2f8f375ceab67815498..883bfd035f40abbcba04a8c212b8e4ecdb2890b1 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern crate foo = ""; //~ ERROR: malformed crate id
-extern crate bar = "#a"; //~ ERROR: malformed crate id
+extern crate foo = ""; //~ ERROR: crate name must not be empty
 
 fn main() {}
diff --git a/src/test/compile-fail/bad-crate-id2.rs b/src/test/compile-fail/bad-crate-id2.rs
new file mode 100644 (file)
index 0000000..22e98b6
--- /dev/null
@@ -0,0 +1,14 @@
+// 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.
+
+extern crate bar = "#a"; //~ ERROR: invalid character `#` in crate name: `#a`
+
+fn main() {}
+
index 9939fc791907d0fb166247c34f1b86e7563d91aa..1c7516ef7e2bfb2e3189c5e276f4f18d998d7a46 100644 (file)
@@ -32,7 +32,7 @@ enum UnsafeEnum<T> {
 static STATIC2: Unsafe<int> = Unsafe{value: 1, marker1: marker::InvariantType};
 static STATIC3: MyUnsafe<int> = MyUnsafe{value: STATIC2};
 
-static STATIC4: &'static Unsafe<int> = &'static STATIC2;
+static STATIC4: &'static Unsafe<int> = &STATIC2;
 //~^ ERROR borrow of immutable static items with unsafe interior is not allowed
 
 struct Wrap<T> {
diff --git a/src/test/compile-fail/borrowck-overloaded-index.rs b/src/test/compile-fail/borrowck-overloaded-index.rs
new file mode 100644 (file)
index 0000000..d34aa1c
--- /dev/null
@@ -0,0 +1,64 @@
+// 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.
+
+struct Foo {
+    x: int,
+    y: int,
+}
+
+impl Index<String,int> for Foo {
+    fn index<'a>(&'a self, z: &String) -> &'a int {
+        if z.as_slice() == "x" {
+            &self.x
+        } else {
+            &self.y
+        }
+    }
+}
+
+impl IndexMut<String,int> for Foo {
+    fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut int {
+        if z.as_slice() == "x" {
+            &mut self.x
+        } else {
+            &mut self.y
+        }
+    }
+}
+
+struct Bar {
+    x: int,
+}
+
+impl Index<int,int> for Bar {
+    fn index<'a>(&'a self, z: &int) -> &'a int {
+        &self.x
+    }
+}
+
+fn main() {
+    let mut f = Foo {
+        x: 1,
+        y: 2,
+    };
+    let mut s = "hello".to_string();
+    let rs = &mut s;
+    println!("{}", f[s]);
+    //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+    f[s] = 10;
+    //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+    let s = Bar {
+        x: 1,
+    };
+    s[2] = 20;
+    //~^ ERROR cannot assign to immutable indexed content
+}
+
+
index da5f7680d8ce759488dd30ffc8f446b05232e622..b7344d72a46c4253bbc19487d47ef34d159edc20 100644 (file)
@@ -113,12 +113,12 @@ fn drop(&mut self) {}
     field2: Variant4("str".to_string())
 };
 
-static STATIC15: &'static [Box<MyOwned>] = &'static [box MyOwned, box MyOwned];
+static STATIC15: &'static [Box<MyOwned>] = &[box MyOwned, box MyOwned];
 //~^ ERROR static items are not allowed to have custom pointers
 //~^^ ERROR static items are not allowed to have custom pointers
 
 static STATIC16: (&'static Box<MyOwned>, &'static Box<MyOwned>) =
-    (&'static box MyOwned, &'static box MyOwned);
+    (&box MyOwned, &box MyOwned);
 //~^ ERROR static items are not allowed to have custom pointers
 //~^^ ERROR static items are not allowed to have custom pointers
 
diff --git a/src/test/compile-fail/crateresolve2.rs b/src/test/compile-fail/crateresolve2.rs
deleted file mode 100644 (file)
index c5e9d12..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve2-1.rs
-// aux-build:crateresolve2-2.rs
-// aux-build:crateresolve2-3.rs
-// error-pattern:using multiple versions of crate `crateresolve2`
-
-extern crate crateresolve2 = "crateresolve2#0.1";
-
-mod m {
-    pub extern crate crateresolve2 = "crateresolve2#0.2";
-}
-
-fn main() {
-    let x: int = false;
-}
diff --git a/src/test/compile-fail/crateresolve5.rs b/src/test/compile-fail/crateresolve5.rs
deleted file mode 100644 (file)
index 8b48014..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2012-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.
-
-// aux-build:crateresolve5-1.rs
-// aux-build:crateresolve5-2.rs
-
-extern crate cr5_1 = "crateresolve5#0.1";
-extern crate cr5_2 = "crateresolve5#0.2";
-
-
-fn main() {
-    // Nominal types from two multiple versions of a crate are different types
-    assert!(cr5_1::nominal() == cr5_2::nominal()); //~ ERROR mismatched types: expected
-}
index 064a3b9b168be722c920abca67ac296850515ba1..47b576b2b85e5e0077df880546e2b7a6d2ce7a0e 100644 (file)
@@ -11,9 +11,9 @@
 #![feature(struct_variant)]
 
 enum Foo { C { a: int, b: int } }
-struct C { a: int, b: int }         //~ ERROR error: duplicate definition of type `C`
+struct C { a: int, b: int }         //~ ERROR error: duplicate definition of type or module `C`
 
 struct A { x: int }
-enum Bar { A { x: int } }           //~ ERROR error: duplicate definition of type `A`
+enum Bar { A { x: int } }           //~ ERROR error: duplicate definition of type or module `A`
 
 fn main() {}
diff --git a/src/test/compile-fail/enum-and-module-in-same-scope.rs b/src/test/compile-fail/enum-and-module-in-same-scope.rs
new file mode 100644 (file)
index 0000000..7464764
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+mod Foo {
+    pub static X: int = 42;
+}
+
+enum Foo {  //~ ERROR duplicate definition of type or module `Foo`
+    X
+}
+
+fn main() {}
index 848deac4d55c04822b94ba8d10d6b77e8dab8ed6..09cf9739614040679a39ddb73be474e7b7d50b71 100644 (file)
@@ -10,9 +10,9 @@
 
 fn main() {
     print!(test!());
-    //~^ ERROR: macro undefined: 'test'
+    //~^ ERROR: macro undefined: 'test!'
     //~^^ ERROR: format argument must be a string literal
 
     concat!(test!());
-    //~^ ERROR: macro undefined: 'test'
+    //~^ ERROR: macro undefined: 'test!'
 }
diff --git a/src/test/compile-fail/issue-11908-1.rs b/src/test/compile-fail/issue-11908-1.rs
deleted file mode 100644 (file)
index dbedf35..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:issue-11908-1.rs
-// ignore-android this test is incompatible with the android test runner
-// error-pattern: multiple dylib candidates for `url` found
-
-// This test ensures that if you have the same rlib or dylib at two locations
-// in the same path that you don't hit an assertion in the compiler.
-//
-// Note that this relies on `liburl` to be in the path somewhere else,
-// and then our aux-built libraries will collide with liburl (they have
-// the same version listed)
-
-extern crate url;
-
-fn main() {}
diff --git a/src/test/compile-fail/issue-11908-2.rs b/src/test/compile-fail/issue-11908-2.rs
deleted file mode 100644 (file)
index 8b916aa..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:issue-11908-2.rs
-// no-prefer-dynamic
-// ignore-android this test is incompatible with the android test runner
-// error-pattern: multiple rlib candidates for `url` found
-
-// see comments in issue-11908-1 for what's going on here
-
-extern crate url;
-
-fn main() {}
-
diff --git a/src/test/compile-fail/issue-12187-1.rs b/src/test/compile-fail/issue-12187-1.rs
new file mode 100644 (file)
index 0000000..ce21e33
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+fn new<T>() -> &'static T {
+    fail!()
+}
+
+fn main() {
+    let &v = new();
+    //~^ ERROR cannot determine a type for this local variable: unconstrained type
+}
diff --git a/src/test/compile-fail/issue-12187-2.rs b/src/test/compile-fail/issue-12187-2.rs
new file mode 100644 (file)
index 0000000..90da109
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+fn new<'r, T>() -> &'r T {
+    fail!()
+}
+
+fn main() {
+    let &v = new();
+    //~^ ERROR cannot determine a type for this local variable: unconstrained type
+}
index 2dcfeac513c3273c778bb1d8654a08f9e5bd954b..921e331e960dcbf57aa857b2b1b3080eeaabbb7c 100644 (file)
@@ -13,8 +13,8 @@ struct vec3 { y: f32, z: f32 }
 
 fn make(v: vec2) {
     let vec3 { y: _, z: _ } = v;
-    //~^ ERROR mismatched types: expected `vec2` but found `vec3`
+    //~^ ERROR `vec3` does not name the structure `vec2`
     //~^^ ERROR struct `vec2` does not have a field named `z`
 }
 
-fn main() { }
\ No newline at end of file
+fn main() { }
index 2c3dda015471fd265aa9ef2d19dc8797bbf3fbd4..00607f850347cc54c5b1c201d5c098e375470506 100644 (file)
 struct t(Box<t>); //~ ERROR this type cannot be instantiated
 
 trait to_str_2 {
-    fn my_to_str() -> String;
+    fn my_to_string() -> String;
 }
 
 // I use an impl here because it will cause
 // the compiler to attempt autoderef and then
 // try to resolve the method.
 impl to_str_2 for t {
-    fn my_to_str() -> String { "t".to_string() }
+    fn my_to_string() -> String { "t".to_string() }
 }
 
 fn new_t(x: t) {
-    x.my_to_str(); //~ ERROR does not implement
+    x.my_to_string(); //~ ERROR does not implement
 }
 
 fn main() {
index 1b11fcac8a385bb0ba403d17a285e608456eed3e..316199b6730bb2684f1d389345cd081778fe4ea6 100644 (file)
@@ -10,6 +10,6 @@
 
 enum a { b, c }
 
-enum a { d, e } //~ ERROR duplicate definition of type `a`
+enum a { d, e } //~ ERROR duplicate definition of type or module `a`
 
 fn main() {}
index 5502b18f094130910049e6f28d78ae2ce6f3f88e..b3f1b2a32eae3434ccc46c862bdad5e0802f83b1 100644 (file)
@@ -10,6 +10,6 @@
 
 pub mod a {}
 
-pub mod a {} //~ ERROR duplicate definition of module `a`
+pub mod a {} //~ ERROR duplicate definition of type or module `a`
 
 fn main() {}
index 9b77d62a065292f74c68a264fa58da80565db02c..57bc11379125f440caa1fda9f6d262ffffe15a50 100644 (file)
@@ -13,17 +13,17 @@ struct Point {
     y: f64,
 }
 
-trait NewTrait {
-    fn a(&self) -> String;
+trait ToString_ {
+    fn to_string(&self) -> String;
 }
 
-impl NewTrait for Point {
+impl ToString_ for Point {
     fn new(x: f64, y: f64) -> Point {
-    //~^ ERROR method `new` is not a member of trait `NewTrait`
+    //~^ ERROR method `new` is not a member of trait `ToString_`
         Point { x: x, y: y }
     }
 
-    fn a(&self) -> String {
+    fn to_string(&self) -> String {
         format!("({}, {})", self.x, self.y)
     }
 }
@@ -32,5 +32,5 @@ fn main() {
     let p = Point::new(0.0, 0.0);
     //~^ ERROR unresolved name `Point::new`
     //~^^ ERROR failed to resolve. Use of undeclared module `Point`
-    println!("{}", p.a());
+    println!("{}", p.to_string());
 }
diff --git a/src/test/compile-fail/lex-bad-char-literals.rs b/src/test/compile-fail/lex-bad-char-literals.rs
new file mode 100644 (file)
index 0000000..0eaa81b
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+static c: char =
+    '\u539_' //~ ERROR: illegal character in numeric character escape
+;
+
+static c2: char =
+    '\Uffffffff' //~ ERROR: illegal numeric character escape
+;
+
+static c3: char =
+    '\x1' //~ ERROR: numeric character escape is too short
+;
+
+static c4: char =
+    '\u23q' //~  ERROR: illegal character in numeric character escape
+;
+//~^^ ERROR: numeric character escape is too short
+
+static s: &'static str =
+    "\x1" //~ ERROR: numeric character escape is too short
+;
+
+static s2: &'static str =
+    "\u23q" //~ ERROR: illegal character in numeric character escape
+    //~^ ERROR: numeric character escape is too short
+;
+
+static c: char =
+    '\●' //~ ERROR: unknown character escape
+;
+
+static s: &'static str =
+    "\●" //~ ERROR: unknown character escape
+;
+
+// THIS MUST BE LAST, since unterminated character constants kill the lexer
+
+static c: char =
+    '●  //~ ERROR: unterminated character constant
+;
diff --git a/src/test/compile-fail/lex-bad-fp-base-1.rs b/src/test/compile-fail/lex-bad-fp-base-1.rs
deleted file mode 100644 (file)
index 659cb5c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let a = 0o1.0; //~ ERROR: octal float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bad-fp-base-2.rs b/src/test/compile-fail/lex-bad-fp-base-2.rs
deleted file mode 100644 (file)
index b1d45f7..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let b = 0o2f32; //~ ERROR: octal float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bad-fp-base-3.rs b/src/test/compile-fail/lex-bad-fp-base-3.rs
deleted file mode 100644 (file)
index 79c4236..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let c = 0o3.0f32; //~ ERROR: octal float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bad-fp-base-4.rs b/src/test/compile-fail/lex-bad-fp-base-4.rs
deleted file mode 100644 (file)
index eaea61b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let d = 0o4e4; //~ ERROR: octal float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bad-fp-base-5.rs b/src/test/compile-fail/lex-bad-fp-base-5.rs
deleted file mode 100644 (file)
index ee25ed9..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let e = 0o5.0e5; //~ ERROR: octal float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bad-fp-base-6.rs b/src/test/compile-fail/lex-bad-fp-base-6.rs
deleted file mode 100644 (file)
index bf08ec1..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let f = 0o6e6f32; //~ ERROR: octal float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bad-fp-base-7.rs b/src/test/compile-fail/lex-bad-fp-base-7.rs
deleted file mode 100644 (file)
index 921ed8f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let g = 0o7.0e7f64; //~ ERROR: octal float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bad-fp-base-8.rs b/src/test/compile-fail/lex-bad-fp-base-8.rs
deleted file mode 100644 (file)
index 10e334e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let h = 0x8.0e+9; //~ ERROR: hexadecimal float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bad-fp-base-9.rs b/src/test/compile-fail/lex-bad-fp-base-9.rs
deleted file mode 100644 (file)
index 3ea151c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let i = 0x9.0e-9; //~ ERROR: hexadecimal float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bad-fp-lit.rs b/src/test/compile-fail/lex-bad-fp-lit.rs
deleted file mode 100644 (file)
index 5a5e9d7..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static f: float =
-    1e+ //~ ERROR: scan_exponent: bad fp literal
-;
diff --git a/src/test/compile-fail/lex-bad-numeric-literals.rs b/src/test/compile-fail/lex-bad-numeric-literals.rs
new file mode 100644 (file)
index 0000000..9a490be
--- /dev/null
@@ -0,0 +1,35 @@
+// 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.
+
+fn main() {
+    0o1.0; //~ ERROR: octal float literal is not supported
+    0o2f32; //~ ERROR: octal float literal is not supported
+    0o3.0f32; //~ ERROR: octal float literal is not supported
+    0o4e4; //~ ERROR: octal float literal is not supported
+    0o5.0e5; //~ ERROR: octal float literal is not supported
+    0o6e6f32; //~ ERROR: octal float literal is not supported
+    0o7.0e7f64; //~ ERROR: octal float literal is not supported
+    0x8.0e+9; //~ ERROR: hexadecimal float literal is not supported
+    0x9.0e-9; //~ ERROR: hexadecimal float literal is not supported
+    0o; //~ ERROR: no valid digits
+    1e+; //~ ERROR: expected at least one digit in exponent
+    0x539.0; //~ ERROR: hexadecimal float literal is not supported
+    99999999999999999999999999999999; //~ ERROR: int literal is too large
+    99999999999999999999999999999999u32; //~ ERROR: int literal is too large
+    0x; //~ ERROR: no valid digits
+    0xu32; //~ ERROR: no valid digits
+    0ou32; //~ ERROR: no valid digits
+    0bu32; //~ ERROR: no valid digits
+    0b; //~ ERROR: no valid digits
+    0o123f64; //~ ERROR: octal float literal is not supported
+    0o123.456; //~ ERROR: octal float literal is not supported
+    0b101f64; //~ ERROR: binary float literal is not supported
+    0b111.101; //~ ERROR: binary float literal is not supported
+}
diff --git a/src/test/compile-fail/lex-bad-token.rs b/src/test/compile-fail/lex-bad-token.rs
new file mode 100644 (file)
index 0000000..d28d9a2
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+● //~ ERROR: unknown start of token
diff --git a/src/test/compile-fail/lex-hex-float-lit.rs b/src/test/compile-fail/lex-hex-float-lit.rs
deleted file mode 100644 (file)
index 457c612..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static f: float =
-    0x539.0 //~ ERROR: hexadecimal float literal is not supported
-;
diff --git a/src/test/compile-fail/lex-illegal-num-char-escape.rs b/src/test/compile-fail/lex-illegal-num-char-escape.rs
deleted file mode 100644 (file)
index 8f4c756..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static c: char =
-    '\u539_' //~ ERROR: illegal character in numeric character escape
-;
-
-static c2: char =
-    '\Uffffffff' //~ ERROR: illegal numeric character escape
-;
-
-static c3: char =
-    '\x1' //~ ERROR: numeric character escape is too short
-;
-
-static c4: char =
-    '\u23q' //~  ERROR: illegal character in numeric character escape
-;
-//~^^ ERROR: numeric character escape is too short
-
-static s: &'static str =
-    "\x1" //~ ERROR: numeric character escape is too short
-;
-
-static s2: &'static str =
-    "\u23q" //~ ERROR: illegal character in numeric character escape
-;
-//~^^ ERROR: numeric character escape is too short
diff --git a/src/test/compile-fail/lex-int-lit-too-large-2.rs b/src/test/compile-fail/lex-int-lit-too-large-2.rs
deleted file mode 100644 (file)
index 39d1cba..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static i: int =
-    99999999999999999999999999999999u32 //~ ERROR: int literal is too large
-;
diff --git a/src/test/compile-fail/lex-int-lit-too-large.rs b/src/test/compile-fail/lex-int-lit-too-large.rs
deleted file mode 100644 (file)
index 6343be6..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static i: int =
-    99999999999999999999999999999999 //~ ERROR: int literal is too large
-;
diff --git a/src/test/compile-fail/lex-no-valid-digits-2.rs b/src/test/compile-fail/lex-no-valid-digits-2.rs
deleted file mode 100644 (file)
index 549dbf5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static i: int =
-    0xu32 //~ ERROR: no valid digits
-;
diff --git a/src/test/compile-fail/lex-no-valid-digits.rs b/src/test/compile-fail/lex-no-valid-digits.rs
deleted file mode 100644 (file)
index 6a5b8e9..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static i: int =
-    0x //~ ERROR: no valid digits
-;
diff --git a/src/test/compile-fail/lex-unknown-char-escape.rs b/src/test/compile-fail/lex-unknown-char-escape.rs
deleted file mode 100644 (file)
index f2445c2..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static c: char =
-    '\●' //~ ERROR: unknown character escape
-;
diff --git a/src/test/compile-fail/lex-unknown-start-tok.rs b/src/test/compile-fail/lex-unknown-start-tok.rs
deleted file mode 100644 (file)
index 1bb6823..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    ● //~ ERROR: unknown start of token
-}
diff --git a/src/test/compile-fail/lex-unknown-str-escape.rs b/src/test/compile-fail/lex-unknown-str-escape.rs
deleted file mode 100644 (file)
index 9a59c42..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static s: &'static str =
-    "\●" //~ ERROR: unknown character escape
-;
diff --git a/src/test/compile-fail/lex-unterminated-char-const.rs b/src/test/compile-fail/lex-unterminated-char-const.rs
deleted file mode 100644 (file)
index 551360f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static c: char =
-    '●  //~ ERROR: unterminated character constant
-;
index 537c7d625554fc89383be292a547c7d15c3f976f..784930003d047570b32b4d7dc027b761983ff824 100644 (file)
@@ -32,4 +32,9 @@ enum Foo5 {
 trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
 }
 
+#[repr(C)]
+struct foo7 {
+    bar: int,
+}
+
 fn main() { }
index e5a5c7dd1c7c26a589bc9cc82ed2b68cfbfb7f1e..676a6e7cb4452f5e2843c207a339084095626336 100644 (file)
@@ -47,4 +47,9 @@ fn main() {
     let x = -2147483648_i32; // should be OK
     let x: i32 = -2147483649; //~ error: literal out of range for its type
     let x = -2147483649_i32; //~ error: literal out of range for its type
+
+    let x = -3.40282348e+38_f32; //~ error: literal out of range for its type
+    let x =  3.40282348e+38_f32; //~ error: literal out of range for its type
+    let x = -1.7976931348623159e+308_f64; //~ error: literal out of range for its type
+    let x =  1.7976931348623159e+308_f64; //~ error: literal out of range for its type
 }
index f1b36d719e9591603450e80b089e4a3d031aa4ea..279cf6d94cbf13626c615f6e6a5237d33e62bc82 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-tidy-linelength
+
 #![allow(dead_code)]
 #![deny(uppercase_variables)]
 
@@ -30,7 +32,7 @@ fn main() {
     let mut buff = [0u8, ..16];
     match f.read(buff) {
         Ok(cnt) => println!("read this many bytes: {}", cnt),
-        Err(IoError{ kind: EndOfFile, .. }) => println!("Got end of file: {}", EndOfFile.to_str()),
+        Err(IoError{ kind: EndOfFile, .. }) => println!("Got end of file: {}", EndOfFile.to_string()),
                         //~^ ERROR variable names should start with a lowercase character
     }
 
index 4bfa614063b5097189c2eb174e369426f209544f..e46d00c4ab9f65a73a612bb933d99da819decccb 100644 (file)
@@ -12,7 +12,7 @@
 
 fn main() {
     let a: Vec<int> = Vec::new();
-    a.iter().advance(|_| -> bool {
+    a.iter().all(|_| -> bool {
         //~^ ERROR mismatched types
     });
 }
index 73323def28d78d09e3f1117869c4276a0362b23b..1a2fb33eaabfed231cfcd2a4187c3b1f6d825fc3 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-tidy-linelength
 
 struct S {
     x: Box<E>
@@ -29,7 +30,7 @@ fn main() {
         f(&s, |hellothere| {
             match hellothere.x { //~ ERROR cannot move out
                 box Foo(_) => {}
-                box Bar(x) => println!("{}", x.to_str()), //~ NOTE attempting to move value to here
+                box Bar(x) => println!("{}", x.to_string()), //~ NOTE attempting to move value to here
                 box Baz => {}
             }
         })
index f772b96c697b7b9cc996e9f23584debc18892d31..c7b0bc8822be1dfda61e88f2fb02eed62226f10e 100644 (file)
@@ -12,7 +12,7 @@ struct S {
  y: int
 }
 
-impl Cmp, ToStr for S { //~ ERROR: expected `{` but found `,`
+impl Cmp, ToString for S { //~ ERROR: expected `{` but found `,`
   fn eq(&&other: S) { false }
-  fn to_str(&self) -> String { "hi".to_string() }
+  fn to_string(&self) -> String { "hi".to_string() }
 }
index 383a0ac46193fc7e8f58360b1efc3605180fe0e7..602ffe2680b04a7c7b79e7263d05810c0bc7d573 100644 (file)
@@ -14,7 +14,7 @@
 // Tests that the new `box` syntax works with unique pointers and GC pointers.
 
 use std::gc::{Gc, GC};
-use std::owned::{Box, HEAP};
+use std::boxed::{Box, HEAP};
 
 pub fn main() {
     let x: Gc<int> = box(HEAP) 2;  //~ ERROR mismatched types
index 779a1ec7a5bf022d5f11d7168f3f9135c8d5242f..2fb097f111db47f98727566112fc8e35047c49f0 100644 (file)
@@ -21,7 +21,7 @@ mod baz {
         impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+        impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
 
         fn foo() {
@@ -33,7 +33,7 @@ fn foo() {
     impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
     impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
     impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-    impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+    impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
     impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
 
     fn foo() {
@@ -48,7 +48,7 @@ mod qux_inner {
         impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+        impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
         impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
 
         fn foo() {
index fecc597b8fd2fff6ec0fd2acbdb3e647ee1bd1be..c0f7bea25b57ad88fddc5f218e6c75bd06fa1cdb 100644 (file)
@@ -20,7 +20,7 @@
 impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
 impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
 impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
 impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
 
 fn main() {
diff --git a/src/test/compile-fail/no-oct-float-literal.rs b/src/test/compile-fail/no-oct-float-literal.rs
deleted file mode 100644 (file)
index 511116b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:octal float literal is not supported
-
-fn main() {
-    0o123f64;
-    0o123.456;
-    0o123p4f;
-}
index 7fba306d868607103ed3dd124cca1fd481908d1d..6dc5ad8b606c37e7055f17596f5db1b43def01f0 100644 (file)
@@ -23,7 +23,7 @@ enum Color {
 
 fn struct_with_a_nested_enum_and_vector() {
     match (Foo { first: true, second: None }) {
-    //~^ ERROR non-exhaustive patterns: `Foo{first: false, second: Some([_, _, _, _])}` not covered
+//~^ ERROR non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered
         Foo { first: true, second: None } => (),
         Foo { first: true, second: Some(_) } => (),
         Foo { first: false, second: None } => (),
@@ -40,7 +40,7 @@ fn enum_with_multiple_missing_variants() {
 
 fn enum_struct_variant() {
     match Red {
-    //~^ ERROR non-exhaustive patterns: `CustomRGBA{a: true, r: _, g: _, b: _}` not covered
+    //~^ ERROR non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
         Red => (),
         Green => (),
         CustomRGBA { a: false, r: _, g: _, b: 0 } => (),
diff --git a/src/test/compile-fail/rustc-diagnostics-1.rs b/src/test/compile-fail/rustc-diagnostics-1.rs
new file mode 100644 (file)
index 0000000..55d8360
--- /dev/null
@@ -0,0 +1,28 @@
+// 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.
+
+#![feature(rustc_diagnostic_macros)]
+
+__register_diagnostic!(E0001)
+__register_diagnostic!(E0003)
+
+fn main() {
+    __diagnostic_used!(E0002);
+    //~^ ERROR unknown diagnostic code E0002
+
+    __diagnostic_used!(E0001);
+    //~^ NOTE previous invocation
+
+    __diagnostic_used!(E0001);
+    //~^ WARNING diagnostic code E0001 already used
+}
+
+__build_diagnostic_array!(DIAGNOSTICS)
+//~^ WARN diagnostic code E0003 never used
diff --git a/src/test/compile-fail/rustc-diagnostics-2.rs b/src/test/compile-fail/rustc-diagnostics-2.rs
new file mode 100644 (file)
index 0000000..c4e011b
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+#![feature(rustc_diagnostic_macros)]
+
+__register_diagnostic!(E0001)
+__register_diagnostic!(E0001)
+//~^ ERROR diagnostic code E0001 already registered
+
+fn main() {
+}
+
+__build_diagnostic_array!(DIAGNOSTICS)
diff --git a/src/test/compile-fail/rustc-diagnostics-3.rs b/src/test/compile-fail/rustc-diagnostics-3.rs
new file mode 100644 (file)
index 0000000..d160664
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+__register_diagnostic!(E0001)
+//~^ ERROR macro undefined: '__register_diagnostic!'
+
+fn main() {
+    __diagnostic_used!(E0001);
+    //~^ ERROR macro undefined: '__diagnostic_used!'
+}
+
+__build_diagnostic_array!(DIAGNOSTICS)
+//~^ ERROR macro undefined: '__build_diagnostic_array!'
diff --git a/src/test/compile-fail/typeck-cast-pointer-to-float.rs b/src/test/compile-fail/typeck-cast-pointer-to-float.rs
new file mode 100644 (file)
index 0000000..22a0978
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+fn main() {
+    let x : i16 = 22;
+    ((&x) as *const i16) as f32;
+    //~^ ERROR: cannot cast from pointer to float directly: `*const i16` as `f32`
+}
index fad20a7e37374a07f0f15f23a435b35198e77098..9f91337db9f21a6b106e7b93925ede0f0790b4eb 100644 (file)
@@ -11,7 +11,7 @@
 enum E {}
 
 fn f(e: E) {
-    println!("{}", (e as int).to_str());   //~ ERROR non-scalar cast
+    println!("{}", (e as int).to_string());   //~ ERROR non-scalar cast
 }
 
 fn main() {}
index fd09d78a4fa625a4d45ca766482943a6789a728a..6fd749b129819362c479ecf4d9ef759d7df1107e 100644 (file)
@@ -10,5 +10,5 @@
 
 // error-pattern: instantiating a type parameter with an incompatible type
 fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<T>() }
+fn foo<Sized? T>() { bar::<T>() }
 fn main() { }
index f586fbb576b323110c24e5b6d9dac73b489254b4..651eb26cadc6fe268a1526d29dab7ae4fa2b2c61 100644 (file)
@@ -10,5 +10,5 @@
 
 // error-pattern: instantiating a type parameter with an incompatible type
 fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<Option<T>>() }
+fn foo<Sized? T>() { bar::<Option<T>>() }
 fn main() { }
index 9fab3accbb9de8dcb8b7ae03c1e33aebb4ee6916..ec6aafb43f46f5dc04e082838d20b2e64559207c 100644 (file)
@@ -13,5 +13,5 @@
 struct Foo<T> { data: T }
 
 fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<Foo<T>>() }
+fn foo<Sized? T>() { bar::<Foo<T>>() }
 fn main() { }
index c5cc7e8f7163b271d4c4a97535bb173500daf6d7..c07dcf9368385425b6cbd0411a5ac443666075b4 100644 (file)
 
 
 // Unbounded.
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
     f2::<X>(x); //~ ERROR instantiating a type parameter with an incompatible type `X`, which does n
 }
 fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T for type {}
-fn f3<type X: T>(x: &X) {
+trait T for Sized? {}
+fn f3<Sized? X: T>(x: &X) {
     f4::<X>(x); //~ ERROR instantiating a type parameter with an incompatible type `X`, which does n
 }
 fn f4<X: T>(x: &X) {
 }
 
 // Test with unsized enum.
-enum E<type X> {
+enum E<Sized? X> {
     V(X),
 }
 
 fn f5<Y>(x: &Y) {}
-fn f6<type X>(x: &X) {}
-fn f7<type X>(x1: &E<X>, x2: &E<X>) {
+fn f6<Sized? X>(x: &X) {}
+fn f7<Sized? X>(x1: &E<X>, x2: &E<X>) {
     f5(x1); //~ERROR instantiating a type parameter with an incompatible type `E<X>`, which does not
     f6(x2); // ok
 }
 
 
 // Test with unsized struct.
-struct S<type X> {
+struct S<Sized? X> {
     x: X,
 }
 
-fn f8<type X>(x1: &S<X>, x2: &S<X>) {
+fn f8<Sized? X>(x1: &S<X>, x2: &S<X>) {
     f5(x1); //~ERROR instantiating a type parameter with an incompatible type `S<X>`, which does not
     f6(x2); // ok
 }
 
 // Test some tuples.
-fn f9<type X>(x1: Box<S<X>>, x2: Box<E<X>>) {
+fn f9<Sized? X>(x1: Box<S<X>>, x2: Box<E<X>>) {
     f5(&(*x1, 34i)); //~ERROR instantiating a type parameter with an incompatible type `(S<X>,int)`,
     f5(&(32i, *x2)); //~ERROR instantiating a type parameter with an incompatible type `(int,E<X>)`,
 }
@@ -60,20 +60,20 @@ fn f9<type X>(x1: Box<S<X>>, x2: Box<E<X>>) {
 // impl - bounded
 trait T1<Z: T> {
 }
-struct S3<type Y>;
-impl<type X: T> T1<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type
+struct S3<Sized? Y>;
+impl<Sized? X: T> T1<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type
 }
 
 // impl - unbounded
 trait T2<Z> {
 }
-impl<type X> T2<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type `X`
+impl<Sized? X> T2<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type `X
 
 // impl - struct
-trait T3<type Z> {
+trait T3<Sized? Z> {
 }
 struct S4<Y>;
-impl<type X> T3<X> for S4<X> { //ERROR instantiating a type parameter with an incompatible type `X`
+impl<Sized? X> T3<X> for S4<X> { //ERROR instantiating a type parameter with an incompatible type `X
 }
 */
 
index 968716320fd5ed6b63f1f842181622bac368729f..e377c9d5f417342f578373fbe512b4a46c1d32f4 100644 (file)
@@ -11,7 +11,7 @@
 // Test that bounds are sized-compatible.
 
 trait T {}
-fn f<type Y: T>() {
+fn f<Sized? Y: T>() {
 //~^ERROR incompatible bounds on type parameter Y, bound T does not allow unsized type
 }
 
index 614b8e3a5ab67904e60ff1acaea0882b0bddca40..7028f7e798b014b99f1a529c7ec795f23281e7e7 100644 (file)
@@ -9,19 +9,19 @@
 // except according to those terms.
 #![feature(struct_variant)]
 
-// Test `type` types not allowed in fields.
+// Test `Sized?` types not allowed in fields.
 
-struct S1<type X> {
+struct S1<Sized? X> {
     f1: X, //~ ERROR type `f1` is dynamically sized. dynamically sized types may only appear as the
     f2: int,
 }
-struct S2<type X> {
+struct S2<Sized? X> {
     f: int,
     g: X, //~ ERROR type `g` is dynamically sized. dynamically sized types may only appear as the ty
     h: int,
 }
 
-enum E<type X> {
+enum E<Sized? X> {
     V1(X, int), //~ERROR type `X` is dynamically sized. dynamically sized types may only appear as t
     V2{f1: X, f: int}, //~ERROR type `f1` is dynamically sized. dynamically sized types may only app
 }
index 061b003b5e3f023360e1e3d64c68437eddb89d15..def1146526b3920ab687411646849e2564fc55bc 100644 (file)
@@ -8,37 +8,37 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test `type` local variables.
+// Test `Sized?` local variables.
 
 
-trait T for type {}
+trait T for Sized? {}
 
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
     let _: X; //~ERROR variable `_` has dynamically sized type `X`
     let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
     let y: X; //~ERROR variable `y` has dynamically sized type `X`
     let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
 }
-fn f2<type X: T>(x: &X) {
+fn f2<Sized? X: T>(x: &X) {
     let _: X; //~ERROR variable `_` has dynamically sized type `X`
     let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
     let y: X; //~ERROR variable `y` has dynamically sized type `X`
     let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
 }
 
-fn f3<type X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f3<Sized? X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
     let y: X = *x1; //~ERROR variable `y` has dynamically sized type `X`
     let y = *x2; //~ERROR variable `y` has dynamically sized type `X`
     let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
 }
-fn f4<type X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f4<Sized? X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
     let y: X = *x1;         //~ERROR variable `y` has dynamically sized type `X`
     let y = *x2;            //~ERROR variable `y` has dynamically sized type `X`
     let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
 }
 
-fn g1<type X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
-fn g2<type X: T>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+fn g1<Sized? X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+fn g2<Sized? X: T>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
 
 pub fn main() {
 }
index 44058c1ddda190faec96844058b370847bc06605..ecc52c0ee7d58491b5f59f2d063b0ca078bcf7d4 100644 (file)
 #[must_use]
 enum MustUse { Test }
 
+#[must_use = "some message"]
+enum MustUseMsg { Test2 }
+
 fn foo<T>() -> T { fail!() }
 
 fn bar() -> int { return foo::<int>(); }
 fn baz() -> MustUse { return foo::<MustUse>(); }
+fn qux() -> MustUseMsg { return foo::<MustUseMsg>(); }
 
 #[allow(unused_result)]
 fn test() {
     foo::<int>();
     foo::<MustUse>(); //~ ERROR: unused result which must be used
+    foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
 }
 
 #[allow(unused_result, unused_must_use)]
 fn test2() {
     foo::<int>();
     foo::<MustUse>();
+    foo::<MustUseMsg>();
 }
 
 fn main() {
     foo::<int>(); //~ ERROR: unused result
     foo::<MustUse>(); //~ ERROR: unused result which must be used
+    foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
 
     let _ = foo::<int>();
     let _ = foo::<MustUse>();
+    let _ = foo::<MustUseMsg>();
 }
index 753c91d1dc9580ffde569ad6e219f1294ca0ea94..043f3a233a6253705718e010b41c340379f7af01 100644 (file)
@@ -23,10 +23,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 struct List {
-    list: Vec<Box<ToStr>> }
+    list: Vec<Box<ToString>> }
 
 impl List {
-    fn push(&mut self, n: Box<ToStr>) {
+    fn push(&mut self, n: Box<ToString>) {
         self.list.push(n);
     }
 }
@@ -35,6 +35,6 @@ fn main() {
     let n = box Number { n: 42 };
     let mut l = box List { list: Vec::new() };
     l.push(n);
-    let x = n.to_str();
+    let x = n.to_string();
     //~^ ERROR: use of moved value: `n`
 }
diff --git a/src/test/compile-fail/use-meta.rc b/src/test/compile-fail/use-meta.rc
deleted file mode 100644 (file)
index 9cb84c5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:can't find crate for `std`
-
-extern crate std = "std#bogus";
index 47de06c48569643acd172b9eeb9b000d4b558685..8f718add2a312afee49d955138cdd9ad2356d524 100644 (file)
@@ -21,4 +21,4 @@ pub fn p() -> C {
     C
 }
 
-fn main() { }
\ No newline at end of file
+fn main() { }
index 3b28af9b0e83f09c4db60be429cc14b171290f2d..c7753a67464ac64ad0e9b8193c8996632a076f41 100644 (file)
@@ -6,7 +6,6 @@ TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
 
 all:
        $(RUSTC) lib.rs
-       ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
        $(CC) main.c -o $(call RUN_BINFILE,main) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -lboot
        $(call RUN,main)
        $(call REMOVE_DYLIBS,boot)
index 69c65ef8b037a2869ee00682bf449942c742565d..7f17018c486c0e11ef543dc54e8fa4fa69bff0c9 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="boot#0.1"]
+#![crate_name="boot"]
 #![crate_type="dylib"]
 
 extern crate rustuv;
index 3b28af9b0e83f09c4db60be429cc14b171290f2d..c7753a67464ac64ad0e9b8193c8996632a076f41 100644 (file)
@@ -6,7 +6,6 @@ TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
 
 all:
        $(RUSTC) lib.rs
-       ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
        $(CC) main.c -o $(call RUN_BINFILE,main) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -lboot
        $(call RUN,main)
        $(call REMOVE_DYLIBS,boot)
index e743004a9cbc6caf86e4a8ba6395674954f9fc2d..a5b4430ab6a0c30d4a64da45bb359b77e4f65997 100644 (file)
@@ -4,7 +4,6 @@ HOST_LIB_DIR=$(TMPDIR)/../../../stage$(RUST_BUILD_STAGE)/lib
 
 all:
        $(RUSTC) foo.rs
-       ln -s $(call DYLIB,foo-*) $(call DYLIB,foo)
        $(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -Wl,-rpath,$(TMPDIR)
        $(call RUN,bar)
        $(call REMOVE_DYLIBS,foo)
index 40b6feac678233f1154f768c1112215bae4a4f94..8a6d6e4dd6d786122f2a338232d128c33cb32532 100644 (file)
@@ -10,7 +10,6 @@ endif
 ifneq ($(shell uname),FreeBSD)
 all:
        $(RUSTC) foo.rs
-       ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
        $(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRAFLAGS) -lstdc++
        $(call RUN,bar)
        rm $(call STATICLIB,foo*)
index a44481b4b7f23d75f339fa247fe7729c05d8db14..23d155fe23db33ede53de6780c652c98b4c59e83 100644 (file)
@@ -1,10 +1,9 @@
 -include ../tools.mk
 
 all:
-       [ `$(RUSTC) --crate-id crate.rs` = "foo#0.11.0" ]
-       [ `$(RUSTC) --crate-name crate.rs` = "foo" ]
-       [ `$(RUSTC) --crate-file-name crate.rs` = "foo" ]
-       [ `$(RUSTC) --crate-file-name --crate-type=lib --test crate.rs` = "foo" ]
-       [ `$(RUSTC) --crate-file-name --test lib.rs` = "mylib" ]
-       $(RUSTC) --crate-file-name lib.rs
-       $(RUSTC) --crate-file-name rlib.rs
+       [ `$(RUSTC) --print-crate-name crate.rs` = "foo" ]
+       [ `$(RUSTC) --print-file-name crate.rs` = "foo" ]
+       [ `$(RUSTC) --print-file-name --crate-type=lib --test crate.rs` = "foo" ]
+       [ `$(RUSTC) --print-file-name --test lib.rs` = "mylib" ]
+       $(RUSTC) --print-file-name lib.rs
+       $(RUSTC) --print-file-name rlib.rs
index 9faa7c016284bf054eec1849d20b436bb524263a..305b3dc70a625006de0c6f3a198e046bcf6a1ff0 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "foo#0.11.0"]
+#![crate_name = "foo"]
 
 // Querying about the crate metadata should *not* parse the entire crate, it
 // only needs the crate attributes (which are guaranteed to be at the top) be
index b40e055b3cba91642646a3aef6228df1e60fef48..639a5d0387b8ea045146515086885abdd0c89e4e 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "mylib"]
+#![crate_name = "mylib"]
 #![crate_type = "lib"]
index 94b8371e5375790d2bf63bcee91e4db536506e08..4e0937486003c19db4449023356883814c211b55 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "mylib"]
+#![crate_name = "mylib"]
 #![crate_type = "rlib"]
diff --git a/src/test/run-make/crate-name-priority/Makefile b/src/test/run-make/crate-name-priority/Makefile
new file mode 100644 (file)
index 0000000..2506027
--- /dev/null
@@ -0,0 +1,13 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo.rs
+       rm $(TMPDIR)/$(call BIN,foo)
+       $(RUSTC) foo.rs --crate-name bar
+       rm $(TMPDIR)/$(call BIN,bar)
+       $(RUSTC) foo1.rs
+       rm $(TMPDIR)/$(call BIN,foo)
+       $(RUSTC) foo1.rs --crate-name bar
+       rm $(TMPDIR)/$(call BIN,bar)
+       $(RUSTC) foo1.rs --crate-name bar -o $(TMPDIR)/bar1
+       rm $(TMPDIR)/$(call BIN,bar1)
diff --git a/src/test/run-make/crate-name-priority/foo.rs b/src/test/run-make/crate-name-priority/foo.rs
new file mode 100644 (file)
index 0000000..8ae3d07
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+fn main() {}
diff --git a/src/test/run-make/crate-name-priority/foo1.rs b/src/test/run-make/crate-name-priority/foo1.rs
new file mode 100644 (file)
index 0000000..0f02f10
--- /dev/null
@@ -0,0 +1,14 @@
+// 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.
+
+#![crate_name = "foo"]
+
+fn main() {}
+
index 4255b1d934d9c668edd49fa6a75944fc5c09d85d..7c15785bbb23d61eaa2a5e6315852dd2e9c2de25 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id="foo#0.1"]
+#![crate_name = "foo"]
 
 pub mod foo;
 pub mod bar;
diff --git a/src/test/run-make/extern-flag-disambiguates/Makefile b/src/test/run-make/extern-flag-disambiguates/Makefile
new file mode 100644 (file)
index 0000000..9b86bf9
--- /dev/null
@@ -0,0 +1,24 @@
+-include ../tools.mk
+
+# Attempt to build this dependency tree:
+#
+#      A.1   A.2
+#       |\    |
+#       | \   |
+#        B  \  C
+#         \ | /
+#          \|/
+#           D
+#
+# Note that A.1 and A.2 are crates with the same name.
+
+all:
+       $(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs
+       $(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs
+       $(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib
+       $(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib
+       $(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib
+       $(call RUN,d)
+       $(RUSTC) --cfg after  d.rs --extern a=$(TMPDIR)/liba-1.rlib
+       $(call RUN,d)
+
diff --git a/src/test/run-make/extern-flag-disambiguates/a.rs b/src/test/run-make/extern-flag-disambiguates/a.rs
new file mode 100644 (file)
index 0000000..11b9ba6
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+#![crate_name = "a"]
+#![crate_type = "rlib"]
+
+static FOO: uint = 3;
+
+pub fn token() -> &'static uint { &FOO }
diff --git a/src/test/run-make/extern-flag-disambiguates/b.rs b/src/test/run-make/extern-flag-disambiguates/b.rs
new file mode 100644 (file)
index 0000000..3156cf0
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+#![crate_name = "b"]
+#![crate_type = "rlib"]
+
+extern crate a;
+
+static FOO: uint = 3;
+
+pub fn token() -> &'static uint { &FOO }
+pub fn a_token() -> &'static uint { a::token() }
diff --git a/src/test/run-make/extern-flag-disambiguates/c.rs b/src/test/run-make/extern-flag-disambiguates/c.rs
new file mode 100644 (file)
index 0000000..d3bbc76
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+#![crate_name = "c"]
+#![crate_type = "rlib"]
+
+extern crate a;
+
+static FOO: uint = 3;
+
+pub fn token() -> &'static uint { &FOO }
+pub fn a_token() -> &'static uint { a::token() }
diff --git a/src/test/run-make/extern-flag-disambiguates/d.rs b/src/test/run-make/extern-flag-disambiguates/d.rs
new file mode 100644 (file)
index 0000000..d850daf
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+#[cfg(before)] extern crate a;
+extern crate b;
+extern crate c;
+#[cfg(after)] extern crate a;
+
+fn t(a: &'static uint) -> uint { a as *const _ as uint }
+
+fn main() {
+    assert!(t(a::token()) == t(b::a_token()));
+    assert!(t(a::token()) != t(c::a_token()));
+}
diff --git a/src/test/run-make/extern-flag-fun/Makefile b/src/test/run-make/extern-flag-fun/Makefile
new file mode 100644 (file)
index 0000000..ca5aa05
--- /dev/null
@@ -0,0 +1,16 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) bar.rs --crate-type=rlib
+       $(RUSTC) bar.rs --crate-type=rlib -C extra-filename=-a
+       $(RUSTC) foo.rs --extern hello && exit 1 || exit 0
+       $(RUSTC) foo.rs --extern bar=no-exist && exit 1 || exit 0
+       $(RUSTC) foo.rs --extern bar=foo.rs && exit 1 || exit 0
+       $(RUSTC) foo.rs \
+               --extern bar=$(TMPDIR)/libbar.rlib \
+               --extern bar=$(TMPDIR)/libbar-a.rlib \
+               && exit 1 || exit 0
+       $(RUSTC) foo.rs \
+               --extern bar=$(TMPDIR)/libbar.rlib \
+               --extern bar=$(TMPDIR)/libbar.rlib
+       $(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib
diff --git a/src/test/run-make/extern-flag-fun/bar.rs b/src/test/run-make/extern-flag-fun/bar.rs
new file mode 100644 (file)
index 0000000..2152aa7
--- /dev/null
@@ -0,0 +1,10 @@
+// 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.
+
diff --git a/src/test/run-make/extern-flag-fun/foo.rs b/src/test/run-make/extern-flag-fun/foo.rs
new file mode 100644 (file)
index 0000000..5274166
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+extern crate bar;
+
+fn main() {}
index 61b40d68dd1b56431ce2fbd2a9170cbf9dd35d7a..b431476f84a6636a9e3c7613d8546384df033ae8 100644 (file)
@@ -4,8 +4,8 @@ digraph block {
     N2[label="expr 6"];
     N3[label="expr S6{val: 6,}"];
     N4[label="local _x"];
-    N5[label="pat S6{val: _x}"];
-    N6[label="block { let S6{val: _x} = S6{val: 6,}; }"];
+    N5[label="pat S6 { val: _x }"];
+    N6[label="block { let S6 { val: _x } = S6{val: 6,}; }"];
     N0 -> N2;
     N2 -> N3;
     N3 -> N4;
diff --git a/src/test/run-make/issue-11908/Makefile b/src/test/run-make/issue-11908/Makefile
new file mode 100644 (file)
index 0000000..663a9f7
--- /dev/null
@@ -0,0 +1,23 @@
+# This test ensures that if you have the same rlib or dylib at two locations
+# in the same path that you don't hit an assertion in the compiler.
+#
+# Note that this relies on `liburl` to be in the path somewhere else,
+# and then our aux-built libraries will collide with liburl (they have
+# the same version listed)
+
+-include ../tools.mk
+
+all:
+       mkdir $(TMPDIR)/other
+       $(RUSTC) foo.rs --crate-type=dylib
+       mv $(call DYLIB,foo) $(TMPDIR)/other
+       $(RUSTC) foo.rs --crate-type=dylib
+       $(RUSTC) bar.rs -L $(TMPDIR)/other 2>&1 | \
+               grep "multiple dylib candidates"
+       rm -rf $(TMPDIR)
+       mkdir -p $(TMPDIR)/other
+       $(RUSTC) foo.rs --crate-type=rlib
+       mv $(TMPDIR)/libfoo.rlib $(TMPDIR)/other
+       $(RUSTC) foo.rs --crate-type=rlib
+       $(RUSTC) bar.rs -L $(TMPDIR)/other 2>&1 | \
+               grep "multiple rlib candidates"
diff --git a/src/test/run-make/issue-11908/bar.rs b/src/test/run-make/issue-11908/bar.rs
new file mode 100644 (file)
index 0000000..6316cfa
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+extern crate foo;
+
+fn main() {}
diff --git a/src/test/run-make/issue-11908/foo.rs b/src/test/run-make/issue-11908/foo.rs
new file mode 100644 (file)
index 0000000..0858d3c
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+#![crate_name = "foo"]
index 9b44c3e582a71da13db68407fedadaaf5435796c..6c7e9aa1d59fda347da1af71ffe94d2dcb5f1e21 100644 (file)
@@ -5,6 +5,5 @@ CC := $(CC:-g=)
 
 all:
        $(RUSTC) foo.rs -Z lto
-       ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
        $(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRACFLAGS) -lstdc++
        $(call RUN,bar)
index fbe967786e25ecb61c99a398e60a81ef37134689..04d3ae67207228d9bfe4d16f9873b5cd8bbe3f92 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[crate_type = "rlib"];
+#![crate_type = "rlib"]
diff --git a/src/test/run-make/manual-crate-name/Makefile b/src/test/run-make/manual-crate-name/Makefile
new file mode 100644 (file)
index 0000000..1d14199
--- /dev/null
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) --crate-name foo bar.rs
+       rm $(TMPDIR)/libfoo.rlib
diff --git a/src/test/run-make/manual-crate-name/bar.rs b/src/test/run-make/manual-crate-name/bar.rs
new file mode 100644 (file)
index 0000000..04d3ae6
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+#![crate_type = "rlib"]
diff --git a/src/test/run-make/metadata-flag-frobs-symbols/Makefile b/src/test/run-make/metadata-flag-frobs-symbols/Makefile
new file mode 100644 (file)
index 0000000..09e6ae0
--- /dev/null
@@ -0,0 +1,10 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo.rs -C metadata=a -C extra-filename=-a
+       $(RUSTC) foo.rs -C metadata=b -C extra-filename=-b
+       $(RUSTC) bar.rs \
+               --extern foo1=$(TMPDIR)/libfoo-a.rlib \
+               --extern foo2=$(TMPDIR)/libfoo-b.rlib \
+               -Z print-link-args
+       $(call RUN,bar)
diff --git a/src/test/run-make/metadata-flag-frobs-symbols/bar.rs b/src/test/run-make/metadata-flag-frobs-symbols/bar.rs
new file mode 100644 (file)
index 0000000..44b9e2f
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+extern crate foo1;
+extern crate foo2;
+
+fn main() {
+    let a = foo1::foo();
+    let b = foo2::foo();
+    assert!(a as *const _ != b as *const _);
+}
diff --git a/src/test/run-make/metadata-flag-frobs-symbols/foo.rs b/src/test/run-make/metadata-flag-frobs-symbols/foo.rs
new file mode 100644 (file)
index 0000000..ed04eed
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+#![crate_name = "foo"]
+#![crate_type = "rlib"]
+
+static FOO: uint = 3;
+
+pub fn foo() -> &'static uint { &FOO }
diff --git a/src/test/run-make/multiple-versions/Makefile b/src/test/run-make/multiple-versions/Makefile
new file mode 100644 (file)
index 0000000..e60c16a
--- /dev/null
@@ -0,0 +1,9 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo.rs -C metadata=a -C extra-filename=-1 --crate-type=rlib
+       $(RUSTC) foo.rs -C metadata=b -C extra-filename=-2 --crate-type=rlib
+       $(RUSTC) bar.rs \
+               --extern foo1=$(TMPDIR)/libfoo-1.rlib \
+               --extern foo2=$(TMPDIR)/libfoo-2.rlib \
+               2>&1 | grep "using multiple versions of crate .foo."
diff --git a/src/test/run-make/multiple-versions/bar.rs b/src/test/run-make/multiple-versions/bar.rs
new file mode 100644 (file)
index 0000000..262193a
--- /dev/null
@@ -0,0 +1,14 @@
+// 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.
+
+extern crate foo1;
+extern crate foo2;
+
+fn main() {}
diff --git a/src/test/run-make/multiple-versions/foo.rs b/src/test/run-make/multiple-versions/foo.rs
new file mode 100644 (file)
index 0000000..2661b1f
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+pub fn foo() {}
index 020fbc3299b6831db6acecb421d34bc2c9706c9c..bb5796bd8737ff3c01d46d8aa588766c672a62ab 100644 (file)
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_id = "bar"]
+#![crate_name = "bar"]
 
 fn main() {}
index dda66f051bc8e5f829c2d93ace664476755e29f2..b783dd39a061a52724b639ba4569ae7c956aa443 100644 (file)
@@ -22,4 +22,8 @@ pub fn baz() { }
 
     /// *wow*
     pub trait Doge { }
+
+    pub struct Foo { x: int, y: uint }
+
+    pub fn prawns((a, b): (int, uint), Foo { x, y }: Foo) { }
 }
index debd89d9929b75784bf89d99ae547e876acca937..5d6e629ffc1d1627dccc0be3042322042e096d0f 100644 (file)
@@ -1,9 +1,12 @@
 -include ../tools.mk
 
 all:
-       $(RUSTC) foo.rs -o $(TMPDIR)/.foo
-       rm $(TMPDIR)/.foo
-       $(RUSTC) foo.rs -o $(TMPDIR)/.foo.bar
-       rm $(TMPDIR)/.foo.bar
-       $(RUSTC) foo.rs -o $(TMPDIR)/+foo+bar
-       rm $(TMPDIR)/$(call BIN,+foo+bar)
+       cp foo.rs $(TMPDIR)/.foo.rs
+       $(RUSTC) $(TMPDIR)/.foo.rs 2>&1 \
+               | grep "invalid character.*in crate name:"
+       cp foo.rs $(TMPDIR)/.foo.bar
+       $(RUSTC) $(TMPDIR)/.foo.bar 2>&1 \
+               | grep "invalid character.*in crate name:"
+       cp foo.rs $(TMPDIR)/+foo+bar
+       $(RUSTC) $(TMPDIR)/+foo+bar 2>&1 \
+               | grep "invalid character.*in crate name:"
index dddec5a56249b68d3d42dea178d1b464329a5265..1ffee6aad7603c8e0bf1f9d870ddf31bb20296d8 100644 (file)
@@ -19,13 +19,13 @@ trait iterable<A> {
 
 impl<'a,A> iterable<A> for &'a [A] {
     fn iterate(&self, f: |x: &A| -> bool) -> bool {
-        self.iter().advance(f)
+        self.iter().all(f)
     }
 }
 
 impl<A> iterable<A> for Vec<A> {
     fn iterate(&self, f: |x: &A| -> bool) -> bool {
-        self.iter().advance(f)
+        self.iter().all(f)
     }
 }
 
index 97862844030b2c7c52ba97f790bfdec300246ea3..c2a1c01b919ab05f3a29bb9b63f5acde3778424a 100644 (file)
@@ -37,19 +37,8 @@ fn double() {
 }
 
 fn runtest(me: &str) {
-    let mut env = os::env().move_iter()
-                           .map(|(ref k, ref v)| {
-                               (k.to_string(), v.to_string())
-                           }).collect::<Vec<(String,String)>>();
-    match env.iter()
-             .position(|&(ref s, _)| "RUST_BACKTRACE" == s.as_slice()) {
-        Some(i) => { env.remove(i); }
-        None => {}
-    }
-    env.push(("RUST_BACKTRACE".to_string(), "1".to_string()));
-
     // Make sure that the stack trace is printed
-    let mut p = Command::new(me).arg("fail").env(env.as_slice()).spawn().unwrap();
+    let mut p = Command::new(me).arg("fail").env("RUST_BACKTRACE", "1").spawn().unwrap();
     let out = p.wait_with_output().unwrap();
     assert!(!out.status.success());
     let s = str::from_utf8(out.error.as_slice()).unwrap();
@@ -73,7 +62,8 @@ fn runtest(me: &str) {
             "bad output3: {}", s);
 
     // Make sure a stack trace isn't printed too many times
-    let mut p = Command::new(me).arg("double-fail").env(env.as_slice()).spawn().unwrap();
+    let mut p = Command::new(me).arg("double-fail")
+                                .env("RUST_BACKTRACE", "1").spawn().unwrap();
     let out = p.wait_with_output().unwrap();
     assert!(!out.status.success());
     let s = str::from_utf8(out.error.as_slice()).unwrap();
index 8c2dba243c87c7da5f95bb6729b942eaef6b6b7f..3823a7033f5a61c536ab9a57ed5a81d5660d8aa7 100644 (file)
@@ -13,8 +13,8 @@
 use std::collections::Bitv;
 
 fn bitv_test() {
-    let mut v1 = box Bitv::new(31, false);
-    let v2 = box Bitv::new(31, true);
+    let mut v1 = box Bitv::with_capacity(31, false);
+    let v2 = box Bitv::with_capacity(31, true);
     v1.union(v2);
 }
 
index cb364d23387cfed7cfb5a9f47893c4d355d4b8f8..91075633ab8d844c5ac9ea84725018ac779d362b 100644 (file)
@@ -49,9 +49,9 @@ fn main() {
     assert_eq!(!true, false);
     assert_eq!(!false, true);
 
-    let s = false.to_str();
+    let s = false.to_string();
     assert_eq!(s.as_slice(), "false");
-    let s = true.to_str();
+    let s = true.to_string();
     assert_eq!(s.as_slice(), "true");
 
     assert!(true > false);
index 1bf29fb34825ec05b13184498221826ce82a86db..c0be4abafbe9a2f28c22d0919ed40bf81f4f79f1 100644 (file)
@@ -24,7 +24,7 @@ fn add_int(x: &mut Ints, v: int) {
 
 fn iter_ints(x: &Ints, f: |x: &int| -> bool) -> bool {
     let l = x.values.len();
-    range(0u, l).advance(|i| f(x.values.get(i)))
+    range(0u, l).all(|i| f(x.values.get(i)))
 }
 
 pub fn main() {
index 1e28c44206ffc9492333bac1ed1ca273935d3c92..ac470268d319fc7f2788fb4e9fd1a99918d80eb2 100644 (file)
@@ -46,6 +46,13 @@ pub fn main() {
         _ => fail!(),
     }
 
+    let buf = vec!(97u8, 98, 99, 100);
+    assert_eq!(match buf.slice(0, 3) {
+         b"def" => 1u,
+         b"abc" => 2u,
+         _ => 3u
+    }, 2);
+
     assert_eq!(BAZ, &[97u8, 92u8, 110u8]);
     assert_eq!(br"a\n", &[97u8, 92u8, 110u8]);
     assert_eq!(br"a\n", b"a\\n");
index 19186f4b46bcef9fb0fd50168477d58c822715f3..33ee2ffd3592ce2f6c708892221f2d79d3724c84 100644 (file)
@@ -45,7 +45,7 @@ fn main() {
         debug!("debug");
         info!("info");
     });
-    let s = r.read_to_str().unwrap();
+    let s = r.read_to_string().unwrap();
     assert!(s.as_slice().contains("info"));
     assert!(!s.as_slice().contains("debug"));
 }
index f3d12d21684e4f9324d9746bf96df4cd7bd712c3..e3dbaa62d353264ed5eb1b40e6bf0e49581a1f1f 100644 (file)
 // aux-build:cci_class_cast.rs
 extern crate cci_class_cast;
 
-use std::to_str::ToStr;
+use std::to_str::ToString;
 use cci_class_cast::kitty::cat;
 
-fn print_out(thing: Box<ToStr>, expected: String) {
-  let actual = thing.to_str();
+fn print_out(thing: Box<ToString>, expected: String) {
+  let actual = thing.to_string();
   println!("{}", actual);
   assert_eq!(actual.to_string(), expected);
 }
 
 pub fn main() {
-  let nyan: Box<ToStr> = box cat(0u, 2, "nyan".to_string()) as Box<ToStr>;
+  let nyan: Box<ToString> = box cat(0u, 2, "nyan".to_string()) as Box<ToString>;
   print_out(nyan, "nyan".to_string());
 }
index 3d486144c3eed8005743ab72f61ce5f117b73210..7143888298072da85d34254ace13f980bf6ceddd 100644 (file)
@@ -57,13 +57,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-fn print_out(thing: Box<ToStr>, expected: String) {
-  let actual = thing.to_str();
+fn print_out(thing: Box<ToString>, expected: String) {
+  let actual = thing.to_string();
   println!("{}", actual);
   assert_eq!(actual.to_string(), expected);
 }
 
 pub fn main() {
-  let nyan: Box<ToStr> = box cat(0u, 2, "nyan".to_string()) as Box<ToStr>;
+  let nyan: Box<ToString> = box cat(0u, 2, "nyan".to_string()) as Box<ToString>;
   print_out(nyan, "nyan".to_string());
 }
diff --git a/src/test/run-pass/crate-name-attr-used.rs b/src/test/run-pass/crate-name-attr-used.rs
new file mode 100644 (file)
index 0000000..abc565d
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+// compile-flags:--crate-name crate-name-attr-used -F unused-attribute
+
+#![crate_name = "test"]
+
+fn main() {}
diff --git a/src/test/run-pass/crateresolve1.rs b/src/test/run-pass/crateresolve1.rs
deleted file mode 100644 (file)
index 61e269b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2012-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.
-
-// aux-build:crateresolve1-1.rs
-// aux-build:crateresolve1-2.rs
-// aux-build:crateresolve1-3.rs
-
-extern crate crateresolve1 = "crateresolve1#0.2";
-
-pub fn main() {
-    assert_eq!(crateresolve1::f(), 20);
-}
diff --git a/src/test/run-pass/crateresolve2.rs b/src/test/run-pass/crateresolve2.rs
deleted file mode 100644 (file)
index 5ed1f37..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2012-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.
-
-// aux-build:crateresolve2-1.rs
-// aux-build:crateresolve2-2.rs
-// aux-build:crateresolve2-3.rs
-
-mod a {
-    extern crate crateresolve2 = "crateresolve2#0.1";
-    pub fn f() { assert!(crateresolve2::f() == 10); }
-}
-
-mod b {
-    extern crate crateresolve2 = "crateresolve2#0.2";
-    pub fn f() { assert!(crateresolve2::f() == 20); }
-}
-
-mod c {
-    extern crate crateresolve2 = "crateresolve2#0.3";
-    pub fn f() { assert!(crateresolve2::f() == 30); }
-}
-
-pub fn main() {
-    a::f();
-    b::f();
-    c::f();
-}
diff --git a/src/test/run-pass/crateresolve3.rs b/src/test/run-pass/crateresolve3.rs
deleted file mode 100644 (file)
index cee9e69..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2012-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.
-
-// aux-build:crateresolve3-1.rs
-// aux-build:crateresolve3-2.rs
-
-// verify able to link with crates with same name but different versions
-// as long as no name collision on invoked functions.
-
-mod a {
-    extern crate crateresolve3 = "crateresolve3#0.1";
-    pub fn f() { assert!(crateresolve3::f() == 10); }
-}
-
-mod b {
-    extern crate crateresolve3 = "crateresolve3#0.2";
-    pub fn f() { assert!(crateresolve3::g() == 20); }
-}
-
-pub fn main() {
-    a::f();
-    b::f();
-}
diff --git a/src/test/run-pass/crateresolve4.rs b/src/test/run-pass/crateresolve4.rs
deleted file mode 100644 (file)
index c689615..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2012-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.
-
-// aux-build:crateresolve4a-1.rs
-// aux-build:crateresolve4a-2.rs
-// aux-build:crateresolve4b-1.rs
-// aux-build:crateresolve4b-2.rs
-
-pub mod a {
-    extern crate crateresolve4b = "crateresolve4b#0.1";
-    pub fn f() { assert!(crateresolve4b::f() == 20); }
-}
-
-pub mod b {
-    extern crate crateresolve4b = "crateresolve4b#0.2";
-    pub fn f() { assert!(crateresolve4b::g() == 10); }
-}
-
-pub fn main() {
-    a::f();
-    b::f();
-}
diff --git a/src/test/run-pass/crateresolve5.rs b/src/test/run-pass/crateresolve5.rs
deleted file mode 100644 (file)
index 3f74731..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012-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.
-
-// aux-build:crateresolve5-1.rs
-// aux-build:crateresolve5-2.rs
-
-extern crate cr5_1 = "crateresolve5#0.1";
-extern crate cr5_2 = "crateresolve5#0.2";
-
-pub fn main() {
-    // Structural types can be used between two versions of the same crate
-    assert!(cr5_1::struct_nameval().name == cr5_2::struct_nameval().name);
-    assert!(cr5_1::struct_nameval().val == cr5_2::struct_nameval().val);
-    // Make sure these are actually two different crates
-    assert!(cr5_1::f() == 10 && cr5_2::f() == 20);
-}
diff --git a/src/test/run-pass/crateresolve8.rs b/src/test/run-pass/crateresolve8.rs
deleted file mode 100644 (file)
index f04e383..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012-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.
-
-// aux-build:crateresolve8-1.rs
-
-#![crate_id="crateresolve8#0.1"]
-
-extern crate crateresolve8 = "crateresolve8#0.1";
-//extern crate crateresolve8(vers = "0.1");
-
-pub fn main() {
-    assert_eq!(crateresolve8::f(), 20);
-}
diff --git a/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs
new file mode 100644 (file)
index 0000000..a7738bb
--- /dev/null
@@ -0,0 +1,55 @@
+// 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.
+
+// This briefuly tests the capability of `Cell` and `RefCell` to implement the
+// `Encodable` and `Decodable` traits via `#[deriving(Encodable, Decodable)]`
+
+extern crate serialize;
+
+use std::cell::{Cell, RefCell};
+use std::io::MemWriter;
+use serialize::{Encodable, Decodable};
+use serialize::ebml;
+use serialize::ebml::writer::Encoder;
+use serialize::ebml::reader::Decoder;
+
+#[deriving(Encodable, Decodable)]
+struct A {
+    baz: int
+}
+
+#[deriving(Encodable, Decodable)]
+struct B {
+    foo: Cell<bool>,
+    bar: RefCell<A>,
+}
+
+fn main() {
+    let obj = B {
+        foo: Cell::new(true),
+        bar: RefCell::new( A { baz: 2 } )
+    };
+    let mut w = MemWriter::new();
+    {
+        let mut e = Encoder::new(&mut w);
+        match obj.encode(&mut e) {
+            Ok(()) => (),
+            Err(e) => fail!("Failed to encode: {}", e)
+        };
+    }
+    let doc = ebml::Doc::new(w.get_ref());
+    let mut dec = Decoder::new(doc);
+    let obj2: B = match Decodable::decode(&mut dec) {
+        Ok(v) => v,
+        Err(e) => fail!("Failed to decode: {}", e)
+    };
+    assert!(obj.foo.get() == obj2.foo.get());
+    assert!(obj.bar.borrow().baz == obj2.bar.borrow().baz);
+}
index a5e86dee18e8cadd5d35dc95dc5c5c0229f782bc..fa82e42d793f03ddc52bcaf00588cdff44ef7418 100644 (file)
@@ -41,15 +41,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 pub fn main() {
-    assert_eq!(B1.to_str(), "B1".to_string());
-    assert_eq!(B2.to_str(), "B2".to_string());
-    assert_eq!(C1(3).to_str(), "C1(3)".to_string());
-    assert_eq!(C2(B2).to_str(), "C2(B2)".to_string());
-    assert_eq!(D1{ a: 2 }.to_str(), "D1 { a: 2 }".to_string());
-    assert_eq!(E.to_str(), "E".to_string());
-    assert_eq!(F(3).to_str(), "F(3)".to_string());
-    assert_eq!(G(3, 4).to_str(), "G(3, 4)".to_string());
-    assert_eq!(G(3, 4).to_str(), "G(3, 4)".to_string());
-    assert_eq!(I{ a: 2, b: 4 }.to_str(), "I { a: 2, b: 4 }".to_string());
-    assert_eq!(J(Custom).to_str(), "J(yay)".to_string());
+    assert_eq!(B1.to_string(), "B1".to_string());
+    assert_eq!(B2.to_string(), "B2".to_string());
+    assert_eq!(C1(3).to_string(), "C1(3)".to_string());
+    assert_eq!(C2(B2).to_string(), "C2(B2)".to_string());
+    assert_eq!(D1{ a: 2 }.to_string(), "D1 { a: 2 }".to_string());
+    assert_eq!(E.to_string(), "E".to_string());
+    assert_eq!(F(3).to_string(), "F(3)".to_string());
+    assert_eq!(G(3, 4).to_string(), "G(3, 4)".to_string());
+    assert_eq!(G(3, 4).to_string(), "G(3, 4)".to_string());
+    assert_eq!(I{ a: 2, b: 4 }.to_string(), "I { a: 2, b: 4 }".to_string());
+    assert_eq!(J(Custom).to_string(), "J(yay)".to_string());
 }
diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs
new file mode 100644 (file)
index 0000000..bd9dfc1
--- /dev/null
@@ -0,0 +1,40 @@
+// 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 std::gc::Gc;
+use std::mem::size_of;
+
+trait Trait {}
+
+fn main() {
+    // Closures - || / proc()
+    assert_eq!(size_of::<proc()>(), size_of::<Option<proc()>>());
+    assert_eq!(size_of::<||>(), size_of::<Option<||>>());
+
+    // Functions
+    assert_eq!(size_of::<fn(int)>(), size_of::<Option<fn(int)>>());
+    assert_eq!(size_of::<extern "C" fn(int)>(), size_of::<Option<extern "C" fn(int)>>());
+
+    // Slices - &str / &[T] / &mut [T]
+    assert_eq!(size_of::<&str>(), size_of::<Option<&str>>());
+    assert_eq!(size_of::<&[int]>(), size_of::<Option<&[int]>>());
+    assert_eq!(size_of::<&mut [int]>(), size_of::<Option<&mut [int]>>());
+
+    // Traits - Box<Trait> / &Trait / &mut Trait
+    assert_eq!(size_of::<Box<Trait>>(), size_of::<Option<Box<Trait>>>());
+    assert_eq!(size_of::<&Trait>(), size_of::<Option<&Trait>>());
+    assert_eq!(size_of::<&mut Trait>(), size_of::<Option<&mut Trait>>());
+
+    // Pointers - Box<T> / Gc<T>
+    assert_eq!(size_of::<Box<int>>(), size_of::<Option<Box<int>>>());
+    assert_eq!(size_of::<Gc<int>>(), size_of::<Option<Gc<int>>>());
+
+}
index bb236638905ba9d47c21d65fa67122ff3176c215..7e71be4114836c30a441552d24dd19f13e717c35 100644 (file)
 #![feature(macro_rules)]
 
 use s = std::num::strconv;
-use to_str = std::num::strconv::float_to_str_common;
+use to_string = std::num::strconv::float_to_str_common;
 
 macro_rules! t(($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()) } })
 
 pub fn main() {
     // Basic usage
-    t!(to_str(1.2345678e-5f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpDec, false),
+    t!(to_string(1.2345678e-5f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpDec, false),
              "1.234568e-5")
 
     // Hexadecimal output
-    t!(to_str(7.281738281250e+01f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(7.281738281250e+01f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
               "+1.2345p+6")
-    t!(to_str(-1.777768135071e-02f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(-1.777768135071e-02f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
              "-1.2345p-6")
 
     // Some denormals
-    t!(to_str(4.9406564584124654e-324f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(4.9406564584124654e-324f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
              "1p-1074")
-    t!(to_str(2.2250738585072009e-308f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
+    t!(to_string(2.2250738585072009e-308f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
              "1p-1022")
 }
index 3faf5744199862c9ba9533504c25f459fad7c8ec..5dc25c85325c0f20780e82bf4784a91af87da3d1 100644 (file)
@@ -10,7 +10,7 @@
 
 //aux-build:extern-crosscrate-source.rs
 
-extern crate externcallback = "externcallback#0.1";
+extern crate externcallback;
 
 fn fact(n: uint) -> uint {
     unsafe {
index 62cfd10dbfb468c6a1a298e23f2cc07e24e8dd13..3b7c5083bb48ef1a42e820d111b6db91882f2288 100644 (file)
@@ -17,6 +17,6 @@ struct Struc { a: u8, b: [int, ..3], c: int }
 pub fn main() {
     let arr = [1,2,3];
     let struc = Struc {a: 13u8, b: arr, c: 42};
-    let s = repr::repr_to_str(&struc);
+    let s = repr::repr_to_string(&struc);
     assert_eq!(s, "Struc{a: 13u8, b: [1, 2, 3], c: 42}".to_string());
 }
index c300b8c93359d9ce87f5e58f797d0eae34939e39..10d6e0158f6f225ff2f69cfff12b88d85385b6c8 100644 (file)
 fn main() {
     // Generate sieve of Eratosthenes for n up to 1e6
     let n = 1000000u;
-    let sieve = Bitv::new(n+1, true);
+    let mut sieve = Bitv::with_capacity(n+1, true);
     let limit: uint = (n as f32).sqrt() as uint;
     for i in range(2, limit+1) {
         if sieve[i] {
             let mut j = 0;
             while i*i + j*i <= n {
-                sieve[i*i+j*i] = false;
+                sieve.set(i*i+j*i, false);
                 j += 1;
             }
         }
diff --git a/src/test/run-pass/issue-15149.rs b/src/test/run-pass/issue-15149.rs
new file mode 100644 (file)
index 0000000..d76a710
--- /dev/null
@@ -0,0 +1,56 @@
+// 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.
+
+#![feature(phase)]
+extern crate native;
+#[phase(plugin)]
+extern crate green;
+
+use native::NativeTaskBuilder;
+use std::io::{TempDir, Command, fs};
+use std::os;
+use std::task::TaskBuilder;
+
+// FIXME(#15149) libgreen still needs to be update. There is an open PR for it
+//               but it is not yet merged.
+// green_start!(main)
+
+fn main() {
+    // If we're the child, make sure we were invoked correctly
+    let args = os::args();
+    if args.len() > 1 && args.get(1).as_slice() == "child" {
+        return assert_eq!(args.get(0).as_slice(), "mytest");
+    }
+
+    test();
+    let (tx, rx) = channel();
+    TaskBuilder::new().native().spawn(proc() {
+        tx.send(test());
+    });
+    rx.recv();
+}
+
+fn test() {
+    // If we're the parent, copy our own binary to a tempr directory, and then
+    // make it executable.
+    let dir = TempDir::new("mytest").unwrap();
+    let me = os::self_exe_name().unwrap();
+    let dest = dir.path().join(format!("mytest{}", os::consts::EXE_SUFFIX));
+    fs::copy(&me, &dest).unwrap();
+
+    // Append the temp directory to our own PATH.
+    let mut path = os::split_paths(os::getenv("PATH").unwrap_or(String::new()));
+    path.push(dir.path().clone());
+    let path = os::join_paths(path.as_slice()).unwrap();
+
+    Command::new("mytest").env("PATH", path.as_slice())
+                          .arg("child")
+                          .spawn().unwrap();
+}
diff --git a/src/test/run-pass/issue-15487.rs b/src/test/run-pass/issue-15487.rs
new file mode 100644 (file)
index 0000000..ee75958
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+// ignore-win32
+
+#![feature(link_args)]
+
+#[link_args="-lc  -lm"]
+#[link_args=" -lc"]
+#[link_args="-lc "]
+extern {}
+
+fn main() {}
index d48a944c2f0d8aa060d9d2a4b371fd56cde7923d..4a89d277e9f5634568952f9ca7b0ee1d538d6418 100644 (file)
@@ -79,8 +79,8 @@ fn read_board_grid<rdr:'static + io::Reader>(mut input: rdr)
 
 mod test {
     #[test]
-    pub fn trivial_to_str() {
-        assert!(lambda.to_str() == "\\")
+    pub fn trivial_to_string() {
+        assert!(lambda.to_string() == "\\")
     }
 }
 
index 1d442198aec706084a35842deb24b6d19586259d..1555098f2911be5d5df7100abba6f28eb8ce0fbb 100644 (file)
@@ -10,7 +10,7 @@
 
 enum what { }
 
-fn what_to_str(x: what) -> String
+fn what_to_string(x: what) -> String
 {
     match x {
     }
index 53f92246e54c9966ac9c2de41ada6b4f0b73dd9a..2568d94fcbf9e4f14d62ae0b00bdcb228e0040e2 100644 (file)
@@ -24,6 +24,6 @@ pub fn main() {
     let mut table = HashMap::new();
     table.insert("one".to_string(), 1i);
     table.insert("two".to_string(), 2i);
-    assert!(check_strs(table.to_str().as_slice(), "{one: 1, two: 2}") ||
-            check_strs(table.to_str().as_slice(), "{two: 2, one: 1}"));
+    assert!(check_strs(table.to_string().as_slice(), "{one: 1, two: 2}") ||
+            check_strs(table.to_string().as_slice(), "{two: 2, one: 1}"));
 }
index ac022d5c212388956b446e4ad3992138f25250c9..e38969c25263caada3a4b7fd44ce00e7c3397ef4 100644 (file)
@@ -94,7 +94,7 @@ fn add_pt(&mut self, x: int, y: int) {
     }
 }
 
-// Allows AsciiArt to be converted to a string using the libcore ToStr trait.
+// Allows AsciiArt to be converted to a string using the libcore ToString trait.
 // Note that the %s fmt! specifier will not call this automatically.
 impl fmt::Show for AsciiArt {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -159,7 +159,7 @@ pub fn check_strs(actual: &str, expected: &str) -> bool {
 
 fn test_ascii_art_ctor() {
     let art = AsciiArt(3, 3, '*');
-    assert!(check_strs(art.to_str().as_slice(), "...\n...\n..."));
+    assert!(check_strs(art.to_string().as_slice(), "...\n...\n..."));
 }
 
 
@@ -168,7 +168,7 @@ fn test_add_pt() {
     art.add_pt(0, 0);
     art.add_pt(0, -10);
     art.add_pt(1, 2);
-    assert!(check_strs(art.to_str().as_slice(), "*..\n...\n.*."));
+    assert!(check_strs(art.to_string().as_slice(), "*..\n...\n.*."));
 }
 
 
@@ -176,7 +176,7 @@ fn test_shapes() {
     let mut art = AsciiArt(4, 4, '*');
     art.add_rect(Rect {top_left: Point {x: 0, y: 0}, size: Size {width: 4, height: 4}});
     art.add_point(Point {x: 2, y: 2});
-    assert!(check_strs(art.to_str().as_slice(), "****\n*..*\n*.**\n****"));
+    assert!(check_strs(art.to_string().as_slice(), "****\n*..*\n*.**\n****"));
 }
 
 pub fn main() {
index c9cedc3b7de47ae982a4c5800a26400fcdf16117..3f219da0a879a2e64ea3d5d1e7fafa8db444813f 100644 (file)
 
 pub fn main() {
   trait Text {
-    fn to_str(&self) -> String;
+    fn to_string(&self) -> String;
   }
 
   fn to_string(t: Box<Text>) {
-    println!("{}", t.to_str());
+    println!("{}", t.to_string());
   }
 
 }
index b27720b8579a4b4a51c511d8b366944cbffc0dfd..3ebc3e645737626a839859effb12ba98a3d4a16c 100644 (file)
@@ -96,19 +96,19 @@ enum Result {
     }
 }
 
-priv fn cmd_to_str(cmd: ~[String]) -> String {
+priv fn cmd_to_string(cmd: ~[String]) -> String {
   let mut res = "*".to_string();
-  res.push_str(cmd.len().to_str());
+  res.push_str(cmd.len().to_string());
   res.push_str("\r\n");
     for s in cmd.iter() {
-    res.push_str(["$".to_string(), s.len().to_str(), "\r\n".to_string(),
+    res.push_str(["$".to_string(), s.len().to_string(), "\r\n".to_string(),
                   (*s).clone(), "\r\n".to_string()].concat() );
     }
   res
 }
 
 fn query(cmd: ~[String], sb: TcpSocketBuf) -> Result {
-  let cmd = cmd_to_str(cmd);
+  let cmd = cmd_to_string(cmd);
   //println!("{}", cmd);
   sb.write_str(cmd);
   let res = parse_response(@sb as @io::Reader);
@@ -116,7 +116,7 @@ fn query(cmd: ~[String], sb: TcpSocketBuf) -> Result {
 }
 
 fn query2(cmd: ~[String]) -> Result {
-  let _cmd = cmd_to_str(cmd);
+  let _cmd = cmd_to_string(cmd);
     io::with_str_reader("$3\r\nXXX\r\n".to_string())(|sb| {
     let res = parse_response(@sb as @io::Reader);
     println!("{:?}", res);
index 16fd45a5615f224987bb8d3d316959f4688bd3a1..977cd08ba377082dea01b860d9d12e89ce7e0ff6 100644 (file)
 type FontTableTag = u32;
 
 trait FontTableTagConversions {
-  fn tag_to_str(self);
+  fn tag_to_string(self);
 }
 
 impl FontTableTagConversions for FontTableTag {
-  fn tag_to_str(self) {
+  fn tag_to_string(self) {
     &self;
   }
 }
 
 pub fn main() {
-    5.tag_to_str();
+    5.tag_to_string();
 }
index 543f4bf027bfd10293662e2e1798414a78f6aa9a..5b6012673564d03447fa52a44ef99e7f6a362d11 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct T (&'static [int]);
-static t : T = T (&'static [5, 4, 3]);
+static t : T = T (&[5, 4, 3]);
 pub fn main () {
     let T(ref v) = t;
     assert_eq!(v[0], 5);
index 9e43e3ef1aa75a74e1e329357041000d2bc36903..75494c47dcef10746663b0ab18f249578f0b2ed0 100644 (file)
@@ -27,19 +27,19 @@ trait Test {
     fn get_mut<'r>(&'r mut self) -> &'r mut FooBar;
 }
 
-macro_rules! generate_test(($type_:path, $field:expr) => (
+macro_rules! generate_test(($type_:path, $slf:ident, $field:expr) => (
     impl Test for $type_ {
-        fn get_immut<'r>(&'r self) -> &'r FooBar {
+        fn get_immut<'r>(&'r $slf) -> &'r FooBar {
             &$field as &FooBar
         }
 
-        fn get_mut<'r>(&'r mut self) -> &'r mut FooBar {
+        fn get_mut<'r>(&'r mut $slf) -> &'r mut FooBar {
             &mut $field as &mut FooBar
         }
     }
 ))
 
-generate_test!(Foo, self.bar)
+generate_test!(Foo, self, self.bar)
 
 pub fn main() {
     let mut foo: Foo = Foo { bar: Bar(42) };
index 6ceb2cf87b9a3a528cda5430acea8f97e24957e9..275fe740db157ca60c5e136efde82437d80bae4a 100644 (file)
@@ -17,7 +17,7 @@ pub fn default_instance() -> &'static UninterpretedOption_NamePart {
         static instance: UninterpretedOption_NamePart = UninterpretedOption_NamePart {
             name_part: None,
         };
-        &'static instance
+        &instance
     }
 }
 
diff --git a/src/test/run-pass/issue2378c.rs b/src/test/run-pass/issue2378c.rs
deleted file mode 100644 (file)
index c453a53..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012-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.
-
-// aux-build:issue2378a.rs
-// aux-build:issue2378b.rs
-
-extern crate issue2378a;
-extern crate issue2378b;
-
-use issue2378a::{just};
-use issue2378b::{two_maybes};
-
-pub fn main() {
-    let x = two_maybes{a: just(3i), b: just(5i)};
-    assert_eq!(x[0u], (3, 5));
-}
diff --git a/src/test/run-pass/macro-method-issue-4621.rs b/src/test/run-pass/macro-method-issue-4621.rs
new file mode 100644 (file)
index 0000000..99d47e4
--- /dev/null
@@ -0,0 +1,23 @@
+// 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.
+
+#![feature(macro_rules)]
+
+struct A;
+
+macro_rules! make_thirteen_method {() => (pub fn thirteen(&self)->int {13})}
+impl A { make_thirteen_method!() }
+
+fn main() {
+    assert_eq!(A.thirteen(),13);
+}
+
+
+
diff --git a/src/test/run-pass/match-pattern-bindings.rs b/src/test/run-pass/match-pattern-bindings.rs
new file mode 100644 (file)
index 0000000..61e905e
--- /dev/null
@@ -0,0 +1,38 @@
+// 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.
+
+fn main() {
+    let value = Some(1i);
+    assert_eq!(match value {
+        ref a @ Some(_) => a,
+        ref b @ None => b
+    }, &Some(1i));
+    assert_eq!(match value {
+        ref a @ ref _c @ Some(_) => a,
+        ref b @ None => b
+    }, &Some(1i));
+    assert_eq!(match value {
+        _a @ ref c @ Some(_) => c,
+        ref b @ None => b
+    }, &Some(1i));
+    assert_eq!(match "foobarbaz" {
+        _a @ b @ _ => b
+    }, "foobarbaz");
+
+    let a @ b @ c = "foobarbaz";
+    assert_eq!(a, "foobarbaz");
+    assert_eq!(b, "foobarbaz");
+    assert_eq!(c, "foobarbaz");
+    let value = Some(true);
+    let ref a @ b @ ref c = value;
+    assert_eq!(a, &Some(true));
+    assert_eq!(b, Some(true));
+    assert_eq!(c, &Some(true));
+}
index 2b67ef09c59db5152d610b4ee9741dcba2488888..783dc32426a651f6139d0fa615167766861b684d 100644 (file)
@@ -38,7 +38,7 @@ fn bind<B>(&self, f: |&A| -> Option<B>) -> Option<B> {
 }
 
 fn transform(x: Option<int>) -> Option<String> {
-    x.bind(|n| Some(*n + 1) ).bind(|n| Some(n.to_str()) )
+    x.bind(|n| Some(*n + 1) ).bind(|n| Some(n.to_string()) )
 }
 
 pub fn main() {
index e7d679c41e8538e2a724ea53032430091a95600c..92c5e025b9b2149692aa23bb41c73406015de143 100644 (file)
@@ -20,7 +20,7 @@ pub fn append(&mut self, v: &str) {
     }
 }
 
-fn to_str(sb: StringBuffer) -> String {
+fn to_string(sb: StringBuffer) -> String {
     sb.s
 }
 
@@ -30,6 +30,6 @@ pub fn main() {
     };
     sb.append("Hello, ");
     sb.append("World!");
-    let str = to_str(sb);
+    let str = to_string(sb);
     assert_eq!(str.as_slice(), "Hello, World!");
 }
index b16bef3fc9902c168b676ffb4bc5d5dce9288268..f61a8837e2c7c7dfe31eeb9fb92b6791d465cd73 100644 (file)
@@ -14,7 +14,7 @@
 // Tests that the new `box` syntax works with unique pointers and GC pointers.
 
 use std::gc::{Gc, GC};
-use std::owned::{Box, HEAP};
+use std::boxed::{Box, HEAP};
 
 struct Structure {
     x: int,
@@ -33,4 +33,3 @@ pub fn main() {
     let c = box()(3i + 4);
     let d = box(GC)(5i + 6);
 }
-
index 9fd6e9616757edbcc5a17b68fc5ae25c53a072f4..8532b5f51dc5e68ebe94cb66623b9b532647e52c 100644 (file)
@@ -32,6 +32,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 pub fn main() {
-    println!("{}", Thingy { x: 1, y: 2 }.to_str());
-    println!("{}", PolymorphicThingy { x: Thingy { x: 1, y: 2 } }.to_str());
+    println!("{}", Thingy { x: 1, y: 2 }.to_string());
+    println!("{}", PolymorphicThingy { x: Thingy { x: 1, y: 2 } }.to_string());
 }
index 00e19b8481f217e2a0414f5b14cd63eb631a2a3c..a36d8132b260a86cd50fed157f02e2184122c1d5 100644 (file)
@@ -43,8 +43,12 @@ fn not(&self) -> Point {
 }
 
 impl ops::Index<bool,int> for Point {
-    fn index(&self, x: &bool) -> int {
-        if *x { self.x } else { self.y }
+    fn index<'a>(&'a self, x: &bool) -> &'a int {
+        if *x {
+            &self.x
+        } else {
+            &self.y
+        }
     }
 }
 
diff --git a/src/test/run-pass/order-drop-with-match.rs b/src/test/run-pass/order-drop-with-match.rs
new file mode 100644 (file)
index 0000000..ed5cff3
--- /dev/null
@@ -0,0 +1,64 @@
+// 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.
+
+
+// Test to make sure the destructors run in the right order.
+// Each destructor sets it's tag in the corresponding entry
+// in ORDER matching up to when it ran.
+// Correct order is: matched, inner, outer
+
+static mut ORDER: [uint, ..3] = [0, 0, 0];
+static mut INDEX: uint = 0;
+
+struct A;
+impl Drop for A {
+    fn drop(&mut self) {
+        unsafe {
+            ORDER[INDEX] = 1;
+            INDEX = INDEX + 1;
+        }
+    }
+}
+
+struct B;
+impl Drop for B {
+    fn drop(&mut self) {
+        unsafe {
+            ORDER[INDEX] = 2;
+            INDEX = INDEX + 1;
+        }
+    }
+}
+
+struct C;
+impl Drop for C {
+    fn drop(&mut self) {
+        unsafe {
+            ORDER[INDEX] = 3;
+            INDEX = INDEX + 1;
+        }
+    }
+}
+
+fn main() {
+    {
+        let matched = A;
+        let _outer = C;
+        {
+            match matched {
+                _s => {}
+            }
+            let _inner = B;
+        }
+    }
+    unsafe {
+        assert_eq!(&[1, 2, 3], ORDER.as_slice());
+    }
+}
index de5456ef1c03f553a4a728f875428f7bc9c4daaa..6b1ac0b821c44646d8adf570f2a3ee37050e9f4e 100644 (file)
@@ -31,10 +31,10 @@ fn push(&mut self, key: K, value: V) {
 }
 
 impl<K:PartialEq,V:Clone> Index<K,V> for AssociationList<K,V> {
-    fn index(&self, index: &K) -> V {
+    fn index<'a>(&'a self, index: &K) -> &'a V {
         for pair in self.pairs.iter() {
             if pair.key == *index {
-                return pair.value.clone();
+                return &pair.value
             }
         }
         fail!("No value found for key: {:?}", index);
index 49edf1bad57f0a9525ed357ea0778e6680b9248f..283c76adf0dafcc2a90d17ba8114c6c16af9270e 100644 (file)
@@ -72,7 +72,7 @@ pub fn main() {
     // N.B. This is required because method lookup hasn't been performed so
     // we don't know whether the called method takes mutable self, before
     // the dereference itself is type-checked (a chicken-and-egg problem).
-    (*n).to_str();
+    (*n).to_string();
     assert_eq!(n.counts(), (2, 4));
 
     // Mutable deref used for calling a method taking &mut self.
diff --git a/src/test/run-pass/overloaded-index.rs b/src/test/run-pass/overloaded-index.rs
new file mode 100644 (file)
index 0000000..9d7c068
--- /dev/null
@@ -0,0 +1,53 @@
+// 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.
+
+struct Foo {
+    x: int,
+    y: int,
+}
+
+impl Index<int,int> for Foo {
+    fn index<'a>(&'a self, z: &int) -> &'a int {
+        if *z == 0 {
+            &self.x
+        } else {
+            &self.y
+        }
+    }
+}
+
+impl IndexMut<int,int> for Foo {
+    fn index_mut<'a>(&'a mut self, z: &int) -> &'a mut int {
+        if *z == 0 {
+            &mut self.x
+        } else {
+            &mut self.y
+        }
+    }
+}
+
+fn main() {
+    let mut f = Foo {
+        x: 1,
+        y: 2,
+    };
+    assert_eq!(f[1], 2);
+    f[0] = 3;
+    assert_eq!(f[0], 3);
+    {
+        let p = &mut f[1];
+        *p = 4;
+    }
+    {
+        let p = &f[1];
+        assert_eq!(*p, 4);
+    }
+}
+
index 70839c1884791f5b987fa2f56127694fd954414a..de86ca179b7d75c0cf9c1e0bf525a71a6c591632 100644 (file)
@@ -58,7 +58,7 @@ fn main() {
         let p = Command::new(&child_path)
                         .arg(arg)
                         .cwd(&cwd)
-                        .env(my_env.append_one(env).as_slice())
+                        .env_set_all(my_env.append_one(env).as_slice())
                         .spawn().unwrap().wait_with_output().unwrap();
 
         // display the output
index 68eca8f21a7f5d37c9b4a94e55a96034593bd648..f3a730aa2b39589b823994ebd3c6ab321ff183f7 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::collections::{ Map, MutableMap};
 use std::str::{SendStr, Owned, Slice};
-use std::to_str::ToStr;
+use std::to_str::ToString;
 use self::collections::TreeMap;
 use std::option::Some;
 
index 9267fcac0115aad81645646ef56e5dacf9bcf62c..d0dacc2ff7a9d225a4cec29e68091ac35937b21e 100644 (file)
@@ -31,7 +31,7 @@ trait uint_utils {
 
 impl uint_utils for uint {
     fn str(&self) -> String {
-        self.to_str()
+        self.to_string()
     }
     fn multi(&self, f: |uint|) {
         let mut c = 0u;
diff --git a/src/test/run-pass/string-escapes.rs b/src/test/run-pass/string-escapes.rs
new file mode 100644 (file)
index 0000000..7abe827
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+fn main() {
+    let x = "\\\\\
+    ";
+    assert!(x == r"\\"); // extraneous whitespace stripped
+}
diff --git a/src/test/run-pass/struct-aliases-xcrate.rs b/src/test/run-pass/struct-aliases-xcrate.rs
new file mode 100644 (file)
index 0000000..9046caf
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:xcrate_struct_aliases.rs
+extern crate xcrate_struct_aliases;
+
+use xcrate_struct_aliases::{S, S2};
+
+fn main() {
+    let s = S2 {
+        x: 1,
+        y: 2,
+    };
+    match s {
+        S2 {
+            x: x,
+            y: y
+        } => {
+            assert_eq!(x, 1);
+            assert_eq!(y, 2);
+        }
+    }
+}
+
diff --git a/src/test/run-pass/struct-aliases.rs b/src/test/run-pass/struct-aliases.rs
new file mode 100644 (file)
index 0000000..2cf961a
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct S {
+    x: int,
+    y: int,
+}
+
+type S2 = S;
+
+fn main() {
+    let s = S2 {
+        x: 1,
+        y: 2,
+    };
+    match s {
+        S2 {
+            x: x,
+            y: y
+        } => {
+            assert_eq!(x, 1);
+            assert_eq!(y, 2);
+        }
+    }
+}
+
index 6a71f9df6e45ee70eff9b0cbb27d98739774fc29..ceffd1e363667d313ce04f3cf3a4e226a14361a9 100644 (file)
@@ -21,6 +21,6 @@ fn main() {
     });
     assert!(res.is_err());
 
-    let output = reader.read_to_str().unwrap();
+    let output = reader.read_to_string().unwrap();
     assert!(output.as_slice().contains("Hello, world!"));
 }
index ebc720aa0c888d60f2bc5c675709c38d863f564a..d2408509fc5820c0105e083a149060d1ea67333d 100644 (file)
@@ -54,7 +54,7 @@ fn f() $b
 iotest!(fn eventual_timeout() {
     use native;
     let addr = next_test_ip4();
-    let host = addr.ip.to_str();
+    let host = addr.ip.to_string();
     let port = addr.port;
 
     // Use a native task to receive connections because it turns out libuv is
@@ -82,7 +82,7 @@ fn f() $b
 
 iotest!(fn timeout_success() {
     let addr = next_test_ip4();
-    let host = addr.ip.to_str();
+    let host = addr.ip.to_string();
     let port = addr.port;
     let _l = TcpListener::bind(host.as_slice(), port).unwrap().listen();
 
index de3366708c5a0a0e3ebcef92c1279577bfdf3a4a..f52a3455e4157684c16b98c5b29828db88b4f125 100644 (file)
@@ -61,7 +61,7 @@ fn main() {
     for _ in range(0u, 1000) {
         let tx = tx.clone();
         TaskBuilder::new().stack_size(64 * 1024).spawn(proc() {
-            let host = addr.ip.to_str();
+            let host = addr.ip.to_string();
             let port = addr.port;
             match TcpStream::connect(host.as_slice(), port) {
                 Ok(stream) => {
index c3387a963a701d44c8e4d1f84f80394ac8160327..b36fbca2da048a68f9b82af3c19712e00677ec47 100644 (file)
@@ -27,10 +27,10 @@ fn checktests() {
     let tests = __test::TESTS;
 
     assert!(
-        tests.iter().any(|t| t.desc.name.to_str().as_slice() == "shouldignore" &&
+        tests.iter().any(|t| t.desc.name.to_string().as_slice() == "shouldignore" &&
                          t.desc.ignore));
 
     assert!(
-        tests.iter().any(|t| t.desc.name.to_str().as_slice() == "shouldnotignore" &&
+        tests.iter().any(|t| t.desc.name.to_string().as_slice() == "shouldnotignore" &&
                          !t.desc.ignore));
 }
index daab40f5d90d1de7e41c94a1c61fb10bbb7fa98e..43d3b591ffa1b9225e3073ed6e8d7f1877d7b9be 100644 (file)
@@ -39,7 +39,7 @@ fn to_str_(&self) -> String {
 
 impl to_str for int {
     fn to_str_(&self) -> String {
-        self.to_str()
+        self.to_string()
     }
 }
 
index f3f4c556b77292f6208922a1c1fedc6cc86357ff..eeda6e2c88b454e084d07d29811915224e6bd59d 100644 (file)
 
 
 trait to_str {
-    fn to_string(&self) -> String;
+    fn to_string_(&self) -> String;
 }
 impl to_str for int {
-    fn to_string(&self) -> String { self.to_str() }
+    fn to_string_(&self) -> String { self.to_string() }
 }
 impl to_str for String {
-    fn to_string(&self) -> String { self.clone() }
+    fn to_string_(&self) -> String { self.clone() }
 }
 impl to_str for () {
-    fn to_string(&self) -> String { "()".to_string() }
+    fn to_string_(&self) -> String { "()".to_string() }
 }
 
 trait map<T> {
@@ -40,7 +40,7 @@ fn foo<U, T: map<U>>(x: T) -> Vec<String> {
     x.map(|_e| "hi".to_string() )
 }
 fn bar<U:to_str,T:map<U>>(x: T) -> Vec<String> {
-    x.map(|_e| _e.to_string() )
+    x.map(|_e| _e.to_string_() )
 }
 
 pub fn main() {
index 54a21caafa0b187f9d2f1c97f9d6f6627c95f855..fbe40e837de5f04a1d350b134526c2ceede596f2 100644 (file)
 
 
 trait to_str {
-    fn to_string(&self) -> String;
+    fn to_string_(&self) -> String;
 }
 
 impl to_str for int {
-    fn to_string(&self) -> String { self.to_str() }
+    fn to_string_(&self) -> String { self.to_string() }
 }
 
 impl<T:to_str> to_str for Vec<T> {
-    fn to_string(&self) -> String {
+    fn to_string_(&self) -> String {
         format!("[{}]",
                 self.iter()
-                    .map(|e| e.to_string())
+                    .map(|e| e.to_string_())
                     .collect::<Vec<String>>()
                     .connect(", "))
     }
 }
 
 pub fn main() {
-    assert!(1.to_string() == "1".to_string());
-    assert!((vec!(2i, 3, 4)).to_string() == "[2, 3, 4]".to_string());
+    assert!(1.to_string_() == "1".to_string());
+    assert!((vec!(2i, 3, 4)).to_string_() == "[2, 3, 4]".to_string());
 
     fn indirect<T:to_str>(x: T) -> String {
-        format!("{}!", x.to_string())
+        format!("{}!", x.to_string_())
     }
     assert!(indirect(vec!(10i, 20)) == "[10, 20]!".to_string());
 
index c6a3a0b0409aa76ff8b3bf259c8d584905e6f03f..ed4712ff3be9c55bd8ba81e1b64498f0fee7445c 100644 (file)
@@ -43,7 +43,7 @@ fn default_instance() -> &'static Request {
         // size of struct may be not equal to size of struct, and
         // compiler crashes in internal assertion check.
     };
-    &'static instance
+    &instance
 }
 
 fn non_default_instance() -> &'static Request {
@@ -51,7 +51,7 @@ fn non_default_instance() -> &'static Request {
         foo: TestSome(0x1020304050607080),
         bar: 19,
     };
-    &'static instance
+    &instance
 }
 
 pub fn main() {
index 1a79edb30c9c640a36ac2d4e509ef51f623faf95..f95e9ad7d83c98a2d05bcd87aac823e96ca2d2f1 100644 (file)
@@ -11,7 +11,7 @@
 // This test checks that the `_` type placeholder works
 // correctly for enabling type inference.
 
-static CONSTEXPR: *const int = &'static 413 as *const _;
+static CONSTEXPR: *const int = &413 as *const _;
 
 pub fn main() {
     let x: Vec<_> = range(0u, 5).collect();
index ae4623c6e66eb3b050c8a2a1645b6652c5a67a2d..3a1cc0331a3e6c04ef39c12cfd896361f2660dab 100644 (file)
@@ -10,7 +10,7 @@
 
 // Make sure the destructor is run for unit-like structs.
 
-use std::owned::AnyOwnExt;
+use std::boxed::BoxAny;
 use std::task;
 
 struct Foo;
@@ -26,6 +26,6 @@ pub fn main() {
         let _b = Foo;
     });
 
-    let s = x.unwrap_err().move::<&'static str>().unwrap();
+    let s = x.unwrap_err().downcast::<&'static str>().unwrap();
     assert_eq!(s.as_slice(), "This failure should happen.");
 }
index db0cc83d7866af826dcdadb3602850083b1b822c..f49e8f46e78e6a476f56f7a5380300789f1ed3f5 100644 (file)
@@ -8,20 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test syntax checks for `type` keyword.
+// Test syntax checks for `Sized?` syntax.
 
-trait T1 for type {}
-pub trait T2 for type {}
-trait T3<X: T1> for type: T2 {}
-trait T4<type X> {}
-trait T5<type X, Y> {}
-trait T6<Y, type X> {}
-trait T7<type X, type Y> {}
-trait T8<type X: T2> {}
-struct S1<type X>;
-enum E<type X> {}
-impl <type X> T1 for S1<X> {}
-fn f<type X>() {}
+trait T1 for Sized? {}
+pub trait T2 for Sized? {}
+trait T3<X: T1> for Sized?: T2 {}
+trait T4<Sized? X> {}
+trait T5<Sized? X, Y> {}
+trait T6<Y, Sized? X> {}
+trait T7<Sized? X, Sized? Y> {}
+trait T8<Sized? X: T2> {}
+struct S1<Sized? X>;
+enum E<Sized? X> {}
+impl <Sized? X> T1 for S1<X> {}
+fn f<Sized? X>() {}
 
 pub fn main() {
 }
index 53db7f37e8d51309c4d2e6b224dd092a69dc8c09..9703b55cda760855c10c5bc9fd5b07af1190a0a3 100644 (file)
@@ -13,7 +13,7 @@
 // Test sized-ness checking in substitution.
 
 // Unbounded.
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
     f1::<X>(x);
 }
 fn f2<X>(x: &X) {
@@ -22,8 +22,8 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T for type {}
-fn f3<type X: T>(x: &X) {
+trait T for Sized? {}
+fn f3<Sized? X: T>(x: &X) {
     f3::<X>(x);
 }
 fn f4<X: T>(x: &X) {
@@ -32,7 +32,7 @@ fn f4<X: T>(x: &X) {
 }
 
 // Self type.
-trait T2 for type {
+trait T2 for Sized? {
     fn f() -> Box<Self>;
 }
 struct S;
@@ -41,14 +41,14 @@ fn f() -> Box<S> {
         box S
     }
 }
-fn f5<type X: T2>(x: &X) {
+fn f5<Sized? X: T2>(x: &X) {
     let _: Box<X> = T2::f();
 }
 fn f6<X: T2>(x: &X) {
     let _: Box<X> = T2::f();
 }
 
-trait T3 for type {
+trait T3 for Sized? {
     fn f() -> Box<Self>;
 }
 impl T3 for S {
@@ -56,7 +56,7 @@ fn f() -> Box<S> {
         box S
     }
 }
-fn f7<type X: T3>(x: &X) {
+fn f7<Sized? X: T3>(x: &X) {
     // This is valid, but the unsized bound on X is irrelevant because any type
     // which implements T3 must have statically known size.
     let _: Box<X> = T3::f();
@@ -66,7 +66,7 @@ trait T4<X> {
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
-trait T5<type X> {
+trait T5<Sized? X> {
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
@@ -76,21 +76,21 @@ trait T6<X: T> {
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
-trait T7<type X: T> {
+trait T7<Sized? X: T> {
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
 
 // The last field in a struct or variant may be unsized
-struct S2<type X> {
+struct S2<Sized? X> {
     f: X,
 }
-struct S3<type X> {
+struct S3<Sized? X> {
     f1: int,
     f2: X,
 }
-enum E<type X> {
+enum E<Sized? X> {
     V1(X),
     V2{x: X},
     V3(int, X),
index 3f152cc10610f3ae1894c654f09f4d6a9a9f33ed..dfed391640516d0cf6e6b90e4d65d5c0d685b2f7 100644 (file)
 #![no_std]
 extern crate std;
 extern crate zed = "std";
-extern crate bar = "std#0.11.0";
 
 
 use std::str;
 use x = zed::str;
 mod baz {
-    pub use bar::str;
     pub use x = std::str;
 }
 
index 4d9f80cec6ace370c9957740008af0eca8b8922a..deb08a4608cc0358c533531e7b2d1fff79289caa 100644 (file)
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 pub fn main() {
-    assert_eq!((vec!(0i, 1)).to_str(), "[0, 1]".to_string());
-    assert_eq!((&[1i, 2]).to_str(), "[1, 2]".to_string());
+    assert_eq!((vec!(0i, 1)).to_string(), "[0, 1]".to_string());
+    assert_eq!((&[1i, 2]).to_string(), "[1, 2]".to_string());
 
     let foo = vec!(3i, 4);
     let bar = &[4i, 5];
 
-    assert_eq!(foo.to_str(), "[3, 4]".to_string());
-    assert_eq!(bar.to_str(), "[4, 5]".to_string());
+    assert_eq!(foo.to_string(), "[3, 4]".to_string());
+    assert_eq!(bar.to_string(), "[4, 5]".to_string());
 }