]> git.lizzy.rs Git - rust.git/commitdiff
Merge remote-tracking branch 'mneumann/f-serialize'
authorBrian Anderson <banderson@mozilla.com>
Mon, 14 Jan 2013 20:56:31 +0000 (12:56 -0800)
committerBrian Anderson <banderson@mozilla.com>
Mon, 14 Jan 2013 20:56:31 +0000 (12:56 -0800)
485 files changed:
AUTHORS.txt
CONTRIBUTING.md [new file with mode: 0644]
Makefile.in
README.md
configure
doc/rust.md
doc/tutorial-macros.md
doc/tutorial.md
mk/docs.mk
mk/libuv/arm/unix/android/Makefile [new file with mode: 0755]
mk/libuv/arm/unix/android/src/libuv/run-benchmarks.target.mk [new file with mode: 0755]
mk/libuv/arm/unix/android/src/libuv/run-tests.target.mk [new file with mode: 0755]
mk/libuv/arm/unix/android/src/libuv/uv.Makefile [new file with mode: 0755]
mk/libuv/arm/unix/android/src/libuv/uv.target.mk [new file with mode: 0755]
mk/snap.mk
mk/stage0.mk
mk/tests.mk
src/compiletest/common.rs
src/compiletest/compiletest.rc
src/compiletest/errors.rs
src/compiletest/header.rs
src/compiletest/procsrv.rs
src/compiletest/runtest.rs
src/compiletest/util.rs
src/driver/driver.rs
src/etc/sugarise-doc-comments.py
src/etc/vim/syntax/rust.vim
src/libcargo/cargo.rc
src/libcargo/pgp.rs
src/libcore/at_vec.rs
src/libcore/bool.rs
src/libcore/cast.rs
src/libcore/char.rs
src/libcore/cleanup.rs
src/libcore/clone.rs
src/libcore/cmath.rs
src/libcore/cmp.rs
src/libcore/condition.rs
src/libcore/core.rc
src/libcore/dlist.rs
src/libcore/dvec.rs
src/libcore/either.rs
src/libcore/extfmt.rs
src/libcore/f32.rs
src/libcore/f64.rs
src/libcore/flate.rs
src/libcore/float.rs
src/libcore/gc.rs
src/libcore/hash.rs
src/libcore/int-template.rs
src/libcore/int-template/i16.rs
src/libcore/int-template/i32.rs
src/libcore/int-template/i64.rs
src/libcore/int-template/i8.rs
src/libcore/int-template/int.rs
src/libcore/io.rs
src/libcore/iter-trait.rs
src/libcore/iter-trait/dlist.rs
src/libcore/iter-trait/dvec.rs
src/libcore/iter-trait/option.rs
src/libcore/iter.rs
src/libcore/libc.rs
src/libcore/logging.rs
src/libcore/managed.rs
src/libcore/nil.rs
src/libcore/oldcomm.rs
src/libcore/ops.rs
src/libcore/option.rs
src/libcore/os.rs
src/libcore/owned.rs
src/libcore/path.rs
src/libcore/pipes.rs
src/libcore/prelude.rs [new file with mode: 0644]
src/libcore/private.rs
src/libcore/ptr.rs
src/libcore/rand.rs
src/libcore/reflect.rs
src/libcore/repr.rs
src/libcore/result.rs
src/libcore/rt.rs
src/libcore/run.rs
src/libcore/send_map.rs
src/libcore/stackwalk.rs
src/libcore/str.rs
src/libcore/sys.rs
src/libcore/task/local_data.rs
src/libcore/task/local_data_priv.rs
src/libcore/task/mod.rs
src/libcore/task/rt.rs
src/libcore/task/spawn.rs
src/libcore/to_bytes.rs
src/libcore/to_str.rs
src/libcore/tuple.rs
src/libcore/uint-template.rs
src/libcore/uint-template/uint.rs
src/libcore/util.rs
src/libcore/vec.rs
src/libfuzzer/fuzzer.rc
src/librustc/back/arm.rs [new file with mode: 0644]
src/librustc/back/link.rs
src/librustc/back/rpath.rs
src/librustc/back/target_strs.rs
src/librustc/back/upcall.rs
src/librustc/back/x86.rs
src/librustc/back/x86_64.rs
src/librustc/driver/driver.rs
src/librustc/driver/session.rs
src/librustc/front/config.rs
src/librustc/front/core_inject.rs
src/librustc/front/intrinsic_inject.rs
src/librustc/front/test.rs
src/librustc/lib/llvm.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/filesearch.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/mod.rs
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/borrowck/check_loans.rs
src/librustc/middle/borrowck/gather_loans.rs
src/librustc/middle/borrowck/loan.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/borrowck/preserve.rs
src/librustc/middle/capture.rs
src/librustc/middle/check_alt.rs [deleted file]
src/librustc/middle/check_const.rs
src/librustc/middle/check_loop.rs
src/librustc/middle/check_match.rs [new file with mode: 0644]
src/librustc/middle/const_eval.rs
src/librustc/middle/freevars.rs
src/librustc/middle/kind.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/lint.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/mode.rs
src/librustc/middle/pat_util.rs
src/librustc/middle/privacy.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/trans/_match.rs [new file with mode: 0644]
src/librustc/middle/trans/alt.rs [deleted file]
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/build.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.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/machine.rs
src/librustc/middle/trans/macros.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/trans/reachable.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/shape.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/type_of.rs
src/librustc/middle/trans/type_use.rs
src/librustc/middle/trans/uniq.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/_match.rs [new file with mode: 0644]
src/librustc/middle/typeck/check/alt.rs [deleted file]
src/librustc/middle/typeck/check/demand.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/assignment.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/floating.rs [deleted file]
src/librustc/middle/typeck/infer/glb.rs
src/librustc/middle/typeck/infer/integral.rs [deleted file]
src/librustc/middle/typeck/infer/lattice.rs
src/librustc/middle/typeck/infer/lub.rs
src/librustc/middle/typeck/infer/macros.rs
src/librustc/middle/typeck/infer/mod.rs
src/librustc/middle/typeck/infer/region_inference.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/infer/to_str.rs
src/librustc/middle/typeck/infer/unify.rs
src/librustc/middle/typeck/mod.rs
src/librustc/middle/typeck/rscope.rs
src/librustc/rustc.rc
src/librustc/util/common.rs
src/librustc/util/ppaux.rs
src/librustdoc/astsrv.rs
src/librustdoc/attr_parser.rs
src/librustdoc/attr_pass.rs
src/librustdoc/config.rs
src/librustdoc/demo.rs
src/librustdoc/desc_to_brief_pass.rs
src/librustdoc/doc.rs
src/librustdoc/escape_pass.rs
src/librustdoc/extract.rs
src/librustdoc/fold.rs
src/librustdoc/markdown_index_pass.rs
src/librustdoc/markdown_pass.rs
src/librustdoc/markdown_writer.rs
src/librustdoc/page_pass.rs
src/librustdoc/parse.rs
src/librustdoc/pass.rs
src/librustdoc/path_pass.rs
src/librustdoc/prune_hidden_pass.rs
src/librustdoc/prune_private_pass.rs
src/librustdoc/sectionalize_pass.rs
src/librustdoc/sort_item_name_pass.rs
src/librustdoc/sort_item_type_pass.rs
src/librustdoc/sort_pass.rs
src/librustdoc/text_pass.rs
src/librustdoc/trim_pass.rs
src/librustdoc/tystr_pass.rs
src/librustdoc/unindent_pass.rs
src/librustdoc/util.rs
src/librusti/rusti.rc
src/libstd/arc.rs
src/libstd/arena.rs
src/libstd/base64.rs
src/libstd/bigint.rs [new file with mode: 0644]
src/libstd/bitv.rs
src/libstd/c_vec.rs
src/libstd/cell.rs
src/libstd/cmp.rs
src/libstd/comm.rs
src/libstd/dbg.rs
src/libstd/deque.rs
src/libstd/ebml.rs
src/libstd/flatpipes.rs
src/libstd/fun_treemap.rs
src/libstd/future.rs
src/libstd/getopts.rs
src/libstd/io_util.rs [new file with mode: 0644]
src/libstd/json.rs
src/libstd/list.rs
src/libstd/map.rs
src/libstd/md4.rs
src/libstd/net.rs
src/libstd/net_ip.rs
src/libstd/net_tcp.rs
src/libstd/net_url.rs
src/libstd/par.rs
src/libstd/prettyprint.rs
src/libstd/priority_queue.rs
src/libstd/rl.rs
src/libstd/rope.rs
src/libstd/serialize.rs
src/libstd/sha1.rs
src/libstd/smallintmap.rs
src/libstd/sort.rs
src/libstd/std.rc
src/libstd/sync.rs
src/libstd/task_pool.rs
src/libstd/tempfile.rs
src/libstd/term.rs
src/libstd/test.rs
src/libstd/time.rs
src/libstd/timer.rs
src/libstd/treemap.rs
src/libstd/unicode.rs
src/libstd/uv_global_loop.rs
src/libstd/uv_iotask.rs
src/libstd/uv_ll.rs
src/libstd/workcache.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map.rs
src/libsyntax/ast_util.rs
src/libsyntax/attr.rs
src/libsyntax/codemap.rs
src/libsyntax/diagnostic.rs
src/libsyntax/ext/auto_encode.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/concat_idents.rs
src/libsyntax/ext/deriving.rs
src/libsyntax/ext/env.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/fmt.rs
src/libsyntax/ext/log_syntax.rs
src/libsyntax/ext/pipes/ast_builder.rs
src/libsyntax/ext/pipes/check.rs
src/libsyntax/ext/pipes/liveness.rs
src/libsyntax/ext/pipes/mod.rs
src/libsyntax/ext/pipes/parse_proto.rs
src/libsyntax/ext/pipes/pipec.rs
src/libsyntax/ext/pipes/proto.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/trace_macros.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/parse/attr.rs
src/libsyntax/parse/classify.rs
src/libsyntax/parse/comments.rs
src/libsyntax/parse/common.rs
src/libsyntax/parse/lexer.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/prec.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax/syntax.rc
src/libsyntax/util/interner.rs
src/libsyntax/visit.rs
src/libuv
src/rt/arch/arm/_context.S [new file with mode: 0644]
src/rt/arch/arm/ccall.S [new file with mode: 0644]
src/rt/arch/arm/context.cpp [new file with mode: 0644]
src/rt/arch/arm/context.h [new file with mode: 0644]
src/rt/arch/arm/gpr.cpp [new file with mode: 0644]
src/rt/arch/arm/gpr.h [new file with mode: 0644]
src/rt/arch/arm/record_sp.S [new file with mode: 0644]
src/rt/arch/arm/regs.h [new file with mode: 0644]
src/rt/bigint/bigint.h [deleted file]
src/rt/bigint/bigint_ext.cpp [deleted file]
src/rt/bigint/bigint_int.cpp [deleted file]
src/rt/bigint/low_primes.h [deleted file]
src/rt/rust.cpp
src/rt/rust_android_dummy.cpp [new file with mode: 0644]
src/rt/rust_android_dummy.h [new file with mode: 0644]
src/rt/rust_builtin.cpp
src/rt/rust_sched_loop.cpp
src/rt/rust_task.cpp
src/rt/rust_task.h
src/rt/rust_upcall.cpp
src/rt/rustrt.def.in
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.def.in
src/test/auxiliary/cci_capture_clause.rs
src/test/auxiliary/cci_class_cast.rs
src/test/auxiliary/cci_nested_lib.rs
src/test/auxiliary/issue-2631-a.rs
src/test/auxiliary/issue_3882.rc [new file with mode: 0644]
src/test/auxiliary/issue_3882.rs [new file with mode: 0644]
src/test/auxiliary/noexporttypelib.rs
src/test/auxiliary/static-methods-crate.rs
src/test/auxiliary/static_fn_inline_xc_aux.rs
src/test/auxiliary/static_fn_trait_xc_aux.rs
src/test/auxiliary/test_comm.rs
src/test/bench/core-map.rs
src/test/bench/graph500-bfs.rs
src/test/bench/msgsend-ring.rs
src/test/bench/shootout-mandelbrot.rs
src/test/bench/shootout-nbody.rs
src/test/bench/task-perf-word-count-generic.rs
src/test/compile-fail/access-mode-in-closures.rs [new file with mode: 0644]
src/test/compile-fail/bad-bang-ann-3.rs
src/test/compile-fail/bad-bang-ann.rs
src/test/compile-fail/bang-tailexpr.rs
src/test/compile-fail/block-coerce-no-2.rs
src/test/compile-fail/borrowck-autoref-3261.rs
src/test/compile-fail/closure-that-fails.rs [new file with mode: 0644]
src/test/compile-fail/copy-into-closure.rs
src/test/compile-fail/fully-qualified-type-name3.rs
src/test/compile-fail/issue-1697.rs
src/test/compile-fail/issue-2548.rs
src/test/compile-fail/issue-2718-a.rs
src/test/compile-fail/issue-2766-a.rs
src/test/compile-fail/issue-3477.rs [new file with mode: 0644]
src/test/compile-fail/issue-3563.rs [new file with mode: 0644]
src/test/compile-fail/issue-3601.rs [new file with mode: 0644]
src/test/compile-fail/issue-3707.rs [new file with mode: 0644]
src/test/compile-fail/issue-3820.rs [new file with mode: 0644]
src/test/compile-fail/issue-3973.rs [new file with mode: 0644]
src/test/compile-fail/issue-897-2.rs
src/test/compile-fail/issue-897.rs
src/test/compile-fail/kindck-owned-trait-scoped.rs
src/test/compile-fail/kindck-owned-trait.rs
src/test/compile-fail/kindck-owned.rs
src/test/compile-fail/loop-does-not-diverge.rs
src/test/compile-fail/main-wrong-type-2.rs
src/test/compile-fail/main-wrong-type.rs
src/test/compile-fail/missing-do.rs
src/test/compile-fail/name-clash-nullary.rs
src/test/compile-fail/no-capture-arc.rs
src/test/compile-fail/no-reuse-move-arc.rs
src/test/compile-fail/pptypedef.rs
src/test/compile-fail/static-region-bound.rs [new file with mode: 0644]
src/test/compile-fail/unsafe-fn-autoderef.rs
src/test/run-fail/unwind-lambda.rs
src/test/run-pass-fulldeps/qquote.rs
src/test/run-pass/alignment-gep-tup-like-1.rs
src/test/run-pass/alt-pattern-drop.rs
src/test/run-pass/auto-encode.rs
src/test/run-pass/basic-1.rs
src/test/run-pass/basic-2.rs
src/test/run-pass/basic.rs
src/test/run-pass/binops.rs
src/test/run-pass/capture_nil.rs
src/test/run-pass/cci_capture_clause.rs
src/test/run-pass/chan-leak.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/close-over-big-then-small-data.rs
src/test/run-pass/coherence-impl-in-fn.rs
src/test/run-pass/comm.rs
src/test/run-pass/const-big-enum.rs [new file with mode: 0644]
src/test/run-pass/const-enum-byref-self.rs [new file with mode: 0644]
src/test/run-pass/const-enum-byref.rs [new file with mode: 0644]
src/test/run-pass/const-newtype-enum.rs [new file with mode: 0644]
src/test/run-pass/const-nullary-enum.rs
src/test/run-pass/const-nullary-univariant-enum.rs [new file with mode: 0644]
src/test/run-pass/core-export-f64-sqrt.rs
src/test/run-pass/decl-with-recv.rs
src/test/run-pass/deriving-via-extension-iter-bytes-enum.rs
src/test/run-pass/deriving-via-extension-iter-bytes-struct.rs
src/test/run-pass/deriving-via-extension-type-params.rs
src/test/run-pass/drop-trait-generic.rs
src/test/run-pass/enum-variants.rs [new file with mode: 0644]
src/test/run-pass/export-non-interference2.rs
src/test/run-pass/export-non-interference3.rs
src/test/run-pass/fixed-point-bind-unique.rs
src/test/run-pass/fn-coerce-field.rs
src/test/run-pass/foreign2.rs
src/test/run-pass/hashmap-memory.rs
src/test/run-pass/import-glob-crate.rs
src/test/run-pass/intrinsic-alignment.rs
src/test/run-pass/intrinsic-frame-address.rs
src/test/run-pass/intrinsics-integer.rs
src/test/run-pass/issue-1458.rs
src/test/run-pass/issue-2214.rs
src/test/run-pass/issue-2718.rs
src/test/run-pass/issue-2734.rs
src/test/run-pass/issue-2735.rs
src/test/run-pass/issue-2904.rs
src/test/run-pass/issue-3559
src/test/run-pass/issue-3559.rs
src/test/run-pass/issue-3563-2.rs [new file with mode: 0644]
src/test/run-pass/issue-3563-3.rs [new file with mode: 0644]
src/test/run-pass/issue-3563.rs [deleted file]
src/test/run-pass/issue-3609.rs [new file with mode: 0644]
src/test/run-pass/issue-3656.rs
src/test/run-pass/issue-3847.rs [new file with mode: 0644]
src/test/run-pass/issue-3888.rs [new file with mode: 0644]
src/test/run-pass/issue-3904.rs [new file with mode: 0644]
src/test/run-pass/issue-3935.rs [new file with mode: 0644]
src/test/run-pass/issue-507.rs
src/test/run-pass/issue-687.rs
src/test/run-pass/issue-783.rs
src/test/run-pass/issue_3882.rs [new file with mode: 0644]
src/test/run-pass/ivec-tag.rs
src/test/run-pass/last-use-corner-cases.rs
src/test/run-pass/lazychan.rs
src/test/run-pass/monad.rs
src/test/run-pass/operator-overloading.rs
src/test/run-pass/pipe-bank-proto.rs
src/test/run-pass/pipe-pingpong-bounded.rs
src/test/run-pass/pipe-pingpong-proto.rs
src/test/run-pass/pipe-presentation-examples.rs
src/test/run-pass/recursion.rs [new file with mode: 0644]
src/test/run-pass/reflect-visit-data.rs
src/test/run-pass/rt-circular-buffer.rs
src/test/run-pass/self-type-param.rs [new file with mode: 0644]
src/test/run-pass/send-resource.rs
src/test/run-pass/static-impl.rs
src/test/run-pass/struct-field-assignability.rs [new file with mode: 0644]
src/test/run-pass/super.rs [new file with mode: 0644]
src/test/run-pass/task-comm.rs
src/test/run-pass/trait-static-method-overwriting.rs
src/test/run-pass/vec-matching-autoslice.rs
src/test/run-pass/vec-matching-legal-tail-element-borrow.rs
src/test/run-pass/vec-matching.rs
src/test/run-pass/vec-tail-matching.rs

index 9117d5b3a01b18cad40ebe1953f8306df40548f6..bfd5b01ea8aa6823c973d114ce7ec555b049baf1 100644 (file)
@@ -16,6 +16,7 @@ Arkaitz Jimenez <arkaitzj@gmail.com>
 Armin Ronacher <armin.ronacher@active-4.com>
 Austin Seipp <mad.one@gmail.com>
 auREAX <mark@xn--hwg34fba.ws>
+Ben Alpert <ben@benalpert.com>
 Ben Blum <bblum@andrew.cmu.edu>
 Ben Striegel <ben.striegel@gmail.com>
 Benjamin Herr <ben@0x539.de>
@@ -49,6 +50,7 @@ Erick Tryzelaar <erick.tryzelaar@gmail.com>
 Erik Rose <erik@mozilla.com>
 Evan McClanahan <evan@evanmcc.com>
 Francisco Souza <f@souza.cc>
+Franklin Chen <franklinchen@franklinchen.com>
 Gabriel <g2p.code@gmail.com>
 Gareth Daniel Smith <garethdanielsmith@gmail.com>
 Glenn Willen <gwillen@nerdnet.org>
@@ -58,6 +60,7 @@ Grahame Bowland <grahame@angrygoats.net>
 Haitao Li <lihaitao@gmail.com>
 Huon Wilson <dbau.pp+github@gmail.com>
 Ian D. Bollinger <ian.bollinger@gmail.com>
+Ilyong Cho <ilyoan@gmail.com>
 Isaac Aggrey <isaac.aggrey@gmail.com>
 Ivano Coppola <rgbfirefox@gmail.com>
 Jacob Harris Cryer Kragh <jhckragh@gmail.com>
@@ -74,6 +77,7 @@ Jesse Ruderman <jruderman@gmail.com>
 Jim Blandy <jimb@red-bean.com>
 Jimmy Lu <jimmy.lu.2011@gmail.com>
 Joe Pletcher <joepletcher@gmail.com>
+John Clements <clements@racket-lang.org>
 Jon Morton <jonanin@gmail.com>
 Jonathan Sternberg <jonathansternberg@gmail.com>
 Josh Matthews <josh@joshmatthews.net>
@@ -84,13 +88,14 @@ Kelly Wilson <wilsonk@cpsc.ucalgary.ca>
 Kevin Atkinson <kevina@cs.utah.edu>
 Kevin Cantu <me@kevincantu.org>
 Lennart Kudling <github@kudling.de>
-Lindsey Kuper <lindsey@rockstargirl.org>
+Lindsey Kuper <lindsey@composition.al>
 Luca Bruno <lucab@debian.org>
 Luqman Aden <laden@csclub.uwaterloo.ca>
 Magnus Auvinen <magnus.auvinen@gmail.com>
 Mahmut Bulut <mahmutbulut0@gmail.com>
 Margaret Meyerhofer <mmeyerho@andrew.cmu.edu>
 Marijn Haverbeke <marijnh@gmail.com>
+Mark Lacey <641@rudkx.com>
 Martin DeMello <martindemello@gmail.com>
 Matt Brubeck <mbrubeck@limpet.net>
 Matthew O'Connor <thegreendragon@gmail.com>
@@ -106,6 +111,7 @@ Patrik Kårlin <patrik.karlin@gmail.com>
 Paul Stansifer <paul.stansifer@gmail.com>
 Paul Woolcock <pwoolcoc+github@gmail.com>
 Peter Hull <peterhull90@gmail.com>
+Peter Williams <peter@newton.cx>
 Philipp Brüschweiler <blei42@gmail.com>
 Rafael Ávila de Espíndola <respindola@mozilla.com>
 Ralph Giles <giles@thaumas.net>
@@ -116,9 +122,11 @@ Roland Tanglao <roland@rolandtanglao.com>
 Roy Frostig <rfrostig@mozilla.com>
 Ryan Scheel <ryan.havvy@gmail.com>
 Sean Stangl <sstangl@mozilla.com>
+Sebastian N. Fernandez <cachobot@gmail.com>
 Simon Barber-Dueck <sbarberdueck@gmail.com>
 startling <tdixon51793@gmail.com>
 Stefan Plantikow <stefan.plantikow@googlemail.com>
+Steve Klabnik <steve@steveklabnik.com>
 Taras Shpot <mrshpot@gmail.com>
 Ted Horst <ted.horst@earthlink.net>
 Tim Chevalier <chevalier@alum.wellesley.edu>
@@ -130,5 +138,6 @@ Tycho Sci <tychosci@gmail.com>
 Viktor Dahl <pazaconyoman@gmail.com>
 Vincent Belliard <vincent@famillebelliard.fr>
 Wade Mealing <wmealing@gmail.com>
+William Ting <william.h.ting@gmail.com>
 Yasuhiro Fujii <y-fujii@mimosa-pudica.net>
 Zack Corr <zackcorr95@gmail.com>
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..6528ffa
--- /dev/null
@@ -0,0 +1,12 @@
+## Pull request procedure
+
+Pull requests should be targeted at Rust's `incoming` branch (note that by default Github will aim them at the `master` branch) -- see "Changing The Commit Range and Destination Repository" in Github's documentation on [pull requests](https://help.github.com/articles/using-pull-requests). Before pushing to your Github repo and issuing the pull request, please do two things:
+
+1. [Rebase](http://git-scm.com/book/en/Git-Branching-Rebasing) your local changes against the `incoming` branch. Resolve any conflicts that arise.
+2. Run the full Rust test suite with the `make check` command. You're not off the hook even if you just stick to documentation; code examples in the docs are tested as well!
+
+Pull requests will be treated as "review requests", and we will give feedback we expect to see corrected on [style](https://github.com/mozilla/rust/wiki/Note-style-guide) and substance before pulling. Changes contributed via pull request should focus on a single issue at a time, like any other. We will not look kindly on pull-requests that try to "sneak" unrelated changes in.
+
+Normally, all pull requests must include regression tests (see [[Note-testsuite]]) that test your change. Occasionally, a change will be very difficult to test for. In those cases, please include a note in your commit message explaining why.
+
+For more details, please refer to [[Note-development-policy]].
\ No newline at end of file
index 963f455fe8ab2c8cb8b90ee3417ea722433e92f8..e476ac1dba2d1cf47eda06710cb7f828ca839557 100644 (file)
@@ -241,7 +241,7 @@ DRIVER_CRATE := $(S)src/driver/driver.rs
 ######################################################################
 
 # FIXME: x86-ism
-LLVM_COMPONENTS=x86 ipo bitreader bitwriter linker asmparser jit mcjit \
+LLVM_COMPONENTS=x86 arm ipo bitreader bitwriter linker asmparser jit mcjit \
                 interpreter
 
 define DEF_LLVM_VARS
index 9f4ee0a44ff96f14c769b5ac94101d36ed6d581c..877e2b569872267936fb772adb1db2b3a594c4de 100644 (file)
--- a/README.md
+++ b/README.md
@@ -65,10 +65,11 @@ API-documentation tool, and `cargo`, the Rust package manager.
 
 ## License
 
-Rust is primarily distributed under the terms of the MIT license, with
-portions covered by various BSD-like licenses.
+Rust is primarily distributed under the terms of both the MIT license
+and the Apache License (Version 2.0), with portions covered by various
+BSD-like licenses.
 
-See LICENSE.txt for details.
+See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.
 
 ## More help
 
index f2afa2d26ef8d7f13471e8d8c038597b5db941fb..f466f0fa3d7bc34de864473979083387918cdc77 100755 (executable)
--- a/configure
+++ b/configure
@@ -516,7 +516,7 @@ then
                       | cut -d ' ' -f 2)
 
     case $CFG_CLANG_VERSION in
-        (3.0svn | 3.0 | 3.1 | 4.0 | 4.1)
+        (3.0svn | 3.0 | 3.1 | 3.2 | 4.0 | 4.1)
         step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
         CFG_C_COMPILER="clang"
         ;;
@@ -578,7 +578,7 @@ for t in $CFG_TARGET_TRIPLES
 do
   make_dir rt/$t
   for i in                                          \
-    isaac linenoise bigint sync test arch/i386 arch/x86_64    \
+    isaac linenoise sync test arch/i386 arch/x86_64    \
     libuv libuv/src/ares libuv/src/eio libuv/src/ev
   do
     make_dir rt/$t/$i
@@ -717,7 +717,7 @@ do
     then
         msg "configuring LLVM for $t"
 
-        LLVM_TARGETS="--enable-targets=x86,x86_64"
+        LLVM_TARGETS="--enable-targets=x86,x86_64,arm"
         LLVM_BUILD="--build=$t"
         LLVM_HOST="--host=$t"
         LLVM_TARGET="--target=$t"
index 210e07d198acc8006a09b4a8190f056d1495b9e9..b5f045bc13a555275349dff0d5eb0929b8819797 100644 (file)
@@ -1107,6 +1107,19 @@ let mut a: Animal = Dog;
 a = Cat;
 ~~~~
 
+Enumeration constructors can have either named or unnamed fields:
+~~~~
+enum Animal {
+    Dog (~str, float),
+    Cat { name: ~str, weight: float }
+}
+
+let mut a: Animal = Dog(~"Cocoa", 37.2);
+a = Cat{ name: ~"Spotty", weight: 2.7 };
+~~~~
+
+In this example, `Cat` is a _struct-like enum variant_,
+whereas `Dog` is simply called an enum variant.
 ### Constants
 
 ~~~~~~~~ {.ebnf .gram}
@@ -3245,12 +3258,12 @@ crate name the crate is given a default name that matches the source file,
 with the extension removed. In that case, to turn on logging for a program
 compiled from, e.g. `helloworld.rs`, `RUST_LOG` should be set to `helloworld`.
 
-As a convenience, the logging spec can also be set to a special psuedo-crate,
+As a convenience, the logging spec can also be set to a special pseudo-crate,
 `::help`. In this case, when the application starts, the runtime will
 simply output a list of loaded modules containing log expressions, then exit.
 
 The Rust runtime itself generates logging information. The runtime's logs are
-generated for a number of artificial modules in the `::rt` psuedo-crate,
+generated for a number of artificial modules in the `::rt` pseudo-crate,
 and can be enabled just like the logs for any standard module. The full list
 of runtime logging modules follows.
 
@@ -3328,7 +3341,7 @@ have come and gone during the course of Rust's development:
 
 * The Newsqueak (1988), Alef (1995), and Limbo (1996) family. These
   languages were developed by Rob Pike, Phil Winterbottom, Sean Dorward and
-  others in their group at Bell labs Computing Sciences Research Center
+  others in their group at Bell Labs Computing Sciences Research Center
   (Murray Hill, NJ, USA).
 
 * The Napier (1985) and Napier88 (1988) family. These languages were
index 1def470755c317de0163a8b9ebde0220ba7d6b7a..d1dd14a6d0a8b8b8e6ad263a203ab7b033ab5f63 100644 (file)
@@ -43,7 +43,7 @@ macro_rules! early_return(
             _ => {}
         }
     );
-);
+)
 // ...
 early_return!(input_1 special_a);
 // ...
@@ -115,7 +115,7 @@ to transcribe into the macro expansion; its type need not be repeated.
 The right-hand side must be enclosed by delimiters, which are ignored by the
 transcriber (therefore `() => ((1,2,3))` is a macro that expands to a tuple
 expression, `() => (let $x=$val)` is a macro that expands to a statement, and
-`() => (1,2,3)` is a macro that expands to a syntax errror).
+`() => (1,2,3)` is a macro that expands to a syntax error).
 
 Except for permissibility of `$name` (and `$(...)*`, discussed below), the
 right-hand side of a macro definition is ordinary Rust syntax. In particular,
@@ -160,7 +160,7 @@ macro_rules! early_return(
             _ => {}
         }
     );
-);
+)
 // ...
 early_return!(input_1, [special_a|special_c|special_d]);
 // ...
index d20ce43c3d2c8b2858108ecf86fac1ee982d757f..40dba7afda4d6c14212a240216af5d8a78042511 100644 (file)
@@ -36,7 +36,7 @@ type system and memory model, generics, and modules. [Additional
 tutorials](#what-next) cover specific language features in greater
 depth.
 
-This tutorial assumes that the reader is already familiar with one or more
+This tutorial assumes that the reader is already familiar with one or
 more languages in the C family. Understanding of pointers and general
 memory management techniques will help.
 
@@ -80,7 +80,7 @@ supported build environments that are most likely to work.
 > "[getting started][wiki-start]" notes on the wiki. Even when using
 > the binary installer, the Windows build requires a MinGW installation,
 > the precise details of which are not discussed here. Finally, `rustc` may
-> need to be [referred to as `rustc.exe`][bug-3319]. It's a bummer, I
+> need to be [referred to as `rustc.exe`][bug-3319]. It's a bummer, we
 > know.
 
 [bug-3319]: https://github.com/mozilla/rust/issues/3319
@@ -114,7 +114,7 @@ for more information on them.
 
 When complete, `make install` will place several programs into
 `/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the
-API-documentation tool, `cargo`, the Rust package manager,
+API-documentation tool; `cargo`, the Rust package manager;
 and `rusti`, the Rust REPL.
 
 [wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
@@ -181,10 +181,10 @@ in blocks delineated by curly braces; there are control structures
 for branching and looping, like the familiar `if` and `while`; function
 calls are written `myfunc(arg1, arg2)`; operators are written the same
 and mostly have the same precedence as in C; comments are again like C;
-module names are separated with double-colon, `::`, as with C++.
+module names are separated with double-colon (`::`) as with C++.
 
 The main surface difference to be aware of is that the condition at
-the head of control structures like `if` and `while` do not require
+the head of control structures like `if` and `while` does not require
 parentheses, while their bodies *must* be wrapped in
 braces. Single-statement, unbraced bodies are not allowed.
 
@@ -226,12 +226,12 @@ let monster_size: int = 50;
 ~~~~
 
 Local variables may shadow earlier declarations, as in the previous example:
-`monster_size` was first declared as a `float`, and then then a second
-`monster_size` was declared as an int. If you were to actually compile this
-example, though, the compiler will determine that the second `monster_size` is
+`monster_size` was first declared as a `float`, and then a second
+`monster_size` was declared as an `int`. If you were to actually compile this
+example, though, the compiler would determine that the first `monster_size` is
 unused and issue a warning (because this situation is likely to indicate a
 programmer error). For occasions where unused variables are intentional, their
-name may be prefixed with an underscore to silence the warning, like `let
+names may be prefixed with an underscore to silence the warning, like `let
 _monster_size = 50;`.
 
 Rust identifiers start with an alphabetic
@@ -292,7 +292,7 @@ branch has a different value, and `price` gets the value of the branch that
 was taken.
 
 In short, everything that's not a declaration (declarations are `let` for
-variables, `fn` for functions, and any top-level named items such as
+variables; `fn` for functions; and any top-level named items such as
 [traits](#traits), [enum types](#enums), and [constants](#constants)) is an
 expression, including function bodies.
 
@@ -306,8 +306,8 @@ fn is_four(x: int) -> bool {
 
 ## Primitive types and literals
 
-There are general signed and unsigned integer types, `int`, and `uint`,
-as well as 8-, 16-, 32-, and 64-bit variations, `i8`, `u16`, etc.
+There are general signed and unsigned integer types, `int` and `uint`,
+as well as 8-, 16-, 32-, and 64-bit variants, `i8`, `u16`, etc.
 Integers can be written in decimal (`144`), hexadecimal (`0x90`), or
 binary (`0b10010000`) base. Each integral type has a corresponding literal
 suffix that can be used to indicate the type of a literal: `i` for `int`,
@@ -326,14 +326,14 @@ let c = 100u;    // c is a uint
 let d = 1000i32; // d is an i32
 ~~~~
 
-There are three floating point types, `float`, `f32`, and `f64`.
-Floating point numbers are written `0.0`, `1e6`, or `2.1e-4`.
-Like integers, floating point literals are inferred to the correct type.
-Suffixes `f`, `f32` and `f64` can be used to create literals of a specific type.
+There are three floating-point types: `float`, `f32`, and `f64`.
+Floating-point numbers are written `0.0`, `1e6`, or `2.1e-4`.
+Like integers, floating-point literals are inferred to the correct type.
+Suffixes `f`, `f32`, and `f64` can be used to create literals of a specific type.
 
 The keywords `true` and `false` produce literals of type `bool`.
 
-Characters, the `char` type, are 4-byte unicode codepoints,
+Characters, the `char` type, are four-byte Unicode codepoints,
 whose literals are written between single quotes, as in `'x'`.
 Just like C, Rust understands a number of character escapes, using the backslash
 character, such as `\n`, `\r`, and `\t`. String literals,
@@ -345,8 +345,8 @@ The nil type, written `()`, has a single value, also written `()`.
 ## Operators
 
 Rust's set of operators contains very few surprises. Arithmetic is done with
-`*`, `/`, `%`, `+`, and `-` (multiply, divide, take remainder, add, subtract). `-` is
-also a unary prefix operator that negates numbers. As in C, the bit operators
+`*`, `/`, `%`, `+`, and `-` (multiply, divide, take remainder, add, and subtract). `-` is
+also a unary prefix operator that negates numbers. As in C, the bitwise operators
 `>>`, `<<`, `&`, `|`, and `^` are also supported.
 
 Note that, if applied to an integer value, `!` flips all the bits (like `~` in
@@ -444,7 +444,7 @@ match my_number {
 }
 ~~~~
 
-Unlike in C, there is no 'falling through' between arms: only one arm
+Unlike in C, there is no "falling through" between arms: only one arm
 executes, and it doesn't have to explicitly `break` out of the
 construct when it is finished.
 
@@ -494,7 +494,7 @@ fn angle(vector: (float, float)) -> float {
 A variable name in a pattern matches any value, *and* binds that name
 to the value of the matched value inside of the arm's action. Thus, `(0f,
 y)` matches any tuple whose first element is zero, and binds `y` to
-the second element. `(x, y)` matches any tuple, and binds both
+the second element. `(x, y)` matches any two-element tuple, and binds both
 elements to variables.
 
 Any `match` arm can have a guard clause (written `if EXPR`), called a
@@ -562,7 +562,12 @@ Structs are quite similar to C structs and are even laid out the same way in
 memory (so you can read from a Rust struct in C, and vice-versa). Use the dot
 operator to access struct fields, as in `mypoint.x`.
 
-Fields that you want to mutate must be explicitly marked `mut`.
+Inherited mutability means that any field of a struct may be mutable, if the
+struct is in a mutable slot (or a field of a struct in a mutable slot, and
+so forth).
+
+A struct that is not mutable due to inherited mutability may declare some
+of its fields nevertheless mutable, using the `mut` keyword.
 
 ~~~~
 struct Stack {
@@ -572,10 +577,11 @@ struct Stack {
 ~~~~
 
 With a value of such a type, you can do `mystack.head += 1`. If `mut` were
-omitted from the type, such an assignment would result in a type error.
+omitted from the type, such an assignment to a struct without inherited
+mutability would result in a type error.
 
 `match` patterns destructure structs. The basic syntax is
-`Name {fieldname: pattern, ...}`:
+`Name { fieldname: pattern, ... }`:
 
 ~~~~
 # struct Point { x: float, y: float }
@@ -589,7 +595,7 @@ match mypoint {
 In general, the field names of a struct do not have to appear in the same
 order they appear in the type. When you are not interested in all
 the fields of a struct, a struct pattern may end with `, _` (as in
-`Name {field1, _}`) to indicate that you're ignoring all other fields.
+`Name { field1, _ }`) to indicate that you're ignoring all other fields.
 Additionally, struct fields have a shorthand matching form that simply
 reuses the field name as the binding name.
 
@@ -618,15 +624,15 @@ A value of this type is either a `Circle`, in which case it contains a
 `Point` struct and a float, or a `Rectangle`, in which case it contains
 two `Point` structs. The run-time representation of such a value
 includes an identifier of the actual form that it holds, much like the
-'tagged union' pattern in C, but with better static guarantees.
+"tagged union" pattern in C, but with better static guarantees.
 
 The above declaration will define a type `Shape` that can refer to
 such shapes, and two functions, `Circle` and `Rectangle`, which can be
 used to construct values of the type (taking arguments of the
-specified types). So `Circle(Point {x: 0f, y: 0f}, 10f)` is the way to
+specified types). So `Circle(Point { x: 0f, y: 0f }, 10f)` is the way to
 create a new circle.
 
-Enum variants need not have type parameters. This `enum` declaration,
+Enum variants need not have parameters. This `enum` declaration,
 for example, is equivalent to a C enum:
 
 ~~~~
@@ -659,7 +665,7 @@ variant does not have a discriminator, it defaults to 0. For example,
 the value of `North` is 0, `East` is 1, `South` is 2, and `West` is 3.
 
 When an enum is C-like, you can apply the `as` cast operator to
-convert it to its discriminator value as an int.
+convert it to its discriminator value as an `int`.
 
 <a name="single_variant_enum"></a>
 
@@ -710,7 +716,7 @@ patterns, as in this definition of `area`:
 fn area(sh: Shape) -> float {
     match sh {
         Circle(_, size) => float::consts::pi * size * size,
-        Rectangle(Point {x, y}, Point {x: x2, y: y2}) => (x2 - x) * (y2 - y)
+        Rectangle(Point { x, y }, Point { x: x2, y: y2 }) => (x2 - x) * (y2 - y)
     }
 }
 ~~~~
@@ -721,14 +727,34 @@ introduction form, nullary enum patterns are written without
 parentheses.
 
 ~~~~
-# struct Point {x: float, y: float}
+# struct Point { x: float, y: float }
 # enum Direction { North, East, South, West }
 fn point_from_direction(dir: Direction) -> Point {
     match dir {
-        North => Point {x:  0f, y:  1f},
-        East  => Point {x:  1f, y:  0f},
-        South => Point {x:  0f, y: -1f},
-        West  => Point {x: -1f, y:  0f}
+        North => Point { x:  0f, y:  1f },
+        East  => Point { x:  1f, y:  0f },
+        South => Point { x:  0f, y: -1f },
+        West  => Point { x: -1f, y:  0f }
+    }
+}
+~~~~
+
+Enum variants may also be structs. For example:
+
+~~~~
+# use core::float;
+# struct Point { x: float, y: float }
+# fn square(x: float) -> float { x * x }
+enum Shape {
+    Circle { center: Point, radius: float },
+    Rectangle { top_left: Point, bottom_right: Point }
+}
+fn area(sh: Shape) -> float {
+    match sh {
+        Circle { radius: radius, _ } => float::consts::pi * square(radius),
+        Rectangle { top_left: top_left, bottom_right: bottom_right } => {
+            (bottom_right.x - top_left.x) * (bottom_right.y - top_left.y)
+        }
     }
 }
 ~~~~
@@ -781,7 +807,7 @@ fn line(a: int, b: int, x: int) -> int {
 
 The `return` keyword immediately returns from the body of a function. It
 is optionally followed by an expression to return. A function can
-also return a value by having its top level block produce an
+also return a value by having its top-level block produce an
 expression.
 
 ~~~~
@@ -815,82 +841,12 @@ assert () == oops(5, 3, 1);
 
 As with `match` expressions and `let` bindings, function arguments support
 pattern destructuring. Like `let`, argument patterns must be irrefutable,
-as in this example that unpacks a tuple and returns it.
+as in this example that unpacks the first value from a tuple and returns it.
 
 ~~~
 fn first((value, _): (int, float)) -> int { value }
 ~~~
 
-
-# The Rust memory model
-
-At this junction, let's take a detour to explain the concepts involved
-in Rust's memory model. We've seen some of Rust's pointer sigils (`@`,
-`~`, and `&`) float by in a few examples, and we aren't going to get
-much further without explaining them. Rust has a very particular
-approach to memory management that plays a significant role in shaping
-the subjective experience of programming in the
-language. Understanding the memory landscape will illuminate several
-of Rust's unique features as we encounter them.
-
-Rust has three competing goals that inform its view of memory:
-
-* Memory safety: Memory that the Rust language can observe must be
-  guaranteed to be valid. Under normal circumstances, it must be
-  impossible for Rust to trigger a segmentation fault or leak memory.
-* Performance: High-performance low-level code must be able to use
-  a number of different allocation strategies. Tracing garbage collection must be
-  optional and, if it is not desired, memory safety must not be compromised.
-  Less performance-critical, high-level code should be able to employ a single,
-  garbage-collection-based, heap allocation strategy.
-* Concurrency: Rust code must be free of in-memory data races. (Note that other
-  types of races are still possible.)
-
-## How performance considerations influence the memory model
-
-Most languages that offer strong memory safety guarantees rely on a
-garbage-collected heap to manage all of the objects. This approach is
-straightforward both in concept and in implementation, but has
-significant costs. Languages that follow this path tend to
-aggressively pursue ways to ameliorate allocation costs (think the
-Java Virtual Machine). Rust supports this strategy with _managed
-boxes_: memory allocated on the heap whose lifetime is managed
-by the garbage collector.
-
-By comparison, languages like C++ offer very precise control over
-where objects are allocated. In particular, it is common to allocate them
-directly on the stack, avoiding expensive heap allocation. In Rust
-this is possible as well, and the compiler uses a [clever _pointer
-lifetime analysis_][borrow] to ensure that no variable can refer to stack
-objects after they are destroyed.
-
-[borrow]: tutorial-borrowed-ptr.html
-
-## How concurrency considerations influence the memory model
-
-Memory safety in a concurrent environment involves avoiding race
-conditions between two threads of execution accessing the same
-memory. Even high-level languages often require programmers to make
-correct use of locking to ensure that a program is free of races.
-
-Rust starts from the position that memory cannot be shared between
-tasks. Experience in other languages has proven that isolating each
-task's heap from the others is a reliable strategy and one that is
-easy for programmers to reason about. Heap isolation has the
-additional benefit that garbage collection must only be done
-per-heap. Rust never "stops the world" to reclaim memory.
-
-Complete isolation of heaps between tasks would, however, mean that
-any data transferred between tasks must be copied. While this is a
-fine and useful way to implement communication between tasks, it is
-also very inefficient for large data structures. To reduce the amount
-of copying, Rust also uses a global _exchange heap_. Objects allocated
-in the exchange heap have _ownership semantics_, meaning that there is
-only a single variable that refers to them. For this reason, they are
-referred to as _owned boxes_. All tasks may allocate objects on the
-exchange heap, then transfer ownership of those objects to other
-tasks, avoiding expensive copies.
-
 # Boxes and pointers
 
 Many modern languages have a so-called "uniform representation" for
@@ -898,7 +854,7 @@ aggregate types like structs and enums, so as to represent these types
 as pointers to heap memory by default. In contrast, Rust, like C and
 C++, represents such types directly. Another way to say this is that
 aggregate data in Rust are *unboxed*. This means that if you `let x =
-Point {x: 1f, y: 1f};`, you are creating a struct on the stack. If you
+Point { x: 1f, y: 1f };`, you are creating a struct on the stack. If you
 then copy it into a data structure, you copy the entire struct, not
 just a pointer.
 
@@ -908,7 +864,7 @@ those with mutable fields, it can be useful to have a single copy on
 the stack or on the heap, and refer to that through a pointer.
 
 Rust supports several types of pointers. The safe pointer types are
-`@T` for managed boxes allocated on the local heap, `~T`, for
+`@T`, for managed boxes allocated on the local heap, `~T`, for
 uniquely-owned boxes allocated on the exchange heap, and `&T`, for
 borrowed pointers, which may point to any memory, and whose lifetimes
 are governed by the call stack.
@@ -922,8 +878,8 @@ All pointer types can be dereferenced with the `*` unary operator.
 
 ## Managed boxes
 
-Managed boxes are pointers to heap-allocated, garbage collected
-memory.  Applying the unary `@` operator to an expression creates a
+Managed boxes are pointers to heap-allocated, garbage-collected
+memory. Applying the unary `@` operator to an expression creates a
 managed box. The resulting box contains the result of the
 expression. Copying a managed box, as happens during assignment, only
 copies a pointer, never the contents of the box.
@@ -1018,7 +974,8 @@ As an example, consider a simple struct type, `Point`:
 
 ~~~
 struct Point {
-    x: float, y: float
+    x: float,
+    y: float
 }
 ~~~~
 
@@ -1028,9 +985,9 @@ contains a point, but allocated in a different location:
 
 ~~~
 # struct Point { x: float, y: float }
-let on_the_stack : Point  =  Point {x: 3.0, y: 4.0};
-let managed_box  : @Point = @Point {x: 5.0, y: 1.0};
-let owned_box    : ~Point = ~Point {x: 7.0, y: 9.0};
+let on_the_stack : Point  =  Point { x: 3.0, y: 4.0 };
+let managed_box  : @Point = @Point { x: 5.0, y: 1.0 };
+let owned_box    : ~Point = ~Point { x: 7.0, y: 9.0 };
 ~~~
 
 Suppose we wanted to write a procedure that computed the distance
@@ -1059,9 +1016,9 @@ Now we can call `compute_distance()` in various ways:
 
 ~~~
 # struct Point{ x: float, y: float };
-# let on_the_stack : Point  =  Point {x: 3.0, y: 4.0};
-# let managed_box  : @Point = @Point {x: 5.0, y: 1.0};
-# let owned_box    : ~Point = ~Point {x: 7.0, y: 9.0};
+# let on_the_stack : Point  =  Point { x: 3.0, y: 4.0 };
+# let managed_box  : @Point = @Point { x: 5.0, y: 1.0 };
+# let owned_box    : ~Point = ~Point { x: 7.0, y: 9.0 };
 # fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }
 compute_distance(&on_the_stack, managed_box);
 compute_distance(managed_box, owned_box);
@@ -1071,14 +1028,14 @@ Here the `&` operator is used to take the address of the variable
 `on_the_stack`; this is because `on_the_stack` has the type `Point`
 (that is, a struct value) and we have to take its address to get a
 value. We also call this _borrowing_ the local variable
-`on_the_stack`, because we are created an alias: that is, another
+`on_the_stack`, because we are creating an alias: that is, another
 route to the same data.
 
 In the case of the boxes `managed_box` and `owned_box`, however, no
 explicit action is necessary. The compiler will automatically convert
 a box like `@point` or `~point` to a borrowed pointer like
 `&point`. This is another form of borrowing; in this case, the
-contents of the managed/owned box is being lent out.
+contents of the managed/owned box are being lent out.
 
 Whenever a value is borrowed, there are some limitations on what you
 can do with the original. For example, if the contents of a variable
@@ -1138,7 +1095,7 @@ let area = (*rect).area();
 ~~~
 
 To combat this ugliness the dot operator applies _automatic pointer
-dereferencing_ to the receiver (the value on the left hand side of the
+dereferencing_ to the receiver (the value on the left-hand side of the
 dot), so in most cases, explicitly dereferencing the receiver is not necessary.
 
 ~~~
@@ -1180,7 +1137,7 @@ pointers to vectors are also called 'slices'.
 // A fixed-size stack vector
 let stack_crayons: [Crayon * 3] = [Almond, AntiqueBrass, Apricot];
 
-// A borrowed pointer to stack allocated vector
+// A borrowed pointer to stack-allocated vector
 let stack_crayons: &[Crayon] = &[Aquamarine, Asparagus, AtomicTangerine];
 
 // A local heap (managed) vector of crayons
@@ -1263,7 +1220,7 @@ distinct type. They support most of the same allocation options as
 vectors, though the string literal without a storage sigil (for
 example, `"foo"`) is treated differently than a comparable vector
 (`[foo]`).  Whereas plain vectors are stack-allocated fixed-length
-vectors, plain strings are region pointers to read-only
+vectors, plain strings are borrowed pointers to read-only (static)
 memory. All strings are immutable.
 
 ~~~
@@ -1507,7 +1464,7 @@ do spawn() || {
 }
 ~~~~
 
-Look at all those bars and parentheses - that's two empty argument
+Look at all those bars and parentheses -- that's two empty argument
 lists back to back. Since that is so unsightly, empty argument lists
 may be omitted from `do` expressions.
 
@@ -1586,7 +1543,7 @@ fn contains(v: &[int], elt: int) -> bool {
 ~~~~
 
 Notice that, because `each` passes each value by borrowed pointer,
-the iteratee needs to dereference it before using.
+the iteratee needs to dereference it before using it.
 In these situations it can be convenient to lean on Rust's
 argument patterns to bind `x` to the actual value, not the pointer.
 
@@ -1708,7 +1665,7 @@ s.draw_borrowed();
 // ... and dereferenced
 (& &s).draw_borrowed();
 
-// ... and dereferenced, and borrowed, and
+// ... and dereferenced and borrowed
 (&@~s).draw_borrowed();
 ~~~
 
@@ -1771,9 +1728,9 @@ Inside a generic function, the names of the type parameters
 (capitalized by convention) stand for opaque types. All you can do
 with instances of these types is pass them around: you can't apply any
 operations to them or pattern-match on them. Note that instances of
-generic types are often passed by pointer.  For example, the parameter
+generic types are often passed by pointer. For example, the parameter
 `function()` is supplied with a pointer to a value of type `T` and not
-a value of type `T` itself.  This ensures that the function works with
+a value of type `T` itself. This ensures that the function works with
 the broadest set of types possible, since some types are expensive or
 illegal to copy and pass by value.
 
@@ -1794,7 +1751,7 @@ enum Option<T> {
 ~~~~
 
 These declarations can be instantiated to valid types like `Set<int>`,
-`Stack<int>` and `Option<int>`.
+`Stack<int>`, and `Option<int>`.
 
 The last type in that example, `Option`, appears frequently in Rust code.
 Because Rust does not have null pointers (except in unsafe code), we need
@@ -1803,13 +1760,13 @@ combination of arguments of the appropriate types. The usual way is to write
 a function that returns `Option<T>` instead of `T`.
 
 ~~~~
-# struct Point {x: float, y: float}
+# struct Point { x: float, y: float }
 # enum Shape { Circle(Point, float), Rectangle(Point, Point) }
 fn radius(shape: Shape) -> Option<float> {
-   match shape {
-       Circle(_, radius) => Some(radius),
-       Rectangle(*)      => None
-   }      
+    match shape {
+        Circle(_, radius) => Some(radius),
+        Rectangle(*)      => None
+    }
 }
 ~~~~
 
@@ -1873,12 +1830,12 @@ While most traits can be defined and implemented by user code, three
 traits are automatically derived and implemented for all applicable
 types by the compiler, and may not be overridden:
 
-* `Copy` - Types that can be copied: either implicitly, or explicitly with the
+* `Copy` - Types that can be copied, either implicitly, or explicitly with the
   `copy` operator. All types are copyable unless they have destructors or
   contain types with destructors.
 
 * `Owned` - Owned types. Types are owned unless they contain managed
-  boxes, managed closures, or borrowed pointers.  Owned types may or
+  boxes, managed closures, or borrowed pointers. Owned types may or
   may not be copyable.
 
 * `Const` - Constant (immutable) types. These are types that do not contain
@@ -1895,7 +1852,7 @@ garbage collector reclaimed it.
 
 ~~~
 struct TimeBomb {
-    explosivity: uint,
+    explosivity: uint
 }
 
 impl TimeBomb : Drop {
@@ -1926,7 +1883,7 @@ trait Printable {
 Traits may be implemented for specific types with [impls]. An impl
 that implements a trait includes the name of the trait at the start of
 the definition, as in the following impls of `Printable` for `int`
-and `~str`.
+and `&str`.
 
 [impls]: #functions-and-methods
 
@@ -1985,12 +1942,12 @@ following trait describes types that support an equality operation:
 // In a trait, `self` refers both to the self argument
 // and to the type implementing the trait
 trait Eq {
-  fn equals(&self, other: &self) -> bool;
+    fn equals(&self, other: &self) -> bool;
 }
 
 // In an impl, `self` refers just to the value of the receiver
 impl int: Eq {
-  fn equals(&self, other: &int) -> bool { *other == *self }
+    fn equals(&self, other: &int) -> bool { *other == *self }
 }
 ~~~~
 
@@ -2014,7 +1971,7 @@ impl Circle: Shape {
     static fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }
 }
 impl Square: Shape {
-     static fn new(area: float) -> Square { Square { length: sqrt(area) } }
+    static fn new(area: float) -> Square { Square { length: sqrt(area) } }
 }
 
 let area = 42.5;
@@ -2084,9 +2041,9 @@ fn draw_all<T: Drawable>(shapes: ~[T]) {
 # draw_all(~[c]);
 ~~~~
 
-You can call that on an array of circles, or an array of squares
+You can call that on an array of circles, or an array of rectangles
 (assuming those have suitable `Drawable` traits defined), but not on
-an array containing both circles and squares. When such behavior is
+an array containing both circles and rectangles. When such behavior is
 needed, a trait name can alternately be used as a type, called
 an _object_.
 
@@ -2170,10 +2127,10 @@ Now, we can implement `Circle` on a type only if we also implement `Shape`.
 # fn square(x: float) -> float { x * x }
 struct CircleStruct { center: Point, radius: float }
 impl CircleStruct: Circle {
-     fn radius(&self) -> float { sqrt(self.area() / pi) }
+    fn radius(&self) -> float { sqrt(self.area() / pi) }
 }
 impl CircleStruct: Shape {
-     fn area(&self) -> float { pi * square(self.radius) }
+    fn area(&self) -> float { pi * square(self.radius) }
 }   
 ~~~~
 
@@ -2247,7 +2204,7 @@ fn chicken_farmer() {
 ~~~
 
 These farm animal functions have a new keyword, `pub`, attached to
-them.  The `pub` keyword modifies an item's visibility, making it
+them. The `pub` keyword modifies an item's visibility, making it
 visible outside its containing module. An expression with `::`, like
 `farm::chicken`, can name an item outside of its containing
 module. Items, such as those declared with `fn`, `struct`, `enum`,
@@ -2257,11 +2214,16 @@ Visibility restrictions in Rust exist only at module boundaries. This
 is quite different from most object-oriented languages that also
 enforce restrictions on objects themselves. That's not to say that
 Rust doesn't support encapsulation: both struct fields and methods can
-be private.  But this encapsulation is at the module level, not the
+be private. But this encapsulation is at the module level, not the
 struct level. Note that fields and methods are _public_ by default.
 
 ~~~
 mod farm {
+# use farm;
+# pub type Chicken = int;
+# type Cow = int;
+# enum Human = int;
+# impl Human { fn rest(&self) { } }
 # pub fn make_me_a_farm() -> farm::Farm { farm::Farm { chickens: ~[], cows: ~[], farmer: Human(0) } }
     pub struct Farm {
         priv mut chickens: ~[Chicken],
@@ -2288,19 +2250,15 @@ fn main() {
      farm::feed_animals(&f);
      f.farmer.rest();
 }
-# type Chicken = int;
-# type Cow = int;
-# enum Human = int;
 # fn make_me_a_farm() -> farm::Farm { farm::make_me_a_farm() }
-# fn make_me_a_chicken() -> Chicken { 0 }
-# impl Human { fn rest(&self) { } }
+# fn make_me_a_chicken() -> farm::Chicken { 0 }
 ~~~
 
 ## Crates
 
 The unit of independent compilation in Rust is the crate: rustc
 compiles a single crate at a time, from which it produces either a
-library or executable.
+library or an executable.
 
 When compiling a single `.rs` source file, the file acts as the whole crate.
 You can compile it with the `--lib` compiler switch to create a shared
@@ -2348,7 +2306,7 @@ Compiling this file will cause `rustc` to look for files named
 `cow.rs`, `chicken.rs`, and `horse.rs` in the same directory as the
 `.rc` file, compile them all together, and, based on the presence of
 the `crate_type = "lib"` attribute, output a shared library or an
-executable.  (If the line `#[crate_type = "lib"];` was omitted,
+executable. (If the line `#[crate_type = "lib"];` was omitted,
 `rustc` would create an executable.)
 
 The `#[link(...)]` attribute provides meta information about the
index 2a7b3eccbf6becc3f1a39541a2b7591caacd1eaa..9f64712b9c86027cb9fb274eaa290ebd794a5712 100644 (file)
@@ -152,7 +152,7 @@ else
 
 doc/rust.g: rust.md $(S)src/etc/extract_grammar.py
        @$(call E, extract_grammar: $@)
-       $(Q)$(S)src/etc/extract_grammar.py $< >$@
+       $(Q)$(CFG_PYTHON) $(S)src/etc/extract_grammar.py $< >$@
 
 verify-grammar: doc/rust.g
        @$(call E, LLnextgen: $<)
diff --git a/mk/libuv/arm/unix/android/Makefile b/mk/libuv/arm/unix/android/Makefile
new file mode 100755 (executable)
index 0000000..16323af
--- /dev/null
@@ -0,0 +1,354 @@
+# We borrow heavily from the kernel build setup, though we are simpler since
+# we don't have Kconfig tweaking settings on us.
+
+# The implicit make rules have it looking for RCS files, among other things.
+# We instead explicitly write all the rules we care about.
+# It's even quicker (saves ~200ms) to pass -r on the command line.
+MAKEFLAGS=-r
+
+# The source directory tree.
+srcdir := ../../../../..
+abs_srcdir := $(abspath $(srcdir))
+
+# The name of the builddir.
+builddir_name ?= out
+
+# The V=1 flag on command line makes us verbosely print command lines.
+ifdef V
+  quiet=
+else
+  quiet=quiet_
+endif
+
+# Specify BUILDTYPE=Release on the command line for a release build.
+BUILDTYPE ?= Debug
+
+# Directory all our build output goes into.
+# Note that this must be two directories beneath src/ for unit tests to pass,
+# as they reach into the src/ directory for data with relative paths.
+builddir ?= $(builddir_name)/$(BUILDTYPE)
+abs_builddir := $(abspath $(builddir))
+depsdir := $(builddir)/.deps
+
+# Object output directory.
+obj := $(builddir)/obj
+abs_obj := $(abspath $(obj))
+
+# We build up a list of every single one of the targets so we can slurp in the
+# generated dependency rule Makefiles in one pass.
+all_deps :=
+
+
+
+# C++ apps need to be linked with g++.
+#
+# Note: flock is used to seralize linking. Linking is a memory-intensive
+# process so running parallel links can often lead to thrashing.  To disable
+# the serialization, override LINK via an envrionment variable as follows:
+#
+#   export LINK=g++
+#
+# This will allow make to invoke N linker processes as specified in -jN.
+LINK ?= flock $(builddir)/linker.lock $(CXX)
+
+CC.target ?= $(CC)
+CFLAGS.target ?= $(CFLAGS)
+CXX.target ?= $(CXX)
+CXXFLAGS.target ?= $(CXXFLAGS)
+LINK.target ?= $(LINK)
+LDFLAGS.target ?= $(LDFLAGS)
+AR.target ?= $(AR)
+ARFLAGS.target ?= crsT
+
+# N.B.: the logic of which commands to run should match the computation done
+# in gyp's make.py where ARFLAGS.host etc. is computed.
+# TODO(evan): move all cross-compilation logic to gyp-time so we don't need
+# to replicate this environment fallback in make as well.
+CC.host ?= gcc
+CFLAGS.host ?=
+CXX.host ?= g++
+CXXFLAGS.host ?=
+LINK.host ?= g++
+LDFLAGS.host ?=
+AR.host ?= ar
+ARFLAGS.host := crs
+
+# Define a dir function that can handle spaces.
+# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions
+# "leading spaces cannot appear in the text of the first argument as written.
+# These characters can be put into the argument value by variable substitution."
+empty :=
+space := $(empty) $(empty)
+
+# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces
+replace_spaces = $(subst $(space),?,$1)
+unreplace_spaces = $(subst ?,$(space),$1)
+dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1)))
+
+# Flags to make gcc output dependency info.  Note that you need to be
+# careful here to use the flags that ccache and distcc can understand.
+# We write to a dep file on the side first and then rename at the end
+# so we can't end up with a broken dep file.
+depfile = $(depsdir)/$(call replace_spaces,$@).d
+DEPFLAGS = -MMD -MF $(depfile).raw
+
+# We have to fixup the deps output in a few ways.
+# (1) the file output should mention the proper .o file.
+# ccache or distcc lose the path to the target, so we convert a rule of
+# the form:
+#   foobar.o: DEP1 DEP2
+# into
+#   path/to/foobar.o: DEP1 DEP2
+# (2) we want missing files not to cause us to fail to build.
+# We want to rewrite
+#   foobar.o: DEP1 DEP2 \
+#               DEP3
+# to
+#   DEP1:
+#   DEP2:
+#   DEP3:
+# so if the files are missing, they're just considered phony rules.
+# We have to do some pretty insane escaping to get those backslashes
+# and dollar signs past make, the shell, and sed at the same time.
+# Doesn't work with spaces, but that's fine: .d files have spaces in
+# their names replaced with other characters.
+define fixup_dep
+# The depfile may not exist if the input file didn't have any #includes.
+touch $(depfile).raw
+# Fixup path as in (1).
+sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)
+# Add extra rules as in (2).
+# We remove slashes and replace spaces with new lines;
+# remove blank lines;
+# delete the first line and append a colon to the remaining lines.
+sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\
+  grep -v '^$$'                             |\
+  sed -e 1d -e 's|$$|:|'                     \
+    >> $(depfile)
+rm $(depfile).raw
+endef
+
+# Command definitions:
+# - cmd_foo is the actual command to run;
+# - quiet_cmd_foo is the brief-output summary of the command.
+
+quiet_cmd_cc = CC($(TOOLSET)) $@
+cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $<
+
+quiet_cmd_cxx = CXX($(TOOLSET)) $@
+cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
+
+quiet_cmd_touch = TOUCH $@
+cmd_touch = touch $@
+
+quiet_cmd_copy = COPY $@
+# send stderr to /dev/null to ignore messages when linking directories.
+cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@")
+
+quiet_cmd_alink = AR($(TOOLSET)) $@
+cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) $(ARFLAGS.$(TOOLSET)) $@ $(filter %.o,$^)
+
+# Due to circular dependencies between libraries :(, we wrap the
+# special "figure out circular dependencies" flags around the entire
+# input list during linking.
+quiet_cmd_link = LINK($(TOOLSET)) $@
+cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS)
+
+# We support two kinds of shared objects (.so):
+# 1) shared_library, which is just bundling together many dependent libraries
+# into a link line.
+# 2) loadable_module, which is generating a module intended for dlopen().
+#
+# They differ only slightly:
+# In the former case, we want to package all dependent code into the .so.
+# In the latter case, we want to package just the API exposed by the
+# outermost module.
+# This means shared_library uses --whole-archive, while loadable_module doesn't.
+# (Note that --whole-archive is incompatible with the --start-group used in
+# normal linking.)
+
+# Other shared-object link notes:
+# - Set SONAME to the library filename so our binaries don't reference
+# the local, absolute paths used on the link command-line.
+quiet_cmd_solink = SOLINK($(TOOLSET)) $@
+cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS)
+
+quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
+cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
+
+
+# Define an escape_quotes function to escape single quotes.
+# This allows us to handle quotes properly as long as we always use
+# use single quotes and escape_quotes.
+escape_quotes = $(subst ','\'',$(1))
+# This comment is here just to include a ' to unconfuse syntax highlighting.
+# Define an escape_vars function to escape '$' variable syntax.
+# This allows us to read/write command lines with shell variables (e.g.
+# $LD_LIBRARY_PATH), without triggering make substitution.
+escape_vars = $(subst $$,$$$$,$(1))
+# Helper that expands to a shell command to echo a string exactly as it is in
+# make. This uses printf instead of echo because printf's behaviour with respect
+# to escape sequences is more portable than echo's across different shells
+# (e.g., dash, bash).
+exact_echo = printf '%s\n' '$(call escape_quotes,$(1))'
+
+# Helper to compare the command we're about to run against the command
+# we logged the last time we ran the command.  Produces an empty
+# string (false) when the commands match.
+# Tricky point: Make has no string-equality test function.
+# The kernel uses the following, but it seems like it would have false
+# positives, where one string reordered its arguments.
+#   arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
+#                       $(filter-out $(cmd_$@), $(cmd_$(1))))
+# We instead substitute each for the empty string into the other, and
+# say they're equal if both substitutions produce the empty string.
+# .d files contain ? instead of spaces, take that into account.
+command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\
+                       $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1))))
+
+# Helper that is non-empty when a prerequisite changes.
+# Normally make does this implicitly, but we force rules to always run
+# so we can check their command lines.
+#   $? -- new prerequisites
+#   $| -- order-only dependencies
+prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
+
+# Helper that executes all postbuilds, and deletes the output file when done
+# if any of the postbuilds failed.
+define do_postbuilds
+  @E=0;\
+  for p in $(POSTBUILDS); do\
+    eval $$p;\
+    F=$$?;\
+    if [ $$F -ne 0 ]; then\
+      E=$$F;\
+    fi;\
+  done;\
+  if [ $$E -ne 0 ]; then\
+    rm -rf "$@";\
+    exit $$E;\
+  fi
+endef
+
+# do_cmd: run a command via the above cmd_foo names, if necessary.
+# Should always run for a given target to handle command-line changes.
+# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
+# Third argument, if non-zero, makes it do POSTBUILDS processing.
+# Note: We intentionally do NOT call dirx for depfile, since it contains ? for
+# spaces already and dirx strips the ? characters.
+define do_cmd
+$(if $(or $(command_changed),$(prereq_changed)),
+  @$(call exact_echo,  $($(quiet)cmd_$(1)))
+  @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))"
+  $(if $(findstring flock,$(word 1,$(cmd_$1))),
+    @$(cmd_$(1))
+    @echo "  $(quiet_cmd_$(1)): Finished",
+    @$(cmd_$(1))
+  )
+  @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
+  @$(if $(2),$(fixup_dep))
+  $(if $(and $(3), $(POSTBUILDS)),
+    $(call do_postbuilds)
+  )
+)
+endef
+
+# Declare the "all" target first so it is the default,
+# even though we don't have the deps yet.
+.PHONY: all
+all:
+
+# Use FORCE_DO_CMD to force a target to run.  Should be coupled with
+# do_cmd.
+.PHONY: FORCE_DO_CMD
+FORCE_DO_CMD:
+
+TOOLSET := target
+# Suffix rules, putting all outputs into $(obj).
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+# Try building from generated source, too.
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+
+ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
+    $(findstring $(join ^,$(prefix)),\
+                 $(join ^,src/libuv/run-benchmarks.target.mk)))),)
+  include src/libuv/run-benchmarks.target.mk
+endif
+ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
+    $(findstring $(join ^,$(prefix)),\
+                 $(join ^,src/libuv/run-tests.target.mk)))),)
+  include src/libuv/run-tests.target.mk
+endif
+ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
+    $(findstring $(join ^,$(prefix)),\
+                 $(join ^,src/libuv/uv.target.mk)))),)
+  include src/libuv/uv.target.mk
+endif
+
+#quiet_cmd_regen_makefile = ACTION Regenerating $@
+#cmd_regen_makefile = ./src/libuv/build/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." -Isrc/libuv/common.gypi "--depth=." "--generator-output=mk/libuv/arm/unix/android" "-Ddefault_configuration=Default" "-Dcomponent=static_library" "-Dlibrary=static_library" "-Dtarget_arch=arm" "-DOS=linux" src/libuv/uv.gyp
+#Makefile: $(srcdir)/src/libuv/uv.gyp $(srcdir)/src/libuv/common.gypi
+#      $(call do_cmd,regen_makefile)
+
+# "all" is a concatenation of the "all" targets from all the included
+# sub-makefiles. This is just here to clarify.
+all:
+
+# Add in dependency-tracking rules.  $(all_deps) is the list of every single
+# target in our tree. Only consider the ones with .d (dependency) info:
+d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d))
+ifneq ($(d_files),)
+  # Rather than include each individual .d file, concatenate them into a
+  # single file which make is able to load faster.  We split this into
+  # commands that take 1000 files at a time to avoid overflowing the
+  # command line.
+  $(shell cat $(wordlist 1,1000,$(d_files)) > $(depsdir)/all.deps)
+
+  ifneq ($(word 1001,$(d_files)),)
+    $(error Found unprocessed dependency files (gyp didn't generate enough rules!))
+  endif
+
+  # make looks for ways to re-generate included makefiles, but in our case, we
+  # don't have a direct way. Explicitly telling make that it has nothing to do
+  # for them makes it go faster.
+  $(depsdir)/all.deps: ;
+
+  include $(depsdir)/all.deps
+endif
diff --git a/mk/libuv/arm/unix/android/src/libuv/run-benchmarks.target.mk b/mk/libuv/arm/unix/android/src/libuv/run-benchmarks.target.mk
new file mode 100755 (executable)
index 0000000..20ff960
--- /dev/null
@@ -0,0 +1,115 @@
+# This file is generated by gyp; do not edit.
+
+TOOLSET := target
+TARGET := run-benchmarks
+DEFS_Debug := '-D_LARGEFILE_SOURCE' \
+       '-D_FILE_OFFSET_BITS=64' \
+       '-D_GNU_SOURCE' \
+       '-DEIO_STACKSIZE=262144' \
+       '-DDEBUG' \
+       '-D_DEBUG' \
+       '-DEV_VERIFY=2'
+
+# Flags passed to all source files.
+CFLAGS_Debug := \
+       -Wall \
+       -ansi \
+       -fvisibility=hidden \
+       -g \
+       -O0
+
+# Flags passed to only C files.
+CFLAGS_C_Debug := 
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Debug := -fno-rtti \
+       -fno-exceptions
+
+INCS_Debug := -I$(srcdir)/src/libuv/include
+
+DEFS_Release := '-D_LARGEFILE_SOURCE' \
+       '-D_FILE_OFFSET_BITS=64' \
+       '-D_GNU_SOURCE' \
+       '-DEIO_STACKSIZE=262144' \
+       '-DNDEBUG'
+
+# Flags passed to all source files.
+CFLAGS_Release :=  \
+       -Wall \
+       -ansi \
+       -fvisibility=hidden \
+       -O3 \
+       -fomit-frame-pointer \
+       -fdata-sections \
+       -ffunction-sections
+
+# Flags passed to only C files.
+CFLAGS_C_Release := 
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Release := -fno-rtti \
+       -fno-exceptions
+
+INCS_Release := -I$(srcdir)/src/libuv/include
+
+OBJS := $(obj).target/$(TARGET)/src/libuv/test/benchmark-ares.o \
+       $(obj).target/$(TARGET)/src/libuv/test/benchmark-getaddrinfo.o \
+       $(obj).target/$(TARGET)/src/libuv/test/benchmark-ping-pongs.o \
+       $(obj).target/$(TARGET)/src/libuv/test/benchmark-pound.o \
+       $(obj).target/$(TARGET)/src/libuv/test/benchmark-pump.o \
+       $(obj).target/$(TARGET)/src/libuv/test/benchmark-sizes.o \
+       $(obj).target/$(TARGET)/src/libuv/test/benchmark-spawn.o \
+       $(obj).target/$(TARGET)/src/libuv/test/benchmark-thread.o \
+       $(obj).target/$(TARGET)/src/libuv/test/benchmark-tcp-write-batch.o \
+       $(obj).target/$(TARGET)/src/libuv/test/benchmark-udp-packet-storm.o \
+       $(obj).target/$(TARGET)/src/libuv/test/dns-server.o \
+       $(obj).target/$(TARGET)/src/libuv/test/echo-server.o \
+       $(obj).target/$(TARGET)/src/libuv/test/blackhole-server.o \
+       $(obj).target/$(TARGET)/src/libuv/test/run-benchmarks.o \
+       $(obj).target/$(TARGET)/src/libuv/test/runner.o \
+       $(obj).target/$(TARGET)/src/libuv/test/runner-unix.o
+
+# Add to the list of files we specially track dependencies for.
+all_deps += $(OBJS)
+
+# Make sure our dependencies are built before any of us.
+$(OBJS): | $(obj).target/src/libuv/libuv.a
+
+# CFLAGS et al overrides must be target-local.
+# See "Target-specific Variable Values" in the GNU Make manual.
+$(OBJS): TOOLSET := $(TOOLSET)
+$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
+$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
+
+# Suffix rules, putting all outputs into $(obj).
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+# Try building from generated source, too.
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+# End of this set of suffix rules
+### Rules for final target.
+
+$(builddir)/run-benchmarks: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
+$(builddir)/run-benchmarks: LIBS := $(LIBS)
+$(builddir)/run-benchmarks: LD_INPUTS := $(OBJS) $(obj).target/src/libuv/libuv.a
+$(builddir)/run-benchmarks: TOOLSET := $(TOOLSET)
+$(builddir)/run-benchmarks: $(OBJS) $(obj).target/src/libuv/libuv.a FORCE_DO_CMD
+       $(call do_cmd,link)
+
+all_deps += $(builddir)/run-benchmarks
+# Add target alias
+.PHONY: run-benchmarks
+run-benchmarks: $(builddir)/run-benchmarks
+
+# Add executable to "all" target.
+.PHONY: all
+all: $(builddir)/run-benchmarks
+
diff --git a/mk/libuv/arm/unix/android/src/libuv/run-tests.target.mk b/mk/libuv/arm/unix/android/src/libuv/run-tests.target.mk
new file mode 100755 (executable)
index 0000000..c4d8c20
--- /dev/null
@@ -0,0 +1,158 @@
+# This file is generated by gyp; do not edit.
+
+TOOLSET := target
+TARGET := run-tests
+DEFS_Debug := '-D_LARGEFILE_SOURCE' \
+       '-D_FILE_OFFSET_BITS=64' \
+       '-D_GNU_SOURCE' \
+       '-DEIO_STACKSIZE=262144' \
+       '-DDEBUG' \
+       '-D_DEBUG' \
+       '-DEV_VERIFY=2'
+
+# Flags passed to all source files.
+CFLAGS_Debug := \
+       -Wall \
+       -ansi \
+       -fvisibility=hidden \
+       -g \
+       -O0
+
+# Flags passed to only C files.
+CFLAGS_C_Debug := 
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Debug := -fno-rtti \
+       -fno-exceptions
+
+INCS_Debug := -I$(srcdir)/src/libuv/include
+
+DEFS_Release := '-D_LARGEFILE_SOURCE' \
+       '-D_FILE_OFFSET_BITS=64' \
+       '-D_GNU_SOURCE' \
+       '-DEIO_STACKSIZE=262144' \
+       '-DNDEBUG'
+
+# Flags passed to all source files.
+CFLAGS_Release :=  \
+       -Wall \
+       -ansi \
+       -fvisibility=hidden \
+       -O3 \
+       -fomit-frame-pointer \
+       -fdata-sections \
+       -ffunction-sections
+
+# Flags passed to only C files.
+CFLAGS_C_Release := 
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Release := -fno-rtti \
+       -fno-exceptions
+
+INCS_Release := -I$(srcdir)/src/libuv/include
+
+OBJS := $(obj).target/$(TARGET)/src/libuv/test/blackhole-server.o \
+       $(obj).target/$(TARGET)/src/libuv/test/echo-server.o \
+       $(obj).target/$(TARGET)/src/libuv/test/run-tests.o \
+       $(obj).target/$(TARGET)/src/libuv/test/runner.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-get-loadavg.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-util.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-async.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-error.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-callback-stack.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-connection-fail.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-cwd-and-chdir.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-delayed-accept.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-eio-overflow.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-fail-always.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-fs.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-fs-event.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-get-currentexe.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-get-memory.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-getaddrinfo.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-gethostbyname.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-getsockname.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-hrtime.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-idle.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-ipc.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-ipc-threads.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-loop-handles.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-multiple-listen.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-pass-always.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-ping-pong.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-pipe-bind-error.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-pipe-connect-error.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-platform-output.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-process-title.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-ref.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-shutdown-eof.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-spawn.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-stdio-over-pipes.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tcp-bind-error.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tcp-bind6-error.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tcp-close.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tcp-flags.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tcp-connect-error.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tcp-connect6-error.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tcp-write-error.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tcp-write-to-half-open-connection.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tcp-writealot.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-threadpool.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-mutexes.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-thread.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-timer-again.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-timer.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-tty.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-udp-dgram-too-big.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-udp-ipv6.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-udp-options.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-udp-send-and-recv.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-udp-multicast-join.o \
+       $(obj).target/$(TARGET)/src/libuv/test/test-counters-init.o \
+       $(obj).target/$(TARGET)/src/libuv/test/runner-unix.o
+
+# Add to the list of files we specially track dependencies for.
+all_deps += $(OBJS)
+
+# Make sure our dependencies are built before any of us.
+$(OBJS): | $(obj).target/src/libuv/libuv.a
+
+# CFLAGS et al overrides must be target-local.
+# See "Target-specific Variable Values" in the GNU Make manual.
+$(OBJS): TOOLSET := $(TOOLSET)
+$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
+$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
+
+# Suffix rules, putting all outputs into $(obj).
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+# Try building from generated source, too.
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+# End of this set of suffix rules
+### Rules for final target.
+
+$(builddir)/run-tests: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
+$(builddir)/run-tests: LIBS := $(LIBS)
+$(builddir)/run-tests: LD_INPUTS := $(OBJS) $(obj).target/src/libuv/libuv.a
+$(builddir)/run-tests: TOOLSET := $(TOOLSET)
+$(builddir)/run-tests: $(OBJS) $(obj).target/src/libuv/libuv.a FORCE_DO_CMD
+       $(call do_cmd,link)
+
+all_deps += $(builddir)/run-tests
+# Add target alias
+.PHONY: run-tests
+run-tests: $(builddir)/run-tests
+
+# Add executable to "all" target.
+.PHONY: all
+all: $(builddir)/run-tests
+
diff --git a/mk/libuv/arm/unix/android/src/libuv/uv.Makefile b/mk/libuv/arm/unix/android/src/libuv/uv.Makefile
new file mode 100755 (executable)
index 0000000..ba3abfe
--- /dev/null
@@ -0,0 +1,6 @@
+# This file is generated by gyp; do not edit.
+
+export builddir_name ?= mk/libuv/arm/unix/android/./src/libuv/out
+.PHONY: all
+all:
+       $(MAKE) -C ../.. uv run-benchmarks run-tests
diff --git a/mk/libuv/arm/unix/android/src/libuv/uv.target.mk b/mk/libuv/arm/unix/android/src/libuv/uv.target.mk
new file mode 100755 (executable)
index 0000000..2c23cae
--- /dev/null
@@ -0,0 +1,184 @@
+# This file is generated by gyp; do not edit.
+
+TOOLSET := target
+TARGET := uv
+DEFS_Debug := '-D_LARGEFILE_SOURCE' \
+       '-D_FILE_OFFSET_BITS=64' \
+       '-D_GNU_SOURCE' \
+       '-DEIO_STACKSIZE=262144' \
+       '-DHAVE_CONFIG_H' \
+       '-DEV_CONFIG_H="config_android.h"' \
+       '-DEIO_CONFIG_H="config_android.h"' \
+       '-DDEBUG' \
+       '-D_DEBUG' \
+       '-DEV_VERIFY=2'
+
+# Flags passed to all source files.
+CFLAGS_Debug :=  \
+       -Wall \
+       -ansi \
+       -fvisibility=hidden \
+       -g \
+       --std=gnu89 \
+       -pedantic \
+       -Wall \
+       -Wextra \
+       -Wno-unused-parameter \
+       -g \
+       -O0
+
+# Flags passed to only C files.
+CFLAGS_C_Debug := 
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Debug := -fno-rtti \
+       -fno-exceptions
+
+INCS_Debug := -I$(srcdir)/src/libuv/include \
+       -I$(srcdir)/src/libuv/include/uv-private \
+       -I$(srcdir)/src/libuv/src \
+       -I$(srcdir)/src/libuv/src/unix/ev \
+       -I$(srcdir)/src/libuv/src/ares/config_android
+
+DEFS_Release := '-D_LARGEFILE_SOURCE' \
+       '-D_FILE_OFFSET_BITS=64' \
+       '-D_GNU_SOURCE' \
+       '-DEIO_STACKSIZE=262144' \
+       '-DHAVE_CONFIG_H' \
+       '-DEV_CONFIG_H="config_android.h"' \
+       '-DEIO_CONFIG_H="config_android.h"' \
+       '-DNDEBUG'
+
+# Flags passed to all source files.
+CFLAGS_Release :=  \
+       -Wall \
+       -ansi \
+       -fvisibility=hidden \
+       -g \
+       --std=gnu89 \
+       -pedantic \
+       -Wall \
+       -Wextra \
+       -Wno-unused-parameter \
+       -O3 \
+       -fomit-frame-pointer \
+       -fdata-sections \
+       -ffunction-sections
+
+# Flags passed to only C files.
+CFLAGS_C_Release := 
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Release := -fno-rtti \
+       -fno-exceptions
+
+INCS_Release := -I$(srcdir)/src/libuv/include \
+       -I$(srcdir)/src/libuv/include/uv-private \
+       -I$(srcdir)/src/libuv/src \
+       -I$(srcdir)/src/libuv/src/unix/ev \
+       -I$(srcdir)/src/libuv/src/ares/config_android
+
+OBJS := $(obj).target/$(TARGET)/src/libuv/src/uv-common.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_cancel.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares__close_sockets.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_data.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_destroy.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_expand_name.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_expand_string.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_fds.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_free_hostent.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_free_string.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_gethostbyaddr.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_gethostbyname.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares__get_hostent.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_getnameinfo.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_getopt.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_getsock.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_init.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_library_init.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_llist.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_mkquery.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_nowarn.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_options.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_parse_aaaa_reply.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_parse_a_reply.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_parse_mx_reply.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_parse_ns_reply.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_parse_ptr_reply.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_parse_srv_reply.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_parse_txt_reply.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_process.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_query.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares__read_line.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_search.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_send.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_strcasecmp.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_strdup.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_strerror.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_timeout.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares__timeval.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_version.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/ares_writev.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/bitncmp.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/inet_net_pton.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/inet_ntop.o \
+       $(obj).target/$(TARGET)/src/libuv/src/ares/windows_port.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/core.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/uv-eio.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/fs.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/udp.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/tcp.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/pipe.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/tty.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/stream.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/cares.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/dl.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/error.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/thread.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/process.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/eio/eio.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/ev/ev.o \
+       $(obj).target/$(TARGET)/src/libuv/src/unix/linux.o
+
+# Add to the list of files we specially track dependencies for.
+all_deps += $(OBJS)
+
+# CFLAGS et al overrides must be target-local.
+# See "Target-specific Variable Values" in the GNU Make manual.
+$(OBJS): TOOLSET := $(TOOLSET)
+$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
+$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
+
+# Suffix rules, putting all outputs into $(obj).
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+# Try building from generated source, too.
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+
+# End of this set of suffix rules
+### Rules for final target.
+
+LIBS := -lm
+
+$(obj).target/src/libuv/libuv.a: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
+$(obj).target/src/libuv/libuv.a: LIBS := $(LIBS)
+$(obj).target/src/libuv/libuv.a: TOOLSET := $(TOOLSET)
+$(obj).target/src/libuv/libuv.a: $(OBJS) FORCE_DO_CMD
+       $(call do_cmd,alink)
+
+all_deps += $(obj).target/src/libuv/libuv.a
+# Add target alias
+.PHONY: uv
+uv: $(obj).target/src/libuv/libuv.a
+
+# Add target alias to "all" target.
+.PHONY: all
+all: uv
+
index 382f3cb4a8849c033ef0322255648283c02c5b91..21bdc3b80d8543718fedb78c69e2fa5dfde394e4 100644 (file)
@@ -14,10 +14,10 @@ define DEF_SNAP_FOR_STAGE_H
 
 ifdef CFG_INSTALL_SNAP
 snap-stage$(1)-H-$(2): $$(HSREQ$(1)_H_$(2))
-       $(S)src/etc/make-snapshot.py stage$(1) $(2) install
+       $(CFG_PYTHON) $(S)src/etc/make-snapshot.py stage$(1) $(2) install
 else
 snap-stage$(1)-H-$(2): $$(HSREQ$(1)_H_$(2))
-       $(S)src/etc/make-snapshot.py stage$(1) $(2)
+       $(CFG_PYTHON) $(S)src/etc/make-snapshot.py stage$(1) $(2)
 endif
 
 endef
@@ -30,4 +30,4 @@ snap-stage1: snap-stage1-H-$(CFG_HOST_TRIPLE)
 
 snap-stage2: snap-stage2-H-$(CFG_HOST_TRIPLE)
 
-snap-stage3: snap-stage3-H-$(CFG_HOST_TRIPLE)
\ No newline at end of file
+snap-stage3: snap-stage3-H-$(CFG_HOST_TRIPLE)
index b64f5df9ca038b8a6042bce78e2665d29d8e539f..e1a83c18f4d46cbe2b6566c68bc732a29acaf536 100644 (file)
@@ -11,7 +11,7 @@ $(HBIN0_H_$(CFG_HOST_TRIPLE))/rustc$(X):              \
 ifdef CFG_ENABLE_LOCAL_RUST
        $(Q)$(S)src/etc/local_stage0.sh $(CFG_HOST_TRIPLE) $(CFG_LOCAL_RUST_ROOT)
 else 
-       $(Q)$(S)src/etc/get-snapshot.py $(CFG_HOST_TRIPLE) $(SNAPSHOT_FILE)
+       $(Q)$(CFG_PYTHON) $(S)src/etc/get-snapshot.py $(CFG_HOST_TRIPLE) $(SNAPSHOT_FILE)
 ifdef CFG_ENABLE_PAX_FLAGS
        @$(call E, apply PaX flags: $@)
        @"$(CFG_PAXCTL)" -cm "$@"
index 3f085494f567d11c8772ada6d178328896250b21..454d540d84db92f652b435dece4eb13fd0a1080e 100644 (file)
@@ -701,7 +701,7 @@ tmp/$(FT).rc tmp/$(FT_DRIVER).rs: \
                $(RPASS_TESTS) \
                $(S)src/etc/combine-tests.py
        @$(call E, check: building combined stage2 test runner)
-       $(Q)$(S)src/etc/combine-tests.py
+       $(Q)$(CFG_PYTHON) $(S)src/etc/combine-tests.py
 
 define DEF_CHECK_FAST_FOR_T_H
 # $(1) unused
index 20b7e32d0c99522d02e860b69b03af54091d00a7..5b93c55ddc65ebb64c0ffeacfe9bb28110c2fba0 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use cmp;
+
 enum mode { mode_compile_fail, mode_run_fail, mode_run_pass, mode_pretty, }
 
 impl mode : cmp::Eq {
index 8505e481638696a51b488d34eddb7813cb4ace18..ba6862039d44d4c0ee99c204eb14cdd903ee8b0c 100644 (file)
@@ -211,7 +211,7 @@ fn is_test(config: config, testfile: &Path) -> bool {
 
 fn make_test(config: config, testfile: &Path) ->
    test::TestDesc {
-    {
+    test::TestDesc {
         name: make_test_name(config, testfile),
         testfn: make_test_closure(config, testfile),
         ignore: header::is_test_ignored(config, testfile),
index 632619f138103de397a7909b11baad1de8acff7b..54723253141f8da1a3648b675c8a6eab3fa9cce7 100644 (file)
@@ -8,8 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use common::config;
+use io;
 use io::ReaderUtil;
+use str;
 
 export load_errors;
 export expected_error;
@@ -33,8 +37,8 @@ fn parse_expected(line_num: uint, line: ~str) -> ~[expected_error] unsafe {
     let error_tag = ~"//~";
     let mut idx;
     match str::find_str(line, error_tag) {
-      option::None => return ~[],
-      option::Some(nn) => { idx = (nn as uint) + str::len(error_tag); }
+      None => return ~[],
+      Some(nn) => { idx = (nn as uint) + str::len(error_tag); }
     }
 
     // "//~^^^ kind msg" denotes a message expected
index 24645e02b2008b187ae7f9fb9e7935f1f7a0df76..9fe5d9acb9b68c0f1c63ea0cc8ec02cc2867be3d 100644 (file)
@@ -8,8 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use common;
 use common::config;
+use io;
 use io::ReaderUtil;
+use os;
+use str;
 
 export test_props;
 export load_props;
@@ -34,12 +40,12 @@ fn load_props(testfile: &Path) -> test_props {
     let mut error_patterns = ~[];
     let mut aux_builds = ~[];
     let mut exec_env = ~[];
-    let mut compile_flags = option::None;
-    let mut pp_exact = option::None;
+    let mut compile_flags = None;
+    let mut pp_exact = None;
     for iter_header(testfile) |ln| {
         match parse_error_pattern(ln) {
-          option::Some(ep) => error_patterns.push(ep),
-          option::None => ()
+          Some(ep) => error_patterns.push(ep),
+          None => ()
         };
 
         if compile_flags.is_none() {
@@ -78,7 +84,7 @@ fn is_test_ignored(config: config, testfile: &Path) -> bool {
     return found;
 
     fn xfail_target() -> ~str {
-        ~"xfail-" + os::sysname()
+        ~"xfail-" + str::from_slice(os::SYSNAME)
     }
 }
 
@@ -124,12 +130,12 @@ fn parse_exec_env(line: ~str) -> Option<(~str, ~str)> {
 
 fn parse_pp_exact(line: ~str, testfile: &Path) -> Option<Path> {
     match parse_name_value_directive(line, ~"pp-exact") {
-      option::Some(s) => option::Some(Path(s)),
-      option::None => {
+      Some(s) => Some(Path(s)),
+      None => {
         if parse_name_directive(line, ~"pp-exact") {
-            option::Some(testfile.file_path())
+            Some(testfile.file_path())
         } else {
-            option::None
+            None
         }
       }
     }
@@ -143,12 +149,12 @@ fn parse_name_value_directive(line: ~str,
                               directive: ~str) -> Option<~str> unsafe {
     let keycolon = directive + ~":";
     match str::find_str(line, keycolon) {
-        option::Some(colon) => {
+        Some(colon) => {
             let value = str::slice(line, colon + str::len(keycolon),
                                    str::len(line));
             debug!("%s: %s", directive,  value);
-            option::Some(value)
+            Some(value)
         }
-        option::None => option::None
+        None => None
     }
 }
index 23f9e819bc4deca5839a3e20d5a989d8f4a4849b..6e61fcabe0bcebf64ee9372dffa6564a10a6adce 100644 (file)
@@ -8,9 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use run::spawn_process;
+use core::prelude::*;
+
+use io;
 use io::{ReaderUtil, WriterUtil};
+use libc;
 use libc::{c_int, pid_t};
+use os;
+use run;
+use run::spawn_process;
+use pipes;
+use str;
+use task;
+use vec;
 
 export run;
 
@@ -108,14 +118,16 @@ fn writeclose(fd: c_int, s: Option<~str>) {
 }
 
 fn readclose(fd: c_int) -> ~str {
-    // Copied from run::program_output
-    let file = os::fdopen(fd);
-    let reader = io::FILE_reader(file, false);
-    let mut buf = ~"";
-    while !reader.eof() {
-        let bytes = reader.read_bytes(4096u);
-        str::push_str(&mut buf, str::from_bytes(bytes));
+    unsafe {
+        // Copied from run::program_output
+        let file = os::fdopen(fd);
+        let reader = io::FILE_reader(file, false);
+        let mut buf = ~"";
+        while !reader.eof() {
+            let bytes = reader.read_bytes(4096u);
+            str::push_str(&mut buf, str::from_bytes(bytes));
+        }
+        os::fclose(file);
+        return buf;
     }
-    os::fclose(file);
-    return buf;
 }
index 959bc344f1d50477dced3026ccfbb4163a38179d..7b0ef583f40f3be21f5516baab941887b8f977a5 100644 (file)
@@ -8,15 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use io;
 use io::WriterUtil;
+use os;
+use str;
+use uint;
+use vec;
 
+use common;
 use common::mode_run_pass;
 use common::mode_run_fail;
 use common::mode_compile_fail;
 use common::mode_pretty;
 use common::config;
+use errors;
+use header;
 use header::load_props;
 use header::test_props;
+use procsrv;
+use util;
 use util::logv;
 
 export run;
@@ -117,7 +129,7 @@ fn run_pretty_test(config: config, props: test_props, testfile: &Path) {
     } else { logv(config, ~"testing for converging pretty-printing"); }
 
     let rounds =
-        match props.pp_exact { option::Some(_) => 1, option::None => 2 };
+        match props.pp_exact { Some(_) => 1, None => 2 };
 
     let mut srcs = ~[io::read_whole_file_str(testfile).get()];
 
@@ -137,11 +149,11 @@ fn run_pretty_test(config: config, props: test_props, testfile: &Path) {
 
     let mut expected =
         match props.pp_exact {
-          option::Some(file) => {
+          Some(file) => {
             let filepath = testfile.dir_path().push_rel(&file);
             io::read_whole_file_str(&filepath).get()
           }
-          option::None => { srcs[vec::len(srcs) - 2u] }
+          None => { srcs[vec::len(srcs) - 2u] }
         };
     let mut actual = srcs[vec::len(srcs) - 1u];
 
@@ -165,7 +177,7 @@ fn run_pretty_test(config: config, props: test_props, testfile: &Path) {
 
     fn print_source(config: config, testfile: &Path, src: ~str) -> procres {
         compose_and_run(config, testfile, make_pp_args(config, testfile),
-                        ~[], config.compile_lib_path, option::Some(src))
+                        ~[], config.compile_lib_path, Some(src))
     }
 
     fn make_pp_args(config: config, _testfile: &Path) -> procargs {
@@ -199,7 +211,7 @@ fn typecheck_source(config: config, props: test_props,
         compose_and_run_compiler(
             config, props, testfile,
             make_typecheck_args(config, testfile),
-            option::Some(src))
+            Some(src))
     }
 
     fn make_typecheck_args(config: config, testfile: &Path) -> procargs {
@@ -418,7 +430,7 @@ fn exec_compiled_test(config: config, props: test_props,
     compose_and_run(config, testfile,
                     make_run_args(config, props, testfile),
                     props.exec_env,
-                    config.run_lib_path, option::None)
+                    config.run_lib_path, None)
 }
 
 fn compose_and_run_compiler(
@@ -441,7 +453,7 @@ fn compose_and_run_compiler(
             make_compile_args(config, props, ~[~"--lib"] + extra_link_args,
                               |a,b| make_lib_name(a, b, testfile), &abs_ab);
         let auxres = compose_and_run(config, &abs_ab, aux_args, ~[],
-                                     config.compile_lib_path, option::None);
+                                     config.compile_lib_path, None);
         if auxres.status != 0 {
             fatal_procres(
                 fmt!("auxiliary build of %s failed to compile: ",
@@ -491,7 +503,8 @@ fn make_lib_name(config: config, auxfile: &Path, testfile: &Path) -> Path {
 }
 
 fn make_exe_name(config: config, testfile: &Path) -> Path {
-    Path(output_base_name(config, testfile).to_str() + os::exe_suffix())
+    Path(output_base_name(config, testfile).to_str() +
+            str::from_slice(os::EXE_SUFFIX))
 }
 
 fn make_run_args(config: config, _props: test_props, testfile: &Path) ->
@@ -501,8 +514,8 @@ fn make_run_args(config: config, _props: test_props, testfile: &Path) ->
             // then split apart its command
             let runtool =
                 match config.runtool {
-                  option::Some(s) => option::Some(s),
-                  option::None => option::None
+                  Some(s) => Some(s),
+                  None => None
                 };
             split_maybe_args(runtool)
         };
@@ -513,12 +526,12 @@ fn make_run_args(config: config, _props: test_props, testfile: &Path) ->
 
 fn split_maybe_args(argstr: Option<~str>) -> ~[~str] {
     fn rm_whitespace(v: ~[~str]) -> ~[~str] {
-        vec::filter(v, |s| !str::is_whitespace(*s))
+        v.filtered(|s| !str::is_whitespace(*s))
     }
 
     match argstr {
-      option::Some(s) => rm_whitespace(str::split_char(s, ' ')),
-      option::None => ~[]
+      Some(s) => rm_whitespace(str::split_char(s, ' ')),
+      None => ~[]
     }
 }
 
index 569d89fd3fe5236d4ae798a000af8050e419b6f2..13614c58855630b0e2d22928575659b4336d1210 100644 (file)
@@ -8,8 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use io;
+use os;
 use os::getenv;
 
+use common;
 use common::config;
 
 fn make_new_path(path: ~str) -> ~str {
@@ -17,10 +22,10 @@ fn make_new_path(path: ~str) -> ~str {
     // Windows just uses PATH as the library search path, so we have to
     // maintain the current value while adding our own
     match getenv(lib_path_env_var()) {
-      option::Some(curr) => {
+      Some(curr) => {
         fmt!("%s%s%s", path, path_div(), curr)
       }
-      option::None => path
+      None => path
     }
 }
 
index 5801c23f814628edd181d1c2edca8fe63b4af708..0c1cc566fe2ec43ff1c4007033afd6813845fb66 100644 (file)
 extern mod core(vers = "0.6");
 
 #[cfg(cargo)]
-extern mod self(name = "cargo", vers = "0.6");
+extern mod this(name = "cargo", vers = "0.6");
 
 #[cfg(fuzzer)]
-extern mod self(name = "fuzzer", vers = "0.6");
+extern mod this(name = "fuzzer", vers = "0.6");
 
 #[cfg(rustdoc)]
-extern mod self(name = "rustdoc", vers = "0.6");
+extern mod this(name = "rustdoc", vers = "0.6");
 
 #[cfg(rusti)]
-extern mod self(name = "rusti", vers = "0.6");
+extern mod this(name = "rusti", vers = "0.6");
 
 #[cfg(rustc)]
-extern mod self(name = "rustc", vers = "0.6");
+extern mod this(name = "rustc", vers = "0.6");
 
-fn main() { self::main() }
\ No newline at end of file
+fn main() { this::main() }
index 04c8a4ebff25e611d8674f1eae03ef7b9b87f0ac..bd21447ffcc50217d91afc645f36932a39b647f8 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 #
 # this script attempts to turn doc comment attributes (#[doc = "..."])
index d71b9fbcf959df32b6b800f7c277ac166870bc5d..af308f23a318210626a5cab71041701e5c1ef3c0 100644 (file)
@@ -2,7 +2,7 @@
 " Language:     Rust
 " Maintainer:   Patrick Walton <pcwalton@mozilla.com>
 " Maintainer:   Ben Blum <bblum@cs.cmu.edu>
-" Last Change:  2012 Dec 14
+" Last Change:  2012 Dec 25
 
 if version < 600
   syntax clear
@@ -44,8 +44,8 @@ syn keyword   rustType        off_t dev_t ino_t pid_t mode_t ssize_t
 
 syn keyword   rustTrait       Const Copy Send Owned " inherent traits
 syn keyword   rustTrait       Eq Ord Num Ptr
-syn keyword   rustTrait       Add Sub Mul Div Modulo Neg BitAnd BitOr BitXor
-syn keyword   rustTrait       Shl Shr Index
+syn keyword   rustTrait       Drop Add Sub Mul Div Modulo Neg BitAnd BitOr
+syn keyword   rustTrait       BitXor Shl Shr Index
 
 syn keyword   rustSelf        self
 syn keyword   rustBoolean     true false
index d4e68746fd4c47783eb5744c46554208cd09c6f0..ea67d0ea858d12f132ffe8216c603318b1348593 100644 (file)
@@ -294,7 +294,8 @@ fn load_link(mis: ~[@ast::meta_item]) -> (Option<~str>,
     let mut uuid = None;
     for mis.each |a| {
         match a.node {
-            ast::meta_name_value(v, {node: ast::lit_str(s), span: _}) => {
+            ast::meta_name_value(v, ast::spanned { node: ast::lit_str(s),
+                                                   _ }) => {
                 match v {
                     ~"name" => name = Some(*s),
                     ~"vers" => vers = Some(*s),
@@ -321,7 +322,8 @@ fn load_crate(filename: &Path) -> Option<Crate> {
 
     for c.node.attrs.each |a| {
         match a.node.value.node {
-            ast::meta_name_value(v, {node: ast::lit_str(_), span: _}) => {
+            ast::meta_name_value(v, ast::spanned { node: ast::lit_str(_),
+                                                   _ }) => {
                 match v {
                     ~"desc" => desc = Some(v),
                     ~"sigs" => sigs = Some(v),
@@ -401,7 +403,7 @@ fn load_crate(filename: &Path) -> Option<Crate> {
     let e = @{
         mut deps: ~[]
     };
-    let v = visit::mk_simple_visitor(@{
+    let v = visit::mk_simple_visitor(@visit::SimpleVisitor {
         visit_view_item: |a| goto_view_item(sess, e, a),
         visit_item: |a| goto_item(e, a),
         .. *visit::default_simple_visitor()
@@ -805,7 +807,7 @@ fn install_one_crate(c: &Cargo, path: &Path, cf: &Path) {
       Some(bp) => bp
     };
     let newv = os::list_dir_path(&buildpath);
-    let exec_suffix = os::exe_suffix();
+    let exec_suffix = str::from_slice(os::EXE_SUFFIX);
     for newv.each |ct| {
         if (exec_suffix != ~"" && str::ends_with(ct.to_str(),
                                                  exec_suffix)) ||
index 6659ed031ca79eec51d9f26dd8c6ec3874e5a210..829a82baf7fab234f490a6851f996d3e7f2daa62 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::os;
+use core::path::Path;
+use core::run;
+
 fn gpgv(args: ~[~str]) -> { status: int, out: ~str, err: ~str } {
     return run::program_output(~"gpgv", args);
 }
index dc5faf49ea4c78d7e32bb2a108c7b4cea60f0e5c..1b6ac13ceab86d924748af6a3818a10be02bb2e4 100644 (file)
 #[forbid(deprecated_pattern)];
 
 use cast::transmute;
+use kinds::Copy;
+use iter;
+use libc;
+use option::Option;
 use ptr::addr_of;
+use sys;
+use uint;
+use vec;
 
 /// Code for dealing with @-vectors. This is pretty incomplete, and
 /// contains a bunch of duplication from the code for ~-vectors.
 
 #[abi = "cdecl"]
-extern mod rustrt {
+pub extern mod rustrt {
     #[legacy_exports];
-    fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
-                                 ++v: **vec::raw::VecRepr,
-                                 ++n: libc::size_t);
+    unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
+                                        ++v: **vec::raw::VecRepr,
+                                        ++n: libc::size_t);
 }
 
 #[abi = "rust-intrinsic"]
-extern mod rusti {
+pub extern mod rusti {
     #[legacy_exports];
     fn move_val_init<T>(dst: &mut T, -src: T);
 }
@@ -95,7 +102,7 @@ fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
 #[inline(always)]
 pub pure fn build_sized_opt<A>(size: Option<uint>,
                                builder: &fn(push: pure fn(v: A))) -> @[A] {
-    build_sized(size.get_default(4), builder)
+    build_sized(size.get_or_default(4), builder)
 }
 
 // Appending
@@ -145,6 +152,10 @@ fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
 
 #[cfg(notest)]
 pub mod traits {
+    use at_vec::append;
+    use kinds::Copy;
+    use ops::Add;
+
     pub impl<T: Copy> @[T] : Add<&[const T],@[T]> {
         #[inline(always)]
         pure fn add(&self, rhs: & &self/[const T]) -> @[T] {
@@ -157,6 +168,15 @@ pub impl<T: Copy> @[T] : Add<&[const T],@[T]> {
 pub mod traits {}
 
 pub mod raw {
+    use at_vec::{capacity, rusti, rustrt};
+    use cast::transmute;
+    use libc;
+    use ptr::addr_of;
+    use ptr;
+    use sys;
+    use uint;
+    use vec;
+
     pub type VecRepr = vec::raw::VecRepr;
     pub type SliceRepr = vec::raw::SliceRepr;
 
index 6d2ed9b423e64292cabe5c5d1538e945c81bed4b..3e7b88b7b78f7b1d4c5edecbfb975fefb1c53c78 100644 (file)
 
 //! Boolean logic
 
+use bool;
+use cmp;
 use cmp::Eq;
+use option::{None, Option, Some};
 
 /// Negation / inverse
 pub pure fn not(v: bool) -> bool { !v }
index 4ae891915455cfe6e26bbc13180c047d6f38bcff..950a753d73f0fb9a6dcf7802da53bb920027749c 100644 (file)
@@ -108,6 +108,8 @@ pub unsafe fn copy_lifetime_vec<S,T>(_ptr: &a/[S], ptr: &T) -> &a/T {
 
 #[cfg(test)]
 pub mod tests {
+    use cast::{bump_box_refcount, reinterpret_cast, transmute};
+
     #[test]
     pub fn test_reinterpret_cast() {
         assert 1u == unsafe { reinterpret_cast(&1) };
index f16268c34583fb63cd46b6f06d91d4e0c739b5a7..b656879e7a422657bb70501fea89a573f7842074 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use char;
 use cmp::Eq;
+use option::{None, Option, Some};
+use str;
+use u32;
+use uint;
+use unicode;
 
 /*
     Lu  Uppercase_Letter    an uppercase letter
@@ -58,6 +64,7 @@
  * Indicates whether a character is in lower case, defined
  * in terms of the Unicode General Category 'Ll'
  */
+#[inline(always)]
 pub pure fn is_lowercase(c: char) -> bool {
     return unicode::general_category::Ll(c);
 }
@@ -66,6 +73,7 @@
  * Indicates whether a character is in upper case, defined
  * in terms of the Unicode General Category 'Lu'.
  */
+#[inline(always)]
 pub pure fn is_uppercase(c: char) -> bool {
     return unicode::general_category::Lu(c);
 }
@@ -75,6 +83,7 @@
  * terms of the Unicode General Categories 'Zs', 'Zl', 'Zp'
  * additional 'Cc'-category control codes in the range [0x09, 0x0d]
  */
+#[inline(always)]
 pub pure fn is_whitespace(c: char) -> bool {
     return ('\x09' <= c && c <= '\x0d')
         || unicode::general_category::Zs(c)
@@ -87,6 +96,7 @@
  * defined in terms of the Unicode General Categories 'Nd', 'Nl', 'No'
  * and the Derived Core Property 'Alphabetic'.
  */
+#[inline(always)]
 pub pure fn is_alphanumeric(c: char) -> bool {
     return unicode::derived_property::Alphabetic(c) ||
         unicode::general_category::Nd(c) ||
 }
 
 /// Indicates whether the character is an ASCII character
+#[inline(always)]
 pub pure fn is_ascii(c: char) -> bool {
    c - ('\x7F' & c) == '\x00'
 }
 
 /// Indicates whether the character is numeric (Nd, Nl, or No)
+#[inline(always)]
 pub pure fn is_digit(c: char) -> bool {
     return unicode::general_category::Nd(c) ||
         unicode::general_category::Nl(c) ||
  * 'b' or 'B', 11, etc. Returns none if the char does not
  * refer to a digit in the given radix.
  */
+#[inline]
 pub pure fn to_digit(c: char, radix: uint) -> Option<uint> {
     let val = match c {
       '0' .. '9' => c as uint - ('0' as uint),
  *
  * -1 if a < b, 0 if a == b, +1 if a > b
  */
+#[inline(always)]
 pub pure fn cmp(a: char, b: char) -> int {
     return  if b > a { -1 }
     else if b < a { 1 }
index 9fd0a50a99c5ef1b23b9f9d3040828c158ee3c99..656f672479e9998a4d26c95103f336b77678c88c 100644 (file)
@@ -40,11 +40,13 @@ struct AllocHeader { priv opaque: () }
 struct MemoryRegion { priv opaque: () }
 
 #[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
 struct Registers {
     data: [u32 * 16]
 }
 
 #[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
 struct Context {
     regs: Registers,
     next: *Context,
@@ -70,6 +72,7 @@ struct BoxedRegion {
 }
 
 #[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
 struct Task {
     // Public fields
     refcount: intptr_t,                 // 0
@@ -160,6 +163,7 @@ pub unsafe fn annihilate() {
 extern mod rustrt {
     #[legacy_exports];
     #[rust_stack]
-    /*priv*/ fn rust_get_task() -> *c_void;
+    // FIXME (#4386): Unable to make following method private.
+    /* priv */ unsafe fn rust_get_task() -> *c_void;
 }
 
index a0569348b2e5aaaf6f7bc1c55b6aa0cb97b1b048..6fbcf2df454069723405f150c167175520eebeae 100644 (file)
@@ -16,5 +16,6 @@ pub trait Clone {
 }
 
 impl (): Clone {
+    #[inline(always)]
     fn clone(&self) -> () { () }
 }
index 284b1b88a3b8d4edcc7f1855a06ae2bfe2850cf0..6341481809e21685875edef693821a0ec27ff32f 100644 (file)
 
     // Alpabetically sorted by link_name
 
-    pure fn acos(n: c_double) -> c_double;
-    pure fn asin(n: c_double) -> c_double;
-    pure fn atan(n: c_double) -> c_double;
-    pure fn atan2(a: c_double, b: c_double) -> c_double;
-    pure fn cbrt(n: c_double) -> c_double;
-    pure fn ceil(n: c_double) -> c_double;
-    pure fn copysign(x: c_double, y: c_double) -> c_double;
-    pure fn cos(n: c_double) -> c_double;
-    pure fn cosh(n: c_double) -> c_double;
-    pure fn erf(n: c_double) -> c_double;
-    pure fn erfc(n: c_double) -> c_double;
-    pure fn exp(n: c_double) -> c_double;
-    pure fn expm1(n: c_double) -> c_double;
-    pure fn exp2(n: c_double) -> c_double;
-    #[link_name="fabs"] pure fn abs(n: c_double) -> c_double;
+    unsafe fn acos(n: c_double) -> c_double;
+    unsafe fn asin(n: c_double) -> c_double;
+    unsafe fn atan(n: c_double) -> c_double;
+    unsafe fn atan2(a: c_double, b: c_double) -> c_double;
+    unsafe fn cbrt(n: c_double) -> c_double;
+    unsafe fn ceil(n: c_double) -> c_double;
+    unsafe fn copysign(x: c_double, y: c_double) -> c_double;
+    unsafe fn cos(n: c_double) -> c_double;
+    unsafe fn cosh(n: c_double) -> c_double;
+    unsafe fn erf(n: c_double) -> c_double;
+    unsafe fn erfc(n: c_double) -> c_double;
+    unsafe fn exp(n: c_double) -> c_double;
+    unsafe fn expm1(n: c_double) -> c_double;
+    unsafe fn exp2(n: c_double) -> c_double;
+    #[link_name="fabs"] unsafe fn abs(n: c_double) -> c_double;
     // rename: for clarity and consistency with add/sub/mul/div
-    #[link_name="fdim"] pure fn abs_sub(a: c_double, b: c_double) -> c_double;
-    pure fn floor(n: c_double) -> c_double;
+    #[link_name="fdim"]
+    unsafe fn abs_sub(a: c_double, b: c_double) -> c_double;
+    unsafe fn floor(n: c_double) -> c_double;
     // rename: for clarity and consistency with add/sub/mul/div
-    #[link_name="fma"] pure fn mul_add(a: c_double, b: c_double,
+    #[link_name="fma"] unsafe fn mul_add(a: c_double, b: c_double,
                                        c: c_double) -> c_double;
-    #[link_name="fmax"] pure fn fmax(a: c_double, b: c_double) -> c_double;
-    #[link_name="fmin"] pure fn fmin(a: c_double, b: c_double) -> c_double;
-    pure fn nextafter(x: c_double, y: c_double) -> c_double;
-    pure fn frexp(n: c_double, value: &mut c_int) -> c_double;
-    pure fn hypot(x: c_double, y: c_double) -> c_double;
-    pure fn ldexp(x: c_double, n: c_int) -> c_double;
+    #[link_name="fmax"] unsafe fn fmax(a: c_double, b: c_double) -> c_double;
+    #[link_name="fmin"] unsafe fn fmin(a: c_double, b: c_double) -> c_double;
+    unsafe fn nextafter(x: c_double, y: c_double) -> c_double;
+    unsafe fn frexp(n: c_double, value: &mut c_int) -> c_double;
+    unsafe fn hypot(x: c_double, y: c_double) -> c_double;
+    unsafe fn ldexp(x: c_double, n: c_int) -> c_double;
     #[cfg(unix)]
-    #[link_name="lgamma_r"] pure fn lgamma(n: c_double,
+    #[link_name="lgamma_r"] unsafe fn lgamma(n: c_double,
                                            sign: &mut c_int) -> c_double;
     #[cfg(windows)]
-    #[link_name="__lgamma_r"] pure fn lgamma(n: c_double,
+    #[link_name="__lgamma_r"] unsafe fn lgamma(n: c_double,
                                              sign: &mut c_int) -> c_double;
     // renamed: log is a reserved keyword; ln seems more natural, too
-    #[link_name="log"] pure fn ln(n: c_double) -> c_double;
+    #[link_name="log"] unsafe fn ln(n: c_double) -> c_double;
     // renamed: "logb" /often/ is confused for log2 by beginners
-    #[link_name="logb"] pure fn log_radix(n: c_double) -> c_double;
+    #[link_name="logb"] unsafe fn log_radix(n: c_double) -> c_double;
     // renamed: to be consitent with log as ln
-    #[link_name="log1p"] pure fn ln1p(n: c_double) -> c_double;
-    pure fn log10(n: c_double) -> c_double;
-    pure fn log2(n: c_double) -> c_double;
-    #[link_name="ilogb"] pure fn ilog_radix(n: c_double) -> c_int;
-    pure fn modf(n: c_double, iptr: &mut c_double) -> c_double;
-    pure fn pow(n: c_double, e: c_double) -> c_double;
+    #[link_name="log1p"] unsafe fn ln1p(n: c_double) -> c_double;
+    unsafe fn log10(n: c_double) -> c_double;
+    unsafe fn log2(n: c_double) -> c_double;
+    #[link_name="ilogb"] unsafe fn ilog_radix(n: c_double) -> c_int;
+    unsafe fn modf(n: c_double, iptr: &mut c_double) -> c_double;
+    unsafe fn pow(n: c_double, e: c_double) -> c_double;
 // FIXME (#1379): enable when rounding modes become available
-//    pure fn rint(n: c_double) -> c_double;
-    pure fn round(n: c_double) -> c_double;
+//    unsafe fn rint(n: c_double) -> c_double;
+    unsafe fn round(n: c_double) -> c_double;
     // rename: for consistency with logradix
-    #[link_name="scalbn"] pure fn ldexp_radix(n: c_double, i: c_int) ->
+    #[link_name="scalbn"] unsafe fn ldexp_radix(n: c_double, i: c_int) ->
         c_double;
-    pure fn sin(n: c_double) -> c_double;
-    pure fn sinh(n: c_double) -> c_double;
-    pure fn sqrt(n: c_double) -> c_double;
-    pure fn tan(n: c_double) -> c_double;
-    pure fn tanh(n: c_double) -> c_double;
-    pure fn tgamma(n: c_double) -> c_double;
-    pure fn trunc(n: c_double) -> c_double;
+    unsafe fn sin(n: c_double) -> c_double;
+    unsafe fn sinh(n: c_double) -> c_double;
+    unsafe fn sqrt(n: c_double) -> c_double;
+    unsafe fn tan(n: c_double) -> c_double;
+    unsafe fn tanh(n: c_double) -> c_double;
+    unsafe fn tgamma(n: c_double) -> c_double;
+    unsafe fn trunc(n: c_double) -> c_double;
 
     // These are commonly only available for doubles
 
-    pure fn j0(n: c_double) -> c_double;
-    pure fn j1(n: c_double) -> c_double;
-    pure fn jn(i: c_int, n: c_double) -> c_double;
+    unsafe fn j0(n: c_double) -> c_double;
+    unsafe fn j1(n: c_double) -> c_double;
+    unsafe fn jn(i: c_int, n: c_double) -> c_double;
 
-    pure fn y0(n: c_double) -> c_double;
-    pure fn y1(n: c_double) -> c_double;
-    pure fn yn(i: c_int, n: c_double) -> c_double;
+    unsafe fn y0(n: c_double) -> c_double;
+    unsafe fn y1(n: c_double) -> c_double;
+    unsafe fn yn(i: c_int, n: c_double) -> c_double;
 }
 
 #[link_name = "m"]
 
     // Alpabetically sorted by link_name
 
-    #[link_name="acosf"] pure fn acos(n: c_float) -> c_float;
-    #[link_name="asinf"] pure fn asin(n: c_float) -> c_float;
-    #[link_name="atanf"] pure fn atan(n: c_float) -> c_float;
-    #[link_name="atan2f"] pure fn atan2(a: c_float, b: c_float) -> c_float;
-    #[link_name="cbrtf"] pure fn cbrt(n: c_float) -> c_float;
-    #[link_name="ceilf"] pure fn ceil(n: c_float) -> c_float;
-    #[link_name="copysignf"] pure fn copysign(x: c_float,
+    #[link_name="acosf"] unsafe fn acos(n: c_float) -> c_float;
+    #[link_name="asinf"] unsafe fn asin(n: c_float) -> c_float;
+    #[link_name="atanf"] unsafe fn atan(n: c_float) -> c_float;
+    #[link_name="atan2f"] unsafe fn atan2(a: c_float, b: c_float) -> c_float;
+    #[link_name="cbrtf"] unsafe fn cbrt(n: c_float) -> c_float;
+    #[link_name="ceilf"] unsafe fn ceil(n: c_float) -> c_float;
+    #[link_name="copysignf"] unsafe fn copysign(x: c_float,
                                               y: c_float) -> c_float;
-    #[link_name="cosf"] pure fn cos(n: c_float) -> c_float;
-    #[link_name="coshf"] pure fn cosh(n: c_float) -> c_float;
-    #[link_name="erff"] pure fn erf(n: c_float) -> c_float;
-    #[link_name="erfcf"] pure fn erfc(n: c_float) -> c_float;
-    #[link_name="expf"] pure fn exp(n: c_float) -> c_float;
-    #[link_name="expm1f"]pure fn expm1(n: c_float) -> c_float;
-    #[link_name="exp2f"] pure fn exp2(n: c_float) -> c_float;
-    #[link_name="fabsf"] pure fn abs(n: c_float) -> c_float;
-    #[link_name="fdimf"] pure fn abs_sub(a: c_float, b: c_float) -> c_float;
-    #[link_name="floorf"] pure fn floor(n: c_float) -> c_float;
-    #[link_name="frexpf"] pure fn frexp(n: c_float,
+    #[link_name="cosf"] unsafe fn cos(n: c_float) -> c_float;
+    #[link_name="coshf"] unsafe fn cosh(n: c_float) -> c_float;
+    #[link_name="erff"] unsafe fn erf(n: c_float) -> c_float;
+    #[link_name="erfcf"] unsafe fn erfc(n: c_float) -> c_float;
+    #[link_name="expf"] unsafe fn exp(n: c_float) -> c_float;
+    #[link_name="expm1f"]unsafe fn expm1(n: c_float) -> c_float;
+    #[link_name="exp2f"] unsafe fn exp2(n: c_float) -> c_float;
+    #[link_name="fabsf"] unsafe fn abs(n: c_float) -> c_float;
+    #[link_name="fdimf"] unsafe fn abs_sub(a: c_float, b: c_float) -> c_float;
+    #[link_name="floorf"] unsafe fn floor(n: c_float) -> c_float;
+    #[link_name="frexpf"] unsafe fn frexp(n: c_float,
                                         value: &mut c_int) -> c_float;
-    #[link_name="fmaf"] pure fn mul_add(a: c_float,
+    #[link_name="fmaf"] unsafe fn mul_add(a: c_float,
                                         b: c_float, c: c_float) -> c_float;
-    #[link_name="fmaxf"] pure fn fmax(a: c_float, b: c_float) -> c_float;
-    #[link_name="fminf"] pure fn fmin(a: c_float, b: c_float) -> c_float;
-    #[link_name="nextafterf"] pure fn nextafter(x: c_float,
+    #[link_name="fmaxf"] unsafe fn fmax(a: c_float, b: c_float) -> c_float;
+    #[link_name="fminf"] unsafe fn fmin(a: c_float, b: c_float) -> c_float;
+    #[link_name="nextafterf"] unsafe fn nextafter(x: c_float,
                                                 y: c_float) -> c_float;
-    #[link_name="hypotf"] pure fn hypot(x: c_float, y: c_float) -> c_float;
-    #[link_name="ldexpf"] pure fn ldexp(x: c_float, n: c_int) -> c_float;
+    #[link_name="hypotf"] unsafe fn hypot(x: c_float, y: c_float) -> c_float;
+    #[link_name="ldexpf"] unsafe fn ldexp(x: c_float, n: c_int) -> c_float;
 
     #[cfg(unix)]
-    #[link_name="lgammaf_r"] pure fn lgamma(n: c_float,
+    #[link_name="lgammaf_r"] unsafe fn lgamma(n: c_float,
                                             sign: &mut c_int) -> c_float;
 
     #[cfg(windows)]
-    #[link_name="__lgammaf_r"] pure fn lgamma(n: c_float,
+    #[link_name="__lgammaf_r"] unsafe fn lgamma(n: c_float,
                                               sign: &mut c_int) -> c_float;
 
-    #[link_name="logf"] pure fn ln(n: c_float) -> c_float;
-    #[link_name="logbf"] pure fn log_radix(n: c_float) -> c_float;
-    #[link_name="log1pf"] pure fn ln1p(n: c_float) -> c_float;
-    #[link_name="log2f"] pure fn log2(n: c_float) -> c_float;
-    #[link_name="log10f"] pure fn log10(n: c_float) -> c_float;
-    #[link_name="ilogbf"] pure fn ilog_radix(n: c_float) -> c_int;
-    #[link_name="modff"] pure fn modf(n: c_float,
+    #[link_name="logf"] unsafe fn ln(n: c_float) -> c_float;
+    #[link_name="logbf"] unsafe fn log_radix(n: c_float) -> c_float;
+    #[link_name="log1pf"] unsafe fn ln1p(n: c_float) -> c_float;
+    #[link_name="log2f"] unsafe fn log2(n: c_float) -> c_float;
+    #[link_name="log10f"] unsafe fn log10(n: c_float) -> c_float;
+    #[link_name="ilogbf"] unsafe fn ilog_radix(n: c_float) -> c_int;
+    #[link_name="modff"] unsafe fn modf(n: c_float,
                                       iptr: &mut c_float) -> c_float;
-    #[link_name="powf"] pure fn pow(n: c_float, e: c_float) -> c_float;
+    #[link_name="powf"] unsafe fn pow(n: c_float, e: c_float) -> c_float;
 // FIXME (#1379): enable when rounding modes become available
-//    #[link_name="rintf"] pure fn rint(n: c_float) -> c_float;
-    #[link_name="roundf"] pure fn round(n: c_float) -> c_float;
-    #[link_name="scalbnf"] pure fn ldexp_radix(n: c_float, i: c_int)
+//    #[link_name="rintf"] unsafe fn rint(n: c_float) -> c_float;
+    #[link_name="roundf"] unsafe fn round(n: c_float) -> c_float;
+    #[link_name="scalbnf"] unsafe fn ldexp_radix(n: c_float, i: c_int)
         -> c_float;
-    #[link_name="sinf"] pure fn sin(n: c_float) -> c_float;
-    #[link_name="sinhf"] pure fn sinh(n: c_float) -> c_float;
-    #[link_name="sqrtf"] pure fn sqrt(n: c_float) -> c_float;
-    #[link_name="tanf"] pure fn tan(n: c_float) -> c_float;
-    #[link_name="tanhf"] pure fn tanh(n: c_float) -> c_float;
-    #[link_name="tgammaf"] pure fn tgamma(n: c_float) -> c_float;
-    #[link_name="truncf"] pure fn trunc(n: c_float) -> c_float;
+    #[link_name="sinf"] unsafe fn sin(n: c_float) -> c_float;
+    #[link_name="sinhf"] unsafe fn sinh(n: c_float) -> c_float;
+    #[link_name="sqrtf"] unsafe fn sqrt(n: c_float) -> c_float;
+    #[link_name="tanf"] unsafe fn tan(n: c_float) -> c_float;
+    #[link_name="tanhf"] unsafe fn tanh(n: c_float) -> c_float;
+    #[link_name="tgammaf"] unsafe fn tgamma(n: c_float) -> c_float;
+    #[link_name="truncf"] unsafe fn trunc(n: c_float) -> c_float;
 }
 
 // PORT check these by running src/etc/machconsts.c for your architecture
index 0f9e12058ba1037fb0b0d4873f1371fd6ad48473..05dc74fb3c8e670a9af5f5ef351cdedd912971d4 100644 (file)
 *
 * Eventually this may be simplified to only require
 * an `eq` method, with the other generated from
-* a default implementation.
+* a default implementation. However it should
+* remain possible to implement `ne` separately, for
+* compatibility with floating-point NaN semantics
+* (cf. IEEE 754-2008 section 5.11).
 */
 #[lang="eq"]
 pub trait Eq {
@@ -43,7 +46,10 @@ pub trait Eq {
 *
 * Eventually this may be simplified to only require
 * an `le` method, with the others generated from
-* default implementations.
+* default implementations. However it should remain
+* possible to implement the others separately, for
+* compatibility with floating-point NaN semantics
+* (cf. IEEE 754-2008 section 5.11).
 */
 #[lang="ord"]
 pub trait Ord {
@@ -53,26 +59,32 @@ pub trait Ord {
     pure fn gt(&self, other: &self) -> bool;
 }
 
+#[inline(always)]
 pub pure fn lt<T: Ord>(v1: &T, v2: &T) -> bool {
     (*v1).lt(v2)
 }
 
-pub pure fn le<T: Ord Eq>(v1: &T, v2: &T) -> bool {
-    (*v1).lt(v2) || (*v1).eq(v2)
+#[inline(always)]
+pub pure fn le<T: Ord>(v1: &T, v2: &T) -> bool {
+    (*v1).le(v2)
 }
 
+#[inline(always)]
 pub pure fn eq<T: Eq>(v1: &T, v2: &T) -> bool {
     (*v1).eq(v2)
 }
 
+#[inline(always)]
 pub pure fn ne<T: Eq>(v1: &T, v2: &T) -> bool {
     (*v1).ne(v2)
 }
 
+#[inline(always)]
 pub pure fn ge<T: Ord>(v1: &T, v2: &T) -> bool {
     (*v1).ge(v2)
 }
 
+#[inline(always)]
 pub pure fn gt<T: Ord>(v1: &T, v2: &T) -> bool {
     (*v1).gt(v2)
 }
index df8063772a6d225d5fee04ee74ee11014aab40be..c4001717ca17c9ced82efd830f5b04575704a96b 100644 (file)
@@ -8,8 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::*;
+use task;
+use task::local_data::{local_data_pop, local_data_set};
+
 // helper for transmutation, shown below.
-type RustClosure = (int,int);
+type RustClosure = (int, int);
+
 pub struct Handler<T, U> {
     handle: RustClosure,
     prev: Option<@Handler<T, U>>,
@@ -17,109 +22,97 @@ pub struct Handler<T, U> {
 
 pub struct Condition<T, U> {
     name: &static/str,
-    key: task::local_data::LocalDataKey<Handler<T,U>>
+    key: task::local_data::LocalDataKey<Handler<T, U>>
 }
 
-impl<T, U>  Condition<T,U> {
-
-    fn trap(&self, h: &self/fn(&T) ->U) -> Trap/&self<T,U> {
+impl<T, U> Condition<T, U> {
+    fn trap(&self, h: &self/fn(T) -> U) -> Trap/&self<T, U> {
         unsafe {
             let p : *RustClosure = ::cast::transmute(&h);
             let prev = task::local_data::local_data_get(self.key);
-            let h = @Handler{handle: *p, prev: prev};
-            move Trap { cond: self, handler: h }
+            let h = @Handler { handle: *p, prev: prev };
+            Trap { cond: self, handler: h }
         }
     }
 
-    fn raise(t:&T) -> U  {
-        do self.raise_default(t) {
-            fail fmt!("Unhandled condition: %s: %?",
-                      self.name,
-                      t);
-        }
+    fn raise(t: T) -> U {
+        let msg = fmt!("Unhandled condition: %s: %?", self.name, t);
+        self.raise_default(t, || fail copy msg)
     }
 
-    fn raise_default(t:&T, default: fn() -> U) -> U {
+    fn raise_default(t: T, default: &fn() -> U) -> U {
         unsafe {
-            match task::local_data::local_data_pop(self.key) {
+            match local_data_pop(self.key) {
                 None => {
                     debug!("Condition.raise: found no handler");
                     default()
                 }
-
                 Some(handler) => {
                     debug!("Condition.raise: found handler");
                     match handler.prev {
-                        None => (),
-                        Some(hp) =>
-                        task::local_data::local_data_set(self.key, hp)
+                        None => {}
+                        Some(hp) => local_data_set(self.key, hp)
                     }
-                    let handle : &fn(&T) -> U =
+                    let handle : &fn(T) -> U =
                         ::cast::transmute(handler.handle);
                     let u = handle(t);
-                    task::local_data::local_data_set(self.key,
-                                                     handler);
-                    move u
+                    local_data_set(self.key, handler);
+                    u
                 }
             }
         }
     }
 }
 
-
-
 struct Trap<T, U> {
-    cond: &Condition<T,U>,
+    cond: &Condition<T, U>,
     handler: @Handler<T, U>
 }
 
-impl<T, U> Trap<T,U> {
+impl<T, U> Trap<T, U> {
     fn in<V>(&self, inner: &self/fn() -> V) -> V {
         unsafe {
             let _g = Guard { cond: self.cond };
             debug!("Trap: pushing handler to TLS");
-            task::local_data::local_data_set(self.cond.key, self.handler);
+            local_data_set(self.cond.key, self.handler);
             inner()
         }
     }
 }
 
 struct Guard<T, U> {
-    cond: &Condition<T,U>,
-    drop {
+    cond: &Condition<T, U>
+}
+
+impl<T, U> Guard<T, U> : Drop {
+    fn finalize(&self) {
         unsafe {
             debug!("Guard: popping handler from TLS");
-            let curr = task::local_data::local_data_pop(self.cond.key);
+            let curr = local_data_pop(self.cond.key);
             match curr {
-                None => (),
-                Some(h) =>
-                match h.prev {
-                    None => (),
-                    Some(hp) => {
-                        task::local_data::local_data_set(self.cond.key, hp)
-                    }
+                None => {}
+                Some(h) => match h.prev {
+                    None => {}
+                    Some(hp) => local_data_set(self.cond.key, hp)
                 }
             }
         }
     }
 }
 
-
 #[cfg(test)]
 mod test {
-
     condition! {
         sadness: int -> int;
     }
 
     fn trouble(i: int) {
-        debug!("trouble: raising conition");
-        let j = sadness::cond.raise(&i);
+        debug!("trouble: raising condition");
+        let j = sadness::cond.raise(i);
         debug!("trouble: handler recovered with %d", j);
     }
 
     fn nested_trap_test_inner() {
-
         let mut inner_trapped = false;
 
         do sadness::cond.trap(|_j| {
@@ -136,7 +129,6 @@ fn nested_trap_test_inner() {
 
     #[test]
     fn nested_trap_test_outer() {
-
         let mut outer_trapped = false;
 
         do sadness::cond.trap(|_j| {
@@ -152,7 +144,6 @@ fn nested_trap_test_outer() {
     }
 
     fn nested_reraise_trap_test_inner() {
-
         let mut inner_trapped = false;
 
         do sadness::cond.trap(|_j| {
@@ -160,7 +151,7 @@ fn nested_reraise_trap_test_inner() {
             inner_trapped = true;
             let i = 10;
             debug!("nested_reraise_trap_test_inner: handler re-raising");
-            sadness::cond.raise(&i)
+            sadness::cond.raise(i)
         }).in {
             debug!("nested_reraise_trap_test_inner: in protected block");
             trouble(1);
@@ -171,7 +162,6 @@ fn nested_reraise_trap_test_inner() {
 
     #[test]
     fn nested_reraise_trap_test_outer() {
-
         let mut outer_trapped = false;
 
         do sadness::cond.trap(|_j| {
@@ -187,12 +177,11 @@ fn nested_reraise_trap_test_outer() {
 
     #[test]
     fn test_default() {
-
         let mut trapped = false;
 
         do sadness::cond.trap(|j| {
             debug!("test_default: in handler");
-            sadness::cond.raise_default(j, || {trapped=true; 5})
+            sadness::cond.raise_default(j, || { trapped=true; 5 })
         }).in {
             debug!("test_default: in protected block");
             trouble(1);
@@ -200,5 +189,4 @@ fn test_default() {
 
         assert trapped;
     }
-
 }
index bac6bae90a0ab1a7d18f3fd239a4f3bc682cc493..81b9077fb3e0fcc56bec3fe3d4592787aa685130 100644 (file)
@@ -53,6 +53,9 @@ Implicitly, all crates behave as if they included the following prologue:
 #[warn(vecs_implicitly_copyable)];
 #[deny(non_camel_case_types)];
 
+/* The Prelude. */
+
+pub mod prelude;
 
 /* Primitive types */
 
@@ -169,7 +172,7 @@ pub mod util;
 
 pub use kinds::{Const, Copy, Owned, Durable};
 pub use ops::{Drop};
-pub use ops::{Add, Sub, Mul, Div, Modulo, Neg};
+pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
 pub use ops::{BitAnd, BitOr, BitXor};
 pub use ops::{Shl, Shr, Index};
 
@@ -188,7 +191,7 @@ pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
 pub use str::{StrSlice, Trimmable};
 pub use vec::{ConstVector, CopyableVector, ImmutableVector};
 pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
-pub use vec::{MutableVector, MutableCopyableVector};
+pub use vec::{OwnedVector, OwnedCopyableVector};
 pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
 pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
 
@@ -235,7 +238,7 @@ mod stackwalk;
 // 'core' so that macro-expanded references to core::error and such
 // can be resolved within libcore.
 #[doc(hidden)] // FIXME #3538
-mod core {
+pub mod core {
     pub const error : u32 = 1_u32;
     pub const warn : u32 = 2_u32;
     pub const info : u32 = 3_u32;
@@ -243,14 +246,8 @@ mod core {
 
     pub use cmp;
     pub use condition;
-}
-
-
-// Similar to above. Some magic to make core testable.
-#[cfg(test)]
-mod std {
-    extern mod std(vers = "0.6");
-    pub use std::std::test;
+    pub use option;
+    pub use kinds;
 }
 
 
index 35ff98ac17dae6471cc6f38d81ac6966f2178f25..1aa6c5a01972f42247d105b9c5bae9e43f541982 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use kinds::Copy;
+use managed;
+use option::{None, Option, Some};
+use option;
+use vec;
+
 type DListLink<T> = Option<DListNode<T>>;
 
 enum DListNode<T> = @{
@@ -90,13 +96,13 @@ impl<T> DListNode<T> {
 }
 
 /// Creates a new dlist node with the given data.
-pure fn new_dlist_node<T>(data: T) -> DListNode<T> {
+pub pure fn new_dlist_node<T>(data: T) -> DListNode<T> {
     DListNode(@{data: move data, mut linked: false,
                  mut prev: None, mut next: None})
 }
 
 /// Creates a new, empty dlist.
-pure fn DList<T>() -> DList<T> {
+pub pure fn DList<T>() -> DList<T> {
     DList_(@{mut size: 0, mut hd: None, mut tl: None})
 }
 
@@ -116,7 +122,7 @@ pub fn from_vec<T: Copy>(vec: &[T]) -> DList<T> {
 
 /// Produce a list from a list of lists, leaving no elements behind in the
 /// input. O(number of sub-lists).
-fn concat<T>(lists: DList<DList<T>>) -> DList<T> {
+pub fn concat<T>(lists: DList<DList<T>>) -> DList<T> {
     let result = DList();
     while !lists.is_empty() {
         result.append(lists.pop().get());
@@ -469,6 +475,12 @@ fn pop_tail()  -> Option<T> { self.pop_tail_n().map  (|nobe| nobe.data) }
 #[cfg(test)]
 mod tests {
     #[legacy_exports];
+
+    use dlist::{DList, concat, from_vec, new_dlist_node};
+    use iter;
+    use option::{None, Some};
+    use vec;
+
     #[test]
     fn test_dlist_concat() {
         let a = from_vec(~[1,2]);
index 236d6bce9f033515f21e9fcac7b94682ea29ba1b..92ac1faf30696e7fd4922d4e9f1ff67a8eb17879 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use cast;
 use cast::reinterpret_cast;
+use prelude::*;
 use ptr::null;
+use vec;
 
 /**
  * A growable, modifiable vector type that accumulates elements into a
index 6c0254ff7790257b25a2ba6342089841887786a0..c4f07db662180fd531119d73905b0f19ed412366 100644 (file)
 //! A type that represents one of two alternatives
 
 use cmp::Eq;
+use cmp;
+use kinds::Copy;
 use result::Result;
+use result;
+use vec;
 
 /// The either type
 #[deriving_eq]
@@ -24,6 +28,7 @@ pub enum Either<T, U> {
     Right(U)
 }
 
+#[inline(always)]
 pub fn either<T, U, V>(f_left: fn(&T) -> V,
                        f_right: fn(&U) -> V, value: &Either<T, U>) -> V {
     /*!
@@ -66,8 +71,7 @@ pub fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
     }
 }
 
-// XXX bad copies. take arg by val
-pub fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
+pub fn partition<T, U>(eithers: ~[Either<T, U>])
     -> (~[T], ~[U]) {
     /*!
      * Extracts from a vector of either all the left values and right values
@@ -78,27 +82,27 @@ pub fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
 
     let mut lefts: ~[T] = ~[];
     let mut rights: ~[U] = ~[];
-    for vec::each(eithers) |elt| {
-        match *elt {
-          Left(copy l) => lefts.push(l),
-          Right(copy r) => rights.push(r)
+    do vec::consume(eithers) |_i, elt| {
+        match elt {
+          Left(l) => lefts.push(l),
+          Right(r) => rights.push(r)
         }
     }
     return (move lefts, move rights);
 }
 
-// XXX bad copies
-pub pure fn flip<T: Copy, U: Copy>(eith: &Either<T, U>) -> Either<U, T> {
+#[inline(always)]
+pub pure fn flip<T, U>(eith: Either<T, U>) -> Either<U, T> {
     //! Flips between left and right of a given either
 
-    match *eith {
-      Right(copy r) => Left(r),
-      Left(copy l) => Right(l)
+    match eith {
+      Right(r) => Left(r),
+      Left(l) => Right(l)
     }
 }
 
-// XXX bad copies
-pub pure fn to_result<T: Copy, U: Copy>(eith: &Either<T, U>)
+#[inline(always)]
+pub pure fn to_result<T, U>(eith: Either<T, U>)
     -> Result<U, T> {
     /*!
      * Converts either::t to a result::t
@@ -107,25 +111,27 @@ pub fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
      * an ok result, and the "left" choice a fail
      */
 
-    match *eith {
-      Right(copy r) => result::Ok(r),
-      Left(copy l) => result::Err(l)
+    match eith {
+      Right(r) => result::Ok(r),
+      Left(l) => result::Err(l)
     }
 }
 
+#[inline(always)]
 pub pure fn is_left<T, U>(eith: &Either<T, U>) -> bool {
     //! Checks whether the given value is a left
 
     match *eith { Left(_) => true, _ => false }
 }
 
+#[inline(always)]
 pub pure fn is_right<T, U>(eith: &Either<T, U>) -> bool {
     //! Checks whether the given value is a right
 
     match *eith { Right(_) => true, _ => false }
 }
 
-// tjc: fix the next two after a snapshot
+#[inline(always)]
 pub pure fn unwrap_left<T,U>(eith: Either<T,U>) -> T {
     //! Retrieves the value in the left branch. Fails if the either is Right.
 
@@ -134,6 +140,7 @@ pub fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
     }
 }
 
+#[inline(always)]
 pub pure fn unwrap_right<T,U>(eith: Either<T,U>) -> U {
     //! Retrieves the value in the right branch. Fails if the either is Left.
 
index 1c9ad6ba81a2a9f651483aff129d086ba7561694..420c113443e4519f5a3a5db984ef8410bd92c7b8 100644 (file)
@@ -82,7 +82,8 @@
 
 use cmp::Eq;
 use option::{Some, None};
-
+use prelude::*;
+use str;
 
 /*
  * We have a 'ct' (compile-time) module that parses format strings into a
 // Functions used by the fmt extension at compile time
 #[doc(hidden)]
 pub mod ct {
+    use char;
+    use prelude::*;
+    use str;
+    use vec;
+
+    #[deriving_eq]
     pub enum Signedness { Signed, Unsigned, }
+
+    #[deriving_eq]
     pub enum Caseness { CaseUpper, CaseLower, }
+
+    #[deriving_eq]
     pub enum Ty {
         TyBool,
         TyStr,
@@ -111,6 +122,8 @@ pub enum Ty {
         TyFloat,
         TyPoly,
     }
+
+    #[deriving_eq]
     pub enum Flag {
         FlagLeftJustify,
         FlagLeftZeroPad,
@@ -118,6 +131,8 @@ pub enum Flag {
         FlagSignAlways,
         FlagAlternate,
     }
+
+    #[deriving_eq]
     pub enum Count {
         CountIs(uint),
         CountIsParam(uint),
@@ -125,204 +140,326 @@ pub enum Count {
         CountImplied,
     }
 
-    // A formatted conversion from an expression to a string
-    pub type Conv =
-        {param: Option<uint>,
-         flags: ~[Flag],
-         width: Count,
-         precision: Count,
-         ty: Ty};
+    #[deriving_eq]
+    struct Parsed<T> {
+        val: T,
+        next: uint
+    }
 
+    impl<T> Parsed<T> {
+        static pure fn new(val: T, next: uint) -> Parsed<T> {
+            Parsed {val: val, next: next}
+        }
+    }
+
+    // A formatted conversion from an expression to a string
+    #[deriving_eq]
+    pub struct Conv {
+        param: Option<uint>,
+        flags: ~[Flag],
+        width: Count,
+        precision: Count,
+        ty: Ty
+    }
 
     // A fragment of the output sequence
+    #[deriving_eq]
     pub enum Piece { PieceString(~str), PieceConv(Conv), }
-    pub type ErrorFn = fn@(&str) -> ! ;
+
+    pub type ErrorFn = @fn(&str) -> !;
 
     pub fn parse_fmt_string(s: &str, err: ErrorFn) -> ~[Piece] {
-        let mut pieces: ~[Piece] = ~[];
-        let lim = str::len(s);
-        let mut buf = ~"";
-        fn flush_buf(buf: ~str, pieces: &mut ~[Piece]) -> ~str {
-            if buf.len() > 0 {
-                let piece = PieceString(move buf);
-                pieces.push(move piece);
+        fn push_slice(ps: &mut ~[Piece], s: &str, from: uint, to: uint) {
+            if to > from {
+                ps.push(PieceString(s.slice(from, to)));
             }
-            return ~"";
         }
+
+        let lim = s.len();
+        let mut h = 0;
         let mut i = 0;
+        let mut pieces = ~[];
+
         while i < lim {
-            let size = str::utf8_char_width(s[i]);
-            let curr = str::slice(s, i, i+size);
-            if curr == ~"%" {
+            if s[i] == '%' as u8 {
                 i += 1;
+
                 if i >= lim {
                     err(~"unterminated conversion at end of string");
-                }
-                let curr2 = str::slice(s, i, i+1);
-                if curr2 == ~"%" {
-                    buf += curr2;
+                } else if s[i] == '%' as u8 {
+                    push_slice(&mut pieces, s, h, i);
                     i += 1;
                 } else {
-                    buf = flush_buf(move buf, &mut pieces);
-                    let rs = parse_conversion(s, i, lim, err);
-                    pieces.push(copy rs.piece);
-                    i = rs.next;
+                    push_slice(&mut pieces, s, h, i - 1);
+                    let Parsed {val, next} = parse_conversion(s, i, lim, err);
+                    pieces.push(val);
+                    i = next;
                 }
-            } else { buf += curr; i += size; }
+
+                h = i;
+            } else {
+                i += str::utf8_char_width(s[i]);
+            }
         }
-        flush_buf(move buf, &mut pieces);
-        move pieces
+
+        push_slice(&mut pieces, s, h, i);
+        pieces
     }
-    pub fn peek_num(s: &str, i: uint, lim: uint) ->
-       Option<{num: uint, next: uint}> {
-        let mut j = i;
-        let mut accum = 0u;
+
+    pub fn peek_num(s: &str, i: uint, lim: uint) -> Option<Parsed<uint>> {
+        let mut i = i;
+        let mut accum = 0;
         let mut found = false;
-        while j < lim {
-            match char::to_digit(s[j] as char, 10) {
+
+        while i < lim {
+            match char::to_digit(s[i] as char, 10) {
                 Some(x) => {
                     found = true;
                     accum *= 10;
                     accum += x;
-                    j += 1;
-                },
+                    i += 1;
+                }
                 None => break
             }
         }
+
         if found {
-            Some({num: accum, next: j})
+            Some(Parsed::new(accum, i))
         } else {
             None
         }
     }
-    pub fn parse_conversion(s: &str, i: uint, lim: uint,
-                            err: ErrorFn) ->
-       {piece: Piece, next: uint} {
-        let parm = parse_parameter(s, i, lim);
-        let flags = parse_flags(s, parm.next, lim);
-        let width = parse_count(s, flags.next, lim);
+
+    pub fn parse_conversion(s: &str, i: uint, lim: uint, err: ErrorFn) ->
+        Parsed<Piece> {
+        let param = parse_parameter(s, i, lim);
+        // avoid copying ~[Flag] by destructuring
+        let Parsed {val: flags_val, next: flags_next} = parse_flags(s,
+            param.next, lim);
+        let width = parse_count(s, flags_next, lim);
         let prec = parse_precision(s, width.next, lim);
         let ty = parse_type(s, prec.next, lim, err);
-        return {piece:
-                 PieceConv({param: parm.param,
-                             flags: copy flags.flags,
-                             width: width.count,
-                             precision: prec.count,
-                             ty: ty.ty}),
-             next: ty.next};
+
+        Parsed::new(PieceConv(Conv {
+            param: param.val,
+            flags: flags_val,
+            width: width.val,
+            precision: prec.val,
+            ty: ty.val}), ty.next)
     }
+
     pub fn parse_parameter(s: &str, i: uint, lim: uint) ->
-       {param: Option<uint>, next: uint} {
-        if i >= lim { return {param: None, next: i}; }
-        let num = peek_num(s, i, lim);
-        return match num {
-              None => {param: None, next: i},
-              Some(t) => {
-                let n = t.num;
-                let j = t.next;
-                if j < lim && s[j] == '$' as u8 {
-                    {param: Some(n), next: j + 1}
-                } else { {param: None, next: i} }
-              }
+        Parsed<Option<uint>> {
+        if i >= lim { return Parsed::new(None, i); }
+
+        match peek_num(s, i, lim) {
+            Some(num) if num.next < lim && s[num.next] == '$' as u8 =>
+                Parsed::new(Some(num.val), num.next + 1),
+            _ => Parsed::new(None, i)
+        }
+    }
+
+    pub fn parse_flags(s: &str, i: uint, lim: uint) -> Parsed<~[Flag]> {
+        let mut i = i;
+        let mut flags = ~[];
+
+        while i < lim {
+            let f = match s[i] {
+                '-' as u8 => FlagLeftJustify,
+                '0' as u8 => FlagLeftZeroPad,
+                ' ' as u8 => FlagSpaceForSign,
+                '+' as u8 => FlagSignAlways,
+                '#' as u8 => FlagAlternate,
+                _ => break
             };
+
+            flags.push(f);
+            i += 1;
+        }
+
+        Parsed::new(flags, i)
     }
-    pub fn parse_flags(s: &str, i: uint, lim: uint) ->
-       {flags: ~[Flag], next: uint} {
-        let noflags: ~[Flag] = ~[];
-        if i >= lim { return {flags: move noflags, next: i}; }
-
-        fn more(f: Flag, s: &str, i: uint, lim: uint) ->
-           {flags: ~[Flag], next: uint} {
-            let next = parse_flags(s, i + 1u, lim);
-            let rest = copy next.flags;
-            let j = next.next;
-            let curr: ~[Flag] = ~[f];
-            return {flags: vec::append(move curr, rest), next: j};
+
+    pub fn parse_count(s: &str, i: uint, lim: uint) -> Parsed<Count> {
+        if i >= lim {
+            Parsed::new(CountImplied, i)
+        } else if s[i] == '*' as u8 {
+            let param = parse_parameter(s, i + 1, lim);
+            let j = param.next;
+
+            match param.val {
+                None => Parsed::new(CountIsNextParam, j),
+                Some(n) => Parsed::new(CountIsParam(n), j)
+            }
+        } else {
+            match peek_num(s, i, lim) {
+                None => Parsed::new(CountImplied, i),
+                Some(num) => Parsed::new(CountIs(num.val), num.next)
+            }
         }
-        // Unfortunate, but because s is borrowed, can't use a closure
-     //   fn more(f: Flag, s: &str) { more_(f, s, i, lim); }
-        let f = s[i];
-        return if f == '-' as u8 {
-                more(FlagLeftJustify, s, i, lim)
-            } else if f == '0' as u8 {
-                more(FlagLeftZeroPad, s, i, lim)
-            } else if f == ' ' as u8 {
-                more(FlagSpaceForSign, s, i, lim)
-            } else if f == '+' as u8 {
-                more(FlagSignAlways, s, i, lim)
-            } else if f == '#' as u8 {
-                more(FlagAlternate, s, i, lim)
-            } else { {flags: move noflags, next: i} };
-    }
-        pub fn parse_count(s: &str, i: uint, lim: uint)
-        -> {count: Count, next: uint} {
-        return if i >= lim {
-                {count: CountImplied, next: i}
-            } else if s[i] == '*' as u8 {
-                let param = parse_parameter(s, i + 1, lim);
-                let j = param.next;
-                match param.param {
-                  None => {count: CountIsNextParam, next: j},
-                  Some(n) => {count: CountIsParam(n), next: j}
-                }
-            } else {
-                let num = peek_num(s, i, lim);
-                match num {
-                  None => {count: CountImplied, next: i},
-                  Some(num) => {
-                    count: CountIs(num.num),
-                    next: num.next
-                  }
-                }
-            };
     }
-    pub fn parse_precision(s: &str, i: uint, lim: uint) ->
-       {count: Count, next: uint} {
-        return if i >= lim {
-                {count: CountImplied, next: i}
-            } else if s[i] == '.' as u8 {
-                let count = parse_count(s, i + 1u, lim);
 
+    pub fn parse_precision(s: &str, i: uint, lim: uint) -> Parsed<Count> {
+        if i < lim && s[i] == '.' as u8 {
+            let count = parse_count(s, i + 1, lim);
 
-                // If there were no digits specified, i.e. the precision
-                // was ".", then the precision is 0
-                match count.count {
-                  CountImplied => {count: CountIs(0), next: count.next},
-                  _ => count
-                }
-            } else { {count: CountImplied, next: i} };
+            // If there were no digits specified, i.e. the precision
+            // was ".", then the precision is 0
+            match count.val {
+                CountImplied => Parsed::new(CountIs(0), count.next),
+                _ => count
+            }
+        } else {
+            Parsed::new(CountImplied, i)
+        }
     }
+
     pub fn parse_type(s: &str, i: uint, lim: uint, err: ErrorFn) ->
-       {ty: Ty, next: uint} {
+        Parsed<Ty> {
         if i >= lim { err(~"missing type in conversion"); }
-        let tstr = str::slice(s, i, i+1u);
+
         // FIXME (#2249): Do we really want two signed types here?
         // How important is it to be printf compatible?
-        let t =
-            if tstr == ~"b" {
-                TyBool
-            } else if tstr == ~"s" {
-                TyStr
-            } else if tstr == ~"c" {
-                TyChar
-            } else if tstr == ~"d" || tstr == ~"i" {
-                TyInt(Signed)
-            } else if tstr == ~"u" {
-                TyInt(Unsigned)
-            } else if tstr == ~"x" {
-                TyHex(CaseLower)
-            } else if tstr == ~"X" {
-                TyHex(CaseUpper)
-            } else if tstr == ~"t" {
-                TyBits
-            } else if tstr == ~"o" {
-                TyOctal
-            } else if tstr == ~"f" {
-                TyFloat
-            } else if tstr == ~"?" {
-                TyPoly
-            } else { err(~"unknown type in conversion: " + tstr) };
-        return {ty: t, next: i + 1u};
+        let t = match s[i] {
+            'b' as u8 => TyBool,
+            's' as u8 => TyStr,
+            'c' as u8 => TyChar,
+            'd' as u8 | 'i' as u8 => TyInt(Signed),
+            'u' as u8 => TyInt(Unsigned),
+            'x' as u8 => TyHex(CaseLower),
+            'X' as u8 => TyHex(CaseUpper),
+            't' as u8 => TyBits,
+            'o' as u8 => TyOctal,
+            'f' as u8 => TyFloat,
+            '?' as u8 => TyPoly,
+            _ => err(~"unknown type in conversion: " + s.substr(i, 1))
+        };
+
+        Parsed::new(t, i + 1)
+    }
+
+    #[cfg(test)]
+    fn die(s: &str) -> ! { fail s.to_owned() }
+
+    #[test]
+    fn test_parse_count() {
+        fn test(s: &str, count: Count, next: uint) -> bool {
+            parse_count(s, 0, s.len()) == Parsed::new(count, next)
+        }
+
+        assert test("", CountImplied, 0);
+        assert test("*", CountIsNextParam, 1);
+        assert test("*1", CountIsNextParam, 1);
+        assert test("*1$", CountIsParam(1), 3);
+        assert test("123", CountIs(123), 3);
+    }
+
+    #[test]
+    fn test_parse_flags() {
+        fn pack(fs: &[Flag]) -> uint {
+            fs.foldl(0, |&p, &f| p | (1 << f as uint))
+        }
+
+        fn test(s: &str, flags: &[Flag], next: uint) {
+            let f = parse_flags(s, 0, s.len());
+            assert pack(f.val) == pack(flags);
+            assert f.next == next;
+        }
+
+        test("", [], 0);
+        test("!#-+ 0", [], 0);
+        test("#-+", [FlagAlternate, FlagLeftJustify, FlagSignAlways], 3);
+        test(" 0", [FlagSpaceForSign, FlagLeftZeroPad], 2);
+    }
+
+    #[test]
+    fn test_parse_fmt_string() {
+        assert parse_fmt_string("foo %s bar", die) == ~[
+            PieceString(~"foo "),
+            PieceConv(Conv {param: None, flags: ~[], width: CountImplied,
+                            precision: CountImplied, ty: TyStr}),
+            PieceString(~" bar")];
+
+        assert parse_fmt_string("%s", die) == ~[
+            PieceConv(Conv {param: None, flags: ~[], width: CountImplied,
+                            precision: CountImplied, ty: TyStr })];
+
+        assert parse_fmt_string("%%%%", die) == ~[
+            PieceString(~"%"), PieceString(~"%")];
+    }
+
+    #[test]
+    fn test_parse_parameter() {
+        fn test(s: &str, param: Option<uint>, next: uint) -> bool {
+            parse_parameter(s, 0, s.len()) == Parsed::new(param, next)
+        }
+
+        assert test("", None, 0);
+        assert test("foo", None, 0);
+        assert test("123", None, 0);
+        assert test("123$", Some(123), 4);
+    }
+
+    #[test]
+    fn test_parse_precision() {
+        fn test(s: &str, count: Count, next: uint) -> bool {
+            parse_precision(s, 0, s.len()) == Parsed::new(count, next)
+        }
+
+        assert test("", CountImplied, 0);
+        assert test(".", CountIs(0), 1);
+        assert test(".*", CountIsNextParam, 2);
+        assert test(".*1", CountIsNextParam, 2);
+        assert test(".*1$", CountIsParam(1), 4);
+        assert test(".123", CountIs(123), 4);
+    }
+
+    #[test]
+    fn test_parse_type() {
+        fn test(s: &str, ty: Ty) -> bool {
+            parse_type(s, 0, s.len(), die) == Parsed::new(ty, 1)
+        }
+
+        assert test("b", TyBool);
+        assert test("c", TyChar);
+        assert test("d", TyInt(Signed));
+        assert test("f", TyFloat);
+        assert test("i", TyInt(Signed));
+        assert test("o", TyOctal);
+        assert test("s", TyStr);
+        assert test("t", TyBits);
+        assert test("x", TyHex(CaseLower));
+        assert test("X", TyHex(CaseUpper));
+        assert test("?", TyPoly);
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_parse_type_missing() {
+        parse_type("", 0, 0, die);
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_parse_type_unknown() {
+        parse_type("!", 0, 1, die);
+    }
+
+    #[test]
+    fn test_peek_num() {
+        let s1 = "";
+        assert peek_num(s1, 0, s1.len()).is_none();
+
+        let s2 = "foo";
+        assert peek_num(s2, 0, s2.len()).is_none();
+
+        let s3 = "123";
+        assert peek_num(s3, 0, s3.len()) == Some(Parsed::new(123, 3));
+
+        let s4 = "123foo";
+        assert peek_num(s4, 0, s4.len()) == Some(Parsed::new(123, 3));
     }
 }
 
@@ -332,6 +469,12 @@ pub fn parse_type(s: &str, i: uint, lim: uint, err: ErrorFn) ->
 // implement it 0this way, I think.
 #[doc(hidden)]
 pub mod rt {
+    use float;
+    use str;
+    use sys;
+    use uint;
+    use vec;
+
     pub const flag_none : u32 = 0u32;
     pub const flag_left_justify   : u32 = 0b00000000000001u32;
     pub const flag_left_zero_pad  : u32 = 0b00000000000010u32;
index 5e34c7c5530b67ae5e4bf2bb0ac00f066d46dd69..4c1cc890de9e449c29a2bd8350a2879e3e1f0dcc 100644 (file)
 
 //! Operations and constants for `f32`
 
-pub use cmath::c_float_utils::*;
+use cmath;
+use cmp;
+use libc::{c_float, c_int};
+use num;
+
 pub use cmath::c_float_targ_consts::*;
 
+macro_rules! delegate(
+    (
+        fn $name:ident(
+            $(
+                $arg:ident : $arg_ty:ty
+            ),*
+        ) -> $rv:ty = $bound_name:path
+    ) => (
+        pub pure fn $name($( $arg : $arg_ty ),*) -> $rv {
+            unsafe {
+                $bound_name($( $arg ),*)
+            }
+        }
+    )
+)
+
+delegate!(fn acos(n: c_float) -> c_float = cmath::c_float_utils::acos)
+delegate!(fn asin(n: c_float) -> c_float = cmath::c_float_utils::asin)
+delegate!(fn atan(n: c_float) -> c_float = cmath::c_float_utils::atan)
+delegate!(fn atan2(a: c_float, b: c_float) -> c_float =
+    cmath::c_float_utils::atan2)
+delegate!(fn cbrt(n: c_float) -> c_float = cmath::c_float_utils::cbrt)
+delegate!(fn ceil(n: c_float) -> c_float = cmath::c_float_utils::ceil)
+delegate!(fn copysign(x: c_float, y: c_float) -> c_float =
+    cmath::c_float_utils::copysign)
+delegate!(fn cos(n: c_float) -> c_float = cmath::c_float_utils::cos)
+delegate!(fn cosh(n: c_float) -> c_float = cmath::c_float_utils::cosh)
+delegate!(fn erf(n: c_float) -> c_float = cmath::c_float_utils::erf)
+delegate!(fn erfc(n: c_float) -> c_float = cmath::c_float_utils::erfc)
+delegate!(fn exp(n: c_float) -> c_float = cmath::c_float_utils::exp)
+delegate!(fn expm1(n: c_float) -> c_float = cmath::c_float_utils::expm1)
+delegate!(fn exp2(n: c_float) -> c_float = cmath::c_float_utils::exp2)
+delegate!(fn abs(n: c_float) -> c_float = cmath::c_float_utils::abs)
+delegate!(fn abs_sub(a: c_float, b: c_float) -> c_float =
+    cmath::c_float_utils::abs_sub)
+delegate!(fn floor(n: c_float) -> c_float = cmath::c_float_utils::floor)
+delegate!(fn mul_add(a: c_float, b: c_float, c: c_float) -> c_float =
+    cmath::c_float_utils::mul_add)
+delegate!(fn fmax(a: c_float, b: c_float) -> c_float =
+    cmath::c_float_utils::fmax)
+delegate!(fn fmin(a: c_float, b: c_float) -> c_float =
+    cmath::c_float_utils::fmin)
+delegate!(fn nextafter(x: c_float, y: c_float) -> c_float =
+    cmath::c_float_utils::nextafter)
+delegate!(fn frexp(n: c_float, value: &mut c_int) -> c_float =
+    cmath::c_float_utils::frexp)
+delegate!(fn hypot(x: c_float, y: c_float) -> c_float =
+    cmath::c_float_utils::hypot)
+delegate!(fn ldexp(x: c_float, n: c_int) -> c_float =
+    cmath::c_float_utils::ldexp)
+delegate!(fn lgamma(n: c_float, sign: &mut c_int) -> c_float =
+    cmath::c_float_utils::lgamma)
+delegate!(fn ln(n: c_float) -> c_float = cmath::c_float_utils::ln)
+delegate!(fn log_radix(n: c_float) -> c_float =
+    cmath::c_float_utils::log_radix)
+delegate!(fn ln1p(n: c_float) -> c_float = cmath::c_float_utils::ln1p)
+delegate!(fn log10(n: c_float) -> c_float = cmath::c_float_utils::log10)
+delegate!(fn log2(n: c_float) -> c_float = cmath::c_float_utils::log2)
+delegate!(fn ilog_radix(n: c_float) -> c_int =
+    cmath::c_float_utils::ilog_radix)
+delegate!(fn modf(n: c_float, iptr: &mut c_float) -> c_float =
+    cmath::c_float_utils::modf)
+delegate!(fn pow(n: c_float, e: c_float) -> c_float =
+    cmath::c_float_utils::pow)
+delegate!(fn round(n: c_float) -> c_float = cmath::c_float_utils::round)
+delegate!(fn ldexp_radix(n: c_float, i: c_int) -> c_float =
+    cmath::c_float_utils::ldexp_radix)
+delegate!(fn sin(n: c_float) -> c_float = cmath::c_float_utils::sin)
+delegate!(fn sinh(n: c_float) -> c_float = cmath::c_float_utils::sinh)
+delegate!(fn sqrt(n: c_float) -> c_float = cmath::c_float_utils::sqrt)
+delegate!(fn tan(n: c_float) -> c_float = cmath::c_float_utils::tan)
+delegate!(fn tanh(n: c_float) -> c_float = cmath::c_float_utils::tanh)
+delegate!(fn tgamma(n: c_float) -> c_float = cmath::c_float_utils::tgamma)
+delegate!(fn trunc(n: c_float) -> c_float = cmath::c_float_utils::trunc)
+
 // These are not defined inside consts:: for consistency with
 // the integer types
 
 
 pub const neg_infinity: f32 = -1.0_f32/0.0_f32;
 
+#[inline(always)]
 pub pure fn is_NaN(f: f32) -> bool { f != f }
 
+#[inline(always)]
 pub pure fn add(x: f32, y: f32) -> f32 { return x + y; }
 
+#[inline(always)]
 pub pure fn sub(x: f32, y: f32) -> f32 { return x - y; }
 
+#[inline(always)]
 pub pure fn mul(x: f32, y: f32) -> f32 { return x * y; }
 
+#[inline(always)]
 pub pure fn div(x: f32, y: f32) -> f32 { return x / y; }
 
+#[inline(always)]
 pub pure fn rem(x: f32, y: f32) -> f32 { return x % y; }
 
+#[inline(always)]
 pub pure fn lt(x: f32, y: f32) -> bool { return x < y; }
 
+#[inline(always)]
 pub pure fn le(x: f32, y: f32) -> bool { return x <= y; }
 
+#[inline(always)]
 pub pure fn eq(x: f32, y: f32) -> bool { return x == y; }
 
+#[inline(always)]
 pub pure fn ne(x: f32, y: f32) -> bool { return x != y; }
 
+#[inline(always)]
 pub pure fn ge(x: f32, y: f32) -> bool { return x >= y; }
 
+#[inline(always)]
 pub pure fn gt(x: f32, y: f32) -> bool { return x > y; }
 
 // FIXME (#1999): replace the predicates below with llvm intrinsics or
 // calls to the libmath macros in the rust runtime for performance.
 
 /// Returns true if `x` is a positive number, including +0.0f320 and +Infinity
+#[inline(always)]
 pub pure fn is_positive(x: f32) -> bool
     { return x > 0.0f32 || (1.0f32/x) == infinity; }
 
 /// Returns true if `x` is a negative number, including -0.0f320 and -Infinity
+#[inline(always)]
 pub pure fn is_negative(x: f32) -> bool
     { return x < 0.0f32 || (1.0f32/x) == neg_infinity; }
 
  *
  * This is the same as `f32::is_negative`.
  */
+#[inline(always)]
 pub pure fn is_nonpositive(x: f32) -> bool {
   return x < 0.0f32 || (1.0f32/x) == neg_infinity;
 }
  *
  * This is the same as `f32::is_positive`.)
  */
+#[inline(always)]
 pub pure fn is_nonnegative(x: f32) -> bool {
   return x > 0.0f32 || (1.0f32/x) == infinity;
 }
 
 /// Returns true if `x` is a zero number (positive or negative zero)
+#[inline(always)]
 pub pure fn is_zero(x: f32) -> bool {
     return x == 0.0f32 || x == -0.0f32;
 }
 
 /// Returns true if `x`is an infinite number
+#[inline(always)]
 pub pure fn is_infinite(x: f32) -> bool {
     return x == infinity || x == neg_infinity;
 }
 
 /// Returns true if `x`is a finite number
+#[inline(always)]
 pub pure fn is_finite(x: f32) -> bool {
     return !(is_NaN(x) || is_infinite(x));
 }
@@ -140,45 +238,63 @@ pub mod consts {
     pub const ln_10: f32 = 2.30258509299404568401799145468436421_f32;
 }
 
+#[inline(always)]
 pub pure fn signbit(x: f32) -> int {
     if is_negative(x) { return 1; } else { return 0; }
 }
 
+#[inline(always)]
 pub pure fn logarithm(n: f32, b: f32) -> f32 {
     return log2(n) / log2(b);
 }
 
 #[cfg(notest)]
 impl f32 : cmp::Eq {
+    #[inline(always)]
     pure fn eq(&self, other: &f32) -> bool { (*self) == (*other) }
+    #[inline(always)]
     pure fn ne(&self, other: &f32) -> bool { (*self) != (*other) }
 }
 
 #[cfg(notest)]
 impl f32 : cmp::Ord {
+    #[inline(always)]
     pure fn lt(&self, other: &f32) -> bool { (*self) < (*other) }
+    #[inline(always)]
     pure fn le(&self, other: &f32) -> bool { (*self) <= (*other) }
+    #[inline(always)]
     pure fn ge(&self, other: &f32) -> bool { (*self) >= (*other) }
+    #[inline(always)]
     pure fn gt(&self, other: &f32) -> bool { (*self) > (*other) }
 }
 
 impl f32: num::Num {
+    #[inline(always)]
     pure fn add(&self, other: &f32) -> f32 { return *self + *other; }
+    #[inline(always)]
     pure fn sub(&self, other: &f32) -> f32 { return *self - *other; }
+    #[inline(always)]
     pure fn mul(&self, other: &f32) -> f32 { return *self * *other; }
+    #[inline(always)]
     pure fn div(&self, other: &f32) -> f32 { return *self / *other; }
+    #[inline(always)]
     pure fn modulo(&self, other: &f32) -> f32 { return *self % *other; }
+    #[inline(always)]
     pure fn neg(&self)                -> f32 { return -*self;        }
 
+    #[inline(always)]
     pure fn to_int(&self)         -> int { return *self as int; }
+    #[inline(always)]
     static pure fn from_int(n: int) -> f32 { return n as f32;    }
 }
 
 impl f32: num::Zero {
+    #[inline(always)]
     static pure fn zero() -> f32 { 0.0 }
 }
 
 impl f32: num::One {
+    #[inline(always)]
     static pure fn one() -> f32 { 1.0 }
 }
 
index 2e35d0360b62e70d05aebb159062b57895164ab4..cbcdc2e81e6ec8f514833a5d5c24182e6acc224f 100644 (file)
 
 //! Operations and constants for `f64`
 
-pub use cmath::c_double_utils::*;
+use cmath;
+use cmp;
+use libc::{c_double, c_int};
+use libc;
+use num;
+
 pub use cmath::c_double_targ_consts::*;
 
+macro_rules! delegate(
+    (
+        fn $name:ident(
+            $(
+                $arg:ident : $arg_ty:ty
+            ),*
+        ) -> $rv:ty = $bound_name:path
+    ) => (
+        pub pure fn $name($( $arg : $arg_ty ),*) -> $rv {
+            unsafe {
+                $bound_name($( $arg ),*)
+            }
+        }
+    )
+)
+
+delegate!(fn acos(n: c_double) -> c_double = cmath::c_double_utils::acos)
+delegate!(fn asin(n: c_double) -> c_double = cmath::c_double_utils::asin)
+delegate!(fn atan(n: c_double) -> c_double = cmath::c_double_utils::atan)
+delegate!(fn atan2(a: c_double, b: c_double) -> c_double =
+    cmath::c_double_utils::atan2)
+delegate!(fn cbrt(n: c_double) -> c_double = cmath::c_double_utils::cbrt)
+delegate!(fn ceil(n: c_double) -> c_double = cmath::c_double_utils::ceil)
+delegate!(fn copysign(x: c_double, y: c_double) -> c_double =
+    cmath::c_double_utils::copysign)
+delegate!(fn cos(n: c_double) -> c_double = cmath::c_double_utils::cos)
+delegate!(fn cosh(n: c_double) -> c_double = cmath::c_double_utils::cosh)
+delegate!(fn erf(n: c_double) -> c_double = cmath::c_double_utils::erf)
+delegate!(fn erfc(n: c_double) -> c_double = cmath::c_double_utils::erfc)
+delegate!(fn exp(n: c_double) -> c_double = cmath::c_double_utils::exp)
+delegate!(fn expm1(n: c_double) -> c_double = cmath::c_double_utils::expm1)
+delegate!(fn exp2(n: c_double) -> c_double = cmath::c_double_utils::exp2)
+delegate!(fn abs(n: c_double) -> c_double = cmath::c_double_utils::abs)
+delegate!(fn abs_sub(a: c_double, b: c_double) -> c_double =
+    cmath::c_double_utils::abs_sub)
+delegate!(fn floor(n: c_double) -> c_double = cmath::c_double_utils::floor)
+delegate!(fn mul_add(a: c_double, b: c_double, c: c_double) -> c_double =
+    cmath::c_double_utils::mul_add)
+delegate!(fn fmax(a: c_double, b: c_double) -> c_double =
+    cmath::c_double_utils::fmax)
+delegate!(fn fmin(a: c_double, b: c_double) -> c_double =
+    cmath::c_double_utils::fmin)
+delegate!(fn nextafter(x: c_double, y: c_double) -> c_double =
+    cmath::c_double_utils::nextafter)
+delegate!(fn frexp(n: c_double, value: &mut c_int) -> c_double =
+    cmath::c_double_utils::frexp)
+delegate!(fn hypot(x: c_double, y: c_double) -> c_double =
+    cmath::c_double_utils::hypot)
+delegate!(fn ldexp(x: c_double, n: c_int) -> c_double =
+    cmath::c_double_utils::ldexp)
+delegate!(fn lgamma(n: c_double, sign: &mut c_int) -> c_double =
+    cmath::c_double_utils::lgamma)
+delegate!(fn ln(n: c_double) -> c_double = cmath::c_double_utils::ln)
+delegate!(fn log_radix(n: c_double) -> c_double =
+    cmath::c_double_utils::log_radix)
+delegate!(fn ln1p(n: c_double) -> c_double = cmath::c_double_utils::ln1p)
+delegate!(fn log10(n: c_double) -> c_double = cmath::c_double_utils::log10)
+delegate!(fn log2(n: c_double) -> c_double = cmath::c_double_utils::log2)
+delegate!(fn ilog_radix(n: c_double) -> c_int =
+    cmath::c_double_utils::ilog_radix)
+delegate!(fn modf(n: c_double, iptr: &mut c_double) -> c_double =
+    cmath::c_double_utils::modf)
+delegate!(fn pow(n: c_double, e: c_double) -> c_double =
+    cmath::c_double_utils::pow)
+delegate!(fn round(n: c_double) -> c_double = cmath::c_double_utils::round)
+delegate!(fn ldexp_radix(n: c_double, i: c_int) -> c_double =
+    cmath::c_double_utils::ldexp_radix)
+delegate!(fn sin(n: c_double) -> c_double = cmath::c_double_utils::sin)
+delegate!(fn sinh(n: c_double) -> c_double = cmath::c_double_utils::sinh)
+delegate!(fn sqrt(n: c_double) -> c_double = cmath::c_double_utils::sqrt)
+delegate!(fn tan(n: c_double) -> c_double = cmath::c_double_utils::tan)
+delegate!(fn tanh(n: c_double) -> c_double = cmath::c_double_utils::tanh)
+delegate!(fn tgamma(n: c_double) -> c_double = cmath::c_double_utils::tgamma)
+delegate!(fn trunc(n: c_double) -> c_double = cmath::c_double_utils::trunc)
+delegate!(fn j0(n: c_double) -> c_double = cmath::c_double_utils::j0)
+delegate!(fn j1(n: c_double) -> c_double = cmath::c_double_utils::j1)
+delegate!(fn jn(i: c_int, n: c_double) -> c_double =
+    cmath::c_double_utils::jn)
+delegate!(fn y0(n: c_double) -> c_double = cmath::c_double_utils::y0)
+delegate!(fn y1(n: c_double) -> c_double = cmath::c_double_utils::y1)
+delegate!(fn yn(i: c_int, n: c_double) -> c_double =
+    cmath::c_double_utils::yn)
+
 // FIXME (#1433): obtain these in a different way
 
 // These are not defined inside consts:: for consistency with
 
 pub const neg_infinity: f64 = -1.0_f64/0.0_f64;
 
+#[inline(always)]
 pub pure fn is_NaN(f: f64) -> bool { f != f }
 
+#[inline(always)]
 pub pure fn add(x: f64, y: f64) -> f64 { return x + y; }
 
+#[inline(always)]
 pub pure fn sub(x: f64, y: f64) -> f64 { return x - y; }
 
+#[inline(always)]
 pub pure fn mul(x: f64, y: f64) -> f64 { return x * y; }
 
+#[inline(always)]
 pub pure fn div(x: f64, y: f64) -> f64 { return x / y; }
 
+#[inline(always)]
 pub pure fn rem(x: f64, y: f64) -> f64 { return x % y; }
 
+#[inline(always)]
 pub pure fn lt(x: f64, y: f64) -> bool { return x < y; }
 
+#[inline(always)]
 pub pure fn le(x: f64, y: f64) -> bool { return x <= y; }
 
+#[inline(always)]
 pub pure fn eq(x: f64, y: f64) -> bool { return x == y; }
 
+#[inline(always)]
 pub pure fn ne(x: f64, y: f64) -> bool { return x != y; }
 
+#[inline(always)]
 pub pure fn ge(x: f64, y: f64) -> bool { return x >= y; }
 
+#[inline(always)]
 pub pure fn gt(x: f64, y: f64) -> bool { return x > y; }
 
-pub pure fn sqrt(x: f64) -> f64 {
-    cmath::c_double_utils::sqrt(x as libc::c_double) as f64
-}
-
 /// Returns true if `x` is a positive number, including +0.0f640 and +Infinity
+#[inline(always)]
 pub pure fn is_positive(x: f64) -> bool
     { return x > 0.0f64 || (1.0f64/x) == infinity; }
 
 /// Returns true if `x` is a negative number, including -0.0f640 and -Infinity
+#[inline(always)]
 pub pure fn is_negative(x: f64) -> bool
     { return x < 0.0f64 || (1.0f64/x) == neg_infinity; }
 
  *
  * This is the same as `f64::is_negative`.
  */
+#[inline(always)]
 pub pure fn is_nonpositive(x: f64) -> bool {
   return x < 0.0f64 || (1.0f64/x) == neg_infinity;
 }
  *
  * This is the same as `f64::positive`.
  */
+#[inline(always)]
 pub pure fn is_nonnegative(x: f64) -> bool {
   return x > 0.0f64 || (1.0f64/x) == infinity;
 }
 
 /// Returns true if `x` is a zero number (positive or negative zero)
+#[inline(always)]
 pub pure fn is_zero(x: f64) -> bool {
     return x == 0.0f64 || x == -0.0f64;
 }
 
 /// Returns true if `x`is an infinite number
+#[inline(always)]
 pub pure fn is_infinite(x: f64) -> bool {
     return x == infinity || x == neg_infinity;
 }
 
 /// Returns true if `x`is a finite number
+#[inline(always)]
 pub pure fn is_finite(x: f64) -> bool {
     return !(is_NaN(x) || is_infinite(x));
 }
@@ -159,45 +262,63 @@ pub mod consts {
     pub const ln_10: f64 = 2.30258509299404568401799145468436421_f64;
 }
 
+#[inline(always)]
 pub pure fn signbit(x: f64) -> int {
     if is_negative(x) { return 1; } else { return 0; }
 }
 
+#[inline(always)]
 pub pure fn logarithm(n: f64, b: f64) -> f64 {
     return log2(n) / log2(b);
 }
 
 #[cfg(notest)]
 impl f64 : cmp::Eq {
+    #[inline(always)]
     pure fn eq(&self, other: &f64) -> bool { (*self) == (*other) }
+    #[inline(always)]
     pure fn ne(&self, other: &f64) -> bool { (*self) != (*other) }
 }
 
 #[cfg(notest)]
 impl f64 : cmp::Ord {
+    #[inline(always)]
     pure fn lt(&self, other: &f64) -> bool { (*self) < (*other) }
+    #[inline(always)]
     pure fn le(&self, other: &f64) -> bool { (*self) <= (*other) }
+    #[inline(always)]
     pure fn ge(&self, other: &f64) -> bool { (*self) >= (*other) }
+    #[inline(always)]
     pure fn gt(&self, other: &f64) -> bool { (*self) > (*other) }
 }
 
 impl f64: num::Num {
+    #[inline(always)]
     pure fn add(&self, other: &f64)    -> f64 { return *self + *other; }
+    #[inline(always)]
     pure fn sub(&self, other: &f64)    -> f64 { return *self - *other; }
+    #[inline(always)]
     pure fn mul(&self, other: &f64)    -> f64 { return *self * *other; }
+    #[inline(always)]
     pure fn div(&self, other: &f64)    -> f64 { return *self / *other; }
+    #[inline(always)]
     pure fn modulo(&self, other: &f64) -> f64 { return *self % *other; }
+    #[inline(always)]
     pure fn neg(&self)                -> f64 { return -*self;        }
 
+    #[inline(always)]
     pure fn to_int(&self)         -> int { return *self as int; }
+    #[inline(always)]
     static pure fn from_int(n: int) -> f64 { return n as f64;    }
 }
 
 impl f64: num::Zero {
+    #[inline(always)]
     static pure fn zero() -> f64 { 0.0 }
 }
 
 impl f64: num::One {
+    #[inline(always)]
     static pure fn one() -> f64 { 1.0 }
 }
 
index 506937f053fd05b7690898835f4a2af7849a56f6..39a3aa890df97228541f1ac5f8ba41c678154206 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use libc;
 use libc::{c_void, size_t, c_int};
+use ptr;
+use rand;
+use vec;
 
 extern mod rustrt {
-    fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
-                                  src_buf_len: size_t,
-                                  pout_len: *size_t,
-                                  flags: c_int) -> *c_void;
+    unsafe fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
+                                         src_buf_len: size_t,
+                                         pout_len: *size_t,
+                                         flags: c_int) -> *c_void;
 
-    fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
-                                    src_buf_len: size_t,
-                                    pout_len: *size_t,
-                                    flags: c_int) -> *c_void;
+    unsafe fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
+                                           src_buf_len: size_t,
+                                           pout_len: *size_t,
+                                           flags: c_int) -> *c_void;
 }
 
 const lz_none : c_int = 0x0;   // Huffman-coding only.
@@ -88,8 +92,8 @@ fn test_flate_round_trip() {
         }
         debug!("de/inflate of %u bytes of random word-sequences",
                in.len());
-        let cmp = flate::deflate_bytes(in);
-        let out = flate::inflate_bytes(cmp);
+        let cmp = deflate_bytes(in);
+        let out = inflate_bytes(cmp);
         debug!("%u bytes deflated to %u (%.1f%% size)",
                in.len(), cmp.len(),
                100.0 * ((cmp.len() as float) / (in.len() as float)));
index 02ba4419bcc3ed05dd1c1250d0f064c18e7bdb33..4c79069ad0921f211be026a48d043afbfb013e71 100644 (file)
 
 use m_float = f64;
 
+use cmp::{Eq, Ord};
+use cmp;
+use f64;
+use num;
+use num::Num::from_int;
+use option::{None, Option, Some};
+use str;
+use uint;
+
 pub use f64::{add, sub, mul, div, rem, lt, le, eq, ne, ge, gt};
 pub use f64::logarithm;
 pub use f64::{acos, asin, atan2, cbrt, ceil, copysign, cosh, floor};
@@ -35,8 +44,6 @@
 pub use f64::{modf, pow, round, sinh, tanh, tgamma, trunc};
 pub use f64::signbit;
 pub use f64::{j0, j1, jn, y0, y1, yn};
-use cmp::{Eq, Ord};
-use num::Num::from_int;
 
 pub const NaN: float = 0.0/0.0;
 
@@ -188,6 +195,7 @@ pub mod consts {
  * * num - The float value
  * * digits - The number of significant digits
  */
+#[inline(always)]
 pub pure fn to_str_exact(num: float, digits: uint) -> ~str {
     to_str_common(num, digits, true)
 }
@@ -208,6 +216,7 @@ pub fn test_to_str_exact_do_decimal() {
  * * num - The float value
  * * digits - The number of significant digits
  */
+#[inline(always)]
 pub pure fn to_str(num: float, digits: uint) -> ~str {
     to_str_common(num, digits, false)
 }
@@ -393,21 +402,47 @@ pub fn test_to_str_exact_do_decimal() {
     return total;
 }
 
+#[inline(always)]
 pub pure fn is_positive(x: float) -> bool { f64::is_positive(x as f64) }
+#[inline(always)]
 pub pure fn is_negative(x: float) -> bool { f64::is_negative(x as f64) }
+#[inline(always)]
 pub pure fn is_nonpositive(x: float) -> bool { f64::is_nonpositive(x as f64) }
+#[inline(always)]
 pub pure fn is_nonnegative(x: float) -> bool { f64::is_nonnegative(x as f64) }
+#[inline(always)]
 pub pure fn is_zero(x: float) -> bool { f64::is_zero(x as f64) }
+#[inline(always)]
 pub pure fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) }
+#[inline(always)]
 pub pure fn is_finite(x: float) -> bool { f64::is_finite(x as f64) }
+#[inline(always)]
 pub pure fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) }
 
-pub pure fn abs(x: float) -> float { f64::abs(x as f64) as float }
-pub pure fn sqrt(x: float) -> float { f64::sqrt(x as f64) as float }
-pub pure fn atan(x: float) -> float { f64::atan(x as f64) as float }
-pub pure fn sin(x: float) -> float { f64::sin(x as f64) as float }
-pub pure fn cos(x: float) -> float { f64::cos(x as f64) as float }
-pub pure fn tan(x: float) -> float { f64::tan(x as f64) as float }
+#[inline(always)]
+pub pure fn abs(x: float) -> float {
+    unsafe { f64::abs(x as f64) as float }
+}
+#[inline(always)]
+pub pure fn sqrt(x: float) -> float {
+    unsafe { f64::sqrt(x as f64) as float }
+}
+#[inline(always)]
+pub pure fn atan(x: float) -> float {
+    unsafe { f64::atan(x as f64) as float }
+}
+#[inline(always)]
+pub pure fn sin(x: float) -> float {
+    unsafe { f64::sin(x as f64) as float }
+}
+#[inline(always)]
+pub pure fn cos(x: float) -> float {
+    unsafe { f64::cos(x as f64) as float }
+}
+#[inline(always)]
+pub pure fn tan(x: float) -> float {
+    unsafe { f64::tan(x as f64) as float }
+}
 
 #[cfg(notest)]
 impl float : Eq {
@@ -444,10 +479,12 @@ impl float: num::Num {
 }
 
 impl float: num::Zero {
+    #[inline(always)]
     static pure fn zero() -> float { 0.0 }
 }
 
 impl float: num::One {
+    #[inline(always)]
     static pure fn one() -> float { 1.0 }
 }
 
index 81936d1777498149145ff230eea80cdb4dfe4797..8bb3610ffb4419607c8565281d0018e8712c332d 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
-pub use stackwalk::Word;
-use libc::size_t;
-use libc::uintptr_t;
+use cast;
+use io;
+use libc::{size_t, uintptr_t};
+use option::{None, Option, Some};
+use ptr;
 use send_map::linear::LinearMap;
+use stackwalk;
+use sys;
+
+pub use stackwalk::Word;
 
 // Mirrors rust_stack.h stk_seg
 struct StackSegment {
@@ -55,12 +61,14 @@ struct StackSegment {
 extern mod rustrt {
     #[legacy_exports];
     #[rust_stack]
-    fn rust_call_tydesc_glue(root: *Word, tydesc: *Word, field: size_t);
+    unsafe fn rust_call_tydesc_glue(root: *Word,
+                                    tydesc: *Word,
+                                    field: size_t);
 
     #[rust_stack]
-    fn rust_gc_metadata() -> *Word;
+    unsafe fn rust_gc_metadata() -> *Word;
 
-    fn rust_get_stack_segment() -> *StackSegment;
+    unsafe fn rust_get_stack_segment() -> *StackSegment;
 }
 
 unsafe fn bump<T, U>(ptr: *T, count: uint) -> *U {
@@ -338,7 +346,7 @@ pub fn cleanup_stack_for_failure() {
             roots.insert(*root, ());
 
             if ptr::is_null(tydesc) {
-                // XXX: Destroy this box
+                // FIXME #4420: Destroy this box
             } else {
                 rustrt::rust_call_tydesc_glue(*root, tydesc, 3 as size_t);
             }
index 5331019e5f33519b00c27523b371d8a97d0c0fbc..d3d6c5ae2424ba760d82f6a871359e19c19e9c8d 100644 (file)
  * CPRNG like rand::rng.
  */
 
-use io::Writer;
-use io::WriterUtil;
+use io;
+use io::{Writer, WriterUtil};
+use os;
 use to_bytes::IterBytes;
+use uint;
+use vec;
 
 /**
  * Types that can meaningfully be hashed should implement this.
index c3fe24fff321bb41fc0f1046bd3b300e5941e8b7..a04610d199520273d13678c4f4ec513c0187add6 100644 (file)
 
 use T = self::inst::T;
 
+use char;
 use cmp::{Eq, Ord};
+use cmp;
 use from_str::FromStr;
+use iter;
+use num;
 use num::Num::from_int;
+use prelude::*;
+use str;
+use uint;
+use vec;
 
 pub const bits : uint = inst::bits;
 pub const bytes : uint = (inst::bits / 8);
 pub const min_value: T = (-1 as T) << (bits - 1);
 pub const max_value: T = min_value - 1 as T;
 
+#[inline(always)]
 pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }
+#[inline(always)]
 pub pure fn max(x: T, y: T) -> T { if x > y { x } else { y } }
 
+#[inline(always)]
 pub pure fn add(x: T, y: T) -> T { x + y }
+#[inline(always)]
 pub pure fn sub(x: T, y: T) -> T { x - y }
+#[inline(always)]
 pub pure fn mul(x: T, y: T) -> T { x * y }
+#[inline(always)]
 pub pure fn div(x: T, y: T) -> T { x / y }
+#[inline(always)]
 pub pure fn rem(x: T, y: T) -> T { x % y }
 
+#[inline(always)]
 pub pure fn lt(x: T, y: T) -> bool { x < y }
+#[inline(always)]
 pub pure fn le(x: T, y: T) -> bool { x <= y }
+#[inline(always)]
 pub pure fn eq(x: T, y: T) -> bool { x == y }
+#[inline(always)]
 pub pure fn ne(x: T, y: T) -> bool { x != y }
+#[inline(always)]
 pub pure fn ge(x: T, y: T) -> bool { x >= y }
+#[inline(always)]
 pub pure fn gt(x: T, y: T) -> bool { x > y }
 
+#[inline(always)]
 pub pure fn is_positive(x: T) -> bool { x > 0 as T }
+#[inline(always)]
 pub pure fn is_negative(x: T) -> bool { x < 0 as T }
+#[inline(always)]
 pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
+#[inline(always)]
 pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }
 
 #[inline(always)]
@@ -56,46 +81,64 @@ pub fn range(lo: T, hi: T, it: fn(T) -> bool) {
 }
 
 /// Computes the bitwise complement
+#[inline(always)]
 pub pure fn compl(i: T) -> T {
     -1 as T ^ i
 }
 
 /// Computes the absolute value
+#[inline(always)]
 pub pure fn abs(i: T) -> T {
     if is_negative(i) { -i } else { i }
 }
 
 #[cfg(notest)]
 impl T : Ord {
+    #[inline(always)]
     pure fn lt(&self, other: &T) -> bool { return (*self) < (*other); }
+    #[inline(always)]
     pure fn le(&self, other: &T) -> bool { return (*self) <= (*other); }
+    #[inline(always)]
     pure fn ge(&self, other: &T) -> bool { return (*self) >= (*other); }
+    #[inline(always)]
     pure fn gt(&self, other: &T) -> bool { return (*self) > (*other); }
 }
 
 #[cfg(notest)]
 impl T : Eq {
+    #[inline(always)]
     pure fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
+    #[inline(always)]
     pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
 }
 
 impl T: num::Num {
+    #[inline(always)]
     pure fn add(&self, other: &T)    -> T { return *self + *other; }
+    #[inline(always)]
     pure fn sub(&self, other: &T)    -> T { return *self - *other; }
+    #[inline(always)]
     pure fn mul(&self, other: &T)    -> T { return *self * *other; }
+    #[inline(always)]
     pure fn div(&self, other: &T)    -> T { return *self / *other; }
+    #[inline(always)]
     pure fn modulo(&self, other: &T) -> T { return *self % *other; }
+    #[inline(always)]
     pure fn neg(&self)              -> T { return -*self;        }
 
+    #[inline(always)]
     pure fn to_int(&self)         -> int { return *self as int; }
+    #[inline(always)]
     static pure fn from_int(n: int) -> T   { return n as T;      }
 }
 
 impl T: num::Zero {
+    #[inline(always)]
     static pure fn zero() -> T { 0 }
 }
 
 impl T: num::One {
+    #[inline(always)]
     static pure fn one() -> T { 1 }
 }
 
@@ -150,16 +193,19 @@ impl T: iter::Times {
 }
 
 /// Parse a string to an int
+#[inline(always)]
 pub pure fn from_str(s: &str) -> Option<T>
 {
     parse_bytes(str::to_bytes(s), 10u)
 }
 
 impl T : FromStr {
+    #[inline(always)]
     static pure fn from_str(s: &str) -> Option<T> { from_str(s) }
 }
 
 /// Convert to a string in a given base
+#[inline(always)]
 pub pure fn to_str(n: T, radix: uint) -> ~str {
     do to_str_bytes(n, radix) |slice| {
         do vec::as_imm_buf(slice) |p, len| {
@@ -168,6 +214,7 @@ impl T : FromStr {
     }
 }
 
+#[inline(always)]
 pub pure fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
     if n < 0 as T {
         uint::to_str_bytes(true, -n as uint, radix, f)
@@ -177,6 +224,7 @@ impl T : FromStr {
 }
 
 /// Convert to a string
+#[inline(always)]
 pub pure fn str(i: T) -> ~str { return to_str(i, 10u); }
 
 #[test]
index 3effa40bd16077e112ae8c57d2378b959c48078e..da60b567f665afd33ea87eacc18ff28d0d9e85f4 100644 (file)
@@ -12,5 +12,5 @@
 
 mod inst {
     pub type T = i16;
-    pub const bits: uint = u16::bits;
-}
\ No newline at end of file
+    pub const bits: uint = ::u16::bits;
+}
index 710868fcb8da05983b4b83ca2795df9c8a4f5e98..1bc45bb71af7eb0dcc8ca638d7b2a6e60e760e4b 100644 (file)
@@ -12,5 +12,5 @@
 
 mod inst {
     pub type T = i32;
-    pub const bits: uint = u32::bits;
+    pub const bits: uint = ::u32::bits;
 }
index 0612322dab6b0582c4c8bdd84902519220faf73f..83d15aa857d95fa52714e8106f8c2b8153dfd8bf 100644 (file)
@@ -12,5 +12,5 @@
 
 mod inst {
     pub type T = i64;
-    pub const bits: uint = u64::bits;
-}
\ No newline at end of file
+    pub const bits: uint = ::u64::bits;
+}
index 37d7e610566a1af52c7402a4c183c437ace1aa40..740442ed725be7fda7e7e14f951b94bf21d23692 100644 (file)
@@ -12,5 +12,5 @@
 
 mod inst {
     pub type T = i8;
-    pub const bits: uint = u8::bits;
-}
\ No newline at end of file
+    pub const bits: uint = ::u8::bits;
+}
index 61a7c3bd07ab33547a2980d16cbd181c2996abd6..224da0dc062d35dde0376e60184cd5d95cf00fcb 100644 (file)
@@ -14,7 +14,7 @@
 
 mod inst {
     pub type T = int;
-    pub const bits: uint = uint::bits;
+    pub const bits: uint = ::uint::bits;
 
     /// Returns `base` raised to the power of `exponent`
     pub pure fn pow(base: int, exponent: uint) -> int {
@@ -50,8 +50,8 @@ fn test_pow() {
 
     #[test]
     fn test_overflows() {
-        assert (max_value > 0);
-        assert (min_value <= 0);
-        assert (min_value + max_value + 1 == 0);
+        assert (::int::max_value > 0);
+        assert (::int::min_value <= 0);
+        assert (::int::min_value + ::int::max_value + 1 == 0);
     }
 }
index e76eb9f2f99d81265d4e4e1ba54df577b9fa74d7..9b5f271a61121f248c0d6167eeee151932686bfc 100644 (file)
 
 use cmp::Eq;
 use dvec::DVec;
+use int;
+use libc;
 use libc::{c_int, c_long, c_uint, c_void, size_t, ssize_t};
 use libc::consts::os::posix88::*;
 use libc::consts::os::extra::*;
+use option;
+use os;
+use prelude::*;
+use ptr;
+use result;
+use str;
+use uint;
+use vec;
 
 #[allow(non_camel_case_types)] // not sure what to do about this
-type fd_t = c_int;
+pub type fd_t = c_int;
 
 #[abi = "cdecl"]
 extern mod rustrt {
-    fn rust_get_stdin() -> *libc::FILE;
-    fn rust_get_stdout() -> *libc::FILE;
-    fn rust_get_stderr() -> *libc::FILE;
+    unsafe fn rust_get_stdin() -> *libc::FILE;
+    unsafe fn rust_get_stdout() -> *libc::FILE;
+    unsafe fn rust_get_stderr() -> *libc::FILE;
 }
 
 // Reading
@@ -410,22 +420,39 @@ fn convert_whence(whence: SeekStyle) -> i32 {
 
 impl *libc::FILE: Reader {
     fn read(&self, bytes: &[mut u8], len: uint) -> uint {
-        do vec::as_mut_buf(bytes) |buf_p, buf_len| {
-            assert buf_len >= len;
+        unsafe {
+            do vec::as_mut_buf(bytes) |buf_p, buf_len| {
+                assert buf_len >= len;
 
-            let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
-                                    len as size_t, *self);
+                let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
+                                        len as size_t, *self);
 
-            count as uint
+                count as uint
+            }
+        }
+    }
+    fn read_byte(&self) -> int {
+        unsafe {
+            libc::fgetc(*self) as int
+        }
+    }
+    fn eof(&self) -> bool {
+        unsafe {
+            return libc::feof(*self) != 0 as c_int;
         }
     }
-    fn read_byte(&self) -> int { return libc::fgetc(*self) as int; }
-    fn eof(&self) -> bool { return libc::feof(*self) != 0 as c_int; }
     fn seek(&self, offset: int, whence: SeekStyle) {
-        assert libc::fseek(*self, offset as c_long, convert_whence(whence))
-            == 0 as c_int;
+        unsafe {
+            assert libc::fseek(*self,
+                               offset as c_long,
+                               convert_whence(whence)) == 0 as c_int;
+        }
+    }
+    fn tell(&self) -> uint {
+        unsafe {
+            return libc::ftell(*self) as uint;
+        }
     }
-    fn tell(&self) -> uint { return libc::ftell(*self) as uint; }
 }
 
 // A forwarding impl of reader that also holds on to a resource for the
@@ -443,12 +470,16 @@ fn seek(&self, off: int, whence: SeekStyle) {
     fn tell(&self) -> uint { self.base.tell() }
 }
 
-struct FILERes {
+pub struct FILERes {
     f: *libc::FILE,
-    drop { libc::fclose(self.f); }
+    drop {
+        unsafe {
+            libc::fclose(self.f);
+        }
+    }
 }
 
-fn FILERes(f: *libc::FILE) -> FILERes {
+pub fn FILERes(f: *libc::FILE) -> FILERes {
     FILERes {
         f: f
     }
@@ -466,18 +497,24 @@ pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader {
 // top-level functions that take a reader, or a set of default methods on
 // reader (which can then be called reader)
 
-pub fn stdin() -> Reader { rustrt::rust_get_stdin() as Reader }
+pub fn stdin() -> Reader {
+    unsafe {
+        rustrt::rust_get_stdin() as Reader
+    }
+}
 
 pub fn file_reader(path: &Path) -> Result<Reader, ~str> {
-    let f = os::as_c_charp(path.to_str(), |pathbuf| {
-        os::as_c_charp("r", |modebuf|
-            libc::fopen(pathbuf, modebuf)
-        )
-    });
-    return if f as uint == 0u { result::Err(~"error opening "
-                                            + path.to_str()) }
-    else {
-        result::Ok(FILE_reader(f, true))
+    unsafe {
+        let f = os::as_c_charp(path.to_str(), |pathbuf| {
+            os::as_c_charp("r", |modebuf|
+                libc::fopen(pathbuf, modebuf)
+            )
+        });
+        return if f as uint == 0u { result::Err(~"error opening "
+                                                + path.to_str()) }
+        else {
+            result::Ok(FILE_reader(f, true))
+        }
     }
 }
 
@@ -493,7 +530,7 @@ fn read(&self, bytes: &[mut u8], len: uint) -> uint {
         let count = uint::min(len, self.bytes.len() - self.pos);
 
         let view = vec::view(self.bytes, self.pos, self.bytes.len());
-        vec::bytes::memcpy(bytes, view, count);
+        vec::bytes::copy_memory(bytes, view, count);
 
         self.pos += count;
 
@@ -560,25 +597,43 @@ fn get_type(&self) -> WriterType { File }
 
 impl *libc::FILE: Writer {
     fn write(&self, v: &[const u8]) {
-        do vec::as_const_buf(v) |vbuf, len| {
-            let nout = libc::fwrite(vbuf as *c_void, 1, len as size_t, *self);
-            if nout != len as size_t {
-                error!("error writing buffer");
-                log(error, os::last_os_error());
-                fail;
+        unsafe {
+            do vec::as_const_buf(v) |vbuf, len| {
+                let nout = libc::fwrite(vbuf as *c_void,
+                                        1,
+                                        len as size_t,
+                                        *self);
+                if nout != len as size_t {
+                    error!("error writing buffer");
+                    log(error, os::last_os_error());
+                    fail;
+                }
             }
         }
     }
     fn seek(&self, offset: int, whence: SeekStyle) {
-        assert libc::fseek(*self, offset as c_long, convert_whence(whence))
-            == 0 as c_int;
+        unsafe {
+            assert libc::fseek(*self,
+                               offset as c_long,
+                               convert_whence(whence)) == 0 as c_int;
+        }
+    }
+    fn tell(&self) -> uint {
+        unsafe {
+            libc::ftell(*self) as uint
+        }
+    }
+    fn flush(&self) -> int {
+        unsafe {
+            libc::fflush(*self) as int
+        }
     }
-    fn tell(&self) -> uint { libc::ftell(*self) as uint }
-    fn flush(&self) -> int { libc::fflush(*self) as int }
     fn get_type(&self) -> WriterType {
-        let fd = libc::fileno(*self);
-        if libc::isatty(fd) == 0 { File   }
-        else                     { Screen }
+        unsafe {
+            let fd = libc::fileno(*self);
+            if libc::isatty(fd) == 0 { File   }
+            else                     { Screen }
+        }
     }
 }
 
@@ -592,17 +647,19 @@ pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> Writer {
 
 impl fd_t: Writer {
     fn write(&self, v: &[const u8]) {
-        let mut count = 0u;
-        do vec::as_const_buf(v) |vbuf, len| {
-            while count < len {
-                let vb = ptr::const_offset(vbuf, count) as *c_void;
-                let nout = libc::write(*self, vb, len as size_t);
-                if nout < 0 as ssize_t {
-                    error!("error writing buffer");
-                    log(error, os::last_os_error());
-                    fail;
+        unsafe {
+            let mut count = 0u;
+            do vec::as_const_buf(v) |vbuf, len| {
+                while count < len {
+                    let vb = ptr::const_offset(vbuf, count) as *c_void;
+                    let nout = libc::write(*self, vb, len as size_t);
+                    if nout < 0 as ssize_t {
+                        error!("error writing buffer");
+                        log(error, os::last_os_error());
+                        fail;
+                    }
+                    count += nout as uint;
                 }
-                count += nout as uint;
             }
         }
     }
@@ -616,16 +673,22 @@ fn tell(&self) -> uint {
     }
     fn flush(&self) -> int { 0 }
     fn get_type(&self) -> WriterType {
-        if libc::isatty(*self) == 0 { File } else { Screen }
+        unsafe {
+            if libc::isatty(*self) == 0 { File } else { Screen }
+        }
     }
 }
 
-struct FdRes {
+pub struct FdRes {
     fd: fd_t,
-    drop { libc::close(self.fd); }
+    drop {
+        unsafe {
+            libc::close(self.fd);
+        }
+    }
 }
 
-fn FdRes(fd: fd_t) -> FdRes {
+pub fn FdRes(fd: fd_t) -> FdRes {
     FdRes {
         fd: fd
     }
@@ -658,9 +721,11 @@ fn wb() -> c_int { O_WRONLY as c_int }
           NoFlag => ()
         }
     }
-    let fd = do os::as_c_charp(path.to_str()) |pathbuf| {
-        libc::open(pathbuf, fflags,
-                   (S_IRUSR | S_IWUSR) as c_int)
+    let fd = unsafe {
+        do os::as_c_charp(path.to_str()) |pathbuf| {
+            libc::open(pathbuf, fflags,
+                       (S_IRUSR | S_IWUSR) as c_int)
+        }
     };
     if fd < (0 as c_int) {
         result::Err(fmt!("error opening %s: %s", path.to_str(),
@@ -903,14 +968,16 @@ pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<Writer, ~str> {
 
 // FIXME: fileflags // #2004
 pub fn buffered_file_writer(path: &Path) -> Result<Writer, ~str> {
-    let f = do os::as_c_charp(path.to_str()) |pathbuf| {
-        do os::as_c_charp("w") |modebuf| {
-            libc::fopen(pathbuf, modebuf)
-        }
-    };
-    return if f as uint == 0u { result::Err(~"error opening "
-                                            + path.to_str()) }
-    else { result::Ok(FILE_writer(f, true)) }
+    unsafe {
+        let f = do os::as_c_charp(path.to_str()) |pathbuf| {
+            do os::as_c_charp("w") |modebuf| {
+                libc::fopen(pathbuf, modebuf)
+            }
+        };
+        return if f as uint == 0u { result::Err(~"error opening "
+                                                + path.to_str()) }
+        else { result::Ok(FILE_writer(f, true)) }
+    }
 }
 
 // FIXME (#2004) it would be great if this could be a const
@@ -940,7 +1007,7 @@ fn write(&self, v: &[const u8]) {
 
             {
                 let view = vec::mut_view(bytes, self.pos, count);
-                vec::bytes::memcpy(view, v, v_len);
+                vec::bytes::copy_memory(view, v, v_len);
             }
 
             self.pos += v_len;
@@ -1019,6 +1086,12 @@ pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
 // fsync related
 
 pub mod fsync {
+    use io::{FILERes, FdRes, fd_t};
+    use kinds::Copy;
+    use libc;
+    use option::Option;
+    use option;
+    use os;
 
     pub enum Level {
         // whatever fsync does on that platform
@@ -1065,12 +1138,16 @@ pub fn Res<t: Copy>(arg: Arg<t>) -> Res<t>{
     // outer res
     pub fn FILE_res_sync(file: &FILERes, opt_level: Option<Level>,
                          blk: fn(v: Res<*libc::FILE>)) {
-        blk(move Res({
-            val: file.f, opt_level: opt_level,
-            fsync_fn: fn@(file: *libc::FILE, l: Level) -> int {
-                return os::fsync_fd(libc::fileno(file), l) as int;
-            }
-        }));
+        unsafe {
+            blk(move Res({
+                val: file.f, opt_level: opt_level,
+                fsync_fn: fn@(file: *libc::FILE, l: Level) -> int {
+                    unsafe {
+                        return os::fsync_fd(libc::fileno(file), l) as int;
+                    }
+                }
+            }));
+        }
     }
 
     // fsync fd after executing blk
@@ -1101,6 +1178,15 @@ pub fn obj_sync(o: FSyncable, opt_level: Option<Level>,
 
 #[cfg(test)]
 mod tests {
+    use debug;
+    use i32;
+    use io::{BytesWriter, SeekCur, SeekEnd, SeekSet};
+    use io;
+    use path::Path;
+    use result;
+    use str;
+    use u64;
+    use vec;
 
     #[test]
     fn test_simple() {
index 644a0fd76b75491d95d4ab0be593bb8f0a5123f5..942db1c5f292673815c422ff905471ede8d6153c 100644 (file)
 #[forbid(deprecated_pattern)];
 
 use cmp::{Eq, Ord};
+use iter::BaseIter;
+use iter;
+use kinds::Copy;
+use option::Option;
 
 use self::inst::{IMPL_T, EACH, SIZE_HINT};
 
 impl<A> IMPL_T<A>: iter::BaseIter<A> {
+    #[inline(always)]
     pure fn each(&self, blk: fn(v: &A) -> bool) { EACH(self, blk) }
+    #[inline(always)]
     pure fn size_hint(&self) -> Option<uint> { SIZE_HINT(self) }
 }
 
 impl<A> IMPL_T<A>: iter::ExtendedIter<A> {
+    #[inline(always)]
     pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) {
         iter::eachi(self, blk)
     }
+    #[inline(always)]
     pure fn all(&self, blk: fn(&A) -> bool) -> bool {
         iter::all(self, blk)
     }
+    #[inline(always)]
     pure fn any(&self, blk: fn(&A) -> bool) -> bool {
         iter::any(self, blk)
     }
+    #[inline(always)]
     pure fn foldl<B>(&self, b0: B, blk: fn(&B, &A) -> B) -> B {
         iter::foldl(self, move b0, blk)
     }
+    #[inline(always)]
     pure fn position(&self, f: fn(&A) -> bool) -> Option<uint> {
         iter::position(self, f)
     }
+    #[inline(always)]
     pure fn map_to_vec<B>(&self, op: fn(&A) -> B) -> ~[B] {
         iter::map_to_vec(self, op)
     }
+    #[inline(always)]
     pure fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: fn(&A) -> IB)
         -> ~[B] {
         iter::flat_map_to_vec(self, op)
@@ -51,22 +64,29 @@ impl<A> IMPL_T<A>: iter::ExtendedIter<A> {
 }
 
 impl<A: Eq> IMPL_T<A>: iter::EqIter<A> {
+    #[inline(always)]
     pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) }
+    #[inline(always)]
     pure fn count(&self, x: &A) -> uint { iter::count(self, x) }
 }
 
 impl<A: Copy> IMPL_T<A>: iter::CopyableIter<A> {
+    #[inline(always)]
     pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] {
         iter::filter_to_vec(self, pred)
     }
+    #[inline(always)]
     pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) }
+    #[inline(always)]
     pure fn find(&self, f: fn(&A) -> bool) -> Option<A> {
         iter::find(self, f)
     }
 }
 
 impl<A: Copy Ord> IMPL_T<A>: iter::CopyableOrderedIter<A> {
+    #[inline(always)]
     pure fn min(&self) -> A { iter::min(self) }
+    #[inline(always)]
     pure fn max(&self) -> A { iter::max(self) }
 }
 
index ce5f775878cf36f8d74f1e6eac2d8192431f5aef..754b8f8b72fc8b3dec87c88a9017360c7fa05821 100644 (file)
@@ -9,6 +9,11 @@
 // except according to those terms.
 
 mod inst {
+    use dlist;
+    use managed;
+    use option::{Option, Some};
+    use option;
+
     #[allow(non_camel_case_types)]
     pub type IMPL_T<A> = dlist::DList<A>;
 
@@ -42,7 +47,8 @@ mod inst {
         }
     }
 
+    #[inline(always)]
     pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
         Some(self.len())
     }
-}
\ No newline at end of file
+}
index 9b7016c17d5c1dc8db574c87fd644fc24c99e997..af788989e9c0f03d222b12abf908243869a11e79 100644 (file)
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 mod inst {
+    use dvec;
+    use option::{Option, Some};
+
     #[allow(non_camel_case_types)]
     pub type IMPL_T<A> = dvec::DVec<A>;
 
@@ -17,6 +20,7 @@ mod inst {
     *
     * Attempts to access this dvec during iteration will fail.
     */
+    #[inline(always)]
     pub pure fn EACH<A>(self: &IMPL_T<A>, f: fn(v: &A) -> bool) {
         unsafe {
             do self.swap |v| {
@@ -26,7 +30,8 @@ mod inst {
         }
     }
 
+    #[inline(always)]
     pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
         Some(self.len())
     }
-}
\ No newline at end of file
+}
index a3a18a5509a17953f92271c62fbb1396a644303e..986dbf7f3d1862693fbb02a4e9dd41c3c7dec9c8 100644 (file)
@@ -9,9 +9,12 @@
 // except according to those terms.
 
 mod inst {
+    use option::{None, Option, Some};
+
     #[allow(non_camel_case_types)]
     pub type IMPL_T<A> = Option<A>;
 
+    #[inline(always)]
     pub pure fn EACH<A>(self: &IMPL_T<A>, f: fn(v: &A) -> bool) {
         match *self {
             None => (),
@@ -19,10 +22,11 @@ mod inst {
         }
     }
 
+    #[inline(always)]
     pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
         match *self {
             None => Some(0),
             Some(_) => Some(1)
         }
     }
-}
\ No newline at end of file
+}
index a9b3401aa6f2dfc6765f523146b9442e6d4e0387..658e250bc36b482dc52c38addfd18ff8d960ca8a 100644 (file)
@@ -18,6 +18,9 @@
 #[forbid(deprecated_pattern)];
 
 use cmp::{Eq, Ord};
+use kinds::Copy;
+use option::{None, Option, Some};
+use vec;
 
 /// A function used to initialize the elements of a sequence
 pub type InitOp<T> = &fn(uint) -> T;
@@ -77,7 +80,7 @@ pub trait Buildable<A> {
      * # Arguments
      *
      * * size - A hint for an initial size of the sequence
-     * * builder - A function that will construct the sequence. It recieves
+     * * builder - A function that will construct the sequence. It receives
      *             as an argument a function that will push an element
      *             onto the sequence being constructed.
      */
@@ -85,6 +88,7 @@ pub trait Buildable<A> {
                                 builder: fn(push: pure fn(A))) -> self;
 }
 
+#[inline(always)]
 pub pure fn eachi<A,IA:BaseIter<A>>(self: &IA,
                                     blk: fn(uint, &A) -> bool) {
     let mut i = 0;
@@ -94,6 +98,7 @@ pub trait Buildable<A> {
     }
 }
 
+#[inline(always)]
 pub pure fn all<A,IA:BaseIter<A>>(self: &IA,
                                   blk: fn(&A) -> bool) -> bool {
     for self.each |a| {
@@ -102,6 +107,7 @@ pub trait Buildable<A> {
     return true;
 }
 
+#[inline(always)]
 pub pure fn any<A,IA:BaseIter<A>>(self: &IA,
                                   blk: fn(&A) -> bool) -> bool {
     for self.each |a| {
@@ -110,6 +116,7 @@ pub trait Buildable<A> {
     return false;
 }
 
+#[inline(always)]
 pub pure fn filter_to_vec<A:Copy,IA:BaseIter<A>>(
     self: &IA, prd: fn(&A) -> bool) -> ~[A] {
     do vec::build_sized_opt(self.size_hint()) |push| {
@@ -119,6 +126,7 @@ pub trait Buildable<A> {
     }
 }
 
+#[inline(always)]
 pub pure fn map_to_vec<A,B,IA:BaseIter<A>>(self: &IA,
                                            op: fn(&A) -> B)
     -> ~[B] {
@@ -129,6 +137,7 @@ pub trait Buildable<A> {
     }
 }
 
+#[inline(always)]
 pub pure fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(
     self: &IA, op: fn(&A) -> IB) -> ~[B] {
     do vec::build |push| {
@@ -140,6 +149,7 @@ pub trait Buildable<A> {
     }
 }
 
+#[inline(always)]
 pub pure fn foldl<A,B,IA:BaseIter<A>>(self: &IA, b0: B,
                                       blk: fn(&B, &A) -> B)
     -> B {
@@ -150,10 +160,12 @@ pub trait Buildable<A> {
     move b
 }
 
+#[inline(always)]
 pub pure fn to_vec<A:Copy,IA:BaseIter<A>>(self: &IA) -> ~[A] {
     foldl::<A,~[A],IA>(self, ~[], |r, a| vec::append(copy (*r), ~[*a]))
 }
 
+#[inline(always)]
 pub pure fn contains<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> bool {
     for self.each |a| {
         if *a == *x { return true; }
@@ -161,6 +173,7 @@ pub trait Buildable<A> {
     return false;
 }
 
+#[inline(always)]
 pub pure fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
     do foldl(self, 0) |count, value| {
         if *value == *x {
@@ -171,6 +184,7 @@ pub trait Buildable<A> {
     }
 }
 
+#[inline(always)]
 pub pure fn position<A,IA:BaseIter<A>>(self: &IA, f: fn(&A) -> bool)
     -> Option<uint>
 {
@@ -186,6 +200,7 @@ pub trait Buildable<A> {
 // iter interface, such as would provide "reach" in addition to "each". as is,
 // it would have to be implemented with foldr, which is too inefficient.
 
+#[inline(always)]
 pub pure fn repeat(times: uint, blk: fn() -> bool) {
     let mut i = 0;
     while i < times {
@@ -194,6 +209,7 @@ pub trait Buildable<A> {
     }
 }
 
+#[inline(always)]
 pub pure fn min<A:Copy Ord,IA:BaseIter<A>>(self: &IA) -> A {
     match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
         match a {
@@ -208,6 +224,7 @@ pub trait Buildable<A> {
     }
 }
 
+#[inline(always)]
 pub pure fn max<A:Copy Ord,IA:BaseIter<A>>(self: &IA) -> A {
     match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
         match a {
@@ -222,6 +239,7 @@ pub trait Buildable<A> {
     }
 }
 
+#[inline(always)]
 pub pure fn find<A: Copy,IA:BaseIter<A>>(self: &IA,
                                    f: fn(&A) -> bool) -> Option<A> {
     for self.each |i| {
@@ -238,7 +256,7 @@ pub trait Buildable<A> {
  *
  * # Arguments
  *
- * * builder - A function that will construct the sequence. It recieves
+ * * builder - A function that will construct the sequence. It receives
  *             as an argument a function that will push an element
  *             onto the sequence being constructed.
  */
@@ -257,7 +275,7 @@ pub trait Buildable<A> {
  *
  * * size - An option, maybe containing initial size of the sequence
  *          to reserve
- * * builder - A function that will construct the sequence. It recieves
+ * * builder - A function that will construct the sequence. It receives
  *             as an argument a function that will push an element
  *             onto the sequence being constructed.
  */
@@ -266,12 +284,13 @@ pub trait Buildable<A> {
     size: Option<uint>,
     builder: fn(push: pure fn(A))) -> B {
 
-    Buildable::build_sized(size.get_default(4), builder)
+    Buildable::build_sized(size.get_or_default(4), builder)
 }
 
 // Functions that combine iteration and building
 
 /// Apply a function to each element of an iterable and return the results
+#[inline(always)]
 pub fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: &IT, f: fn(&T) -> U)
     -> BU {
     do build_sized_opt(v.size_hint()) |push| {
@@ -287,6 +306,7 @@ pub fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: &IT, f: fn(&T) -> U)
  * Creates a generic sequence of size `n_elts` and initializes the elements
  * to the value returned by the function `op`.
  */
+#[inline(always)]
 pub pure fn from_fn<T,BT: Buildable<T>>(n_elts: uint,
                                         op: InitOp<T>) -> BT {
     do Buildable::build_sized(n_elts) |push| {
@@ -301,6 +321,7 @@ pub fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: &IT, f: fn(&T) -> U)
  * Creates an immutable vector of size `n_elts` and initializes the elements
  * to the value `t`.
  */
+#[inline(always)]
 pub pure fn from_elem<T: Copy,BT: Buildable<T>>(n_elts: uint,
                                                 t: T) -> BT {
     do Buildable::build_sized(n_elts) |push| {
index 80e3a22dcba221f78bfde6aba45758e363d41a20..ecd48fe16bc35c7a0047af944eda8c6dbb53df6c 100644 (file)
 pub use libc::funcs::posix88::unistd::{rmdir, unlink, write};
 
 
-mod types {
+pub mod types {
 
     // Types tend to vary *per architecture* so we pull their definitions out
     // into this module.
@@ -198,12 +198,14 @@ pub mod bsd44 {}
     // Standard types that are scalar but vary by OS and arch.
 
     #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
     pub mod os {
         pub mod common {
             pub mod posix01 {}
         }
 
         #[cfg(target_arch = "x86")]
+        #[cfg(target_arch = "arm")]
         pub mod arch {
             pub mod c95 {
                 pub type c_char = i8;
@@ -230,6 +232,8 @@ pub mod c99 {
                 pub type uintptr_t = uint;
             }
             pub mod posix88 {
+                use prelude::*;
+
                 pub type off_t = i32;
                 pub type dev_t = u64;
                 pub type ino_t = u32;
@@ -241,6 +245,12 @@ pub mod posix88 {
                 pub type ssize_t = i32;
             }
             pub mod posix01 {
+                use libc::types::os::arch::c95::{c_int, c_short, c_long,
+                                                 time_t};
+                use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
+                use libc::types::os::arch::posix88::{mode_t, off_t};
+                use libc::types::os::arch::posix88::{uid_t};
+
                 pub type nlink_t = u32;
                 pub type blksize_t = i32;
                 pub type blkcnt_t = i32;
@@ -310,6 +320,11 @@ pub mod posix88 {
                 pub type ssize_t = i64;
             }
             pub mod posix01 {
+                use libc::types::os::arch::c95::{c_int, c_long, time_t};
+                use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
+                use libc::types::os::arch::posix88::{mode_t, off_t};
+                use libc::types::os::arch::posix88::{uid_t};
+
                 pub type nlink_t = u64;
                 pub type blksize_t = i64;
                 pub type blkcnt_t = i64;
@@ -387,6 +402,12 @@ pub mod posix88 {
                 pub type ssize_t = i64;
             }
             pub mod posix01 {
+                use libc::types::common::c99::{uint8_t, uint32_t, int32_t};
+                use libc::types::os::arch::c95::{c_long, time_t};
+                use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
+                use libc::types::os::arch::posix88::{mode_t, off_t};
+                use libc::types::os::arch::posix88::{uid_t};
+
                 pub type nlink_t = u16;
                 pub type blksize_t = i64;
                 pub type blkcnt_t = i64;
@@ -429,6 +450,11 @@ pub mod extra {
     pub mod os {
         pub mod common {
             pub mod posix01 {
+                use libc::types::os::arch::c95::{c_int, c_short};
+                use libc::types::os::arch::extra::{int64, time64_t};
+                use libc::types::os::arch::posix88::{dev_t, ino_t};
+                use libc::types::os::arch::posix88::mode_t;
+
                 // Note: this is the struct called stat64 in win32. Not stat,
                 // nor stati64.
                 pub struct stat {
@@ -439,7 +465,7 @@ pub struct stat {
                     st_uid: c_short,
                     st_gid: c_short,
                     st_rdev: dev_t,
-                    st_size: int64_t,
+                    st_size: int64,
                     st_atime: time64_t,
                     st_mtime: time64_t,
                     st_ctime: time64_t,
@@ -489,6 +515,12 @@ pub mod posix08 {
             pub mod bsd44 {
             }
             pub mod extra {
+                use libc::types::common::c95::c_void;
+                use libc::types::os::arch::c95::{c_char, c_int, c_uint};
+                use libc::types::os::arch::c95::{c_long, c_ulong};
+                use libc::types::os::arch::c95::{wchar_t};
+                use libc::types::os::arch::c99::{c_ulonglong};
+
                 pub type BOOL = c_int;
                 pub type BYTE = u8;
                 pub type CCHAR = c_char;
@@ -520,6 +552,7 @@ pub mod extra {
                 pub type WORD = u16;
 
                 pub type time64_t = i64;
+                pub type int64 = i64;
             }
         }
     }
@@ -528,33 +561,6 @@ pub mod extra {
     pub mod os {
         pub mod common {
             pub mod posix01 {
-                pub type nlink_t = u16;
-                pub type blksize_t = i64;
-                pub type blkcnt_t = i32;
-                pub struct stat {
-                    st_dev: dev_t,
-                    st_mode: mode_t,
-                    st_nlink: nlink_t,
-                    st_ino: ino_t,
-                    st_uid: uid_t,
-                    st_gid: gid_t,
-                    st_rdev: dev_t,
-                    st_atime: time_t,
-                    st_atime_nsec: c_long,
-                    st_mtime: time_t,
-                    st_mtime_nsec: c_long,
-                    st_ctime: time_t,
-                    st_ctime_nsec: c_long,
-                    st_birthtime: time_t,
-                    st_birthtime_nsec: c_long,
-                    st_size: off_t,
-                    st_blocks: blkcnt_t,
-                    st_blksize: blksize_t,
-                    st_flags: uint32_t,
-                    st_gen: uint32_t,
-                    st_lspare: int32_t,
-                    st_qspare: [int64_t * 2],
-                }
             }
         }
 
@@ -596,6 +602,39 @@ pub mod posix88 {
                 pub type ssize_t = i32;
             }
             pub mod posix01 {
+                use libc::types::common::c99::{int32_t, int64_t, uint32_t};
+                use libc::types::os::arch::c95::{c_long, time_t};
+                use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t,
+                                                     mode_t, off_t, uid_t};
+
+                pub type nlink_t = u16;
+                pub type blksize_t = i64;
+                pub type blkcnt_t = i32;
+
+                pub struct stat {
+                    st_dev: dev_t,
+                    st_mode: mode_t,
+                    st_nlink: nlink_t,
+                    st_ino: ino_t,
+                    st_uid: uid_t,
+                    st_gid: gid_t,
+                    st_rdev: dev_t,
+                    st_atime: time_t,
+                    st_atime_nsec: c_long,
+                    st_mtime: time_t,
+                    st_mtime_nsec: c_long,
+                    st_ctime: time_t,
+                    st_ctime_nsec: c_long,
+                    st_birthtime: time_t,
+                    st_birthtime_nsec: c_long,
+                    st_size: off_t,
+                    st_blocks: blkcnt_t,
+                    st_blksize: blksize_t,
+                    st_flags: uint32_t,
+                    st_gen: uint32_t,
+                    st_lspare: int32_t,
+                    st_qspare: [int64_t * 2],
+                }
             }
             pub mod posix08 {
             }
@@ -643,6 +682,40 @@ pub mod posix88 {
                 pub type ssize_t = i64;
             }
             pub mod posix01 {
+                use libc::types::common::c99::{int32_t, int64_t};
+                use libc::types::common::c99::{uint32_t};
+                use libc::types::os::arch::c95::{c_long, time_t};
+                use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
+                use libc::types::os::arch::posix88::{mode_t, off_t, uid_t};
+
+                pub type nlink_t = u16;
+                pub type blksize_t = i64;
+                pub type blkcnt_t = i32;
+
+                pub struct stat {
+                    st_dev: dev_t,
+                    st_mode: mode_t,
+                    st_nlink: nlink_t,
+                    st_ino: ino_t,
+                    st_uid: uid_t,
+                    st_gid: gid_t,
+                    st_rdev: dev_t,
+                    st_atime: time_t,
+                    st_atime_nsec: c_long,
+                    st_mtime: time_t,
+                    st_mtime_nsec: c_long,
+                    st_ctime: time_t,
+                    st_ctime_nsec: c_long,
+                    st_birthtime: time_t,
+                    st_birthtime_nsec: c_long,
+                    st_size: off_t,
+                    st_blocks: blkcnt_t,
+                    st_blksize: blksize_t,
+                    st_flags: uint32_t,
+                    st_gen: uint32_t,
+                    st_lspare: int32_t,
+                    st_qspare: [int64_t * 2],
+                }
             }
             pub mod posix08 {
             }
@@ -726,6 +799,7 @@ pub mod extra {
 
 
     #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
     pub mod os {
         pub mod c95 {
             pub const EXIT_FAILURE : int = 1;
@@ -934,119 +1008,126 @@ pub mod funcs {
     // or anything. The same is not true of POSIX.
 
     pub mod c95 {
+        use libc::types::common::c95::{FILE, c_void, fpos_t};
+        use libc::types::common::posix88::dirent_t;
+        use libc::types::os::arch::c95::{c_char, c_double, c_int, c_long};
+        use libc::types::os::arch::c95::{c_uint, c_ulong, c_void, size_t};
+
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod ctype {
-            fn isalnum(c: c_int) -> c_int;
-            fn isalpha(c: c_int) -> c_int;
-            fn iscntrl(c: c_int) -> c_int;
-            fn isdigit(c: c_int) -> c_int;
-            fn isgraph(c: c_int) -> c_int;
-            fn islower(c: c_int) -> c_int;
-            fn isprint(c: c_int) -> c_int;
-            fn ispunct(c: c_int) -> c_int;
-            fn isspace(c: c_int) -> c_int;
-            fn isupper(c: c_int) -> c_int;
-            fn isxdigit(c: c_int) -> c_int;
-            fn tolower(c: c_char) -> c_char;
-            fn toupper(c: c_char) -> c_char;
+            unsafe fn isalnum(c: c_int) -> c_int;
+            unsafe fn isalpha(c: c_int) -> c_int;
+            unsafe fn iscntrl(c: c_int) -> c_int;
+            unsafe fn isdigit(c: c_int) -> c_int;
+            unsafe fn isgraph(c: c_int) -> c_int;
+            unsafe fn islower(c: c_int) -> c_int;
+            unsafe fn isprint(c: c_int) -> c_int;
+            unsafe fn ispunct(c: c_int) -> c_int;
+            unsafe fn isspace(c: c_int) -> c_int;
+            unsafe fn isupper(c: c_int) -> c_int;
+            unsafe fn isxdigit(c: c_int) -> c_int;
+            unsafe fn tolower(c: c_char) -> c_char;
+            unsafe fn toupper(c: c_char) -> c_char;
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod stdio {
-            fn fopen(filename: *c_char, mode: *c_char) -> *FILE;
-            fn freopen(filename: *c_char, mode: *c_char,
+            unsafe fn fopen(filename: *c_char, mode: *c_char) -> *FILE;
+            unsafe fn freopen(filename: *c_char, mode: *c_char,
                        file: *FILE) -> *FILE;
-            fn fflush(file: *FILE) -> c_int;
-            fn fclose(file: *FILE) -> c_int;
-            fn remove(filename: *c_char) -> c_int;
-            fn rename(oldname: *c_char, newname: *c_char) -> c_int;
-            fn tmpfile() -> *FILE;
-            fn setvbuf(stream: *FILE, buffer: *c_char,
+            unsafe fn fflush(file: *FILE) -> c_int;
+            unsafe fn fclose(file: *FILE) -> c_int;
+            unsafe fn remove(filename: *c_char) -> c_int;
+            unsafe fn rename(oldname: *c_char, newname: *c_char) -> c_int;
+            unsafe fn tmpfile() -> *FILE;
+            unsafe fn setvbuf(stream: *FILE, buffer: *c_char,
                        mode: c_int, size: size_t) -> c_int;
-            fn setbuf(stream: *FILE, buf: *c_char);
+            unsafe fn setbuf(stream: *FILE, buf: *c_char);
             // Omitted: printf and scanf variants.
-            fn fgetc(stream: *FILE) -> c_int;
-            fn fgets(buf: *mut c_char, n: c_int,
+            unsafe fn fgetc(stream: *FILE) -> c_int;
+            unsafe fn fgets(buf: *mut c_char, n: c_int,
                      stream: *FILE) -> *c_char;
-            fn fputc(c: c_int, stream: *FILE) -> c_int;
-            fn fputs(s: *c_char, stream: *FILE) -> *c_char;
+            unsafe fn fputc(c: c_int, stream: *FILE) -> c_int;
+            unsafe fn fputs(s: *c_char, stream: *FILE) -> *c_char;
             // Omitted: getc, getchar (might be macros).
 
             // Omitted: gets, so ridiculously unsafe that it should not
             // survive.
 
             // Omitted: putc, putchar (might be macros).
-            fn puts(s: *c_char) -> c_int;
-            fn ungetc(c: c_int, stream: *FILE) -> c_int;
-            fn fread(ptr: *mut c_void, size: size_t,
+            unsafe fn puts(s: *c_char) -> c_int;
+            unsafe fn ungetc(c: c_int, stream: *FILE) -> c_int;
+            unsafe fn fread(ptr: *mut c_void, size: size_t,
                      nobj: size_t, stream: *FILE) -> size_t;
-            fn fwrite(ptr: *c_void, size: size_t,
+            unsafe fn fwrite(ptr: *c_void, size: size_t,
                       nobj: size_t, stream: *FILE) -> size_t;
-            fn fseek(stream: *FILE, offset: c_long,
+            unsafe fn fseek(stream: *FILE, offset: c_long,
                      whence: c_int) -> c_int;
-            fn ftell(stream: *FILE) -> c_long;
-            fn rewind(stream: *FILE);
-            fn fgetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
-            fn fsetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
-            fn feof(stream: *FILE) -> c_int;
-            fn ferror(stream: *FILE) -> c_int;
-            fn perror(s: *c_char);
+            unsafe fn ftell(stream: *FILE) -> c_long;
+            unsafe fn rewind(stream: *FILE);
+            unsafe fn fgetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
+            unsafe fn fsetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
+            unsafe fn feof(stream: *FILE) -> c_int;
+            unsafe fn ferror(stream: *FILE) -> c_int;
+            unsafe fn perror(s: *c_char);
         }
 
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod stdlib {
-            fn abs(i: c_int) -> c_int;
-            fn labs(i: c_long) -> c_long;
+            unsafe fn abs(i: c_int) -> c_int;
+            unsafe fn labs(i: c_long) -> c_long;
             // Omitted: div, ldiv (return pub type incomplete).
-            fn atof(s: *c_char) -> c_double;
-            fn atoi(s: *c_char) -> c_int;
-            fn strtod(s: *c_char, endp: **c_char) -> c_double;
-            fn strtol(s: *c_char, endp: **c_char, base: c_int) -> c_long;
-            fn strtoul(s: *c_char, endp: **c_char,
-                       base: c_int) -> c_ulong;
-            fn calloc(nobj: size_t, size: size_t) -> *c_void;
-            fn malloc(size: size_t) -> *c_void;
-            fn realloc(p: *c_void, size: size_t) -> *c_void;
-            fn free(p: *c_void);
-            fn abort() -> !;
-            fn exit(status: c_int) -> !;
+            unsafe fn atof(s: *c_char) -> c_double;
+            unsafe fn atoi(s: *c_char) -> c_int;
+            unsafe fn strtod(s: *c_char, endp: **c_char) -> c_double;
+            unsafe fn strtol(s: *c_char, endp: **c_char, base: c_int)
+                          -> c_long;
+            unsafe fn strtoul(s: *c_char, endp: **c_char, base: c_int)
+                           -> c_ulong;
+            unsafe fn calloc(nobj: size_t, size: size_t) -> *c_void;
+            unsafe fn malloc(size: size_t) -> *c_void;
+            unsafe fn realloc(p: *c_void, size: size_t) -> *c_void;
+            unsafe fn free(p: *c_void);
+            unsafe fn abort() -> !;
+            unsafe fn exit(status: c_int) -> !;
             // Omitted: atexit.
-            fn system(s: *c_char) -> c_int;
-            fn getenv(s: *c_char) -> *c_char;
+            unsafe fn system(s: *c_char) -> c_int;
+            unsafe fn getenv(s: *c_char) -> *c_char;
             // Omitted: bsearch, qsort
-            fn rand() -> c_int;
-            fn srand(seed: c_uint);
+            unsafe fn rand() -> c_int;
+            unsafe fn srand(seed: c_uint);
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod string {
-            fn strcpy(dst: *c_char, src: *c_char) -> *c_char;
-            fn strncpy(dst: *c_char, src: *c_char, n: size_t) -> *c_char;
-            fn strcat(s: *c_char, ct: *c_char) -> *c_char;
-            fn strncat(s: *c_char, ct: *c_char, n: size_t) -> *c_char;
-            fn strcmp(cs: *c_char, ct: *c_char) -> c_int;
-            fn strncmp(cs: *c_char, ct: *c_char, n: size_t) -> c_int;
-            fn strcoll(cs: *c_char, ct: *c_char) -> c_int;
-            fn strchr(cs: *c_char, c: c_int) -> *c_char;
-            fn strrchr(cs: *c_char, c: c_int) -> *c_char;
-            fn strspn(cs: *c_char, ct: *c_char) -> size_t;
-            fn strcspn(cs: *c_char, ct: *c_char) -> size_t;
-            fn strpbrk(cs: *c_char, ct: *c_char) -> *c_char;
-            fn strstr(cs: *c_char, ct: *c_char) -> *c_char;
-            fn strlen(cs: *c_char) -> size_t;
-            fn strerror(n: c_int) -> *c_char;
-            fn strtok(s: *c_char, t: *c_char) -> *c_char;
-            fn strxfrm(s: *c_char, ct: *c_char, n: size_t) -> size_t;
-            fn memcpy(s: *c_void, ct: *c_void, n: size_t) -> *c_void;
-            fn memmove(s: *c_void, ct: *c_void, n: size_t) -> *c_void;
-            fn memcmp(cx: *c_void, ct: *c_void, n: size_t) -> c_int;
-            fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void;
-            fn memset(s: *c_void, c: c_int, n: size_t) -> *c_void;
+            unsafe fn strcpy(dst: *c_char, src: *c_char) -> *c_char;
+            unsafe fn strncpy(dst: *c_char, src: *c_char, n: size_t)
+                           -> *c_char;
+            unsafe fn strcat(s: *c_char, ct: *c_char) -> *c_char;
+            unsafe fn strncat(s: *c_char, ct: *c_char, n: size_t) -> *c_char;
+            unsafe fn strcmp(cs: *c_char, ct: *c_char) -> c_int;
+            unsafe fn strncmp(cs: *c_char, ct: *c_char, n: size_t) -> c_int;
+            unsafe fn strcoll(cs: *c_char, ct: *c_char) -> c_int;
+            unsafe fn strchr(cs: *c_char, c: c_int) -> *c_char;
+            unsafe fn strrchr(cs: *c_char, c: c_int) -> *c_char;
+            unsafe fn strspn(cs: *c_char, ct: *c_char) -> size_t;
+            unsafe fn strcspn(cs: *c_char, ct: *c_char) -> size_t;
+            unsafe fn strpbrk(cs: *c_char, ct: *c_char) -> *c_char;
+            unsafe fn strstr(cs: *c_char, ct: *c_char) -> *c_char;
+            unsafe fn strlen(cs: *c_char) -> size_t;
+            unsafe fn strerror(n: c_int) -> *c_char;
+            unsafe fn strtok(s: *c_char, t: *c_char) -> *c_char;
+            unsafe fn strxfrm(s: *c_char, ct: *c_char, n: size_t) -> size_t;
+            unsafe fn memcpy(s: *c_void, ct: *c_void, n: size_t) -> *c_void;
+            unsafe fn memmove(s: *c_void, ct: *c_void, n: size_t) -> *c_void;
+            unsafe fn memcmp(cx: *c_void, ct: *c_void, n: size_t) -> c_int;
+            unsafe fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void;
+            unsafe fn memset(s: *c_void, c: c_int, n: size_t) -> *c_void;
         }
     }
 
@@ -1061,43 +1142,51 @@ pub mod posix88 {
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod stat_ {
+            use libc::types::os::common::posix01::stat;
+            use libc::types::os::arch::c95::{c_int, c_char};
+
             #[link_name = "_chmod"]
-            fn chmod(path: *c_char, mode: c_int) -> c_int;
+            unsafe fn chmod(path: *c_char, mode: c_int) -> c_int;
 
             #[link_name = "_mkdir"]
-            fn mkdir(path: *c_char) -> c_int;
+            unsafe fn mkdir(path: *c_char) -> c_int;
 
             #[link_name = "_fstat64"]
-            fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
+            unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
 
             #[link_name = "_stat64"]
-            fn stat(path: *c_char, buf: *mut stat) -> c_int;
+            unsafe fn stat(path: *c_char, buf: *mut stat) -> c_int;
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod stdio {
+            use libc::types::common::c95::FILE;
+            use libc::types::os::arch::c95::{c_int, c_char};
+
             #[link_name = "_popen"]
-            fn popen(command: *c_char, mode: *c_char) -> *FILE;
+            unsafe fn popen(command: *c_char, mode: *c_char) -> *FILE;
 
             #[link_name = "_pclose"]
-            fn pclose(stream: *FILE) -> c_int;
+            unsafe fn pclose(stream: *FILE) -> c_int;
 
             #[link_name = "_fdopen"]
-            fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
+            unsafe fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
 
             #[link_name = "_fileno"]
-            fn fileno(stream: *FILE) -> c_int;
+            unsafe fn fileno(stream: *FILE) -> c_int;
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod fcntl {
+            use libc::types::os::arch::c95::{c_int, c_char};
+
             #[link_name = "_open"]
-            fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
+            unsafe fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
 
             #[link_name = "_creat"]
-            fn creat(path: *c_char, mode: c_int) -> c_int;
+            unsafe fn creat(path: *c_char, mode: c_int) -> c_int;
         }
 
         #[nolink]
@@ -1109,212 +1198,241 @@ pub mod posix88 {
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod unistd {
+            use libc::types::common::c95::c_void;
+            use libc::types::os::arch::c95::{c_int, c_uint, c_char,
+                                             c_long, size_t};
+            use libc::types::os::arch::c99::intptr_t;
+
             #[link_name = "_access"]
-            fn access(path: *c_char, amode: c_int) -> c_int;
+            unsafe fn access(path: *c_char, amode: c_int) -> c_int;
 
             #[link_name = "_chdir"]
-            fn chdir(dir: *c_char) -> c_int;
+            unsafe fn chdir(dir: *c_char) -> c_int;
 
             #[link_name = "_close"]
-            fn close(fd: c_int) -> c_int;
+            unsafe fn close(fd: c_int) -> c_int;
 
             #[link_name = "_dup"]
-            fn dup(fd: c_int) -> c_int;
+            unsafe fn dup(fd: c_int) -> c_int;
 
             #[link_name = "_dup2"]
-            fn dup2(src: c_int, dst: c_int) -> c_int;
+            unsafe fn dup2(src: c_int, dst: c_int) -> c_int;
 
             #[link_name = "_execv"]
-            fn execv(prog: *c_char, argv: **c_char) -> intptr_t;
+            unsafe fn execv(prog: *c_char, argv: **c_char) -> intptr_t;
 
             #[link_name = "_execve"]
-            fn execve(prog: *c_char, argv: **c_char,
+            unsafe fn execve(prog: *c_char, argv: **c_char,
                       envp: **c_char) -> c_int;
 
             #[link_name = "_execvp"]
-            fn execvp(c: *c_char, argv: **c_char) -> c_int;
+            unsafe fn execvp(c: *c_char, argv: **c_char) -> c_int;
 
             #[link_name = "_execvpe"]
-            fn execvpe(c: *c_char, argv: **c_char,
+            unsafe fn execvpe(c: *c_char, argv: **c_char,
                        envp: **c_char) -> c_int;
 
             #[link_name = "_getcwd"]
-            fn getcwd(buf: *c_char, size: size_t) -> *c_char;
+            unsafe fn getcwd(buf: *c_char, size: size_t) -> *c_char;
 
             #[link_name = "_getpid"]
-            fn getpid() -> c_int;
+            unsafe fn getpid() -> c_int;
 
             #[link_name = "_isatty"]
-            fn isatty(fd: c_int) -> c_int;
+            unsafe fn isatty(fd: c_int) -> c_int;
 
             #[link_name = "_lseek"]
-            fn lseek(fd: c_int, offset: c_long, origin: c_int) -> c_long;
+            unsafe fn lseek(fd: c_int, offset: c_long, origin: c_int)
+                         -> c_long;
 
             #[link_name = "_pipe"]
-            fn pipe(fds: *mut c_int, psize: c_uint,
+            unsafe fn pipe(fds: *mut c_int, psize: c_uint,
                     textmode: c_int) -> c_int;
 
             #[link_name = "_read"]
-            fn read(fd: c_int, buf: *mut c_void, count: c_uint) -> c_int;
+            unsafe fn read(fd: c_int, buf: *mut c_void, count: c_uint)
+                        -> c_int;
 
             #[link_name = "_rmdir"]
-            fn rmdir(path: *c_char) -> c_int;
+            unsafe fn rmdir(path: *c_char) -> c_int;
 
             #[link_name = "_unlink"]
-            fn unlink(c: *c_char) -> c_int;
+            unsafe fn unlink(c: *c_char) -> c_int;
 
             #[link_name = "_write"]
-            fn write(fd: c_int, buf: *c_void, count: c_uint) -> c_int;
+            unsafe fn write(fd: c_int, buf: *c_void, count: c_uint) -> c_int;
 
         }
     }
 
 
     #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
     #[cfg(target_os = "macos")]
     #[cfg(target_os = "freebsd")]
     pub mod posix88 {
+        use libc::types::common::c95::{FILE, c_void};
+        use libc::types::common::posix88::{DIR, dirent_t};
+        use libc::types::os::arch::c95::{c_char, c_int, c_long, c_uint};
+        use libc::types::os::arch::c95::{size_t};
+        use libc::types::os::arch::posix01::stat;
+        use libc::types::os::arch::posix88::{gid_t, mode_t, off_t, pid_t};
+        use libc::types::os::arch::posix88::{ssize_t, uid_t};
+
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod stat_ {
-            fn chmod(path: *c_char, mode: mode_t) -> c_int;
-            fn fchmod(fd: c_int, mode: mode_t) -> c_int;
+            unsafe fn chmod(path: *c_char, mode: mode_t) -> c_int;
+            unsafe fn fchmod(fd: c_int, mode: mode_t) -> c_int;
 
             #[cfg(target_os = "linux")]
             #[cfg(target_os = "freebsd")]
-            fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
+            #[cfg(target_os = "android")]
+           unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
 
             #[cfg(target_os = "macos")]
             #[link_name = "fstat64"]
-            fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
+            unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
 
-            fn mkdir(path: *c_char, mode: mode_t) -> c_int;
-            fn mkfifo(path: *c_char, mode: mode_t) -> c_int;
+            unsafe fn mkdir(path: *c_char, mode: mode_t) -> c_int;
+            unsafe fn mkfifo(path: *c_char, mode: mode_t) -> c_int;
 
             #[cfg(target_os = "linux")]
             #[cfg(target_os = "freebsd")]
-            fn stat(path: *c_char, buf: *mut stat) -> c_int;
+            #[cfg(target_os = "android")]
+            unsafe fn stat(path: *c_char, buf: *mut stat) -> c_int;
 
             #[cfg(target_os = "macos")]
             #[link_name = "stat64"]
-            fn stat(path: *c_char, buf: *mut stat) -> c_int;
+            unsafe fn stat(path: *c_char, buf: *mut stat) -> c_int;
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod stdio {
-            fn popen(command: *c_char, mode: *c_char) -> *FILE;
-            fn pclose(stream: *FILE) -> c_int;
-            fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
-            fn fileno(stream: *FILE) -> c_int;
+            unsafe fn popen(command: *c_char, mode: *c_char) -> *FILE;
+            unsafe fn pclose(stream: *FILE) -> c_int;
+            unsafe fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
+            unsafe fn fileno(stream: *FILE) -> c_int;
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod fcntl {
-            fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
-            fn creat(path: *c_char, mode: mode_t) -> c_int;
-            fn fcntl(fd: c_int, cmd: c_int) -> c_int;
+            unsafe fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
+            unsafe fn creat(path: *c_char, mode: mode_t) -> c_int;
+            unsafe fn fcntl(fd: c_int, cmd: c_int) -> c_int;
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod dirent {
-            fn opendir(dirname: *c_char) -> *DIR;
-            fn closedir(dirp: *DIR) -> c_int;
-            fn readdir(dirp: *DIR) -> *dirent_t;
-            fn rewinddir(dirp: *DIR);
-            fn seekdir(dirp: *DIR, loc: c_long);
-            fn telldir(dirp: *DIR) -> c_long;
+            unsafe fn opendir(dirname: *c_char) -> *DIR;
+            unsafe fn closedir(dirp: *DIR) -> c_int;
+            unsafe fn readdir(dirp: *DIR) -> *dirent_t;
+            unsafe fn rewinddir(dirp: *DIR);
+            unsafe fn seekdir(dirp: *DIR, loc: c_long);
+            unsafe fn telldir(dirp: *DIR) -> c_long;
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod unistd {
-            fn access(path: *c_char, amode: c_int) -> c_int;
-            fn alarm(seconds: c_uint) -> c_uint;
-            fn chdir(dir: *c_char) -> c_int;
-            fn chown(path: *c_char, uid: uid_t, gid: gid_t) -> c_int;
-            fn close(fd: c_int) -> c_int;
-            fn dup(fd: c_int) -> c_int;
-            fn dup2(src: c_int, dst: c_int) -> c_int;
-            fn execv(prog: *c_char, argv: **c_char) -> c_int;
-            fn execve(prog: *c_char, argv: **c_char,
-                      envp: **c_char) -> c_int;
-            fn execvp(c: *c_char, argv: **c_char) -> c_int;
-            fn fork() -> pid_t;
-            fn fpathconf(filedes: c_int, name: c_int) -> c_long;
-            fn getcwd(buf: *c_char, size: size_t) -> *c_char;
-            fn getegid() -> gid_t;
-            fn geteuid() -> uid_t;
-            fn getgid() -> gid_t ;
-            fn getgroups(ngroups_max: c_int, groups: *mut gid_t) -> c_int;
-            fn getlogin() -> *c_char;
-            fn getopt(argc: c_int, argv: **c_char,
-                      optstr: *c_char) -> c_int;
-            fn getpgrp() -> pid_t;
-            fn getpid() -> pid_t;
-            fn getppid() -> pid_t;
-            fn getuid() -> uid_t;
-            fn isatty(fd: c_int) -> c_int;
-            fn link(src: *c_char, dst: *c_char) -> c_int;
-            fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t;
-            fn pathconf(path: *c_char, name: c_int) -> c_long;
-            fn pause() -> c_int;
-            fn pipe(fds: *mut c_int) -> c_int;
-            fn read(fd: c_int, buf: *mut c_void,
+            unsafe fn access(path: *c_char, amode: c_int) -> c_int;
+            unsafe fn alarm(seconds: c_uint) -> c_uint;
+            unsafe fn chdir(dir: *c_char) -> c_int;
+            unsafe fn chown(path: *c_char, uid: uid_t, gid: gid_t) -> c_int;
+            unsafe fn close(fd: c_int) -> c_int;
+            unsafe fn dup(fd: c_int) -> c_int;
+            unsafe fn dup2(src: c_int, dst: c_int) -> c_int;
+            unsafe fn execv(prog: *c_char, argv: **c_char) -> c_int;
+            unsafe fn execve(prog: *c_char, argv: **c_char, envp: **c_char)
+                          -> c_int;
+            unsafe fn execvp(c: *c_char, argv: **c_char) -> c_int;
+            unsafe fn fork() -> pid_t;
+            unsafe fn fpathconf(filedes: c_int, name: c_int) -> c_long;
+            unsafe fn getcwd(buf: *c_char, size: size_t) -> *c_char;
+            unsafe fn getegid() -> gid_t;
+            unsafe fn geteuid() -> uid_t;
+            unsafe fn getgid() -> gid_t ;
+            unsafe fn getgroups(ngroups_max: c_int, groups: *mut gid_t)
+                             -> c_int;
+            unsafe fn getlogin() -> *c_char;
+            unsafe fn getopt(argc: c_int, argv: **c_char, optstr: *c_char)
+                          -> c_int;
+            unsafe fn getpgrp() -> pid_t;
+            unsafe fn getpid() -> pid_t;
+            unsafe fn getppid() -> pid_t;
+            unsafe fn getuid() -> uid_t;
+            unsafe fn isatty(fd: c_int) -> c_int;
+            unsafe fn link(src: *c_char, dst: *c_char) -> c_int;
+            unsafe fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t;
+            unsafe fn pathconf(path: *c_char, name: c_int) -> c_long;
+            unsafe fn pause() -> c_int;
+            unsafe fn pipe(fds: *mut c_int) -> c_int;
+            unsafe fn read(fd: c_int, buf: *mut c_void,
                     count: size_t) -> ssize_t;
-            fn rmdir(path: *c_char) -> c_int;
-            fn setgid(gid: gid_t) -> c_int;
-            fn setpgid(pid: pid_t, pgid: pid_t) -> c_int;
-            fn setsid() -> pid_t;
-            fn setuid(uid: uid_t) -> c_int;
-            fn sleep(secs: c_uint) -> c_uint;
-            fn sysconf(name: c_int) -> c_long;
-            fn tcgetpgrp(fd: c_int) -> pid_t;
-            fn ttyname(fd: c_int) -> *c_char;
-            fn unlink(c: *c_char) -> c_int;
-            fn write(fd: c_int, buf: *c_void, count: size_t) -> ssize_t;
+            unsafe fn rmdir(path: *c_char) -> c_int;
+            unsafe fn setgid(gid: gid_t) -> c_int;
+            unsafe fn setpgid(pid: pid_t, pgid: pid_t) -> c_int;
+            unsafe fn setsid() -> pid_t;
+            unsafe fn setuid(uid: uid_t) -> c_int;
+            unsafe fn sleep(secs: c_uint) -> c_uint;
+            unsafe fn sysconf(name: c_int) -> c_long;
+            unsafe fn tcgetpgrp(fd: c_int) -> pid_t;
+            unsafe fn ttyname(fd: c_int) -> *c_char;
+            unsafe fn unlink(c: *c_char) -> c_int;
+            unsafe fn write(fd: c_int, buf: *c_void, count: size_t)
+                         -> ssize_t;
         }
     }
 
     #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
     #[cfg(target_os = "macos")]
     #[cfg(target_os = "freebsd")]
     pub mod posix01 {
+        use libc::types::os::arch::c95::{c_char, c_int, size_t};
+        use libc::types::os::arch::posix01::stat;
+        use libc::types::os::arch::posix88::{pid_t, ssize_t};
+
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod stat_ {
             #[cfg(target_os = "linux")]
             #[cfg(target_os = "freebsd")]
-            fn lstat(path: *c_char, buf: *mut stat) -> c_int;
+            #[cfg(target_os = "android")]
+            unsafe fn lstat(path: *c_char, buf: *mut stat) -> c_int;
 
             #[cfg(target_os = "macos")]
             #[link_name = "lstat64"]
-            fn lstat(path: *c_char, buf: *mut stat) -> c_int;
+            unsafe fn lstat(path: *c_char, buf: *mut stat) -> c_int;
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod unistd {
-            fn readlink(path: *c_char, buf: *mut c_char,
+            unsafe fn readlink(path: *c_char, buf: *mut c_char,
                         bufsz: size_t) -> ssize_t;
 
-            fn fsync(fd: c_int) -> c_int;
+            unsafe fn fsync(fd: c_int) -> c_int;
 
             #[cfg(target_os = "linux")]
-            fn fdatasync(fd: c_int) -> c_int;
+            #[cfg(target_os = "android")]
+            unsafe fn fdatasync(fd: c_int) -> c_int;
 
-            fn setenv(name: *c_char, val: *c_char,
+            unsafe fn setenv(name: *c_char, val: *c_char,
                       overwrite: c_int) -> c_int;
-            fn unsetenv(name: *c_char) -> c_int;
-            fn putenv(string: *c_char) -> c_int;
+            unsafe fn unsetenv(name: *c_char) -> c_int;
+            unsafe fn putenv(string: *c_char) -> c_int;
+
+            unsafe fn symlink(path1: *c_char, path2: *c_char) -> c_int;
         }
 
         #[nolink]
         #[abi = "cdecl"]
         pub extern mod wait {
-            fn waitpid(pid: pid_t, status: *mut c_int,
+            unsafe fn waitpid(pid: pid_t, status: *mut c_int,
                        options: c_int) -> pid_t;
         }
     }
@@ -1333,6 +1451,7 @@ pub mod posix01 {
 
     #[cfg(target_os = "win32")]
     #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
     #[cfg(target_os = "macos")]
     #[cfg(target_os = "freebsd")]
     pub mod posix08 {
@@ -1347,30 +1466,35 @@ pub mod posix08 {
     #[nolink]
     #[abi = "cdecl"]
     pub extern mod bsd44 {
-        fn sysctl(name: *c_int, namelen: c_uint,
+        use libc::types::common::c95::{c_void};
+        use libc::types::os::arch::c95::{c_char, c_int, c_uint, size_t};
+
+        unsafe fn sysctl(name: *c_int, namelen: c_uint,
                   oldp: *mut c_void, oldlenp: *mut size_t,
                   newp: *c_void, newlen: size_t) -> c_int;
 
-        fn sysctlbyname(name: *c_char,
+        unsafe fn sysctlbyname(name: *c_char,
                         oldp: *mut c_void, oldlenp: *mut size_t,
                         newp: *c_void, newlen: size_t) -> c_int;
 
-        fn sysctlnametomib(name: *c_char, mibp: *mut c_int,
+        unsafe fn sysctlnametomib(name: *c_char, mibp: *mut c_int,
                            sizep: *mut size_t) -> c_int;
     }
 
 
     #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
     #[cfg(target_os = "win32")]
     pub mod bsd44 {
     }
 
-
     #[cfg(target_os = "macos")]
     #[nolink]
     #[abi = "cdecl"]
     pub extern mod extra {
-        fn _NSGetExecutablePath(buf: *mut c_char,
+        use libc::types::os::arch::c95::{c_char, c_int};
+
+        unsafe fn _NSGetExecutablePath(buf: *mut c_char,
                                 bufsize: *mut u32) -> c_int;
     }
 
@@ -1379,40 +1503,45 @@ pub mod extra {
     }
 
     #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
     pub mod extra {
     }
 
 
     #[cfg(target_os = "win32")]
     pub mod extra {
+        use libc::types::os::arch::c95::c_int;
+        use libc::types::os::arch::extra::{DWORD, HMODULE, LPCWSTR, LPWSTR};
+        use libc::types::os::arch::extra::{BOOL, LPSECURITY_ATTRIBUTES};
+
         #[abi = "stdcall"]
         pub extern mod kernel32 {
-            fn GetEnvironmentVariableW(n: LPCWSTR,
+            unsafe fn GetEnvironmentVariableW(n: LPCWSTR,
                                        v: LPWSTR,
                                        nsize: DWORD) -> DWORD;
-            fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL;
+            unsafe fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL;
 
-            fn GetModuleFileNameW(hModule: HMODULE,
+            unsafe fn GetModuleFileNameW(hModule: HMODULE,
                                   lpFilename: LPWSTR,
                                   nSize: DWORD) -> DWORD;
-            fn CreateDirectoryW(lpPathName: LPCWSTR,
+            unsafe fn CreateDirectoryW(lpPathName: LPCWSTR,
                                 lpSecurityAttributes:
                                 LPSECURITY_ATTRIBUTES) -> BOOL;
-            fn CopyFileW(lpExistingFileName: LPCWSTR,
+            unsafe fn CopyFileW(lpExistingFileName: LPCWSTR,
                          lpNewFileName: LPCWSTR,
                          bFailIfExists: BOOL) -> BOOL;
-            fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL;
-            fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
-            fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
+            unsafe fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL;
+            unsafe fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
+            unsafe fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
 
-            fn GetLastError() -> DWORD;
+            unsafe fn GetLastError() -> DWORD;
         }
 
         #[abi = "cdecl"]
         #[nolink]
         pub extern mod msvcrt {
             #[link_name = "_commit"]
-            pub fn commit(fd: c_int) -> c_int;
+            unsafe fn commit(fd: c_int) -> c_int;
         }
     }
 }
index d8bcab62b8fa4124548ebb3cb177b080a083cc6c..922995a5af79ca680f08dfbbb679f80888b4fceb 100644 (file)
 #[forbid(deprecated_pattern)];
 
 use cast::transmute;
+use io;
+use libc;
+use repr;
+use vec;
 
 #[nolink]
 extern mod rustrt {
-    fn rust_log_console_on();
-    fn rust_log_console_off();
-    fn rust_log_str(level: u32, string: *libc::c_char, size: libc::size_t);
+    unsafe fn rust_log_console_on();
+    unsafe fn rust_log_console_off();
+    unsafe fn rust_log_str(level: u32,
+                           string: *libc::c_char,
+                           size: libc::size_t);
 }
 
 /// Turns on logging to stdout globally
 pub fn console_on() {
-    rustrt::rust_log_console_on();
+    unsafe {
+        rustrt::rust_log_console_on();
+    }
 }
 
 /**
@@ -36,7 +44,9 @@ pub fn console_on() {
  * the RUST_LOG environment variable
  */
 pub fn console_off() {
-    rustrt::rust_log_console_off();
+    unsafe {
+        rustrt::rust_log_console_off();
+    }
 }
 
 #[cfg(notest)]
index bc6a56868a5c44e75fb791e654251a3f5cea16c2..8395526276c8ee73bd56fe76416fcc2eeb636149 100644 (file)
 #[forbid(deprecated_pattern)];
 
 use cmp::{Eq, Ord};
-use intrinsic::TyDesc;
+use prelude::*;
+use ptr;
 
 pub mod raw {
+    use intrinsic::TyDesc;
+
     pub struct BoxHeaderRepr {
         ref_count: uint,
         type_desc: *TyDesc,
@@ -32,6 +35,7 @@ pub struct BoxRepr {
 
 }
 
+#[inline(always)]
 pub pure fn ptr_eq<T>(a: @T, b: @T) -> bool {
     //! Determine if two shared boxes point to the same object
     unsafe { ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) }
@@ -39,15 +43,21 @@ pub struct BoxRepr {
 
 #[cfg(notest)]
 impl<T:Eq> @const T : Eq {
+    #[inline(always)]
     pure fn eq(&self, other: &@const T) -> bool { *(*self) == *(*other) }
+    #[inline(always)]
     pure fn ne(&self, other: &@const T) -> bool { *(*self) != *(*other) }
 }
 
 #[cfg(notest)]
 impl<T:Ord> @const T : Ord {
+    #[inline(always)]
     pure fn lt(&self, other: &@const T) -> bool { *(*self) < *(*other) }
+    #[inline(always)]
     pure fn le(&self, other: &@const T) -> bool { *(*self) <= *(*other) }
+    #[inline(always)]
     pure fn ge(&self, other: &@const T) -> bool { *(*self) >= *(*other) }
+    #[inline(always)]
     pure fn gt(&self, other: &@const T) -> bool { *(*self) > *(*other) }
 }
 
index 5e306d4b57d7b1a7c92c64b488642be38e42d430..f3eb62a3a3ad03758c36a692e7e5c48ec0a22c6d 100644 (file)
 
 #[cfg(notest)]
 impl () : Eq {
+    #[inline(always)]
     pure fn eq(&self, _other: &()) -> bool { true }
+    #[inline(always)]
     pure fn ne(&self, _other: &()) -> bool { false }
 }
 
 #[cfg(notest)]
 impl () : Ord {
+    #[inline(always)]
     pure fn lt(&self, _other: &()) -> bool { false }
+    #[inline(always)]
     pure fn le(&self, _other: &()) -> bool { true }
+    #[inline(always)]
     pure fn ge(&self, _other: &()) -> bool { true }
+    #[inline(always)]
     pure fn gt(&self, _other: &()) -> bool { false }
 }
 
index a5b0336ab60d943c46303c98dff18aef75cf8c8c..ae3116b08f0c42d33ba581d1b5844a0f27af52bf 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use cast;
+use either;
 use either::Either;
+use iter;
+use libc;
 use libc::size_t;
+use prelude::*;
+use ptr;
+use result;
+use sys;
+use task;
+use vec;
+
 // After snapshot, change p2::addr_of => addr_of
 
 /**
@@ -79,7 +90,10 @@ pub enum Chan<T: Owned> {
 
 /// Constructs a port
 pub fn Port<T: Owned>() -> Port<T> {
-    Port_(@PortPtr(rustrt::new_port(sys::size_of::<T>() as size_t)))
+    unsafe {
+        Port_(@PortPtr(rustrt::new_port(sys::nonzero_size_of::<T>()
+                                        as size_t)))
+    }
 }
 
 impl<T: Owned> Port<T> {
@@ -148,11 +162,13 @@ fn as_raw_port<T: Owned, U>(ch: Chan<T>, f: fn(*rust_port) -> U) -> U {
 
     struct PortRef {
         p: *rust_port,
-       drop {
-         if !ptr::is_null(self.p) {
-           rustrt::rust_port_drop(self.p);
-         }
-       }
+        drop {
+            unsafe {
+                if !ptr::is_null(self.p) {
+                    rustrt::rust_port_drop(self.p);
+                }
+            }
+        }
     }
 
     fn PortRef(p: *rust_port) -> PortRef {
@@ -161,15 +177,17 @@ fn PortRef(p: *rust_port) -> PortRef {
         }
     }
 
-    let p = PortRef(rustrt::rust_port_take(*ch));
+    unsafe {
+        let p = PortRef(rustrt::rust_port_take(*ch));
 
-    if ptr::is_null(p.p) {
-        fail ~"unable to locate port for channel"
-    } else if rustrt::get_task_id() != rustrt::rust_port_task(p.p) {
-        fail ~"unable to access unowned port"
-    }
+        if ptr::is_null(p.p) {
+            fail ~"unable to locate port for channel"
+        } else if rustrt::get_task_id() != rustrt::rust_port_task(p.p) {
+            fail ~"unable to access unowned port"
+        }
 
-    f(p.p)
+        f(p.p)
+    }
 }
 
 /**
@@ -177,7 +195,9 @@ fn PortRef(p: *rust_port) -> PortRef {
  * construct it.
  */
 pub fn Chan<T: Owned>(p: &Port<T>) -> Chan<T> {
-    Chan_(rustrt::get_port_id((**p).po))
+    unsafe {
+        Chan_(rustrt::get_port_id((**p).po))
+    }
 }
 
 /**
@@ -185,14 +205,16 @@ pub fn Chan<T: Owned>(p: &Port<T>) -> Chan<T> {
  * whereupon the caller loses access to it.
  */
 pub fn send<T: Owned>(ch: Chan<T>, data: T) {
-    let Chan_(p) = ch;
-    let data_ptr = ptr::addr_of(&data) as *();
-    let res = rustrt::rust_port_id_send(p, data_ptr);
-    if res != 0 unsafe {
-        // Data sent successfully
-        cast::forget(move data);
+    unsafe {
+        let Chan_(p) = ch;
+        let data_ptr = ptr::addr_of(&data) as *();
+        let res = rustrt::rust_port_id_send(p, data_ptr);
+        if res != 0 unsafe {
+            // Data sent successfully
+            cast::forget(move data);
+        }
+        task::yield();
     }
-    task::yield();
 }
 
 /**
@@ -215,61 +237,67 @@ fn peek_chan<T: Owned>(ch: Chan<T>) -> bool {
 
 /// Receive on a raw port pointer
 fn recv_<T: Owned>(p: *rust_port) -> T {
-    let yield = 0;
-    let yieldp = ptr::addr_of(&yield);
-    let mut res;
-    res = rusti::init::<T>();
-    rustrt::port_recv(ptr::addr_of(&res) as *uint, p, yieldp);
-
-    if yield != 0 {
-        // Data isn't available yet, so res has not been initialized.
-        task::yield();
-    } else {
-        // In the absence of compiler-generated preemption points
-        // this is a good place to yield
-        task::yield();
+    unsafe {
+        let yield = 0;
+        let yieldp = ptr::addr_of(&yield);
+        let mut res;
+        res = rusti::init::<T>();
+        rustrt::port_recv(ptr::addr_of(&res) as *uint, p, yieldp);
+
+        if yield != 0 {
+            // Data isn't available yet, so res has not been initialized.
+            task::yield();
+        } else {
+            // In the absence of compiler-generated preemption points
+            // this is a good place to yield
+            task::yield();
+        }
+        move res
     }
-    move res
 }
 
 fn peek_(p: *rust_port) -> bool {
-    // Yield here before we check to see if someone sent us a message
-    // FIXME #524, if the compiler generates yields, we don't need this
-    task::yield();
-    rustrt::rust_port_size(p) != 0 as libc::size_t
+    unsafe {
+        // Yield here before we check to see if someone sent us a message
+        // FIXME #524, if the compiler generates yields, we don't need this
+        task::yield();
+        rustrt::rust_port_size(p) != 0 as libc::size_t
+    }
 }
 
 /// Receive on one of two ports
 pub fn select2<A: Owned, B: Owned>(p_a: Port<A>, p_b: Port<B>)
     -> Either<A, B> {
-    let ports = ~[(**p_a).po, (**p_b).po];
-    let yield = 0, yieldp = ptr::addr_of(&yield);
-
-    let mut resport: *rust_port;
-    resport = rusti::init::<*rust_port>();
-    do vec::as_imm_buf(ports) |ports, n_ports| {
-        rustrt::rust_port_select(ptr::addr_of(&resport), ports,
-                                 n_ports as size_t, yieldp);
-    }
+    unsafe {
+        let ports = ~[(**p_a).po, (**p_b).po];
+        let yield = 0, yieldp = ptr::addr_of(&yield);
+
+        let mut resport: *rust_port;
+        resport = rusti::init::<*rust_port>();
+        do vec::as_imm_buf(ports) |ports, n_ports| {
+            rustrt::rust_port_select(ptr::addr_of(&resport), ports,
+                                     n_ports as size_t, yieldp);
+        }
 
-    if yield != 0 {
-        // Wait for data
-        task::yield();
-    } else {
-        // As in recv, this is a good place to yield anyway until
-        // the compiler generates yield calls
-        task::yield();
-    }
+        if yield != 0 {
+            // Wait for data
+            task::yield();
+        } else {
+            // As in recv, this is a good place to yield anyway until
+            // the compiler generates yield calls
+            task::yield();
+        }
 
-    // Now we know the port we're supposed to receive from
-    assert resport != ptr::null();
+        // Now we know the port we're supposed to receive from
+        assert resport != ptr::null();
 
-    if resport == (**p_a).po {
-        either::Left(recv(p_a))
-    } else if resport == (**p_b).po {
-        either::Right(recv(p_b))
-    } else {
-        fail ~"unexpected result from rust_port_select";
+        if resport == (**p_a).po {
+            either::Left(recv(p_a))
+        } else if resport == (**p_b).po {
+            either::Right(recv(p_b))
+        } else {
+            fail ~"unexpected result from rust_port_select";
+        }
     }
 }
 
@@ -284,24 +312,25 @@ enum rust_port {}
 
 #[abi = "cdecl"]
 extern mod rustrt {
-    fn rust_port_id_send(target_port: port_id, data: *()) -> libc::uintptr_t;
+    unsafe fn rust_port_id_send(target_port: port_id, data: *())
+                             -> libc::uintptr_t;
 
-    fn new_port(unit_sz: libc::size_t) -> *rust_port;
-    fn del_port(po: *rust_port);
-    fn rust_port_begin_detach(po: *rust_port,
+    unsafe fn new_port(unit_sz: libc::size_t) -> *rust_port;
+    unsafe fn del_port(po: *rust_port);
+    unsafe fn rust_port_begin_detach(po: *rust_port,
                               yield: *libc::uintptr_t);
-    fn rust_port_end_detach(po: *rust_port);
-    fn get_port_id(po: *rust_port) -> port_id;
-    fn rust_port_size(po: *rust_port) -> libc::size_t;
-    fn port_recv(dptr: *uint, po: *rust_port,
+    unsafe fn rust_port_end_detach(po: *rust_port);
+    unsafe fn get_port_id(po: *rust_port) -> port_id;
+    unsafe fn rust_port_size(po: *rust_port) -> libc::size_t;
+    unsafe fn port_recv(dptr: *uint, po: *rust_port,
                  yield: *libc::uintptr_t);
-    fn rust_port_select(dptr: **rust_port, ports: **rust_port,
+    unsafe fn rust_port_select(dptr: **rust_port, ports: **rust_port,
                         n_ports: libc::size_t,
                         yield: *libc::uintptr_t);
-    fn rust_port_take(port_id: port_id) -> *rust_port;
-    fn rust_port_drop(p: *rust_port);
-    fn rust_port_task(p: *rust_port) -> libc::uintptr_t;
-    fn get_task_id() -> libc::uintptr_t;
+    unsafe fn rust_port_take(port_id: port_id) -> *rust_port;
+    unsafe fn rust_port_drop(p: *rust_port);
+    unsafe fn rust_port_task(p: *rust_port) -> libc::uintptr_t;
+    unsafe fn get_task_id() -> libc::uintptr_t;
 }
 
 #[abi = "rust-intrinsic"]
index 3c6f5638d8d7c17611ad99ea60c5c0459056ef29..36293d6a1c0cef105a7bf00683b2870e935192c0 100644 (file)
@@ -15,7 +15,7 @@
 
 #[lang="drop"]
 pub trait Drop {
-    fn finalize(&self);  // XXX: Rename to "drop"? --pcwalton
+    fn finalize(&self);  // FIXME(#4332): Rename to "drop"? --pcwalton
 }
 
 #[lang="add"]
@@ -48,6 +48,11 @@ pub trait Neg<Result> {
     pure fn neg(&self) -> Result;
 }
 
+#[lang="not"]
+pub trait Not<Result> {
+    pure fn not(&self) -> Result;
+}
+
 #[lang="bitand"]
 pub trait BitAnd<RHS,Result> {
     pure fn bitand(&self, rhs: &RHS) -> Result;
@@ -77,4 +82,3 @@ pub trait Shr<RHS,Result> {
 pub trait Index<Index,Result> {
     pure fn index(&self, index: Index) -> Result;
 }
-
index a4f385ea12cd8221c2ee4e028a7fc1c7972494d0..48f2ae719384e1d818bf37042948844217e23580 100644 (file)
 #[forbid(deprecated_pattern)];
 
 use cmp::Eq;
+use kinds::Copy;
+use option;
+use ptr;
+use str;
+use util;
+use num::Zero;
 
 /// The option type
 #[deriving_eq]
@@ -53,6 +59,7 @@ pub enum Option<T> {
     Some(T),
 }
 
+#[inline(always)]
 pub pure fn get<T: Copy>(opt: Option<T>) -> T {
     /*!
     Gets the value out of an option
@@ -75,6 +82,7 @@ pub enum Option<T> {
     }
 }
 
+#[inline(always)]
 pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
     /*!
     Gets an immutable reference to the value inside an option.
@@ -96,21 +104,24 @@ pub enum Option<T> {
     }
 }
 
+#[inline(always)]
 pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
     //! Maps a `some` value by reference from one type to another
 
     match *opt { Some(ref x) => Some(f(x)), None => None }
 }
 
+#[inline(always)]
 pub pure fn map_consume<T, U>(opt: Option<T>,
                               f: fn(v: T) -> U) -> Option<U> {
     /*!
      * As `map`, but consumes the option and gives `f` ownership to avoid
      * copying.
      */
-    if opt.is_some() { Some(f(option::unwrap(move opt))) } else { None }
+    match opt { None => None, Some(v) => Some(f(v)) }
 }
 
+#[inline(always)]
 pub pure fn chain<T, U>(opt: Option<T>,
                         f: fn(t: T) -> Option<U>) -> Option<U> {
     /*!
@@ -124,6 +135,7 @@ pub enum Option<T> {
     }
 }
 
+#[inline(always)]
 pub pure fn chain_ref<T, U>(opt: &Option<T>,
                             f: fn(x: &T) -> Option<U>) -> Option<U> {
     /*!
@@ -134,6 +146,7 @@ pub enum Option<T> {
     match *opt { Some(ref x) => f(x), None => None }
 }
 
+#[inline(always)]
 pub pure fn or<T>(opta: Option<T>, optb: Option<T>) -> Option<T> {
     /*!
      * Returns the leftmost some() value, or none if both are none.
@@ -154,24 +167,35 @@ pub enum Option<T> {
     }
 }
 
+#[inline(always)]
 pub pure fn is_none<T>(opt: &Option<T>) -> bool {
     //! Returns true if the option equals `none`
 
     match *opt { None => true, Some(_) => false }
 }
 
+#[inline(always)]
 pub pure fn is_some<T>(opt: &Option<T>) -> bool {
     //! Returns true if the option contains some value
 
     !is_none(opt)
 }
 
-pub pure fn get_default<T: Copy>(opt: Option<T>, def: T) -> T {
+#[inline(always)]
+pub pure fn get_or_zero<T: Copy Zero>(opt: Option<T>) -> T {
+    //! Returns the contained value or zero (for this type)
+
+    match opt { Some(copy x) => x, None => Zero::zero() }
+}
+
+#[inline(always)]
+pub pure fn get_or_default<T: Copy>(opt: Option<T>, def: T) -> T {
     //! Returns the contained value or a default
 
     match opt { Some(copy x) => x, None => def }
 }
 
+#[inline(always)]
 pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
                               f: fn(x: &T) -> U) -> U {
     //! Applies a function to the contained value or returns a default
@@ -179,6 +203,7 @@ pub enum Option<T> {
     match *opt { None => move def, Some(ref t) => f(t) }
 }
 
+#[inline(always)]
 pub pure fn iter<T>(opt: &Option<T>, f: fn(x: &T)) {
     //! Performs an operation on the contained value by reference
     match *opt { None => (), Some(ref t) => f(t) }
@@ -222,6 +247,7 @@ pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
     unwrap(util::replace(opt, None))
 }
 
+#[inline(always)]
 pub pure fn expect<T>(opt: Option<T>, reason: &str) -> T {
     //! As unwrap, but with a specified failure message.
     match move opt {
@@ -252,12 +278,42 @@ impl<T> Option<T> {
     #[inline(always)]
     pure fn map<U>(&self, f: fn(x: &T) -> U) -> Option<U> { map(self, f) }
 
+    /// As `map`, but consumes the option and gives `f` ownership to avoid
+    /// copying.
+    #[inline(always)]
+    pure fn map_consume<U>(self, f: fn(v: T) -> U) -> Option<U> {
+        map_consume(self, f)
+    }
+
     /// Applies a function to the contained value or returns a default
     #[inline(always)]
     pure fn map_default<U>(&self, def: U, f: fn(x: &T) -> U) -> U {
         map_default(self, move def, f)
     }
 
+    /// As `map_default`, but consumes the option and gives `f`
+    /// ownership to avoid copying.
+    #[inline(always)]
+    pure fn map_consume_default<U>(self, def: U, f: fn(v: T) -> U) -> U {
+        match self { None => def, Some(v) => f(v) }
+    }
+
+    /// Apply a function to the contained value or do nothing
+    fn mutate(&mut self, f: fn(T) -> T) {
+        if self.is_some() {
+            *self = Some(f(self.swap_unwrap()));
+        }
+    }
+
+    /// Apply a function to the contained value or set it to a default
+    fn mutate_default(&mut self, def: T, f: fn(T) -> T) {
+        if self.is_some() {
+            *self = Some(f(self.swap_unwrap()));
+        } else {
+            *self = Some(def);
+        }
+    }
+
     /// Performs an operation on the contained value by reference
     #[inline(always)]
     pure fn iter(&self, f: fn(x: &T)) { iter(self, f) }
@@ -289,6 +345,17 @@ impl<T> Option<T> {
     #[inline(always)]
     pure fn unwrap(self) -> T { unwrap(self) }
 
+    /**
+     * The option dance. Moves a value out of an option type and returns it,
+     * replacing the original with `None`.
+     *
+     * # Failure
+     *
+     * Fails if the value equals `None`.
+     */
+    #[inline(always)]
+    fn swap_unwrap(&mut self) -> T { swap_unwrap(self) }
+
     /**
      * Gets the value out of an option, printing a specified message on
      * failure
@@ -320,7 +387,7 @@ impl<T: Copy> Option<T> {
     pure fn get(self) -> T { get(self) }
 
     #[inline(always)]
-    pure fn get_default(self, def: T) -> T { get_default(self, def) }
+    pure fn get_or_default(self, def: T) -> T { get_or_default(self, def) }
 
     /// Applies a function zero or more times until the result is none.
     #[inline(always)]
@@ -329,6 +396,11 @@ impl<T: Copy> Option<T> {
     }
 }
 
+impl<T: Copy Zero> Option<T> {
+    #[inline(always)]
+    pure fn get_or_zero(self) -> T { get_or_zero(self) }
+}
+
 #[test]
 fn test_unwrap_ptr() {
     let x = ~0;
@@ -403,6 +475,14 @@ fn test_option_while_some() {
     assert i == 11;
 }
 
+#[test]
+fn test_get_or_zero() {
+    let some_stuff = Some(42);
+    assert some_stuff.get_or_zero() == 42;
+    let no_stuff: Option<int> = None;
+    assert no_stuff.get_or_zero() == 0;
+}
+
 // Local Variables:
 // mode: rust;
 // fill-column: 78;
index b5e0983a420d1142f51322b0281ec28f377cbe4e..ff3253a8223ffd30ed7ba6cc48b7fb0caf6edc95 100644 (file)
  * to write OS-ignorant code by default.
  */
 
-use libc::{c_char, c_void, c_int, c_uint, size_t, ssize_t,
-           mode_t, pid_t, FILE};
-pub use libc::{close, fclose};
-
+use cast;
+use either;
+use io;
+use libc;
+use libc::{c_char, c_void, c_int, c_uint, size_t, ssize_t};
+use libc::{mode_t, pid_t, FILE};
+use option;
 use option::{Some, None};
+use prelude::*;
+use private;
+use ptr;
+use str;
+use task;
+use task::TaskBuilder;
+use uint;
+use vec;
 
+pub use libc::fclose;
 pub use os::consts::*;
-use task::TaskBuilder;
 
 // FIXME: move these to str perhaps? #2620
 
-extern mod rustrt {
-    fn rust_get_argc() -> c_int;
-    fn rust_get_argv() -> **c_char;
-    fn rust_getcwd() -> ~str;
-    fn rust_path_is_dir(path: *libc::c_char) -> c_int;
-    fn rust_path_exists(path: *libc::c_char) -> c_int;
-    fn rust_list_files2(&&path: ~str) -> ~[~str];
-    fn rust_process_wait(handle: c_int) -> c_int;
-    fn last_os_error() -> ~str;
-    fn rust_set_exit_status(code: libc::intptr_t);
+pub fn close(fd: c_int) -> c_int {
+    unsafe {
+        libc::close(fd)
+    }
 }
 
+extern mod rustrt {
+    unsafe fn rust_get_argc() -> c_int;
+    unsafe fn rust_get_argv() -> **c_char;
+    unsafe fn rust_getcwd() -> ~str;
+    unsafe fn rust_path_is_dir(path: *libc::c_char) -> c_int;
+    unsafe fn rust_path_exists(path: *libc::c_char) -> c_int;
+    unsafe fn rust_list_files2(&&path: ~str) -> ~[~str];
+    unsafe fn rust_process_wait(handle: c_int) -> c_int;
+    unsafe fn last_os_error() -> ~str;
+    unsafe fn rust_set_exit_status(code: libc::intptr_t);
+}
 
-const tmpbuf_sz : uint = 1000u;
+pub const tmpbuf_sz : uint = 1000u;
 
 pub fn getcwd() -> Path {
-    Path(rustrt::rust_getcwd())
+    unsafe {
+        Path(rustrt::rust_getcwd())
+    }
 }
 
 pub fn as_c_charp<T>(s: &str, f: fn(*c_char) -> T) -> T {
@@ -78,31 +96,39 @@ pub fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool)
 
 #[cfg(windows)]
 pub mod win32 {
+    use libc;
+    use vec;
+    use str;
+    use option::{None, Option};
+    use option;
+    use os::tmpbuf_sz;
     use libc::types::os::arch::extra::DWORD;
 
     pub fn fill_utf16_buf_and_decode(f: fn(*mut u16, DWORD) -> DWORD)
         -> Option<~str> {
-        let mut n = tmpbuf_sz as DWORD;
-        let mut res = None;
-        let mut done = false;
-        while !done {
-            let buf = vec::to_mut(vec::from_elem(n as uint, 0u16));
-            do vec::as_mut_buf(buf) |b, _sz| {
-                let k : DWORD = f(b, tmpbuf_sz as DWORD);
-                if k == (0 as DWORD) {
-                    done = true;
-                } else if (k == n &&
-                           libc::GetLastError() ==
-                           libc::ERROR_INSUFFICIENT_BUFFER as DWORD) {
-                    n *= (2 as DWORD);
-                } else {
-                    let sub = vec::slice(buf, 0u, k as uint);
-                    res = option::Some(str::from_utf16(sub));
-                    done = true;
+        unsafe {
+            let mut n = tmpbuf_sz as DWORD;
+            let mut res = None;
+            let mut done = false;
+            while !done {
+                let buf = vec::to_mut(vec::from_elem(n as uint, 0u16));
+                do vec::as_mut_buf(buf) |b, _sz| {
+                    let k : DWORD = f(b, tmpbuf_sz as DWORD);
+                    if k == (0 as DWORD) {
+                        done = true;
+                    } else if (k == n &&
+                               libc::GetLastError() ==
+                               libc::ERROR_INSUFFICIENT_BUFFER as DWORD) {
+                        n *= (2 as DWORD);
+                    } else {
+                        let sub = vec::slice(buf, 0u, k as uint);
+                        res = option::Some(str::from_utf16(sub));
+                        done = true;
+                    }
                 }
             }
+            return res;
         }
-        return res;
     }
 
     pub fn as_utf16_p<T>(s: &str, f: fn(*u16) -> T) -> T {
@@ -127,9 +153,16 @@ pub fn env() -> ~[(~str,~str)] {
 
 mod global_env {
     //! Internal module for serializing access to getenv/setenv
+    use either;
+    use libc;
+    use oldcomm;
+    use option::Option;
+    use private;
+    use str;
+    use task;
 
     extern mod rustrt {
-        fn rust_global_env_chan_ptr() -> *libc::uintptr_t;
+        unsafe fn rust_global_env_chan_ptr() -> *libc::uintptr_t;
     }
 
     enum Msg {
@@ -142,7 +175,7 @@ pub fn getenv(n: &str) -> Option<~str> {
         let env_ch = get_global_env_chan();
         let po = oldcomm::Port();
         oldcomm::send(env_ch, MsgGetEnv(str::from_slice(n),
-                                     oldcomm::Chan(&po)));
+                                        oldcomm::Chan(&po)));
         oldcomm::recv(po)
     }
 
@@ -150,8 +183,8 @@ pub fn setenv(n: &str, v: &str) {
         let env_ch = get_global_env_chan();
         let po = oldcomm::Port();
         oldcomm::send(env_ch, MsgSetEnv(str::from_slice(n),
-                                     str::from_slice(v),
-                                     oldcomm::Chan(&po)));
+                                        str::from_slice(v),
+                                        oldcomm::Chan(&po)));
         oldcomm::recv(po)
     }
 
@@ -163,8 +196,8 @@ pub fn env() -> ~[(~str,~str)] {
     }
 
     fn get_global_env_chan() -> oldcomm::Chan<Msg> {
-        let global_ptr = rustrt::rust_global_env_chan_ptr();
         unsafe {
+            let global_ptr = rustrt::rust_global_env_chan_ptr();
             private::chan_from_global_ptr(global_ptr, || {
                 // FIXME (#2621): This would be a good place to use a very
                 // small foreign stack
@@ -195,24 +228,34 @@ fn global_env_task(msg_po: oldcomm::Port<Msg>) {
     }
 
     mod impl_ {
+        use cast;
+        use libc;
+        use option::Option;
+        use option;
+        use ptr;
+        use str;
+        use vec;
+
         extern mod rustrt {
-            fn rust_env_pairs() -> ~[~str];
+            unsafe fn rust_env_pairs() -> ~[~str];
         }
 
         pub fn env() -> ~[(~str,~str)] {
-            let mut pairs = ~[];
-            for vec::each(rustrt::rust_env_pairs()) |p| {
-                let vs = str::splitn_char(*p, '=', 1u);
-                assert vec::len(vs) == 2u;
-                pairs.push((copy vs[0], copy vs[1]));
+            unsafe {
+                let mut pairs = ~[];
+                for vec::each(rustrt::rust_env_pairs()) |p| {
+                    let vs = str::splitn_char(*p, '=', 1u);
+                    assert vec::len(vs) == 2u;
+                    pairs.push((copy vs[0], copy vs[1]));
+                }
+                move pairs
             }
-            move pairs
         }
 
         #[cfg(unix)]
         pub fn getenv(n: &str) -> Option<~str> {
             unsafe {
-                let s = str::as_c_str(n, libc::getenv);
+                let s = str::as_c_str(n, |s| libc::getenv(s));
                 return if ptr::null::<u8>() == cast::reinterpret_cast(&s) {
                     option::None::<~str>
                 } else {
@@ -224,10 +267,12 @@ pub fn getenv(n: &str) -> Option<~str> {
 
         #[cfg(windows)]
         pub fn getenv(n: &str) -> Option<~str> {
-            use os::win32::*;
-            do as_utf16_p(n) |u| {
-                do fill_utf16_buf_and_decode() |buf, sz| {
-                    libc::GetEnvironmentVariableW(u, buf, sz)
+            unsafe {
+                use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
+                do as_utf16_p(n) |u| {
+                    do fill_utf16_buf_and_decode() |buf, sz| {
+                        libc::GetEnvironmentVariableW(u, buf, sz)
+                    }
                 }
             }
         }
@@ -235,9 +280,11 @@ pub fn getenv(n: &str) -> Option<~str> {
 
         #[cfg(unix)]
         pub fn setenv(n: &str, v: &str) {
-            do str::as_c_str(n) |nbuf| {
-                do str::as_c_str(v) |vbuf| {
-                    libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1i32);
+            unsafe {
+                do str::as_c_str(n) |nbuf| {
+                    do str::as_c_str(v) |vbuf| {
+                        libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
+                    }
                 }
             }
         }
@@ -245,10 +292,12 @@ pub fn setenv(n: &str, v: &str) {
 
         #[cfg(windows)]
         pub fn setenv(n: &str, v: &str) {
-            use os::win32::*;
-            do as_utf16_p(n) |nbuf| {
-                do as_utf16_p(v) |vbuf| {
-                    libc::SetEnvironmentVariableW(nbuf, vbuf);
+            unsafe {
+                use os::win32::as_utf16_p;
+                do as_utf16_p(n) |nbuf| {
+                    do as_utf16_p(v) |vbuf| {
+                        libc::SetEnvironmentVariableW(nbuf, vbuf);
+                    }
                 }
             }
         }
@@ -257,9 +306,11 @@ pub fn setenv(n: &str, v: &str) {
 }
 
 pub fn fdopen(fd: c_int) -> *FILE {
-    return do as_c_charp("r") |modebuf| {
-        libc::fdopen(fd, modebuf)
-    };
+    unsafe {
+        return do as_c_charp("r") |modebuf| {
+            libc::fdopen(fd, modebuf)
+        };
+    }
 }
 
 
@@ -267,101 +318,116 @@ pub fn fdopen(fd: c_int) -> *FILE {
 
 #[cfg(windows)]
 pub fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int {
-    use libc::funcs::extra::msvcrt::*;
-    return commit(fd);
+    unsafe {
+        use libc::funcs::extra::msvcrt::*;
+        return commit(fd);
+    }
 }
 
 #[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
 pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
-    use libc::funcs::posix01::unistd::*;
-    match level {
-      io::fsync::FSync
-      | io::fsync::FullFSync => return fsync(fd),
-      io::fsync::FDataSync => return fdatasync(fd)
+    unsafe {
+        use libc::funcs::posix01::unistd::*;
+        match level {
+          io::fsync::FSync
+          | io::fsync::FullFSync => return fsync(fd),
+          io::fsync::FDataSync => return fdatasync(fd)
+        }
     }
 }
 
 #[cfg(target_os = "macos")]
 pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
-    use libc::consts::os::extra::*;
-    use libc::funcs::posix88::fcntl::*;
-    use libc::funcs::posix01::unistd::*;
-    match level {
-      io::fsync::FSync => return fsync(fd),
-      _ => {
-        // According to man fnctl, the ok retval is only specified to be !=-1
-        if (fcntl(F_FULLFSYNC as c_int, fd) == -1 as c_int)
-            { return -1 as c_int; }
-        else
-            { return 0 as c_int; }
-      }
+    unsafe {
+        use libc::consts::os::extra::*;
+        use libc::funcs::posix88::fcntl::*;
+        use libc::funcs::posix01::unistd::*;
+        match level {
+          io::fsync::FSync => return fsync(fd),
+          _ => {
+            // According to man fnctl, the ok retval is only specified to be
+            // !=-1
+            if (fcntl(F_FULLFSYNC as c_int, fd) == -1 as c_int)
+                { return -1 as c_int; }
+            else
+                { return 0 as c_int; }
+          }
+        }
     }
 }
 
 #[cfg(target_os = "freebsd")]
 pub fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int {
-    use libc::funcs::posix01::unistd::*;
-    return fsync(fd);
+    unsafe {
+        use libc::funcs::posix01::unistd::*;
+        return fsync(fd);
+    }
 }
 
 
 #[cfg(windows)]
 pub fn waitpid(pid: pid_t) -> c_int {
-    return rustrt::rust_process_wait(pid);
+    unsafe {
+        return rustrt::rust_process_wait(pid);
+    }
 }
 
 #[cfg(unix)]
 pub fn waitpid(pid: pid_t) -> c_int {
-    use libc::funcs::posix01::wait::*;
-    let status = 0 as c_int;
+    unsafe {
+        use libc::funcs::posix01::wait::*;
+        let status = 0 as c_int;
 
-    assert (waitpid(pid, ptr::mut_addr_of(&status),
-                    0 as c_int) != (-1 as c_int));
-    return status;
+        assert (waitpid(pid, ptr::mut_addr_of(&status),
+                        0 as c_int) != (-1 as c_int));
+        return status;
+    }
 }
 
 
 #[cfg(unix)]
 pub fn pipe() -> {in: c_int, out: c_int} {
-    let fds = {mut in: 0 as c_int,
-               mut out: 0 as c_int };
-    assert (libc::pipe(ptr::mut_addr_of(&(fds.in))) == (0 as c_int));
-    return {in: fds.in, out: fds.out};
+    unsafe {
+        let fds = {mut in: 0 as c_int,
+                   mut out: 0 as c_int };
+        assert (libc::pipe(ptr::mut_addr_of(&(fds.in))) == (0 as c_int));
+        return {in: fds.in, out: fds.out};
+    }
 }
 
 
 
 #[cfg(windows)]
 pub fn pipe() -> {in: c_int, out: c_int} {
-    // Windows pipes work subtly differently than unix pipes, and their
-    // inheritance has to be handled in a different way that I do not fully
-    // understand. Here we explicitly make the pipe non-inheritable, which
-    // means to pass it to a subprocess they need to be duplicated first, as
-    // in rust_run_program.
-    let fds = { mut in: 0 as c_int,
-                mut out: 0 as c_int };
-    let res = libc::pipe(ptr::mut_addr_of(&(fds.in)),
-                         1024 as c_uint,
-                         (libc::O_BINARY | libc::O_NOINHERIT) as c_int);
-    assert (res == 0 as c_int);
-    assert (fds.in != -1 as c_int && fds.in != 0 as c_int);
-    assert (fds.out != -1 as c_int && fds.in != 0 as c_int);
-    return {in: fds.in, out: fds.out};
+    unsafe {
+        // Windows pipes work subtly differently than unix pipes, and their
+        // inheritance has to be handled in a different way that I do not
+        // fully understand. Here we explicitly make the pipe non-inheritable,
+        // which means to pass it to a subprocess they need to be duplicated
+        // first, as in rust_run_program.
+        let fds = { mut in: 0 as c_int,
+                    mut out: 0 as c_int };
+        let res = libc::pipe(ptr::mut_addr_of(&(fds.in)),
+                             1024 as c_uint,
+                             (libc::O_BINARY | libc::O_NOINHERIT) as c_int);
+        assert (res == 0 as c_int);
+        assert (fds.in != -1 as c_int && fds.in != 0 as c_int);
+        assert (fds.out != -1 as c_int && fds.in != 0 as c_int);
+        return {in: fds.in, out: fds.out};
+    }
 }
 
 fn dup2(src: c_int, dst: c_int) -> c_int {
-    libc::dup2(src, dst)
+    unsafe {
+        libc::dup2(src, dst)
+    }
 }
 
 
 pub fn dll_filename(base: &str) -> ~str {
-    return pre() + str::from_slice(base) + dll_suffix();
-
-    #[cfg(unix)]
-    fn pre() -> ~str { ~"lib" }
-
-    #[cfg(windows)]
-    fn pre() -> ~str { ~"" }
+    return str::from_slice(DLL_PREFIX) + str::from_slice(base) +
+           str::from_slice(DLL_SUFFIX)
 }
 
 
@@ -384,28 +450,44 @@ fn load_self() -> Option<~str> {
     }
 
     #[cfg(target_os = "linux")]
+    #[cfg(target_os = "android")]
     fn load_self() -> Option<~str> {
-        use libc::funcs::posix01::unistd::readlink;
-        do fill_charp_buf() |buf, sz| {
-            do as_c_charp("/proc/self/exe") |proc_self_buf| {
-                readlink(proc_self_buf, buf, sz) != (-1 as ssize_t)
+        unsafe {
+            use libc::funcs::posix01::unistd::readlink;
+
+            let mut path_str = str::with_capacity(tmpbuf_sz);
+            let len = do str::as_c_str(path_str) |buf| {
+                let buf = buf as *mut c_char;
+                do as_c_charp("/proc/self/exe") |proc_self_buf| {
+                    readlink(proc_self_buf, buf, tmpbuf_sz as size_t)
+                }
+            };
+            if len == -1 {
+                None
+            } else {
+                str::raw::set_len(&mut path_str, len as uint);
+                Some(path_str)
             }
         }
     }
 
     #[cfg(target_os = "macos")]
     fn load_self() -> Option<~str> {
-        do fill_charp_buf() |buf, sz| {
-            libc::funcs::extra::_NSGetExecutablePath(
-                buf, ptr::mut_addr_of(&(sz as u32))) == (0 as c_int)
+        unsafe {
+            do fill_charp_buf() |buf, sz| {
+                libc::funcs::extra::_NSGetExecutablePath(
+                    buf, ptr::mut_addr_of(&(sz as u32))) == (0 as c_int)
+            }
         }
     }
 
     #[cfg(windows)]
     fn load_self() -> Option<~str> {
-        use os::win32::*;
-        do fill_utf16_buf_and_decode() |buf, sz| {
-            libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
+        unsafe {
+            use os::win32::fill_utf16_buf_and_decode;
+            do fill_utf16_buf_and_decode() |buf, sz| {
+                libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
+            }
         }
     }
 
@@ -483,14 +565,14 @@ fn getenv_nonempty(v: &str) -> Option<Path> {
     #[cfg(unix)]
     #[allow(non_implicitly_copyable_typarams)]
     fn lookup() -> Path {
-        option::get_default(getenv_nonempty("TMPDIR"),
+        option::get_or_default(getenv_nonempty("TMPDIR"),
                             Path("/tmp"))
     }
 
     #[cfg(windows)]
     #[allow(non_implicitly_copyable_typarams)]
     fn lookup() -> Path {
-        option::get_default(
+        option::get_or_default(
                     option::or(getenv_nonempty("TMP"),
                     option::or(getenv_nonempty("TEMP"),
                     option::or(getenv_nonempty("USERPROFILE"),
@@ -529,15 +611,19 @@ fn walk_dir_(p: &Path, f: fn(&Path) -> bool) -> bool {
 
 /// Indicates whether a path represents a directory
 pub fn path_is_dir(p: &Path) -> bool {
-    do str::as_c_str(p.to_str()) |buf| {
-        rustrt::rust_path_is_dir(buf) != 0 as c_int
+    unsafe {
+        do str::as_c_str(p.to_str()) |buf| {
+            rustrt::rust_path_is_dir(buf) != 0 as c_int
+        }
     }
 }
 
 /// Indicates whether a path exists
 pub fn path_exists(p: &Path) -> bool {
-    do str::as_c_str(p.to_str()) |buf| {
-        rustrt::rust_path_exists(buf) != 0 as c_int
+    unsafe {
+        do str::as_c_str(p.to_str()) |buf| {
+            rustrt::rust_path_exists(buf) != 0 as c_int
+        }
     }
 }
 
@@ -566,20 +652,24 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool {
 
     #[cfg(windows)]
     fn mkdir(p: &Path, _mode: c_int) -> bool {
-        use os::win32::*;
-        // FIXME: turn mode into something useful? #2623
-        do as_utf16_p(p.to_str()) |buf| {
-            libc::CreateDirectoryW(buf, unsafe {
-                cast::reinterpret_cast(&0)
-            })
-                != (0 as libc::BOOL)
+        unsafe {
+            use os::win32::as_utf16_p;
+            // FIXME: turn mode into something useful? #2623
+            do as_utf16_p(p.to_str()) |buf| {
+                libc::CreateDirectoryW(buf, unsafe {
+                    cast::reinterpret_cast(&0)
+                })
+                    != (0 as libc::BOOL)
+            }
         }
     }
 
     #[cfg(unix)]
     fn mkdir(p: &Path, mode: c_int) -> bool {
-        do as_c_charp(p.to_str()) |c| {
-            libc::mkdir(c, mode as mode_t) == (0 as c_int)
+        unsafe {
+            do as_c_charp(p.to_str()) |c| {
+                libc::mkdir(c, mode as mode_t) == (0 as c_int)
+            }
         }
     }
 }
@@ -587,15 +677,16 @@ fn mkdir(p: &Path, mode: c_int) -> bool {
 /// Lists the contents of a directory
 #[allow(non_implicitly_copyable_typarams)]
 pub fn list_dir(p: &Path) -> ~[~str] {
+    unsafe {
+        #[cfg(unix)]
+        fn star(p: &Path) -> Path { copy *p }
 
-    #[cfg(unix)]
-    fn star(p: &Path) -> Path { copy *p }
-
-    #[cfg(windows)]
-    fn star(p: &Path) -> Path { p.push("*") }
+        #[cfg(windows)]
+        fn star(p: &Path) -> Path { p.push("*") }
 
-    do rustrt::rust_list_files2(star(p).to_str()).filter |filename| {
-        *filename != ~"." && *filename != ~".."
+        do rustrt::rust_list_files2(star(p).to_str()).filtered |filename| {
+            *filename != ~"." && *filename != ~".."
+        }
     }
 }
 
@@ -614,17 +705,21 @@ pub fn remove_dir(p: &Path) -> bool {
 
     #[cfg(windows)]
     fn rmdir(p: &Path) -> bool {
-        use os::win32::*;
-        return do as_utf16_p(p.to_str()) |buf| {
-            libc::RemoveDirectoryW(buf) != (0 as libc::BOOL)
-        };
+        unsafe {
+            use os::win32::as_utf16_p;
+            return do as_utf16_p(p.to_str()) |buf| {
+                libc::RemoveDirectoryW(buf) != (0 as libc::BOOL)
+            };
+        }
     }
 
     #[cfg(unix)]
     fn rmdir(p: &Path) -> bool {
-        return do as_c_charp(p.to_str()) |buf| {
-            libc::rmdir(buf) == (0 as c_int)
-        };
+        unsafe {
+            return do as_c_charp(p.to_str()) |buf| {
+                libc::rmdir(buf) == (0 as c_int)
+            };
+        }
     }
 }
 
@@ -633,17 +728,21 @@ pub fn change_dir(p: &Path) -> bool {
 
     #[cfg(windows)]
     fn chdir(p: &Path) -> bool {
-        use os::win32::*;
-        return do as_utf16_p(p.to_str()) |buf| {
-            libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL)
-        };
+        unsafe {
+            use os::win32::as_utf16_p;
+            return do as_utf16_p(p.to_str()) |buf| {
+                libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL)
+            };
+        }
     }
 
     #[cfg(unix)]
     fn chdir(p: &Path) -> bool {
-        return do as_c_charp(p.to_str()) |buf| {
-            libc::chdir(buf) == (0 as c_int)
-        };
+        unsafe {
+            return do as_c_charp(p.to_str()) |buf| {
+                libc::chdir(buf) == (0 as c_int)
+            };
+        }
     }
 }
 
@@ -653,57 +752,61 @@ pub fn copy_file(from: &Path, to: &Path) -> bool {
 
     #[cfg(windows)]
     fn do_copy_file(from: &Path, to: &Path) -> bool {
-        use os::win32::*;
-        return do as_utf16_p(from.to_str()) |fromp| {
-            do as_utf16_p(to.to_str()) |top| {
-                libc::CopyFileW(fromp, top, (0 as libc::BOOL)) !=
-                    (0 as libc::BOOL)
+        unsafe {
+            use os::win32::as_utf16_p;
+            return do as_utf16_p(from.to_str()) |fromp| {
+                do as_utf16_p(to.to_str()) |top| {
+                    libc::CopyFileW(fromp, top, (0 as libc::BOOL)) !=
+                        (0 as libc::BOOL)
+                }
             }
         }
     }
 
     #[cfg(unix)]
     fn do_copy_file(from: &Path, to: &Path) -> bool {
-        let istream = do as_c_charp(from.to_str()) |fromp| {
-            do as_c_charp("rb") |modebuf| {
-                libc::fopen(fromp, modebuf)
+        unsafe {
+            let istream = do as_c_charp(from.to_str()) |fromp| {
+                do as_c_charp("rb") |modebuf| {
+                    libc::fopen(fromp, modebuf)
+                }
+            };
+            if istream as uint == 0u {
+                return false;
             }
-        };
-        if istream as uint == 0u {
-            return false;
-        }
-        let ostream = do as_c_charp(to.to_str()) |top| {
-            do as_c_charp("w+b") |modebuf| {
-                libc::fopen(top, modebuf)
+            let ostream = do as_c_charp(to.to_str()) |top| {
+                do as_c_charp("w+b") |modebuf| {
+                    libc::fopen(top, modebuf)
+                }
+            };
+            if ostream as uint == 0u {
+                fclose(istream);
+                return false;
             }
-        };
-        if ostream as uint == 0u {
-            fclose(istream);
-            return false;
-        }
-        let bufsize = 8192u;
-        let mut buf = vec::with_capacity::<u8>(bufsize);
-        let mut done = false;
-        let mut ok = true;
-        while !done {
-            do vec::as_mut_buf(buf) |b, _sz| {
-              let nread = libc::fread(b as *mut c_void, 1u as size_t,
-                                      bufsize as size_t,
-                                      istream);
-              if nread > 0 as size_t {
-                  if libc::fwrite(b as *c_void, 1u as size_t, nread,
-                                  ostream) != nread {
-                      ok = false;
+            let bufsize = 8192u;
+            let mut buf = vec::with_capacity::<u8>(bufsize);
+            let mut done = false;
+            let mut ok = true;
+            while !done {
+                do vec::as_mut_buf(buf) |b, _sz| {
+                  let nread = libc::fread(b as *mut c_void, 1u as size_t,
+                                          bufsize as size_t,
+                                          istream);
+                  if nread > 0 as size_t {
+                      if libc::fwrite(b as *c_void, 1u as size_t, nread,
+                                      ostream) != nread {
+                          ok = false;
+                          done = true;
+                      }
+                  } else {
                       done = true;
                   }
-              } else {
-                  done = true;
               }
-          }
+            }
+            fclose(istream);
+            fclose(ostream);
+            return ok;
         }
-        fclose(istream);
-        fclose(ostream);
-        return ok;
     }
 }
 
@@ -713,23 +816,29 @@ pub fn remove_file(p: &Path) -> bool {
 
     #[cfg(windows)]
     fn unlink(p: &Path) -> bool {
-        use os::win32::*;
-        return do as_utf16_p(p.to_str()) |buf| {
-            libc::DeleteFileW(buf) != (0 as libc::BOOL)
-        };
+        unsafe {
+            use os::win32::as_utf16_p;
+            return do as_utf16_p(p.to_str()) |buf| {
+                libc::DeleteFileW(buf) != (0 as libc::BOOL)
+            };
+        }
     }
 
     #[cfg(unix)]
     fn unlink(p: &Path) -> bool {
-        return do as_c_charp(p.to_str()) |buf| {
-            libc::unlink(buf) == (0 as c_int)
-        };
+        unsafe {
+            return do as_c_charp(p.to_str()) |buf| {
+                libc::unlink(buf) == (0 as c_int)
+            };
+        }
     }
 }
 
 /// Get a string representing the platform-dependent last error
 pub fn last_os_error() -> ~str {
-    rustrt::last_os_error()
+    unsafe {
+        rustrt::last_os_error()
+    }
 }
 
 /**
@@ -741,7 +850,9 @@ pub fn last_os_error() -> ~str {
  * ignored and the process exits with the default failure status
  */
 pub fn set_exit_status(code: int) {
-    rustrt::rust_set_exit_status(code as libc::intptr_t);
+    unsafe {
+        rustrt::rust_set_exit_status(code as libc::intptr_t);
+    }
 }
 
 unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
@@ -758,7 +869,7 @@ unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
  * Returns a list of the command line arguments.
  */
 #[cfg(target_os = "macos")]
-fn real_args() -> ~[~str] {
+pub fn real_args() -> ~[~str] {
     unsafe {
         let (argc, argv) = (*_NSGetArgc() as c_int,
                             *_NSGetArgv() as **c_char);
@@ -767,8 +878,9 @@ fn real_args() -> ~[~str] {
 }
 
 #[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
 #[cfg(target_os = "freebsd")]
-fn real_args() -> ~[~str] {
+pub fn real_args() -> ~[~str] {
     unsafe {
         let argc = rustrt::rust_get_argc();
         let argv = rustrt::rust_get_argv();
@@ -777,7 +889,7 @@ fn real_args() -> ~[~str] {
 }
 
 #[cfg(windows)]
-fn real_args() -> ~[~str] {
+pub fn real_args() -> ~[~str] {
     let mut nArgs: c_int = 0;
     let lpArgCount = ptr::to_mut_unsafe_ptr(&mut nArgs);
     let lpCmdLine = GetCommandLineW();
@@ -851,56 +963,113 @@ pub fn set_args(new_args: ~[~str]) {
     pub fn _NSGetArgv() -> ***c_char;
 }
 
-#[cfg(unix)]
-pub fn family() -> ~str { ~"unix" }
+pub mod consts {
 
-#[cfg(windows)]
-pub fn family() -> ~str { ~"windows" }
+    #[cfg(unix)]
+    use os::consts::unix::*;
 
-#[cfg(target_os = "macos")]
-mod consts {
-    pub fn sysname() -> ~str { ~"macos" }
-    pub fn exe_suffix() -> ~str { ~"" }
-    pub fn dll_suffix() -> ~str { ~".dylib" }
-}
+    #[cfg(windows)]
+    use os::consts::windows::*;
 
-#[cfg(target_os = "freebsd")]
-mod consts {
-    pub fn sysname() -> ~str { ~"freebsd" }
-    pub fn exe_suffix() -> ~str { ~"" }
-    pub fn dll_suffix() -> ~str { ~".so" }
-}
+    pub mod unix {
+        pub const FAMILY: &str = "unix";
+    }
 
-#[cfg(target_os = "linux")]
-mod consts {
-    pub fn sysname() -> ~str { ~"linux" }
-    pub fn exe_suffix() -> ~str { ~"" }
-    pub fn dll_suffix() -> ~str { ~".so" }
-}
+    pub mod windows {
+        pub const FAMILY: &str = "windows";
+    }
 
-#[cfg(target_os = "win32")]
-mod consts {
-    pub fn sysname() -> ~str { ~"win32" }
-    pub fn exe_suffix() -> ~str { ~".exe" }
-    pub fn dll_suffix() -> ~str { ~".dll" }
-}
+    #[cfg(target_os = "macos")]
+    use os::consts::macos::*;
+
+    #[cfg(target_os = "freebsd")]
+    use os::consts::freebsd::*;
+
+    #[cfg(target_os = "linux")]
+    use os::consts::linux::*;
+
+    #[cfg(target_os = "android")]
+    use os::consts::android::*;
+
+    #[cfg(target_os = "win32")]
+    use os::consts::win32::*;
+
+    pub mod macos {
+        pub const SYSNAME: &str = "macos";
+        pub const DLL_PREFIX: &str = "lib";
+        pub const DLL_SUFFIX: &str = ".dylib";
+        pub const EXE_SUFFIX: &str = "";
+    }
 
-#[cfg(target_arch = "x86")]
-pub fn arch() -> ~str { ~"x86" }
+    pub mod freebsd {
+        pub const SYSNAME: &str = "freebsd";
+        pub const DLL_PREFIX: &str = "lib";
+        pub const DLL_SUFFIX: &str = ".so";
+        pub const EXE_SUFFIX: &str = "";
+    }
+
+    pub mod linux {
+        pub const SYSNAME: &str = "linux";
+        pub const DLL_PREFIX: &str = "lib";
+        pub const DLL_SUFFIX: &str = ".so";
+        pub const EXE_SUFFIX: &str = "";
+    }
+
+    pub mod android {
+        pub const SYSNAME: &str = "android";
+        pub const DLL_PREFIX: &str = "lib";
+        pub const DLL_SUFFIX: &str = ".so";
+        pub const EXE_SUFFIX: &str = "";
+    }
 
-#[cfg(target_arch = "x86_64")]
-pub fn arch() -> ~str { ~"x86_64" }
+    pub mod win32 {
+        pub const SYSNAME: &str = "win32";
+        pub const DLL_PREFIX: &str = "";
+        pub const DLL_SUFFIX: &str = ".dll";
+        pub const EXE_SUFFIX: &str = ".exe";
+    }
+
+
+    #[cfg(target_arch = "x86")]
+    use os::consts::x86::*;
 
-#[cfg(target_arch = "arm")]
-pub fn arch() -> str { ~"arm" }
+    #[cfg(target_arch = "x86_64")]
+    use os::consts::x86_64::*;
+
+    #[cfg(target_arch = "arm")]
+    use os::consts::arm::*;
+
+    pub mod x86 {
+        pub const ARCH: &str = "x86";
+    }
+    pub mod x86_64 {
+        pub const ARCH: &str = "x86_64";
+    }
+    pub mod arm {
+        pub const ARCH: &str = "arm";
+    }
+}
 
 #[cfg(test)]
 #[allow(non_implicitly_copyable_typarams)]
 mod tests {
+    use debug;
+    use libc::{c_int, c_void, size_t};
+    use libc;
+    use option::{None, Option, Some};
+    use option;
+    use os::{as_c_charp, env, getcwd, getenv, make_absolute, real_args};
+    use os::{remove_file, setenv};
+    use os;
+    use path::Path;
+    use rand;
+    use run;
+    use str;
+    use vec;
 
     #[test]
     pub fn last_os_error() {
-        log(debug, last_os_error());
+        log(debug, os::last_os_error());
     }
 
     #[test]
@@ -1085,34 +1254,36 @@ fn copy_file_does_not_exist() {
 
     #[test]
     fn copy_file_ok() {
-      let tempdir = getcwd(); // would like to use $TMPDIR,
-                              // doesn't seem to work on Linux
-      assert (str::len(tempdir.to_str()) > 0u);
-      let in = tempdir.push("in.txt");
-      let out = tempdir.push("out.txt");
-
-      /* Write the temp input file */
-        let ostream = do as_c_charp(in.to_str()) |fromp| {
-            do as_c_charp("w+b") |modebuf| {
-                libc::fopen(fromp, modebuf)
-            }
-      };
-      assert (ostream as uint != 0u);
-      let s = ~"hello";
-      let mut buf = vec::to_mut(str::to_bytes(s) + ~[0 as u8]);
-      do vec::as_mut_buf(buf) |b, _len| {
-          assert (libc::fwrite(b as *c_void, 1u as size_t,
-                               (str::len(s) + 1u) as size_t, ostream)
-                  == buf.len() as size_t)};
-      assert (libc::fclose(ostream) == (0u as c_int));
-      let rs = os::copy_file(&in, &out);
-      if (!os::path_exists(&in)) {
-        fail (fmt!("%s doesn't exist", in.to_str()));
-      }
-      assert(rs);
-      let rslt = run::run_program(~"diff", ~[in.to_str(), out.to_str()]);
-      assert (rslt == 0);
-      assert (remove_file(&in));
-      assert (remove_file(&out));
+        unsafe {
+          let tempdir = getcwd(); // would like to use $TMPDIR,
+                                  // doesn't seem to work on Linux
+          assert (str::len(tempdir.to_str()) > 0u);
+          let in = tempdir.push("in.txt");
+          let out = tempdir.push("out.txt");
+
+          /* Write the temp input file */
+            let ostream = do as_c_charp(in.to_str()) |fromp| {
+                do as_c_charp("w+b") |modebuf| {
+                    libc::fopen(fromp, modebuf)
+                }
+          };
+          assert (ostream as uint != 0u);
+          let s = ~"hello";
+          let mut buf = vec::to_mut(str::to_bytes(s) + ~[0 as u8]);
+          do vec::as_mut_buf(buf) |b, _len| {
+              assert (libc::fwrite(b as *c_void, 1u as size_t,
+                                   (str::len(s) + 1u) as size_t, ostream)
+                      == buf.len() as size_t)};
+          assert (libc::fclose(ostream) == (0u as c_int));
+          let rs = os::copy_file(&in, &out);
+          if (!os::path_exists(&in)) {
+            fail (fmt!("%s doesn't exist", in.to_str()));
+          }
+          assert(rs);
+          let rslt = run::run_program(~"diff", ~[in.to_str(), out.to_str()]);
+          assert (rslt == 0);
+          assert (remove_file(&in));
+          assert (remove_file(&out));
+        }
     }
 }
index 2f369e18fd1528f3647e1136b258ad275546281c..fb14820113e00b92eaae7d620c99627b5a11930e 100644 (file)
 
 #[cfg(notest)]
 impl<T:Eq> ~const T : Eq {
+    #[inline(always)]
     pure fn eq(&self, other: &~const T) -> bool { *(*self) == *(*other) }
+    #[inline(always)]
     pure fn ne(&self, other: &~const T) -> bool { *(*self) != *(*other) }
 }
 
 #[cfg(notest)]
 impl<T:Ord> ~const T : Ord {
+    #[inline(always)]
     pure fn lt(&self, other: &~const T) -> bool { *(*self) < *(*other) }
+    #[inline(always)]
     pure fn le(&self, other: &~const T) -> bool { *(*self) <= *(*other) }
+    #[inline(always)]
     pure fn ge(&self, other: &~const T) -> bool { *(*self) >= *(*other) }
+    #[inline(always)]
     pure fn gt(&self, other: &~const T) -> bool { *(*self) > *(*other) }
 }
 
index 65ed35159314bd343ca290d6c749061c48ad35e7..7f5f334ac1f9a42876f1b1392336aed1b92083ab 100644 (file)
 #[forbid(deprecated_pattern)];
 
 use cmp::Eq;
+use libc;
+use option::{None, Option, Some};
+use ptr;
+use str;
+use to_str::ToStr;
 
 #[deriving_eq]
 pub struct WindowsPath {
@@ -84,9 +89,13 @@ pub trait GenericPath {
 }
 
 #[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
 mod stat {
     #[cfg(target_arch = "x86")]
+    #[cfg(target_arch = "arm")]
     pub mod arch {
+        use libc;
+
         pub fn default_stat() -> libc::stat {
             libc::stat {
                 st_dev: 0,
@@ -115,6 +124,8 @@ pub fn default_stat() -> libc::stat {
 
     #[cfg(target_arch = "x86_64")]
     pub mod arch {
+        use libc;
+
         pub fn default_stat() -> libc::stat {
             libc::stat {
                 st_dev: 0,
@@ -144,6 +155,8 @@ pub fn default_stat() -> libc::stat {
 mod stat {
     #[cfg(target_arch = "x86_64")]
     pub mod arch {
+        use libc;
+
         pub fn default_stat() -> libc::stat {
             libc::stat {
                 st_dev: 0,
@@ -176,6 +189,8 @@ pub fn default_stat() -> libc::stat {
 #[cfg(target_os = "macos")]
 mod stat {
     pub mod arch {
+        use libc;
+
         pub fn default_stat() -> libc::stat {
             libc::stat {
                 st_dev: 0,
@@ -208,6 +223,7 @@ pub fn default_stat() -> libc::stat {
 #[cfg(target_os = "win32")]
 mod stat {
     pub mod arch {
+        use libc;
         pub fn default_stat() -> libc::stat {
             libc::stat {
                 st_dev: 0,
@@ -229,21 +245,25 @@ pub fn default_stat() -> libc::stat {
 
 impl Path {
     fn stat(&self) -> Option<libc::stat> {
-         do str::as_c_str(self.to_str()) |buf| {
-            let mut st = stat::arch::default_stat();
-            let r = libc::stat(buf, ptr::mut_addr_of(&st));
+        unsafe {
+             do str::as_c_str(self.to_str()) |buf| {
+                let mut st = stat::arch::default_stat();
+                let r = libc::stat(buf, ptr::mut_addr_of(&st));
 
-            if r == 0 { Some(move st) } else { None }
+                if r == 0 { Some(move st) } else { None }
+            }
         }
     }
 
     #[cfg(unix)]
     fn lstat(&self) -> Option<libc::stat> {
-         do str::as_c_str(self.to_str()) |buf| {
-            let mut st = stat::arch::default_stat();
-            let r = libc::lstat(buf, ptr::mut_addr_of(&st));
+        unsafe {
+            do str::as_c_str(self.to_str()) |buf| {
+                let mut st = stat::arch::default_stat();
+                let r = libc::lstat(buf, ptr::mut_addr_of(&st));
 
-            if r == 0 { Some(move st) } else { None }
+                if r == 0 { Some(move st) } else { None }
+            }
         }
     }
 
@@ -737,7 +757,11 @@ impl WindowsPath : GenericPath {
 }
 
 // Various windows helpers, and tests for the impl.
-mod windows {
+pub mod windows {
+    use libc;
+    use option::{None, Option, Some};
+    use to_str::ToStr;
+
     #[inline(always)]
     pub pure fn is_sep(u: u8) -> bool {
         u == '/' as u8 || u == '\\' as u8
@@ -779,6 +803,10 @@ mod windows {
 
 #[cfg(test)]
 mod tests {
+    use option::{None, Some};
+    use path::{PosixPath, WindowsPath, windows};
+    use str;
+
     #[test]
     fn test_double_slash_collapsing() {
         let path = PosixPath("tmp/");
index 59d59d335189632a60e1d955aadbc83c48f273a5..db730fb52b46de279f03180d344d5e1fc75d6eeb 100644 (file)
 use cmp::Eq;
 use cast::{forget, reinterpret_cast, transmute};
 use either::{Either, Left, Right};
+use kinds::Owned;
+use libc;
+use option;
 use option::unwrap;
+use pipes;
+use ptr;
+use prelude::*;
+use private;
+use task;
+use vec;
 
 #[doc(hidden)]
 const SPIN_COUNT: uint = 0;
@@ -164,7 +173,11 @@ unsafe fn mark_blocked(this: *rust_task) -> State {
 
     unsafe fn unblock() {
         let old_task = swap_task(&mut self.blocked_task, ptr::null());
-        if !old_task.is_null() { rustrt::rust_task_deref(old_task) }
+        if !old_task.is_null() {
+            unsafe {
+                rustrt::rust_task_deref(old_task)
+            }
+        }
         match swap_state_acq(&mut self.state, Empty) {
           Empty | Blocked => (),
           Terminated => self.state = Terminated,
@@ -193,7 +206,7 @@ fn set_buffer<T: Owned>(b: ~Buffer<T>) unsafe {
 
 #[doc(hidden)]
 pub trait HasBuffer {
-    // XXX This should not have a trailing underscore
+    // FIXME #4421: This should not have a trailing underscore
     fn set_buffer_(b: *libc::c_void);
 }
 
@@ -291,27 +304,30 @@ pub fn swap_task(dst: &mut *rust_task, src: *rust_task) -> *rust_task {
 #[doc(hidden)]
 extern mod rustrt {
     #[rust_stack]
-    fn rust_get_task() -> *rust_task;
+    unsafe fn rust_get_task() -> *rust_task;
     #[rust_stack]
-    fn rust_task_ref(task: *rust_task);
-    fn rust_task_deref(task: *rust_task);
+    unsafe fn rust_task_ref(task: *rust_task);
+    unsafe fn rust_task_deref(task: *rust_task);
 
     #[rust_stack]
-    fn task_clear_event_reject(task: *rust_task);
+    unsafe fn task_clear_event_reject(task: *rust_task);
 
-    fn task_wait_event(this: *rust_task, killed: &mut *libc::c_void) -> bool;
-    pure fn task_signal_event(target: *rust_task, event: *libc::c_void);
+    unsafe fn task_wait_event(this: *rust_task, killed: &mut *libc::c_void)
+                        -> bool;
+    unsafe fn task_signal_event(target: *rust_task, event: *libc::c_void);
 }
 
 #[doc(hidden)]
 fn wait_event(this: *rust_task) -> *libc::c_void {
-    let mut event = ptr::null();
+    unsafe {
+        let mut event = ptr::null();
 
-    let killed = rustrt::task_wait_event(this, &mut event);
-    if killed && !task::failing() {
-        fail ~"killed"
+        let killed = rustrt::task_wait_event(this, &mut event);
+        if killed && !task::failing() {
+            fail ~"killed"
+        }
+        event
     }
-    event
 }
 
 #[doc(hidden)]
@@ -388,9 +404,12 @@ pub fn send<T: Owned, Tbuffer: Owned>(p: SendPacketBuffered<T, Tbuffer>,
             debug!("waking up task for %?", p_);
             let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
             if !old_task.is_null() {
-                rustrt::task_signal_event(
-                    old_task, ptr::addr_of(&(p.header)) as *libc::c_void);
-                rustrt::rust_task_deref(old_task);
+                unsafe {
+                    rustrt::task_signal_event(
+                        old_task,
+                        ptr::addr_of(&(p.header)) as *libc::c_void);
+                    rustrt::rust_task_deref(old_task);
+                }
             }
 
             // The receiver will eventually clean this up.
@@ -436,7 +455,9 @@ struct DropState {
                 let old_task = swap_task(&mut self.p.blocked_task,
                                          ptr::null());
                 if !old_task.is_null() {
-                    rustrt::rust_task_deref(old_task);
+                    unsafe {
+                        rustrt::rust_task_deref(old_task);
+                    }
                 }
             }
         }
@@ -457,9 +478,11 @@ struct DropState {
     }
 
     // regular path
-    let this = rustrt::rust_get_task();
-    rustrt::task_clear_event_reject(this);
-    rustrt::rust_task_ref(this);
+    let this = unsafe { rustrt::rust_get_task() };
+    unsafe {
+        rustrt::task_clear_event_reject(this);
+        rustrt::rust_task_ref(this);
+    };
     debug!("blocked = %x this = %x", p.header.blocked_task as uint,
            this as uint);
     let old_task = swap_task(&mut p.header.blocked_task, this);
@@ -470,7 +493,10 @@ struct DropState {
     let mut first = true;
     let mut count = SPIN_COUNT;
     loop {
-        rustrt::task_clear_event_reject(this);
+        unsafe {
+            rustrt::task_clear_event_reject(this);
+        }
+
         let old_state = swap_state_acq(&mut p.header.state,
                                        Blocked);
         match old_state {
@@ -498,7 +524,9 @@ struct DropState {
             payload <-> p.payload;
             let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
             if !old_task.is_null() {
-                rustrt::rust_task_deref(old_task);
+                unsafe {
+                    rustrt::rust_task_deref(old_task);
+                }
             }
             p.header.state = Empty;
             return Some(option::unwrap(move payload))
@@ -510,7 +538,9 @@ struct DropState {
 
             let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
             if !old_task.is_null() {
-                rustrt::rust_task_deref(old_task);
+                unsafe {
+                    rustrt::rust_task_deref(old_task);
+                }
             }
             return None;
           }
@@ -545,10 +575,12 @@ fn sender_terminate<T: Owned>(p: *Packet<T>) {
         // wake up the target
         let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
         if !old_task.is_null() {
-            rustrt::task_signal_event(
-                old_task,
-                ptr::addr_of(&(p.header)) as *libc::c_void);
-            rustrt::rust_task_deref(old_task);
+            unsafe {
+                rustrt::task_signal_event(
+                    old_task,
+                    ptr::addr_of(&(p.header)) as *libc::c_void);
+                rustrt::rust_task_deref(old_task);
+            }
         }
         // The receiver will eventually clean up.
       }
@@ -574,8 +606,10 @@ fn receiver_terminate<T: Owned>(p: *Packet<T>) {
       Blocked => {
         let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
         if !old_task.is_null() {
-            rustrt::rust_task_deref(old_task);
-            assert old_task == rustrt::rust_get_task();
+            unsafe {
+                rustrt::rust_task_deref(old_task);
+                assert old_task == rustrt::rust_get_task();
+            }
         }
       }
       Terminated | Full => {
@@ -596,9 +630,12 @@ fn receiver_terminate<T: Owned>(p: *Packet<T>) {
 
 */
 fn wait_many<T: Selectable>(pkts: &[T]) -> uint {
-    let this = rustrt::rust_get_task();
+    let this = unsafe { rustrt::rust_get_task() };
+
+    unsafe {
+        rustrt::task_clear_event_reject(this);
+    }
 
-    rustrt::task_clear_event_reject(this);
     let mut data_avail = false;
     let mut ready_packet = pkts.len();
     for pkts.eachi |i, p| unsafe {
@@ -1231,6 +1268,8 @@ pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T)
 }
 
 pub mod rt {
+    use option::{None, Option, Some};
+
     // These are used to hide the option constructors from the
     // compiler because their names are changing
     pub fn make_some<T>(val: T) -> Option<T> { Some(move val) }
@@ -1239,6 +1278,10 @@ pub fn make_none<T>() -> Option<T> { None }
 
 #[cfg(test)]
 pub mod test {
+    use either::{Either, Left, Right};
+    use pipes::{Chan, Port, oneshot, recv_one, stream};
+    use pipes;
+
     #[test]
     pub fn test_select2() {
         let (p1, c1) = pipes::stream();
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
new file mode 100644 (file)
index 0000000..de23fec
--- /dev/null
@@ -0,0 +1,93 @@
+// This file is imported into every module by default.
+
+/* Reexported core operators */
+
+pub use kinds::{Const, Copy, Owned, Durable};
+pub use ops::{Drop};
+pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
+pub use ops::{BitAnd, BitOr, BitXor};
+pub use ops::{Shl, Shr, Index};
+pub use option::{Option, Some, None};
+pub use result::{Result, Ok, Err};
+
+/* Reexported types and traits */
+
+pub use path::Path;
+pub use path::GenericPath;
+pub use path::WindowsPath;
+pub use path::PosixPath;
+
+pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
+pub use str::{StrSlice, Trimmable};
+pub use vec::{ConstVector, CopyableVector, ImmutableVector};
+pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
+pub use vec::{OwnedVector, OwnedCopyableVector};
+pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
+pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
+
+pub use num::Num;
+pub use ptr::Ptr;
+pub use to_str::ToStr;
+pub use clone::Clone;
+
+pub use cmp::{Eq, Ord};
+pub use hash::Hash;
+pub use to_bytes::IterBytes;
+
+/* Reexported modules */
+
+pub use at_vec;
+pub use bool;
+pub use cast;
+pub use char;
+pub use cmp;
+pub use dvec;
+pub use either;
+pub use extfmt;
+pub use f32;
+pub use f64;
+pub use float;
+pub use i16;
+pub use i32;
+pub use i64;
+pub use i8;
+pub use int;
+pub use io;
+pub use iter;
+pub use libc;
+pub use num;
+pub use oldcomm;
+pub use ops;
+pub use option;
+pub use os;
+pub use path;
+pub use pipes;
+pub use private;
+pub use ptr;
+pub use rand;
+pub use result;
+pub use str;
+pub use sys;
+pub use task;
+pub use to_str;
+pub use u16;
+pub use u32;
+pub use u64;
+pub use u8;
+pub use uint;
+pub use vec;
+
+/*
+ * Export the log levels as global constants. Higher levels mean
+ * more-verbosity. Error is the bottom level, default logging level is
+ * warn-and-below.
+ */
+
+/// The error log level
+pub const error : u32 = 1_u32;
+/// The warning log level
+pub const warn : u32 = 2_u32;
+/// The info log level
+pub const info : u32 = 3_u32;
+/// The debug log level
+pub const debug : u32 = 4_u32;
index 2d597bfb1b5f3271bc026fc17996e75c9d33974b..a88a11969359d20d16d63929444cfb3aafbc98cf 100644 (file)
 
 #[doc(hidden)];
 
-use task::TaskBuilder;
-use task::atomically;
+use cast;
+use iter;
+use libc;
+use oldcomm;
+use option;
+use pipes;
+use prelude::*;
+use ptr;
+use result;
+use task;
+use task::{TaskBuilder, atomically};
+use uint;
 
 extern mod rustrt {
     #[legacy_exports];
-    fn rust_task_weaken(ch: rust_port_id);
-    fn rust_task_unweaken(ch: rust_port_id);
+    unsafe fn rust_task_weaken(ch: rust_port_id);
+    unsafe fn rust_task_unweaken(ch: rust_port_id);
 
-    fn rust_create_little_lock() -> rust_little_lock;
-    fn rust_destroy_little_lock(lock: rust_little_lock);
-    fn rust_lock_little_lock(lock: rust_little_lock);
-    fn rust_unlock_little_lock(lock: rust_little_lock);
+    unsafe fn rust_create_little_lock() -> rust_little_lock;
+    unsafe fn rust_destroy_little_lock(lock: rust_little_lock);
+    unsafe fn rust_lock_little_lock(lock: rust_little_lock);
+    unsafe fn rust_unlock_little_lock(lock: rust_little_lock);
+
+    unsafe fn rust_raw_thread_start(f: &fn()) -> *raw_thread;
+    unsafe fn rust_raw_thread_join_delete(thread: *raw_thread);
 }
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
-
     fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
     fn atomic_xadd(dst: &mut int, src: int) -> int;
     fn atomic_xsub(dst: &mut int, src: int) -> int;
 }
 
+#[allow(non_camel_case_types)] // runtime type
+type raw_thread = libc::c_void;
+
+/**
+
+Start a new thread outside of the current runtime context and wait
+for it to terminate.
+
+The executing thread has no access to a task pointer and will be using
+a normal large stack.
+*/
+pub unsafe fn run_in_bare_thread(f: ~fn()) {
+    let (port, chan) = pipes::stream();
+    // XXX Unfortunate that this creates an extra scheduler but it's necessary
+    // since rust_raw_thread_join_delete is blocking
+    do task::spawn_sched(task::SingleThreaded) unsafe {
+        let closure: &fn() = || {
+            f()
+        };
+        let thread = rustrt::rust_raw_thread_start(closure);
+        rustrt::rust_raw_thread_join_delete(thread);
+        chan.send(());
+    }
+    port.recv();
+}
+
+#[test]
+fn test_run_in_bare_thread() unsafe {
+    let i = 100;
+    do run_in_bare_thread {
+        assert i == 100;
+    }
+}
+
 #[allow(non_camel_case_types)] // runtime type
 type rust_port_id = uint;
 
@@ -73,8 +119,7 @@ enum Msg {
         let (setup1_po, setup1_ch) = pipes::stream();
         let (setup2_po, setup2_ch) = pipes::stream();
 
-        // XXX: Ugly type inference hints
-        let setup1_po: pipes::Port<oldcomm::Chan<T>> = setup1_po;
+        // FIXME #4422: Ugly type inference hint
         let setup2_po: pipes::Port<Msg> = setup2_po;
 
         do task_fn().spawn |move f, move setup1_ch, move setup2_po| {
@@ -481,12 +526,18 @@ pub unsafe fn clone_shared_mutable_state<T: Owned>(rc: &SharedMutableState<T>)
 
 struct LittleLock {
     l: rust_little_lock,
-    drop { rustrt::rust_destroy_little_lock(self.l); }
+    drop {
+        unsafe {
+            rustrt::rust_destroy_little_lock(self.l);
+        }
+    }
 }
 
 fn LittleLock() -> LittleLock {
-    LittleLock {
-        l: rustrt::rust_create_little_lock()
+    unsafe {
+        LittleLock {
+            l: rustrt::rust_create_little_lock()
+        }
     }
 }
 
@@ -495,7 +546,11 @@ impl LittleLock {
     unsafe fn lock<T>(f: fn() -> T) -> T {
         struct Unlock {
             l: rust_little_lock,
-            drop { rustrt::rust_unlock_little_lock(self.l); }
+            drop {
+                unsafe {
+                    rustrt::rust_unlock_little_lock(self.l);
+                }
+            }
         }
 
         fn Unlock(l: rust_little_lock) -> Unlock {
@@ -571,6 +626,15 @@ pub fn unwrap_exclusive<T: Owned>(arc: Exclusive<T>) -> T {
 
 #[cfg(test)]
 pub mod tests {
+    use core::option::{None, Some};
+
+    use option;
+    use pipes;
+    use private::{exclusive, unwrap_exclusive};
+    use result;
+    use task;
+    use uint;
+
     #[test]
     pub fn exclusive_arc() {
         let mut futures = ~[];
index c838af700f65e5c319cb9d6c2644e531a7075ac7..17c3c11e572d2ca115500484b2bbd21941f1a6a7 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use cast;
 use cmp::{Eq, Ord};
+use libc;
 use libc::{c_void, size_t};
+use ptr;
+use str;
+use sys;
+use vec;
 
 #[nolink]
 #[abi = "cdecl"]
 extern mod libc_ {
     #[rust_stack]
-    fn memcpy(dest: *mut c_void, src: *const c_void,
-              n: libc::size_t) -> *c_void;
+    unsafe fn memcpy(dest: *mut c_void,
+                     src: *const c_void,
+                     n: libc::size_t)
+                  -> *c_void;
 
     #[rust_stack]
-    fn memmove(dest: *mut c_void, src: *const c_void,
-               n: libc::size_t) -> *c_void;
+    unsafe fn memmove(dest: *mut c_void,
+                      src: *const c_void,
+                      n: libc::size_t)
+                   -> *c_void;
 
     #[rust_stack]
-    fn memset(dest: *mut c_void, c: libc::c_int,
-              len: libc::size_t) -> *c_void;
+    unsafe fn memset(dest: *mut c_void,
+                     c: libc::c_int,
+                     len: libc::size_t)
+                  -> *c_void;
 }
 
 #[abi = "rust-intrinsic"]
@@ -96,9 +108,11 @@ pub unsafe fn position<T>(buf: *T, f: fn(&T) -> bool) -> uint {
 pub pure fn mut_null<T>() -> *mut T { unsafe { cast::reinterpret_cast(&0u) } }
 
 /// Returns true if the pointer is equal to the null pointer.
+#[inline(always)]
 pub pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }
 
 /// Returns true if the pointer is not equal to the null pointer.
+#[inline(always)]
 pub pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
 
 /**
@@ -108,7 +122,7 @@ pub unsafe fn position<T>(buf: *T, f: fn(&T) -> bool) -> uint {
  * and destination may not overlap.
  */
 #[inline(always)]
-pub unsafe fn memcpy<T>(dst: *mut T, src: *const T, count: uint) {
+pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
     let n = count * sys::size_of::<T>();
     libc_::memcpy(dst as *mut c_void, src as *c_void, n as size_t);
 }
@@ -120,13 +134,14 @@ pub unsafe fn memcpy<T>(dst: *mut T, src: *const T, count: uint) {
  * and destination may overlap.
  */
 #[inline(always)]
-pub unsafe fn memmove<T>(dst: *mut T, src: *const T, count: uint) {
+pub unsafe fn copy_overlapping_memory<T>(dst: *mut T, src: *const T,
+                                         count: uint) {
     let n = count * sys::size_of::<T>();
     libc_::memmove(dst as *mut c_void, src as *c_void, n as size_t);
 }
 
 #[inline(always)]
-pub unsafe fn memset<T>(dst: *mut T, c: int, count: uint) {
+pub unsafe fn set_memory<T>(dst: *mut T, c: int, count: uint) {
     let n = count * sys::size_of::<T>();
     libc_::memset(dst as *mut c_void, c as libc::c_int, n as size_t);
 }
@@ -219,32 +234,38 @@ impl<T> *mut T: Ptr<T> {
 // Equality for pointers
 #[cfg(notest)]
 impl<T> *const T : Eq {
+    #[inline(always)]
     pure fn eq(&self, other: &*const T) -> bool unsafe {
         let a: uint = cast::reinterpret_cast(&(*self));
         let b: uint = cast::reinterpret_cast(&(*other));
         return a == b;
     }
+    #[inline(always)]
     pure fn ne(&self, other: &*const T) -> bool { !(*self).eq(other) }
 }
 
 // Comparison for pointers
 #[cfg(notest)]
 impl<T> *const T : Ord {
+    #[inline(always)]
     pure fn lt(&self, other: &*const T) -> bool unsafe {
         let a: uint = cast::reinterpret_cast(&(*self));
         let b: uint = cast::reinterpret_cast(&(*other));
         return a < b;
     }
+    #[inline(always)]
     pure fn le(&self, other: &*const T) -> bool unsafe {
         let a: uint = cast::reinterpret_cast(&(*self));
         let b: uint = cast::reinterpret_cast(&(*other));
         return a <= b;
     }
+    #[inline(always)]
     pure fn ge(&self, other: &*const T) -> bool unsafe {
         let a: uint = cast::reinterpret_cast(&(*self));
         let b: uint = cast::reinterpret_cast(&(*other));
         return a >= b;
     }
+    #[inline(always)]
     pure fn gt(&self, other: &*const T) -> bool unsafe {
         let a: uint = cast::reinterpret_cast(&(*self));
         let b: uint = cast::reinterpret_cast(&(*other));
@@ -255,9 +276,11 @@ impl<T> *const T : Ord {
 // Equality for region pointers
 #[cfg(notest)]
 impl<T:Eq> &const T : Eq {
+    #[inline(always)]
     pure fn eq(&self, other: & &self/const T) -> bool {
         return *(*self) == *(*other);
     }
+    #[inline(always)]
     pure fn ne(&self, other: & &self/const T) -> bool {
         return *(*self) != *(*other);
     }
@@ -266,15 +289,19 @@ impl<T:Eq> &const T : Eq {
 // Comparison for region pointers
 #[cfg(notest)]
 impl<T:Ord> &const T : Ord {
+    #[inline(always)]
     pure fn lt(&self, other: & &self/const T) -> bool {
         *(*self) < *(*other)
     }
+    #[inline(always)]
     pure fn le(&self, other: & &self/const T) -> bool {
         *(*self) <= *(*other)
     }
+    #[inline(always)]
     pure fn ge(&self, other: & &self/const T) -> bool {
         *(*self) >= *(*other)
     }
+    #[inline(always)]
     pure fn gt(&self, other: & &self/const T) -> bool {
         *(*self) > *(*other)
     }
@@ -300,13 +327,13 @@ pub fn test() {
         let mut v0 = ~[32000u16, 32001u16, 32002u16];
         let mut v1 = ~[0u16, 0u16, 0u16];
 
-        ptr::memcpy(ptr::mut_offset(vec::raw::to_mut_ptr(v1), 1u),
+        ptr::copy_memory(ptr::mut_offset(vec::raw::to_mut_ptr(v1), 1u),
                     ptr::offset(vec::raw::to_ptr(v0), 1u), 1u);
         assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
-        ptr::memcpy(vec::raw::to_mut_ptr(v1),
+        ptr::copy_memory(vec::raw::to_mut_ptr(v1),
                     ptr::offset(vec::raw::to_ptr(v0), 2u), 1u);
         assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
-        ptr::memcpy(ptr::mut_offset(vec::raw::to_mut_ptr(v1), 2u),
+        ptr::copy_memory(ptr::mut_offset(vec::raw::to_mut_ptr(v1), 2u),
                     vec::raw::to_ptr(v0), 1u);
         assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
     }
index 8ee857ef927d19634a4e0e5cc35c3150f55d8c16..e2101e06bfab9ebdff7f674a7d4066364151d0dd 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use int;
+use prelude::*;
+use str;
+use task;
+use u32;
+use uint;
+use util;
+use vec;
+
 #[allow(non_camel_case_types)] // runtime type
 enum rctx {}
 
 #[abi = "cdecl"]
 extern mod rustrt {
-    fn rand_seed() -> ~[u8];
-    fn rand_new() -> *rctx;
-    fn rand_new_seeded2(&&seed: ~[u8]) -> *rctx;
-    fn rand_next(c: *rctx) -> u32;
-    fn rand_free(c: *rctx);
+    unsafe fn rand_seed() -> ~[u8];
+    unsafe fn rand_new() -> *rctx;
+    unsafe fn rand_new_seeded2(&&seed: ~[u8]) -> *rctx;
+    unsafe fn rand_next(c: *rctx) -> u32;
+    unsafe fn rand_free(c: *rctx);
 }
 
 /// A random number generator
@@ -256,7 +265,11 @@ fn shuffle_mut<T>(values: &[mut T]) {
 
 struct RandRes {
     c: *rctx,
-    drop { rustrt::rand_free(self.c); }
+    drop {
+        unsafe {
+            rustrt::rand_free(self.c);
+        }
+    }
 }
 
 fn RandRes(c: *rctx) -> RandRes {
@@ -266,17 +279,25 @@ fn RandRes(c: *rctx) -> RandRes {
 }
 
 impl @RandRes: Rng {
-    fn next() -> u32 { return rustrt::rand_next((*self).c); }
+    fn next() -> u32 {
+        unsafe {
+            return rustrt::rand_next((*self).c);
+        }
+    }
 }
 
 /// Create a new random seed for seeded_rng
 pub fn seed() -> ~[u8] {
-    rustrt::rand_seed()
+    unsafe {
+        rustrt::rand_seed()
+    }
 }
 
 /// Create a random number generator with a system specified seed
 pub fn Rng() -> Rng {
-    @RandRes(rustrt::rand_new()) as Rng
+    unsafe {
+        @RandRes(rustrt::rand_new()) as Rng
+    }
 }
 
 /**
@@ -286,7 +307,9 @@ pub fn Rng() -> Rng {
  * length.
  */
 pub fn seeded_rng(seed: &~[u8]) -> Rng {
-    @RandRes(rustrt::rand_new_seeded2(*seed)) as Rng
+    unsafe {
+        @RandRes(rustrt::rand_new_seeded2(*seed)) as Rng
+    }
 }
 
 type XorShiftState = {
@@ -334,11 +357,11 @@ pub fn task_rng() -> Rng {
     }
     match r {
         None => {
-            let rng = @RandRes(rustrt::rand_new());
             unsafe {
+                let rng = @RandRes(rustrt::rand_new());
                 task::local_data::local_data_set(tls_rng_state, rng);
+                rng as Rng
             }
-            rng as Rng
         }
         Some(rng) => rng as Rng
     }
@@ -354,6 +377,10 @@ pub fn random() -> uint {
 
 #[cfg(test)]
 pub mod tests {
+    use debug;
+    use option::{None, Option, Some};
+    use rand;
+
     #[test]
     pub fn rng_seeded() {
         let seed = rand::seed();
index 268d5e1baa6e5c92ad50ac30aa94374e8987395f..55eb53bc0266a509567fd96a5c39ca35dfe00ee3 100644 (file)
@@ -19,6 +19,8 @@
 
 use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor};
 use libc::c_void;
+use sys;
+use vec;
 
 /**
  * Trait for visitor that wishes to reflect on data. To use this, create a
index 111070e5b24c737b593e7e1c49a1a8eb80aef161..1e6aa6324aa5d36e2e2b525d79d8d7ba02af97a0 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
-use io::{Writer, WriterUtil};
-use libc::c_void;
-use to_str::ToStr;
 use cast::transmute;
+use cast;
+use char;
+use dvec::DVec;
+use intrinsic;
 use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
+use io;
+use io::{Writer, WriterUtil};
+use libc::c_void;
+use managed;
+use managed::raw::BoxHeaderRepr;
+use ptr;
+use reflect;
 use reflect::{MovePtr, MovePtrAdaptor, align};
+use repr;
+use str;
+use sys;
+use sys::TypeDesc;
+use to_str::ToStr;
+use uint;
 use vec::UnboxedVecRepr;
 use vec::raw::{VecRepr, SliceRepr};
+use vec;
+
 pub use managed::raw::BoxRepr;
-use dvec::DVec;
 
 /// Helpers
 
@@ -45,7 +60,8 @@ fn write_escaped_char(ch: char) {
             '"' => self.write_str("\\\""),
             '\x20'..'\x7e' => self.write_char(ch),
             _ => {
-                // XXX: This is inefficient because it requires a malloc.
+                // FIXME #4423: This is inefficient because it requires a
+                // malloc.
                 self.write_str(char::escape_unicode(ch))
             }
         }
@@ -81,7 +97,7 @@ impl i32 : Repr {
     fn write_repr(writer: @Writer) { writer.write_int(self as int); }
 }
 impl i64 : Repr {
-    // XXX: This can lose precision.
+    // FIXME #4424: This can lose precision.
     fn write_repr(writer: @Writer) { writer.write_int(self as int); }
 }
 
@@ -98,20 +114,20 @@ impl u32 : Repr {
     fn write_repr(writer: @Writer) { writer.write_uint(self as uint); }
 }
 impl u64 : Repr {
-    // XXX: This can lose precision.
+    // FIXME #4424: This can lose precision.
     fn write_repr(writer: @Writer) { writer.write_uint(self as uint); }
 }
 
 impl float : Repr {
-    // XXX: This mallocs.
+    // FIXME #4423: This mallocs.
     fn write_repr(writer: @Writer) { writer.write_str(self.to_str()); }
 }
 impl f32 : Repr {
-    // XXX: This mallocs.
+    // FIXME #4423 This mallocs.
     fn write_repr(writer: @Writer) { writer.write_str(self.to_str()); }
 }
 impl f64 : Repr {
-    // XXX: This mallocs.
+    // FIXME #4423: This mallocs.
     fn write_repr(writer: @Writer) { writer.write_str(self.to_str()); }
 }
 
index e93d186049ecc90e9a9b9cadd58930bc038b5436..9a09f1901ff7c355bb0fcb09f1344d8d685e7ed7 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use cmp;
 use cmp::Eq;
+use either;
 use either::Either;
+use kinds::Copy;
+use option::{None, Option, Some};
+use vec;
 
 /// The result type
 #[deriving_eq]
@@ -34,6 +39,7 @@ pub enum Result<T, U> {
  *
  * If the result is an error
  */
+#[inline(always)]
 pub pure fn get<T: Copy, U>(res: &Result<T, U>) -> T {
     match *res {
       Ok(copy t) => t,
@@ -50,6 +56,7 @@ pub enum Result<T, U> {
  *
  * If the result is an error
  */
+#[inline(always)]
 pub pure fn get_ref<T, U>(res: &a/Result<T, U>) -> &a/T {
     match *res {
         Ok(ref t) => t,
@@ -66,6 +73,7 @@ pub enum Result<T, U> {
  *
  * If the result is not an error
  */
+#[inline(always)]
 pub pure fn get_err<T, U: Copy>(res: &Result<T, U>) -> U {
     match *res {
       Err(copy u) => u,
@@ -74,6 +82,7 @@ pub enum Result<T, U> {
 }
 
 /// Returns true if the result is `ok`
+#[inline(always)]
 pub pure fn is_ok<T, U>(res: &Result<T, U>) -> bool {
     match *res {
       Ok(_) => true,
@@ -82,6 +91,7 @@ pub enum Result<T, U> {
 }
 
 /// Returns true if the result is `err`
+#[inline(always)]
 pub pure fn is_err<T, U>(res: &Result<T, U>) -> bool {
     !is_ok(res)
 }
@@ -92,6 +102,7 @@ pub enum Result<T, U> {
  * `ok` result variants are converted to `either::right` variants, `err`
  * result variants are converted to `either::left`.
  */
+#[inline(always)]
 pub pure fn to_either<T: Copy, U: Copy>(res: &Result<U, T>)
     -> Either<T, U> {
     match *res {
@@ -114,6 +125,7 @@ pub enum Result<T, U> {
  *         ok(parse_bytes(buf))
  *     }
  */
+#[inline(always)]
 pub pure fn chain<T, U, V>(res: Result<T, V>, op: fn(T)
     -> Result<U, V>) -> Result<U, V> {
     match move res {
@@ -130,6 +142,7 @@ pub enum Result<T, U> {
  * immediately returned.  This function can be used to pass through a
  * successful result while handling an error.
  */
+#[inline(always)]
 pub pure fn chain_err<T, U, V>(
     res: Result<T, V>,
     op: fn(t: V) -> Result<T, U>)
@@ -154,6 +167,7 @@ pub enum Result<T, U> {
  *         print_buf(buf)
  *     }
  */
+#[inline(always)]
 pub pure fn iter<T, E>(res: &Result<T, E>, f: fn(&T)) {
     match *res {
       Ok(ref t) => f(t),
@@ -169,6 +183,7 @@ pub enum Result<T, U> {
  * This function can be used to pass through a successful result while
  * handling an error.
  */
+#[inline(always)]
 pub pure fn iter_err<T, E>(res: &Result<T, E>, f: fn(&E)) {
     match *res {
       Ok(_) => (),
@@ -190,6 +205,7 @@ pub enum Result<T, U> {
  *         parse_bytes(buf)
  *     }
  */
+#[inline(always)]
 pub pure fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: fn(&T) -> U)
   -> Result<U, E> {
     match *res {
@@ -206,6 +222,7 @@ pub enum Result<T, U> {
  * is immediately returned.  This function can be used to pass through a
  * successful result while handling an error.
  */
+#[inline(always)]
 pub pure fn map_err<T: Copy, E, F: Copy>(res: &Result<T, E>, op: fn(&E) -> F)
   -> Result<T, F> {
     match *res {
@@ -284,6 +301,7 @@ impl<T, E: Copy> Result<T, E> {
  *         assert incd == ~[2u, 3u, 4u];
  *     }
  */
+#[inline(always)]
 pub fn map_vec<T,U:Copy,V:Copy>(
     ts: &[T], op: fn(&T) -> Result<V,U>) -> Result<~[V],U> {
 
@@ -297,6 +315,7 @@ pub fn map_vec<T,U:Copy,V:Copy>(
     return Ok(move vs);
 }
 
+#[inline(always)]
 pub fn map_opt<T,U:Copy,V:Copy>(
     o_t: &Option<T>, op: fn(&T) -> Result<V,U>) -> Result<Option<V>,U> {
 
@@ -318,6 +337,7 @@ pub fn map_opt<T,U:Copy,V:Copy>(
  * used in 'careful' code contexts where it is both appropriate and easy
  * to accommodate an error like the vectors being of different lengths.
  */
+#[inline(always)]
 pub fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
                 op: fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
 
@@ -340,6 +360,7 @@ pub fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
  * error.  This could be implemented using `map2()` but it is more efficient
  * on its own as no result vector is built.
  */
+#[inline(always)]
 pub fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
                          op: fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
 
@@ -378,6 +399,10 @@ pub fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
 #[allow(non_implicitly_copyable_typarams)]
 mod tests {
     #[legacy_exports];
+
+    use result::{Err, Ok, Result, chain, get, get_err};
+    use result;
+
     fn op1() -> result::Result<int, ~str> { result::Ok(666) }
 
     fn op2(i: int) -> result::Result<uint, ~str> {
index 120103bd65683dcefd8050707977ee5d5114fa60..e0eb2fcfd83e9d9512058ef58741150bf270919d 100644 (file)
 #[forbid(deprecated_pattern)];
 //! Runtime calls emitted by the compiler.
 
-use libc::c_char;
-use libc::c_void;
-use libc::size_t;
-use libc::uintptr_t;
+use libc::{c_char, c_void, size_t, uintptr_t};
+use str;
+use sys;
 
 use gc::{cleanup_stack_for_failure, gc, Word};
 
 
 extern mod rustrt {
     #[rust_stack]
-    fn rust_upcall_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char;
+    unsafe fn rust_upcall_exchange_malloc(td: *c_char, size: uintptr_t)
+                                       -> *c_char;
 
     #[rust_stack]
-    fn rust_upcall_exchange_free(ptr: *c_char);
+    unsafe fn rust_upcall_exchange_free(ptr: *c_char);
 
     #[rust_stack]
-    fn rust_upcall_malloc(td: *c_char, size: uintptr_t) -> *c_char;
+    unsafe fn rust_upcall_malloc(td: *c_char, size: uintptr_t) -> *c_char;
 
     #[rust_stack]
-    fn rust_upcall_free(ptr: *c_char);
+    unsafe fn rust_upcall_free(ptr: *c_char);
 }
 
-// FIXME (#2861): This needs both the attribute, and the name prefixed with
-// 'rt_', otherwise the compiler won't find it. To fix this, see
-// gather_rust_rtcalls.
 #[rt(fail_)]
+#[lang="fail_"]
 pub fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
     sys::begin_unwind_(expr, file, line);
 }
 
 #[rt(fail_bounds_check)]
-pub fn rt_fail_bounds_check(file: *c_char, line: size_t,
-                        index: size_t, len: size_t) {
+#[lang="fail_bounds_check"]
+pub unsafe fn rt_fail_bounds_check(file: *c_char, line: size_t,
+                                   index: size_t, len: size_t) {
     let msg = fmt!("index out of bounds: the len is %d but the index is %d",
                     len as int, index as int);
     do str::as_buf(msg) |p, _len| {
@@ -58,7 +57,8 @@ pub fn rt_fail_bounds_check(file: *c_char, line: size_t,
 }
 
 #[rt(exchange_malloc)]
-pub fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
+#[lang="exchange_malloc"]
+pub unsafe fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
     return rustrt::rust_upcall_exchange_malloc(td, size);
 }
 
@@ -66,12 +66,14 @@ pub fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
 // inside a landing pad may corrupt the state of the exception handler. If a
 // problem occurs, call exit instead.
 #[rt(exchange_free)]
-pub fn rt_exchange_free(ptr: *c_char) {
+#[lang="exchange_free"]
+pub unsafe fn rt_exchange_free(ptr: *c_char) {
     rustrt::rust_upcall_exchange_free(ptr);
 }
 
 #[rt(malloc)]
-pub fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
+#[lang="malloc"]
+pub unsafe fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
     return rustrt::rust_upcall_malloc(td, size);
 }
 
@@ -79,7 +81,8 @@ pub fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
 // inside a landing pad may corrupt the state of the exception handler. If a
 // problem occurs, call exit instead.
 #[rt(free)]
-pub fn rt_free(ptr: *c_char) {
+#[lang="free"]
+pub unsafe fn rt_free(ptr: *c_char) {
     rustrt::rust_upcall_free(ptr);
 }
 
index 3af854236e1fa2a26aeaa53b178259fe9b96877a..54bce77d30885406f1466355ca360c7bf4806ab3 100644 (file)
 #[forbid(deprecated_pattern)];
 
 //! Process spawning
-use option::{Some, None};
-use libc::{pid_t, c_void, c_int};
+use io;
 use io::ReaderUtil;
+use libc;
+use libc::{pid_t, c_void, c_int};
+use oldcomm;
+use option::{Some, None};
+use os;
+use prelude::*;
+use ptr;
+use run;
+use str;
+use task;
+use vec;
 
 #[abi = "cdecl"]
 extern mod rustrt {
-    fn rust_run_program(argv: **libc::c_char, envp: *c_void,
-                        dir: *libc::c_char,
-                        in_fd: c_int, out_fd: c_int, err_fd: c_int)
-        -> pid_t;
+    unsafe fn rust_run_program(argv: **libc::c_char, envp: *c_void,
+                               dir: *libc::c_char,
+                               in_fd: c_int, out_fd: c_int, err_fd: c_int)
+                            -> pid_t;
 }
 
 /// A value representing a child process
@@ -74,12 +84,14 @@ pub fn spawn_process(prog: &str, args: &[~str],
                  env: &Option<~[(~str,~str)]>,
                  dir: &Option<~str>,
                  in_fd: c_int, out_fd: c_int, err_fd: c_int)
-   -> pid_t {
-    do with_argv(prog, args) |argv| {
-        do with_envp(env) |envp| {
-            do with_dirp(dir) |dirp| {
-                rustrt::rust_run_program(argv, envp, dirp,
-                                         in_fd, out_fd, err_fd)
+              -> pid_t {
+    unsafe {
+        do with_argv(prog, args) |argv| {
+            do with_envp(env) |envp| {
+                do with_dirp(dir) |dirp| {
+                    rustrt::rust_run_program(argv, envp, dirp,
+                                             in_fd, out_fd, err_fd)
+                }
             }
         }
     }
@@ -192,69 +204,83 @@ pub fn run_program(prog: &str, args: &[~str]) -> int {
  * A class with a <program> field
  */
 pub fn start_program(prog: &str, args: &[~str]) -> Program {
-    let pipe_input = os::pipe();
-    let pipe_output = os::pipe();
-    let pipe_err = os::pipe();
-    let pid =
-        spawn_process(prog, args, &None, &None,
-                      pipe_input.in, pipe_output.out,
-                      pipe_err.out);
+    unsafe {
+        let pipe_input = os::pipe();
+        let pipe_output = os::pipe();
+        let pipe_err = os::pipe();
+        let pid =
+            spawn_process(prog, args, &None, &None,
+                          pipe_input.in, pipe_output.out,
+                          pipe_err.out);
+
+        unsafe {
+            if pid == -1 as pid_t { fail; }
+            libc::close(pipe_input.in);
+            libc::close(pipe_output.out);
+            libc::close(pipe_err.out);
+        }
 
-    if pid == -1 as pid_t { fail; }
-    libc::close(pipe_input.in);
-    libc::close(pipe_output.out);
-    libc::close(pipe_err.out);
-
-    type ProgRepr = {pid: pid_t,
-                     mut in_fd: c_int,
-                     out_file: *libc::FILE,
-                     err_file: *libc::FILE,
-                     mut finished: bool};
-
-    fn close_repr_input(r: &ProgRepr) {
-        let invalid_fd = -1i32;
-        if r.in_fd != invalid_fd {
-            libc::close(r.in_fd);
-            r.in_fd = invalid_fd;
+        type ProgRepr = {pid: pid_t,
+                         mut in_fd: c_int,
+                         out_file: *libc::FILE,
+                         err_file: *libc::FILE,
+                         mut finished: bool};
+
+        fn close_repr_input(r: &ProgRepr) {
+            let invalid_fd = -1i32;
+            if r.in_fd != invalid_fd {
+                unsafe {
+                    libc::close(r.in_fd);
+                }
+                r.in_fd = invalid_fd;
+            }
+        }
+        fn finish_repr(r: &ProgRepr) -> int {
+            if r.finished { return 0; }
+            r.finished = true;
+            close_repr_input(r);
+            return waitpid(r.pid);
+        }
+        fn destroy_repr(r: &ProgRepr) {
+            unsafe {
+                finish_repr(r);
+                libc::fclose(r.out_file);
+                libc::fclose(r.err_file);
+            }
+        }
+        struct ProgRes {
+            r: ProgRepr,
+            drop { destroy_repr(&self.r); }
         }
-    }
-    fn finish_repr(r: &ProgRepr) -> int {
-        if r.finished { return 0; }
-        r.finished = true;
-        close_repr_input(r);
-        return waitpid(r.pid);
-    }
-    fn destroy_repr(r: &ProgRepr) {
-        finish_repr(r);
-       libc::fclose(r.out_file);
-       libc::fclose(r.err_file);
-    }
-    struct ProgRes {
-        r: ProgRepr,
-        drop { destroy_repr(&self.r); }
-    }
 
-    fn ProgRes(r: ProgRepr) -> ProgRes {
-        ProgRes {
-            r: move r
+        fn ProgRes(r: ProgRepr) -> ProgRes {
+            ProgRes {
+                r: move r
+            }
         }
-    }
 
-    impl ProgRes: Program {
-        fn get_id() -> pid_t { return self.r.pid; }
-        fn input() -> io::Writer { io::fd_writer(self.r.in_fd, false) }
-        fn output() -> io::Reader { io::FILE_reader(self.r.out_file, false) }
-        fn err() -> io::Reader { io::FILE_reader(self.r.err_file, false) }
-        fn close_input() { close_repr_input(&self.r); }
-        fn finish() -> int { finish_repr(&self.r) }
-        fn destroy() { destroy_repr(&self.r); }
+        impl ProgRes: Program {
+            fn get_id() -> pid_t { return self.r.pid; }
+            fn input() -> io::Writer {
+                io::fd_writer(self.r.in_fd, false)
+            }
+            fn output() -> io::Reader {
+                io::FILE_reader(self.r.out_file, false)
+            }
+            fn err() -> io::Reader {
+                io::FILE_reader(self.r.err_file, false)
+            }
+            fn close_input() { close_repr_input(&self.r); }
+            fn finish() -> int { finish_repr(&self.r) }
+            fn destroy() { destroy_repr(&self.r); }
+        }
+        let repr = {pid: pid,
+                    mut in_fd: pipe_input.out,
+                    out_file: os::fdopen(pipe_output.in),
+                    err_file: os::fdopen(pipe_err.in),
+                    mut finished: false};
+        return ProgRes(move repr) as Program;
     }
-    let repr = {pid: pid,
-                mut in_fd: pipe_input.out,
-                out_file: os::fdopen(pipe_output.in),
-                err_file: os::fdopen(pipe_err.in),
-                mut finished: false};
-    return ProgRes(move repr) as Program;
 }
 
 fn read_all(rd: io::Reader) -> ~str {
@@ -284,63 +310,64 @@ fn read_all(rd: io::Reader) -> ~str {
  */
 pub fn program_output(prog: &str, args: &[~str]) ->
    {status: int, out: ~str, err: ~str} {
+    unsafe {
+        let pipe_in = os::pipe();
+        let pipe_out = os::pipe();
+        let pipe_err = os::pipe();
+        let pid = spawn_process(prog, args, &None, &None,
+                                pipe_in.in, pipe_out.out, pipe_err.out);
 
-    let pipe_in = os::pipe();
-    let pipe_out = os::pipe();
-    let pipe_err = os::pipe();
-    let pid = spawn_process(prog, args, &None, &None,
-                            pipe_in.in, pipe_out.out, pipe_err.out);
+        os::close(pipe_in.in);
+        os::close(pipe_out.out);
+        os::close(pipe_err.out);
+        if pid == -1i32 {
+            os::close(pipe_in.out);
+            os::close(pipe_out.in);
+            os::close(pipe_err.in);
+            fail;
+        }
 
-    os::close(pipe_in.in);
-    os::close(pipe_out.out);
-    os::close(pipe_err.out);
-    if pid == -1i32 {
         os::close(pipe_in.out);
-        os::close(pipe_out.in);
-        os::close(pipe_err.in);
-        fail;
-    }
 
-    os::close(pipe_in.out);
-
-    // Spawn two entire schedulers to read both stdout and sterr
-    // in parallel so we don't deadlock while blocking on one
-    // or the other. FIXME (#2625): Surely there's a much more
-    // clever way to do this.
-    let p = oldcomm::Port();
-    let ch = oldcomm::Chan(&p);
-    do task::spawn_sched(task::SingleThreaded) {
-        let errput = readclose(pipe_err.in);
-        oldcomm::send(ch, (2, move errput));
-    };
-    do task::spawn_sched(task::SingleThreaded) {
-        let output = readclose(pipe_out.in);
-        oldcomm::send(ch, (1, move output));
-    };
-    let status = run::waitpid(pid);
-    let mut errs = ~"";
-    let mut outs = ~"";
-    let mut count = 2;
-    while count > 0 {
-        let stream = oldcomm::recv(p);
-        match stream {
-            (1, copy s) => {
-                outs = move s;
-            }
-            (2, copy s) => {
-                errs = move s;
-            }
-            (n, _) => {
-                fail(fmt!("program_output received an unexpected file \
-                           number: %u", n));
-            }
+        // Spawn two entire schedulers to read both stdout and sterr
+        // in parallel so we don't deadlock while blocking on one
+        // or the other. FIXME (#2625): Surely there's a much more
+        // clever way to do this.
+        let p = oldcomm::Port();
+        let ch = oldcomm::Chan(&p);
+        do task::spawn_sched(task::SingleThreaded) {
+            let errput = readclose(pipe_err.in);
+            oldcomm::send(ch, (2, move errput));
+        };
+        do task::spawn_sched(task::SingleThreaded) {
+            let output = readclose(pipe_out.in);
+            oldcomm::send(ch, (1, move output));
+        };
+        let status = run::waitpid(pid);
+        let mut errs = ~"";
+        let mut outs = ~"";
+        let mut count = 2;
+        while count > 0 {
+            let stream = oldcomm::recv(p);
+            match stream {
+                (1, copy s) => {
+                    outs = move s;
+                }
+                (2, copy s) => {
+                    errs = move s;
+                }
+                (n, _) => {
+                    fail(fmt!("program_output received an unexpected file \
+                               number: %u", n));
+                }
+            };
+            count -= 1;
         };
-        count -= 1;
-    };
-    return {status: status, out: move outs, err: move errs};
+        return {status: status, out: move outs, err: move errs};
+    }
 }
 
-fn writeclose(fd: c_int, s: ~str) {
+pub fn writeclose(fd: c_int, s: ~str) {
     use io::WriterUtil;
 
     error!("writeclose %d, %s", fd as int, s);
@@ -350,18 +377,20 @@ fn writeclose(fd: c_int, s: ~str) {
     os::close(fd);
 }
 
-fn readclose(fd: c_int) -> ~str {
-    let file = os::fdopen(fd);
-    let reader = io::FILE_reader(file, false);
-    let buf = io::with_bytes_writer(|writer| {
-        let mut bytes = [mut 0, ..4096];
-        while !reader.eof() {
-            let nread = reader.read(bytes, bytes.len());
-            writer.write(bytes.view(0, nread));
-        }
-    });
-    os::fclose(file);
-    str::from_bytes(buf)
+pub fn readclose(fd: c_int) -> ~str {
+    unsafe {
+        let file = os::fdopen(fd);
+        let reader = io::FILE_reader(file, false);
+        let buf = io::with_bytes_writer(|writer| {
+            let mut bytes = [mut 0, ..4096];
+            while !reader.eof() {
+                let nread = reader.read(bytes, bytes.len());
+                writer.write(bytes.view(0, nread));
+            }
+        });
+        os::fclose(file);
+        str::from_bytes(buf)
+    }
 }
 
 /// Waits for a process to exit and returns the exit code
@@ -376,6 +405,7 @@ fn waitpid_os(pid: pid_t) -> int {
     #[cfg(unix)]
     fn waitpid_os(pid: pid_t) -> int {
         #[cfg(target_os = "linux")]
+        #[cfg(target_os = "android")]
         fn WIFEXITED(status: i32) -> bool {
             (status & 0xffi32) == 0i32
         }
@@ -387,6 +417,7 @@ fn WIFEXITED(status: i32) -> bool {
         }
 
         #[cfg(target_os = "linux")]
+        #[cfg(target_os = "android")]
         fn WEXITSTATUS(status: i32) -> i32 {
             (status >> 8i32) & 0xffi32
         }
@@ -408,7 +439,12 @@ fn WEXITSTATUS(status: i32) -> i32 {
 
 #[cfg(test)]
 mod tests {
+    use debug;
     use io::WriterUtil;
+    use option::{None, Some};
+    use os;
+    use run::{readclose, writeclose};
+    use run;
 
     // Regression test for memory leaks
     #[ignore(cfg(windows))] // FIXME (#2626)
index af6b2c163779b2ecd13c081036bce839c4ea6e23..4cd3502bd6212fc77f82e38abd7b55a5df28804c 100644 (file)
@@ -20,6 +20,7 @@
 
 use cmp::Eq;
 use hash::Hash;
+use prelude::*;
 use to_bytes::IterBytes;
 
 pub trait SendMap<K:Eq Hash, V: Copy> {
@@ -45,6 +46,17 @@ pub trait SendMap<K:Eq Hash, V: Copy> {
 
 /// Open addressing with linear probing.
 pub mod linear {
+    use cmp::Eq;
+    use cmp;
+    use hash::Hash;
+    use kinds::Copy;
+    use option::{None, Option, Some};
+    use option;
+    use rand;
+    use to_bytes::IterBytes;
+    use uint;
+    use vec;
+
     const INITIAL_CAPACITY: uint = 32u; // 2^5
 
     struct Bucket<K:Eq Hash,V> {
@@ -167,6 +179,7 @@ fn expand(&mut self) {
             let mut old_buckets = vec::from_fn(new_capacity, |_i| None);
             self.buckets <-> old_buckets;
 
+            self.size = 0;
             for uint::range(0, old_capacity) |i| {
                 let mut bucket = None;
                 bucket <-> old_buckets[i];
@@ -451,7 +464,10 @@ impl<K:Hash IterBytes Eq, V: Eq> LinearMap<K, V>: cmp::Eq {
 
 #[test]
 pub mod test {
+    use option::{None, Some};
     use send_map::linear::LinearMap;
+    use send_map::linear;
+    use uint;
 
     #[test]
     pub fn inserts() {
@@ -575,4 +591,22 @@ pub fn test_eq() {
 
         assert m1 == m2;
     }
+
+    #[test]
+    pub fn test_expand() {
+        let mut m = ~LinearMap();
+
+        assert m.len() == 0;
+        assert m.is_empty();
+
+        let mut i = 0u;
+        let old_resize_at = m.resize_at;
+        while old_resize_at == m.resize_at {
+            m.insert(i, i);
+            i += 1;
+        }
+
+        assert m.len() == i;
+        assert !m.is_empty();
+    }
 }
index 1beb1a56efa1bc58c683ca8ed501a89853fd0671..0395cc76542da8b68b6fcaf0225621f0f9c620bc 100644 (file)
@@ -13,7 +13,8 @@
 #[legacy_modes]; // tjc: remove after snapshot
 
 // NB: transitionary, de-mode-ing.
-// XXX: Can't forbid this because frame_address needs a deprecated mode.
+// FIXME #4425: Can't forbid this because frame_address needs a deprecated
+// mode.
 #[allow(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
@@ -84,20 +85,24 @@ fn run(i: int) {
 }
 
 fn breakpoint() {
-    rustrt::rust_dbg_breakpoint()
+    unsafe {
+        rustrt::rust_dbg_breakpoint()
+    }
 }
 
 fn frame_address(f: fn(++x: *u8)) {
-    rusti::frame_address(f)
+    unsafe {
+        rusti::frame_address(f)
+    }
 }
 
 extern mod rustrt {
     #[legacy_exports];
-    fn rust_dbg_breakpoint();
+    unsafe fn rust_dbg_breakpoint();
 }
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     #[legacy_exports];
-    fn frame_address(f: fn(++x: *u8));
+    fn frame_address(f: &once fn(++x: *u8));
 }
index e68966945caad0b7acf435b91b1118febb3f8917..f32dc746e1286ade8c93cad724265f16472b291b 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use at_vec;
+use cast;
+use char;
 use cmp::{Eq, Ord};
+use libc;
 use libc::size_t;
 use io::WriterUtil;
+use option::{None, Option, Some};
+use ptr;
+use str;
 use to_str::ToStr;
+use u8;
+use uint;
+use vec;
 
 /*
 Section: Creating a string
@@ -159,7 +169,7 @@ pub fn push_str_no_overallocate(lhs: &mut ~str, rhs: &str) {
             do as_buf(rhs) |rbuf, _rlen| {
                 let dst = ptr::offset(lbuf, llen);
                 let dst = ::cast::transmute_mut_unsafe(dst);
-                ptr::memcpy(dst, rbuf, rlen);
+                ptr::copy_memory(dst, rbuf, rlen);
             }
         }
         raw::set_len(lhs, llen + rlen);
@@ -176,7 +186,7 @@ pub fn push_str(lhs: &mut ~str, rhs: &str) {
             do as_buf(rhs) |rbuf, _rlen| {
                 let dst = ptr::offset(lbuf, llen);
                 let dst = ::cast::transmute_mut_unsafe(dst);
-                ptr::memcpy(dst, rbuf, rlen);
+                ptr::copy_memory(dst, rbuf, rlen);
             }
         }
         raw::set_len(lhs, llen + rlen);
@@ -1936,6 +1946,12 @@ pub fn reserve_at_least(s: &mut ~str, n: uint) {
 
 /// Unsafe operations
 pub mod raw {
+    use cast;
+    use libc;
+    use ptr;
+    use str::raw;
+    use str::{as_buf, is_utf8, len, reserve_at_least};
+    use vec;
 
     /// Create a Rust string from a null-terminated *u8 buffer
     pub unsafe fn from_buf(buf: *u8) -> ~str {
@@ -1951,7 +1967,7 @@ pub unsafe fn from_buf(buf: *u8) -> ~str {
     pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> ~str {
         let mut v: ~[u8] = vec::with_capacity(len + 1);
         vec::as_mut_buf(v, |vbuf, _len| {
-            ptr::memcpy(vbuf, buf as *u8, len)
+            ptr::copy_memory(vbuf, buf as *u8, len)
         });
         vec::raw::set_len(&mut v, len);
         v.push(0u8);
@@ -2008,7 +2024,7 @@ pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> ~str {
                 do vec::as_imm_buf(v) |vbuf, _vlen| {
                     let vbuf = ::cast::transmute_mut_unsafe(vbuf);
                     let src = ptr::offset(sbuf, begin);
-                    ptr::memcpy(vbuf, src, end - begin);
+                    ptr::copy_memory(vbuf, src, end - begin);
                 }
                 vec::raw::set_len(&mut v, end - begin);
                 v.push(0u8);
@@ -2115,6 +2131,9 @@ impl ~str: Trimmable {
 
 #[cfg(notest)]
 pub mod traits {
+    use ops::Add;
+    use str::append;
+
     impl ~str : Add<&str,~str> {
         #[inline(always)]
         pure fn add(&self, rhs: & &self/str) -> ~str {
@@ -2293,8 +2312,13 @@ impl &str: StrSlice {
 
 #[cfg(test)]
 mod tests {
-
+    use char;
+    use debug;
     use libc::c_char;
+    use libc;
+    use ptr;
+    use str::*;
+    use vec;
 
     #[test]
     fn test_eq() {
@@ -2650,9 +2674,11 @@ fn test_to_upper() {
 
     #[test]
     fn test_to_lower() {
-        assert ~"" == map(~"", |c| libc::tolower(c as c_char) as char);
-        assert ~"ymca" == map(~"YMCA",
-                             |c| libc::tolower(c as c_char) as char);
+        unsafe {
+            assert ~"" == map(~"", |c| libc::tolower(c as c_char) as char);
+            assert ~"ymca" == map(~"YMCA",
+                                 |c| libc::tolower(c as c_char) as char);
+        }
     }
 
     #[test]
@@ -3168,9 +3194,11 @@ fn test_lines_each () {
 
     #[test]
     fn test_map() {
-        assert ~"" == map(~"", |c| libc::toupper(c as c_char) as char);
-        assert ~"YMCA" == map(~"ymca",
-                              |c| libc::toupper(c as c_char) as char);
+        unsafe {
+            assert ~"" == map(~"", |c| libc::toupper(c as c_char) as char);
+            assert ~"YMCA" == map(~"ymca",
+                                  |c| libc::toupper(c as c_char) as char);
+        }
     }
 
     #[test]
index 62ced6019517fc41d3a3f3511d8748eed61fec42..322aa895eb46caf24d48fc93f206306ee027875c 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use cast;
 use cmp::{Eq, Ord};
+use gc;
+use io;
+use libc;
 use libc::{c_void, c_char, size_t};
+use ptr;
+use repr;
+use str;
+use vec;
 
 pub type FreeGlue = fn(*TypeDesc, *c_void);
 
@@ -45,7 +53,7 @@ pub struct Closure {
 
 extern mod rustrt {
     #[rust_stack]
-    fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t);
+    unsafe fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t);
 }
 
 /// Compares contents of two pointers using the default method.
@@ -79,6 +87,17 @@ pub struct Closure {
     unsafe { rusti::size_of::<T>() }
 }
 
+/**
+ * Returns the size of a type, or 1 if the actual size is zero.
+ *
+ * Useful for building structures containing variable-length arrays.
+ */
+#[inline(always)]
+pub pure fn nonzero_size_of<T>() -> uint {
+    let s = size_of::<T>();
+    if s == 0 { 1 } else { s }
+}
+
 /**
  * Returns the ABI-required minimum alignment of a type
  *
@@ -126,7 +145,7 @@ pub struct Closure {
     }
 }
 
-// XXX: Temorary until rt::rt_fail_ goes away
+// FIXME #4427: Temporary until rt::rt_fail_ goes away
 pub pure fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
     unsafe {
         gc::cleanup_stack_for_failure();
@@ -137,6 +156,8 @@ pub struct Closure {
 
 #[cfg(test)]
 pub mod tests {
+    use cast;
+    use sys::{Closure, pref_align_of, size_of, nonzero_size_of};
 
     #[test]
     pub fn size_of_basic() {
@@ -161,6 +182,14 @@ pub fn size_of_64() {
         assert size_of::<*uint>() == 8u;
     }
 
+    #[test]
+    pub fn nonzero_size_of_basic() {
+        type Z = [i8 * 0];
+        assert size_of::<Z>() == 0u;
+        assert nonzero_size_of::<Z>() == 1u;
+        assert nonzero_size_of::<uint>() == size_of::<uint>();
+    }
+
     #[test]
     pub fn align_of_basic() {
         assert pref_align_of::<u8>() == 1u;
index d321966ac5ea17e75cacb37594b9d5c514e50d41..990d309a1594572c2d0daf715f01ab1ffb800897 100644 (file)
 
 */
 
-use task::local_data_priv::{
-    local_pop,
-    local_get,
-    local_set,
-    local_modify
-};
+use prelude::*;
+use rt;
+use task::local_data_priv::{local_get, local_pop, local_modify, local_set};
+use task;
 
 /**
  * Indexes a task-local data slot. The function's code pointer is used for
index 634101ea717bf05b5f07c9c5b419c39398b51457..c08f0f9c997154c512aa118b7a2c2235fe2e8be4 100644 (file)
 
 #[doc(hidden)]; // FIXME #3538
 
+use cast;
+use cmp::Eq;
+use dvec;
+use libc;
+use option;
+use prelude::*;
+use task::rt;
 use task::local_data::LocalDataKey;
 
 #[cfg(notest)]
index 3cd12a5ba66ed009dce230bc276659cc8d3f09a2..c6b0491786d7fb569fc167015c786076e70f9792 100644 (file)
  * ~~~
  */
 
+use cast;
+use cmp;
 use cmp::Eq;
+use iter;
+use libc;
+use oldcomm;
+use option;
 use result::Result;
 use pipes::{stream, Chan, Port};
+use pipes;
+use prelude::*;
+use ptr;
+use result;
 use task::local_data_priv::{local_get, local_set};
 use task::rt::{task_id, rust_task};
+use task;
+use util;
 use util::replace;
 
 mod local_data_priv;
 pub mod spawn;
 
 /// A handle to a task
+#[deriving_eq]
 pub enum Task {
     TaskHandle(task_id)
 }
 
-// XXX: deriving
-impl Task : cmp::Eq {
-    pure fn eq(&self, other: &Task) -> bool { *(*self) == *(*other) }
-    pure fn ne(&self, other: &Task) -> bool { !(*self).eq(other) }
-}
-
 /**
  * Indicates the manner in which a task exited.
  *
@@ -940,69 +947,73 @@ fn test_spawn_sched_childs_on_same_sched() {
 #[nolink]
 #[cfg(test)]
 extern mod testrt {
-    fn rust_dbg_lock_create() -> *libc::c_void;
-    fn rust_dbg_lock_destroy(lock: *libc::c_void);
-    fn rust_dbg_lock_lock(lock: *libc::c_void);
-    fn rust_dbg_lock_unlock(lock: *libc::c_void);
-    fn rust_dbg_lock_wait(lock: *libc::c_void);
-    fn rust_dbg_lock_signal(lock: *libc::c_void);
+    unsafe fn rust_dbg_lock_create() -> *libc::c_void;
+    unsafe fn rust_dbg_lock_destroy(lock: *libc::c_void);
+    unsafe fn rust_dbg_lock_lock(lock: *libc::c_void);
+    unsafe fn rust_dbg_lock_unlock(lock: *libc::c_void);
+    unsafe fn rust_dbg_lock_wait(lock: *libc::c_void);
+    unsafe fn rust_dbg_lock_signal(lock: *libc::c_void);
 }
 
 #[test]
 fn test_spawn_sched_blocking() {
+    unsafe {
 
-    // Testing that a task in one scheduler can block in foreign code
-    // without affecting other schedulers
-    for iter::repeat(20u) {
+        // Testing that a task in one scheduler can block in foreign code
+        // without affecting other schedulers
+        for iter::repeat(20u) {
 
-        let start_po = oldcomm::Port();
-        let start_ch = oldcomm::Chan(&start_po);
-        let fin_po = oldcomm::Port();
-        let fin_ch = oldcomm::Chan(&fin_po);
+            let start_po = oldcomm::Port();
+            let start_ch = oldcomm::Chan(&start_po);
+            let fin_po = oldcomm::Port();
+            let fin_ch = oldcomm::Chan(&fin_po);
 
-        let lock = testrt::rust_dbg_lock_create();
+            let lock = testrt::rust_dbg_lock_create();
 
-        do spawn_sched(SingleThreaded) {
-            testrt::rust_dbg_lock_lock(lock);
+            do spawn_sched(SingleThreaded) {
+                unsafe {
+                    testrt::rust_dbg_lock_lock(lock);
 
-            oldcomm::send(start_ch, ());
+                    oldcomm::send(start_ch, ());
 
-            // Block the scheduler thread
-            testrt::rust_dbg_lock_wait(lock);
-            testrt::rust_dbg_lock_unlock(lock);
+                    // Block the scheduler thread
+                    testrt::rust_dbg_lock_wait(lock);
+                    testrt::rust_dbg_lock_unlock(lock);
 
-            oldcomm::send(fin_ch, ());
-        };
+                    oldcomm::send(fin_ch, ());
+                }
+            };
 
-        // Wait until the other task has its lock
-        oldcomm::recv(start_po);
+            // Wait until the other task has its lock
+            oldcomm::recv(start_po);
 
-        fn pingpong(po: oldcomm::Port<int>, ch: oldcomm::Chan<int>) {
-            let mut val = 20;
-            while val > 0 {
-                val = oldcomm::recv(po);
-                oldcomm::send(ch, val - 1);
+            fn pingpong(po: oldcomm::Port<int>, ch: oldcomm::Chan<int>) {
+                let mut val = 20;
+                while val > 0 {
+                    val = oldcomm::recv(po);
+                    oldcomm::send(ch, val - 1);
+                }
             }
-        }
-
-        let setup_po = oldcomm::Port();
-        let setup_ch = oldcomm::Chan(&setup_po);
-        let parent_po = oldcomm::Port();
-        let parent_ch = oldcomm::Chan(&parent_po);
-        do spawn {
-            let child_po = oldcomm::Port();
-            oldcomm::send(setup_ch, oldcomm::Chan(&child_po));
-            pingpong(child_po, parent_ch);
-        };
 
-        let child_ch = oldcomm::recv(setup_po);
-        oldcomm::send(child_ch, 20);
-        pingpong(parent_po, child_ch);
-        testrt::rust_dbg_lock_lock(lock);
-        testrt::rust_dbg_lock_signal(lock);
-        testrt::rust_dbg_lock_unlock(lock);
-        oldcomm::recv(fin_po);
-        testrt::rust_dbg_lock_destroy(lock);
+            let setup_po = oldcomm::Port();
+            let setup_ch = oldcomm::Chan(&setup_po);
+            let parent_po = oldcomm::Port();
+            let parent_ch = oldcomm::Chan(&parent_po);
+            do spawn {
+                let child_po = oldcomm::Port();
+                oldcomm::send(setup_ch, oldcomm::Chan(&child_po));
+                pingpong(child_po, parent_ch);
+            };
+
+            let child_ch = oldcomm::recv(setup_po);
+            oldcomm::send(child_ch, 20);
+            pingpong(parent_po, child_ch);
+            testrt::rust_dbg_lock_lock(lock);
+            testrt::rust_dbg_lock_signal(lock);
+            testrt::rust_dbg_lock_unlock(lock);
+            oldcomm::recv(fin_po);
+            testrt::rust_dbg_lock_destroy(lock);
+        }
     }
 }
 
index be66e9e26b8354502e4cf078b356bfa935a6f5c7..e95c6d90eee1babb67b02b4c29bf6e27408a80d5 100644 (file)
@@ -16,6 +16,8 @@
 
 #[doc(hidden)]; // FIXME #3538
 
+use libc;
+
 #[allow(non_camel_case_types)] // runtime type
 pub type sched_id = int;
 #[allow(non_camel_case_types)] // runtime type
index 77acf3967e8e02565d566f6db0090f94b9dbbb74..5152c3c049c0d9cc7835c1ed0da21186053017f9 100644 (file)
 #[doc(hidden)]; // FIXME #3538
 #[warn(deprecated_mode)];
 
+use cast;
+use oldcomm;
+use option;
+use pipes::{Chan, Port};
+use pipes;
+use prelude::*;
+use private;
+use ptr;
+use send_map;
+use task::local_data_priv::{local_get, local_set};
 use task::rt::rust_task;
 use task::rt::rust_closure;
+use task::rt;
+use task::{Failure, ManualThreads, PlatformThread, SchedOpts, SingleThreaded};
+use task::{Success, TaskOpts, TaskResult, ThreadPerCore, ThreadPerTask};
+use task::{default_task_opts, unkillable};
+use uint;
+use util;
 
 macro_rules! move_it (
     { $x:expr } => ( unsafe { let y = move *ptr::addr_of(&($x)); move y } )
@@ -576,7 +592,7 @@ fn make_child_wrapper(child: *rust_task, child_arc: TaskGroupArc,
             }
 
             // Run the box annihilator.
-            // XXX: Crashy.
+            // FIXME #4428: Crashy.
             // unsafe { cleanup::annihilate(); }
         };
 
index 900cc97066c5cecd6672517ca53b1b6e5b0e85b5..84e5140d8edbc43399bbc9adb4aadc078447d1f4 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use io;
 use io::Writer;
+use option::{None, Option, Some};
+use str;
 
 pub type Cb = fn(buf: &[const u8]) -> bool;
 
@@ -169,6 +172,8 @@ impl char: IterBytes {
 
 #[cfg(target_word_size = "32")]
 pub mod x32 {
+    use to_bytes::{Cb, IterBytes};
+
     pub impl uint: IterBytes {
         #[inline(always)]
         pure fn iter_bytes(&self, lsb0: bool, f: Cb) {
@@ -179,6 +184,8 @@ pub impl uint: IterBytes {
 
 #[cfg(target_word_size = "64")]
 pub mod x64 {
+    use to_bytes::{Cb, IterBytes};
+
     pub impl uint: IterBytes {
         #[inline(always)]
         pure fn iter_bytes(&self, lsb0: bool, f: Cb) {
index 55055470f10f1303a1f33cfeab9db84849a7ca72..22e187d7768e628ba8170a0094b05f07e819afa4 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+use kinds::Copy;
+use str;
+use vec;
+
 pub trait ToStr { pub pure fn to_str() -> ~str; }
 
 impl int: ToStr {
-    pure fn to_str() -> ~str { int::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::int::str(self) }
 }
 impl i8: ToStr {
-    pure fn to_str() -> ~str { i8::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::i8::str(self) }
 }
 impl i16: ToStr {
-    pure fn to_str() -> ~str { i16::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::i16::str(self) }
 }
 impl i32: ToStr {
-    pure fn to_str() -> ~str { i32::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::i32::str(self) }
 }
 impl i64: ToStr {
-    pure fn to_str() -> ~str { i64::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::i64::str(self) }
 }
 impl uint: ToStr {
-    pure fn to_str() -> ~str { uint::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::uint::str(self) }
 }
 impl u8: ToStr {
-    pure fn to_str() -> ~str { u8::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::u8::str(self) }
 }
 impl u16: ToStr {
-    pure fn to_str() -> ~str { u16::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::u16::str(self) }
 }
 impl u32: ToStr {
-    pure fn to_str() -> ~str { u32::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::u32::str(self) }
 }
 impl u64: ToStr {
-    pure fn to_str() -> ~str { u64::str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::u64::str(self) }
 }
 impl float: ToStr {
-    pure fn to_str() -> ~str { float::to_str(self, 4u) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::float::to_str(self, 4u) }
 }
 impl f32: ToStr {
-    pure fn to_str() -> ~str { float::to_str(self as float, 4u) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::float::to_str(self as float, 4u) }
 }
 impl f64: ToStr {
-    pure fn to_str() -> ~str { float::to_str(self as float, 4u) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::float::to_str(self as float, 4u) }
 }
 impl bool: ToStr {
-    pure fn to_str() -> ~str { bool::to_str(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::bool::to_str(self) }
 }
 impl (): ToStr {
+    #[inline(always)]
     pure fn to_str() -> ~str { ~"()" }
 }
 impl ~str: ToStr {
+    #[inline(always)]
     pure fn to_str() -> ~str { copy self }
 }
 impl &str: ToStr {
-    pure fn to_str() -> ~str { str::from_slice(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::str::from_slice(self) }
 }
 impl @str: ToStr {
-    pure fn to_str() -> ~str { str::from_slice(self) }
+    #[inline(always)]
+    pure fn to_str() -> ~str { ::str::from_slice(self) }
 }
 
 impl<A: ToStr Copy, B: ToStr Copy> (A, B): ToStr {
+    #[inline(always)]
     pure fn to_str() -> ~str {
         let (a, b) = self;
         ~"(" + a.to_str() + ~", " + b.to_str() + ~")"
     }
 }
 impl<A: ToStr Copy, B: ToStr Copy, C: ToStr Copy> (A, B, C): ToStr {
+    #[inline(always)]
     pure fn to_str() -> ~str {
         let (a, b, c) = self;
         ~"(" + a.to_str() + ~", " + b.to_str() + ~", " + c.to_str() + ~")"
@@ -89,6 +113,7 @@ impl<A: ToStr Copy, B: ToStr Copy, C: ToStr Copy> (A, B, C): ToStr {
 }
 
 impl<A: ToStr> ~[A]: ToStr {
+    #[inline(always)]
     pure fn to_str() -> ~str unsafe {
         // Bleh -- not really unsafe
         // push_str and push_char
@@ -104,9 +129,11 @@ impl<A: ToStr> ~[A]: ToStr {
 }
 
 impl<A: ToStr> @A: ToStr {
+    #[inline(always)]
     pure fn to_str() -> ~str { ~"@" + (*self).to_str() }
 }
 impl<A: ToStr> ~A: ToStr {
+    #[inline(always)]
     pure fn to_str() -> ~str { ~"~" + (*self).to_str() }
 }
 
index 5ab013223c667aa15f0157ab0c7539587dfc8b46..c497a2f3c7f14365a3b60c043aa6e04518b429ed 100644 (file)
@@ -15,6 +15,8 @@
 //! Operations on tuples
 
 use cmp::{Eq, Ord};
+use kinds::Copy;
+use vec;
 
 pub trait CopyableTuple<T, U> {
     pure fn first() -> T;
@@ -25,18 +27,21 @@ pub trait CopyableTuple<T, U> {
 impl<T: Copy, U: Copy> (T, U): CopyableTuple<T, U> {
 
     /// Return the first element of self
+    #[inline(always)]
     pure fn first() -> T {
         let (t, _) = self;
         return t;
     }
 
     /// Return the second element of self
+    #[inline(always)]
     pure fn second() -> U {
         let (_, u) = self;
         return u;
     }
 
     /// Return the results of swapping the two elements of self
+    #[inline(always)]
     pure fn swap() -> (U, T) {
         let (t, u) = self;
         return (u, t);
@@ -50,11 +55,13 @@ pub trait ImmutableTuple<T, U> {
 }
 
 impl<T, U> (T, U): ImmutableTuple<T, U> {
+    #[inline(always)]
     pure fn first_ref(&self) -> &self/T {
         match *self {
             (ref t, _) => t,
         }
     }
+    #[inline(always)]
     pure fn second_ref(&self) -> &self/U {
         match *self {
             (_, ref u) => u,
@@ -68,6 +75,7 @@ pub trait ExtendedTupleOps<A,B> {
 }
 
 impl<A: Copy, B: Copy> (&[A], &[B]): ExtendedTupleOps<A,B> {
+    #[inline(always)]
     fn zip(&self) -> ~[(A, B)] {
         match *self {
             (ref a, ref b) => {
@@ -76,6 +84,7 @@ fn zip(&self) -> ~[(A, B)] {
         }
     }
 
+    #[inline(always)]
     fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
         match *self {
             (ref a, ref b) => {
@@ -87,6 +96,7 @@ fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
 
 impl<A: Copy, B: Copy> (~[A], ~[B]): ExtendedTupleOps<A,B> {
 
+    #[inline(always)]
     fn zip(&self) -> ~[(A, B)] {
         match *self {
             (ref a, ref b) => {
@@ -95,6 +105,7 @@ fn zip(&self) -> ~[(A, B)] {
         }
     }
 
+    #[inline(always)]
     fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
         match *self {
             (ref a, ref b) => {
@@ -106,6 +117,7 @@ fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
 
 #[cfg(notest)]
 impl<A: Eq, B: Eq> (A, B) : Eq {
+    #[inline(always)]
     pure fn eq(&self, other: &(A, B)) -> bool {
         match (*self) {
             (ref self_a, ref self_b) => match other {
@@ -115,11 +127,13 @@ impl<A: Eq, B: Eq> (A, B) : Eq {
             }
         }
     }
+    #[inline(always)]
     pure fn ne(&self, other: &(A, B)) -> bool { !(*self).eq(other) }
 }
 
 #[cfg(notest)]
 impl<A: Ord, B: Ord> (A, B) : Ord {
+    #[inline(always)]
     pure fn lt(&self, other: &(A, B)) -> bool {
         match (*self) {
             (ref self_a, ref self_b) => {
@@ -134,13 +148,17 @@ impl<A: Ord, B: Ord> (A, B) : Ord {
             }
         }
     }
+    #[inline(always)]
     pure fn le(&self, other: &(A, B)) -> bool { !(*other).lt(&(*self)) }
+    #[inline(always)]
     pure fn ge(&self, other: &(A, B)) -> bool { !(*self).lt(other) }
+    #[inline(always)]
     pure fn gt(&self, other: &(A, B)) -> bool { (*other).lt(&(*self))  }
 }
 
 #[cfg(notest)]
 impl<A: Eq, B: Eq, C: Eq> (A, B, C) : Eq {
+    #[inline(always)]
     pure fn eq(&self, other: &(A, B, C)) -> bool {
         match (*self) {
             (ref self_a, ref self_b, ref self_c) => match other {
@@ -151,11 +169,13 @@ impl<A: Eq, B: Eq, C: Eq> (A, B, C) : Eq {
             }
         }
     }
+    #[inline(always)]
     pure fn ne(&self, other: &(A, B, C)) -> bool { !(*self).eq(other) }
 }
 
 #[cfg(notest)]
 impl<A: Ord, B: Ord, C: Ord> (A, B, C) : Ord {
+    #[inline(always)]
     pure fn lt(&self, other: &(A, B, C)) -> bool {
         match (*self) {
             (ref self_a, ref self_b, ref self_c) => {
@@ -172,8 +192,11 @@ impl<A: Ord, B: Ord, C: Ord> (A, B, C) : Ord {
             }
         }
     }
+    #[inline(always)]
     pure fn le(&self, other: &(A, B, C)) -> bool { !(*other).lt(&(*self)) }
+    #[inline(always)]
     pure fn ge(&self, other: &(A, B, C)) -> bool { !(*self).lt(other) }
+    #[inline(always)]
     pure fn gt(&self, other: &(A, B, C)) -> bool { (*other).lt(&(*self))  }
 }
 
index 80b393a813cf198483a1780becfae1dc6dd2d160..a7eb2f80725532dfc65466e7d36e31ea948abbec 100644 (file)
 
 use T = self::inst::T;
 
+use char;
 use cmp::{Eq, Ord};
 use from_str::FromStr;
+use iter;
+use num;
+use option::{None, Option, Some};
+use str;
+use uint;
+use vec;
 
 pub const bits : uint = inst::bits;
 pub const bytes : uint = (inst::bits / 8);
 pub const min_value: T = 0 as T;
 pub const max_value: T = 0 as T - 1 as T;
 
+#[inline(always)]
 pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }
+#[inline(always)]
 pub pure fn max(x: T, y: T) -> T { if x > y { x } else { y } }
 
+#[inline(always)]
 pub pure fn add(x: T, y: T) -> T { x + y }
+#[inline(always)]
 pub pure fn sub(x: T, y: T) -> T { x - y }
+#[inline(always)]
 pub pure fn mul(x: T, y: T) -> T { x * y }
+#[inline(always)]
 pub pure fn div(x: T, y: T) -> T { x / y }
+#[inline(always)]
 pub pure fn rem(x: T, y: T) -> T { x % y }
 
+#[inline(always)]
 pub pure fn lt(x: T, y: T) -> bool { x < y }
+#[inline(always)]
 pub pure fn le(x: T, y: T) -> bool { x <= y }
+#[inline(always)]
 pub pure fn eq(x: T, y: T) -> bool { x == y }
+#[inline(always)]
 pub pure fn ne(x: T, y: T) -> bool { x != y }
+#[inline(always)]
 pub pure fn ge(x: T, y: T) -> bool { x >= y }
+#[inline(always)]
 pub pure fn gt(x: T, y: T) -> bool { x > y }
 
+#[inline(always)]
 pub pure fn is_positive(x: T) -> bool { x > 0 as T }
+#[inline(always)]
 pub pure fn is_negative(x: T) -> bool { x < 0 as T }
+#[inline(always)]
 pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
+#[inline(always)]
 pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }
 
 #[inline(always)]
 }
 
 /// Computes the bitwise complement
+#[inline(always)]
 pub pure fn compl(i: T) -> T {
     max_value ^ i
 }
 
 #[cfg(notest)]
 impl T : Ord {
+    #[inline(always)]
     pure fn lt(&self, other: &T) -> bool { (*self) < (*other) }
+    #[inline(always)]
     pure fn le(&self, other: &T) -> bool { (*self) <= (*other) }
+    #[inline(always)]
     pure fn ge(&self, other: &T) -> bool { (*self) >= (*other) }
+    #[inline(always)]
     pure fn gt(&self, other: &T) -> bool { (*self) > (*other) }
 }
 
 #[cfg(notest)]
 impl T : Eq {
+    #[inline(always)]
     pure fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
+    #[inline(always)]
     pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
 }
 
 impl T: num::Num {
+    #[inline(always)]
     pure fn add(&self, other: &T)    -> T { return *self + *other; }
+    #[inline(always)]
     pure fn sub(&self, other: &T)    -> T { return *self - *other; }
+    #[inline(always)]
     pure fn mul(&self, other: &T)    -> T { return *self * *other; }
+    #[inline(always)]
     pure fn div(&self, other: &T)    -> T { return *self / *other; }
+    #[inline(always)]
     pure fn modulo(&self, other: &T) -> T { return *self % *other; }
+    #[inline(always)]
     pure fn neg(&self)              -> T { return -*self;        }
 
+    #[inline(always)]
     pure fn to_int(&self)         -> int { return *self as int; }
+    #[inline(always)]
     static pure fn from_int(n: int) -> T   { return n as T;      }
 }
 
 impl T: num::Zero {
+    #[inline(always)]
     static pure fn zero() -> T { 0 }
 }
 
 impl T: num::One {
+    #[inline(always)]
     static pure fn one() -> T { 1 }
 }
 
@@ -138,12 +179,14 @@ impl T: iter::Times {
 }
 
 /// Parse a string to an int
+#[inline(always)]
 pub pure fn from_str(s: &str) -> Option<T>
 {
     parse_bytes(str::to_bytes(s), 10u)
 }
 
 impl T : FromStr {
+    #[inline(always)]
     static pure fn from_str(s: &str) -> Option<T> { from_str(s) }
 }
 
@@ -170,6 +213,7 @@ pub fn from_str_radix(buf: &str, radix: u64) -> Option<u64> {
  *
  * Fails if `radix` < 2 or `radix` > 16
  */
+#[inline(always)]
 pub pure fn to_str(num: T, radix: uint) -> ~str {
     do to_str_bytes(false, num, radix) |slice| {
         do vec::as_imm_buf(slice) |p, len| {
@@ -223,6 +267,7 @@ pub fn from_str_radix(buf: &str, radix: u64) -> Option<u64> {
 }
 
 /// Convert to a string
+#[inline(always)]
 pub pure fn str(i: T) -> ~str { return to_str(i, 10u); }
 
 #[test]
index b2ae1aa921b7254a16d1e838223acb0371dcc447..4d2da7180ef2e0b6dfc73219464f92f117d5fc8d 100644 (file)
@@ -16,6 +16,9 @@
 };
 
 mod inst {
+    use sys;
+    use uint;
+
     pub type T = uint;
 
     #[cfg(target_arch = "x86")]
index 7dbc9f76f7ac6507fda6e5d4e7a75fdf81747757..423dbaedf267dce19728a7d08d095d9668a23930 100644 (file)
@@ -19,6 +19,7 @@
 #[forbid(deprecated_pattern)];
 
 use cmp::Eq;
+use prelude::*;
 
 /// The identity function.
 #[inline(always)]
@@ -104,6 +105,10 @@ pub fn unreachable() -> ! {
 
 mod tests {
     #[legacy_exports];
+
+    use option::{None, Some};
+    use util::{NonCopyable, id, replace, swap};
+
     #[test]
     fn identity_crisis() {
         // Writing a test for the identity function. How did it come to this?
index 5071fb903d91d1bcb6127974f435c028dae986f1..9527c85481c276b84ad32dd1816556268f48e45c 100644 (file)
 #[forbid(deprecated_pattern)];
 #[warn(non_camel_case_types)];
 
+use cast;
 use cmp::{Eq, Ord};
-use option::{Some, None};
-use ptr::addr_of;
+use iter::BaseIter;
+use iter;
+use kinds::Copy;
+use libc;
 use libc::size_t;
+use option::{None, Option, Some};
+use ptr;
+use ptr::addr_of;
+use sys;
+use uint;
+use vec;
 
 #[abi = "cdecl"]
-extern mod rustrt {
-    fn vec_reserve_shared(++t: *sys::TypeDesc,
-                          ++v: **raw::VecRepr,
-                          ++n: libc::size_t);
+pub extern mod rustrt {
+    unsafe fn vec_reserve_shared(++t: *sys::TypeDesc,
+                                 ++v: **raw::VecRepr,
+                                 ++n: libc::size_t);
 }
 
 #[abi = "rust-intrinsic"]
-extern mod rusti {
+pub extern mod rusti {
     fn move_val_init<T>(dst: &mut T, -src: T);
     fn init<T>() -> T;
 }
@@ -94,7 +103,7 @@ pub fn reserve_at_least<T>(v: &mut ~[T], n: uint) {
 pub pure fn capacity<T>(v: &const ~[T]) -> uint {
     unsafe {
         let repr: **raw::VecRepr = ::cast::transmute(v);
-        (**repr).unboxed.alloc / sys::size_of::<T>()
+        (**repr).unboxed.alloc / sys::nonzero_size_of::<T>()
     }
 }
 
@@ -196,7 +205,7 @@ pub fn reserve_at_least<T>(v: &mut ~[T], n: uint) {
 #[inline(always)]
 pub pure fn build_sized_opt<A>(size: Option<uint>,
                            builder: fn(push: pure fn(v: A))) -> ~[A] {
-    build_sized(size.get_default(4), builder)
+    build_sized(size.get_or_default(4), builder)
 }
 
 /// Produces a mut vector from an immutable vector.
@@ -267,7 +276,7 @@ pub fn reserve_at_least<T>(v: &mut ~[T], n: uint) {
         unsafe {
             ::cast::reinterpret_cast(
                 &(ptr::offset(p, start),
-                  (end - start) * sys::size_of::<T>()))
+                  (end - start) * sys::nonzero_size_of::<T>()))
         }
     }
 }
@@ -280,7 +289,7 @@ pub fn reserve_at_least<T>(v: &mut ~[T], n: uint) {
         unsafe {
             ::cast::reinterpret_cast(
                 &(ptr::mut_offset(p, start),
-                  (end - start) * sys::size_of::<T>()))
+                  (end - start) * sys::nonzero_size_of::<T>()))
         }
     }
 }
@@ -294,7 +303,7 @@ pub fn reserve_at_least<T>(v: &mut ~[T], n: uint) {
         unsafe {
             ::cast::reinterpret_cast(
                 &(ptr::const_offset(p, start),
-                  (end - start) * sys::size_of::<T>()))
+                  (end - start) * sys::nonzero_size_of::<T>()))
         }
     }
 }
@@ -396,6 +405,48 @@ pub fn rsplitn<T: Copy>(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] {
     result
 }
 
+/**
+ * Partitions a vector into two new vectors: those that satisfies the
+ * predicate, and those that do not.
+ */
+pub fn partition<T>(v: ~[T], f: fn(&T) -> bool) -> (~[T], ~[T]) {
+    let mut lefts  = ~[];
+    let mut rights = ~[];
+
+    // FIXME (#4355 maybe): using v.consume here crashes
+    // do v.consume |_, elt| {
+    do consume(v) |_, elt| {
+        if f(&elt) {
+            lefts.push(elt);
+        } else {
+            rights.push(elt);
+        }
+    }
+
+    (lefts, rights)
+}
+
+/**
+ * Partitions a vector into two new vectors: those that satisfies the
+ * predicate, and those that do not.
+ */
+pub pure fn partitioned<T: Copy>(v: &[T], f: fn(&T) -> bool) -> (~[T], ~[T]) {
+    let mut lefts  = ~[];
+    let mut rights = ~[];
+
+    for each(v) |elt| {
+        unsafe {
+            if f(elt) {
+                lefts.push(*elt);
+            } else {
+                rights.push(*elt);
+            }
+        }
+    }
+
+    (lefts, rights)
+}
+
 // Mutators
 
 /// Removes the first element from a vector and return it
@@ -420,7 +471,7 @@ pub fn shift<T>(v: &mut ~[T]) -> T unsafe {
     // We still should have room to work where what last element was
     assert capacity(v) >= ln;
     // Pretend like we have the original length so we can use
-    // the vector memcpy to overwrite the hole we just made
+    // the vector copy_memory to overwrite the hole we just made
     raw::set_len(v, ln);
 
     // Memcopy the head element (the one we want) to the location we just
@@ -428,12 +479,12 @@ pub fn shift<T>(v: &mut ~[T]) -> T unsafe {
     // positions
     let first_slice = view(*v, 0, 1);
     let last_slice = mut_view(*v, next_ln, ln);
-    raw::memcpy(last_slice, first_slice, 1);
+    raw::copy_memory(last_slice, first_slice, 1);
 
     // Memcopy everything to the left one element
     let init_slice = mut_view(*v, 0, next_ln);
     let tail_slice = view(*v, 1, ln);
-    raw::memcpy(init_slice, tail_slice, next_ln);
+    raw::copy_memory(init_slice, tail_slice, next_ln);
 
     // Set the new length. Now the vector is back to normal
     raw::set_len(v, next_ln);
@@ -512,7 +563,7 @@ pub fn pop<T>(v: &mut ~[T]) -> T {
     }
     let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]);
     unsafe {
-        // XXX: Should be rusti::uninit() - we don't need this zeroed
+        // FIXME #4204: Should be rusti::uninit() - we don't need this zeroed
         let mut val = rusti::init();
         val <-> *valptr;
         raw::set_len(v, ln - 1u);
@@ -557,7 +608,7 @@ pub fn push<T>(v: &mut ~[T], initval: T) {
 unsafe fn push_fast<T>(v: &mut ~[T], initval: T) {
     let repr: **raw::VecRepr = ::cast::transmute(v);
     let fill = (**repr).unboxed.fill;
-    (**repr).unboxed.fill += sys::size_of::<T>();
+    (**repr).unboxed.fill += sys::nonzero_size_of::<T>();
     let p = addr_of(&((**repr).unboxed.data));
     let p = ptr::offset(p, fill) as *mut T;
     rusti::move_val_init(&mut(*p), move initval);
@@ -585,7 +636,7 @@ pub fn push_all_move<T>(v: &mut ~[T], rhs: ~[T]) {
     unsafe {
         do as_mut_buf(rhs) |p, len| {
             for uint::range(0, len) |i| {
-                // XXX Should be rusti::uninit() - don't need to zero
+                // FIXME #4204 Should be rusti::uninit() - don't need to zero
                 let mut x = rusti::init();
                 x <-> *ptr::mut_offset(p, i);
                 push(v, x);
@@ -602,7 +653,7 @@ pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
         unsafe {
             // This loop is optimized out for non-drop types.
             for uint::range(newlen, oldlen) |i| {
-                // XXX Should be rusti::uninit() - don't need to zero
+                // FIXME #4204 Should be rusti::uninit() - don't need to zero
                 let mut dropped = rusti::init();
                 dropped <-> *ptr::mut_offset(p, i);
             }
@@ -627,7 +678,7 @@ pub fn dedup<T: Eq>(v: &mut ~[T]) unsafe {
             // last_written < next_to_read < ln
             if *ptr::mut_offset(p, next_to_read) ==
                 *ptr::mut_offset(p, last_written) {
-                // XXX Should be rusti::uninit() - don't need to zero
+                // FIXME #4204 Should be rusti::uninit() - don't need to zero
                 let mut dropped = rusti::init();
                 dropped <-> *ptr::mut_offset(p, next_to_read);
             } else {
@@ -666,7 +717,7 @@ pub fn dedup<T: Eq>(v: &mut ~[T]) unsafe {
 }
 
 #[inline(always)]
-pure fn append_mut<T: Copy>(lhs: ~[mut T], rhs: &[const T]) -> ~[mut T] {
+pub pure fn append_mut<T: Copy>(lhs: ~[mut T], rhs: &[const T]) -> ~[mut T] {
     to_mut(append(from_mut(lhs), rhs))
 }
 
@@ -804,7 +855,24 @@ pub fn map_consume<T, U>(v: ~[T], f: fn(v: T) -> U) -> ~[U] {
  * Apply function `f` to each element of `v` and return a vector containing
  * only those elements for which `f` returned true.
  */
-pub pure fn filter<T: Copy>(v: &[T], f: fn(t: &T) -> bool) -> ~[T] {
+pub fn filter<T>(v: ~[T], f: fn(t: &T) -> bool) -> ~[T] {
+    let mut result = ~[];
+    // FIXME (#4355 maybe): using v.consume here crashes
+    // do v.consume |_, elem| {
+    do consume(v) |_, elem| {
+        if f(&elem) { result.push(elem); }
+    }
+    result
+}
+
+/**
+ * Construct a new vector from the elements of a vector for which some
+ * predicate holds.
+ *
+ * Apply function `f` to each element of `v` and return a vector containing
+ * only those elements for which `f` returned true.
+ */
+pub pure fn filtered<T: Copy>(v: &[T], f: fn(t: &T) -> bool) -> ~[T] {
     let mut result = ~[];
     for each(v) |elem| {
         if f(elem) { unsafe { result.push(*elem); } }
@@ -1170,9 +1238,42 @@ pub fn reverse<T>(v: &[mut T]) {
 }
 
 /**
- * Iterates over a vector, with option to break
+ * Iterates over a vector, yielding each element to a closure.
  *
- * Return true to continue, false to break.
+ * # Arguments
+ *
+ * * `v` - A vector, to be iterated over
+ * * `f` - A closure to do the iterating. Within this closure, return true to
+ * * continue iterating, false to break.
+ *
+ * # Examples
+ * ~~~
+ * [1,2,3].each(|&i| {
+ *     io::println(int::str(i));
+ *     true
+ * });
+ * ~~~
+ *
+ * ~~~
+ * [1,2,3,4,5].each(|&i| {
+ *     if i < 4 {
+ *         io::println(int::str(i));
+ *         true
+ *     }
+ *     else {
+ *         false
+ *     }
+ * });
+ * ~~~
+ *
+ * You probably will want to use each with a `for`/`do` expression, depending
+ * on your iteration needs:
+ *
+ * ~~~
+ * for [1,2,3].each |&i| {
+ *     io::println(int::str(i));
+ * }
+ * ~~~
  */
 #[inline(always)]
 pub pure fn each<T>(v: &r/[T], f: fn(&r/T) -> bool) {
@@ -1348,7 +1449,7 @@ pub fn each2<U, T>(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) {
         let v : *(*T,uint) =
             ::cast::reinterpret_cast(&addr_of(&s));
         let (buf,len) = *v;
-        f(buf, len / sys::size_of::<T>())
+        f(buf, len / sys::nonzero_size_of::<T>())
     }
 }
 
@@ -1361,7 +1462,7 @@ pub fn each2<U, T>(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) {
         let v : *(*const T,uint) =
             ::cast::reinterpret_cast(&addr_of(&s));
         let (buf,len) = *v;
-        f(buf, len / sys::size_of::<T>())
+        f(buf, len / sys::nonzero_size_of::<T>())
     }
 }
 
@@ -1374,7 +1475,7 @@ pub fn each2<U, T>(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) {
         let v : *(*mut T,uint) =
             ::cast::reinterpret_cast(&addr_of(&s));
         let (buf,len) = *v;
-        f(buf, len / sys::size_of::<T>())
+        f(buf, len / sys::nonzero_size_of::<T>())
     }
 }
 
@@ -1477,6 +1578,10 @@ impl<T: Ord> @[T] : Ord {
 
 #[cfg(notest)]
 pub mod traits {
+    use kinds::Copy;
+    use ops::Add;
+    use vec::{append, append_mut};
+
     impl<T: Copy> ~[T] : Add<&[const T],~[T]> {
         #[inline(always)]
         pure fn add(&self, rhs: & &self/[const T]) -> ~[T] {
@@ -1493,93 +1598,96 @@ impl<T: Copy> ~[mut T] : Add<&[const T],~[mut T]> {
 }
 
 pub trait ConstVector {
-    pure fn is_empty() -> bool;
-    pure fn is_not_empty() -> bool;
-    pure fn len() -> uint;
+    pure fn is_empty(&self) -> bool;
+    pure fn is_not_empty(&self) -> bool;
+    pure fn len(&self) -> uint;
 }
 
 /// Extension methods for vectors
 impl<T> &[const T]: ConstVector {
     /// Returns true if a vector contains no elements
     #[inline]
-    pure fn is_empty() -> bool { is_empty(self) }
+    pure fn is_empty(&self) -> bool { is_empty(*self) }
     /// Returns true if a vector contains some elements
     #[inline]
-    pure fn is_not_empty() -> bool { is_not_empty(self) }
+    pure fn is_not_empty(&self) -> bool { is_not_empty(*self) }
     /// Returns the length of a vector
     #[inline]
-    pure fn len() -> uint { len(self) }
+    pure fn len(&self) -> uint { len(*self) }
 }
 
 pub trait CopyableVector<T> {
-    pure fn head() -> T;
-    pure fn init() -> ~[T];
-    pure fn last() -> T;
-    pure fn slice(start: uint, end: uint) -> ~[T];
-    pure fn tail() -> ~[T];
+    pure fn head(&self) -> T;
+    pure fn init(&self) -> ~[T];
+    pure fn last(&self) -> T;
+    pure fn slice(&self, start: uint, end: uint) -> ~[T];
+    pure fn tail(&self) -> ~[T];
 }
 
 /// Extension methods for vectors
 impl<T: Copy> &[const T]: CopyableVector<T> {
     /// Returns the first element of a vector
     #[inline]
-    pure fn head() -> T { head(self) }
+    pure fn head(&self) -> T { head(*self) }
+
     /// Returns all but the last elemnt of a vector
     #[inline]
-    pure fn init() -> ~[T] { init(self) }
+    pure fn init(&self) -> ~[T] { init(*self) }
+
     /// Returns the last element of a `v`, failing if the vector is empty.
     #[inline]
-    pure fn last() -> T { last(self) }
+    pure fn last(&self) -> T { last(*self) }
+
     /// Returns a copy of the elements from [`start`..`end`) from `v`.
     #[inline]
-    pure fn slice(start: uint, end: uint) -> ~[T] { slice(self, start, end) }
+    pure fn slice(&self, start: uint, end: uint) -> ~[T] {
+        slice(*self, start, end)
+    }
+
     /// Returns all but the first element of a vector
     #[inline]
-    pure fn tail() -> ~[T] { tail(self) }
+    pure fn tail(&self) -> ~[T] { tail(*self) }
 }
 
 pub trait ImmutableVector<T> {
-    pure fn view(start: uint, end: uint) -> &self/[T];
-    pure fn foldr<U: Copy>(z: U, p: fn(t: &T, u: U) -> U) -> U;
-    pure fn map<U>(f: fn(t: &T) -> U) -> ~[U];
-    pure fn mapi<U>(f: fn(uint, t: &T) -> U) -> ~[U];
-    fn map_r<U>(f: fn(x: &T) -> U) -> ~[U];
-    pure fn alli(f: fn(uint, t: &T) -> bool) -> bool;
-    pure fn flat_map<U>(f: fn(t: &T) -> ~[U]) -> ~[U];
-    pure fn filter_map<U: Copy>(f: fn(t: &T) -> Option<U>) -> ~[U];
-}
-
-pub trait ImmutableEqVector<T: Eq> {
-    pure fn position(f: fn(t: &T) -> bool) -> Option<uint>;
-    pure fn position_elem(t: &T) -> Option<uint>;
-    pure fn rposition(f: fn(t: &T) -> bool) -> Option<uint>;
-    pure fn rposition_elem(t: &T) -> Option<uint>;
+    pure fn view(&self, start: uint, end: uint) -> &self/[T];
+    pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U;
+    pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U];
+    pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U];
+    fn map_r<U>(&self, f: fn(x: &T) -> U) -> ~[U];
+    pure fn alli(&self, f: fn(uint, t: &T) -> bool) -> bool;
+    pure fn flat_map<U>(&self, f: fn(t: &T) -> ~[U]) -> ~[U];
+    pure fn filter_map<U: Copy>(&self, f: fn(t: &T) -> Option<U>) -> ~[U];
 }
 
 /// Extension methods for vectors
 impl<T> &[T]: ImmutableVector<T> {
     /// Return a slice that points into another slice.
-    pure fn view(start: uint, end: uint) -> &self/[T] {
-        view(self, start, end)
+    #[inline]
+    pure fn view(&self, start: uint, end: uint) -> &self/[T] {
+        view(*self, start, end)
     }
+
     /// Reduce a vector from right to left
     #[inline]
-    pure fn foldr<U: Copy>(z: U, p: fn(t: &T, u: U) -> U) -> U {
-        foldr(self, z, p)
+    pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U {
+        foldr(*self, z, p)
     }
+
     /// Apply a function to each element of a vector and return the results
     #[inline]
-    pure fn map<U>(f: fn(t: &T) -> U) -> ~[U] { map(self, f) }
+    pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U] { map(*self, f) }
+
     /**
      * Apply a function to the index and value of each element in the vector
      * and return the results
      */
-    pure fn mapi<U>(f: fn(uint, t: &T) -> U) -> ~[U] {
-        mapi(self, f)
+    pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U] {
+        mapi(*self, f)
     }
 
     #[inline]
-    fn map_r<U>(f: fn(x: &T) -> U) -> ~[U] {
+    fn map_r<U>(&self, f: fn(x: &T) -> U) -> ~[U] {
         let mut r = ~[];
         let mut i = 0;
         while i < self.len() {
@@ -1594,16 +1702,16 @@ fn map_r<U>(f: fn(x: &T) -> U) -> ~[U] {
      *
      *     If the vector is empty, true is returned.
      */
-    pure fn alli(f: fn(uint, t: &T) -> bool) -> bool {
-        alli(self, f)
+    pure fn alli(&self, f: fn(uint, t: &T) -> bool) -> bool {
+        alli(*self, f)
     }
     /**
      * Apply a function to each element of a vector and return a concatenation
      * of each result vector
      */
     #[inline]
-    pure fn flat_map<U>(f: fn(t: &T) -> ~[U]) -> ~[U] {
-        flat_map(self, f)
+    pure fn flat_map<U>(&self, f: fn(t: &T) -> ~[U]) -> ~[U] {
+        flat_map(*self, f)
     }
     /**
      * Apply a function to each element of a vector and return the results
@@ -1612,11 +1720,18 @@ fn map_r<U>(f: fn(x: &T) -> U) -> ~[U] {
      * the resulting vector.
      */
     #[inline]
-    pure fn filter_map<U: Copy>(f: fn(t: &T) -> Option<U>) -> ~[U] {
-        filter_map(self, f)
+    pure fn filter_map<U: Copy>(&self, f: fn(t: &T) -> Option<U>) -> ~[U] {
+        filter_map(*self, f)
     }
 }
 
+pub trait ImmutableEqVector<T: Eq> {
+    pure fn position(&self, f: fn(t: &T) -> bool) -> Option<uint>;
+    pure fn position_elem(&self, t: &T) -> Option<uint>;
+    pure fn rposition(&self, f: fn(t: &T) -> bool) -> Option<uint>;
+    pure fn rposition_elem(&self, t: &T) -> Option<uint>;
+}
+
 impl<T: Eq> &[T]: ImmutableEqVector<T> {
     /**
      * Find the first index matching some predicate
@@ -1626,14 +1741,14 @@ impl<T: Eq> &[T]: ImmutableEqVector<T> {
      * elements then none is returned.
      */
     #[inline]
-    pure fn position(f: fn(t: &T) -> bool) -> Option<uint> {
-        position(self, f)
+    pure fn position(&self, f: fn(t: &T) -> bool) -> Option<uint> {
+        position(*self, f)
     }
 
     /// Find the first index containing a matching value
     #[inline]
-    pure fn position_elem(x: &T) -> Option<uint> {
-        position_elem(self, x)
+    pure fn position_elem(&self, x: &T) -> Option<uint> {
+        position_elem(*self, x)
     }
 
     /**
@@ -1644,21 +1759,21 @@ impl<T: Eq> &[T]: ImmutableEqVector<T> {
      * returned. If `f` matches no elements then none is returned.
      */
     #[inline]
-    pure fn rposition(f: fn(t: &T) -> bool) -> Option<uint> {
-        rposition(self, f)
+    pure fn rposition(&self, f: fn(t: &T) -> bool) -> Option<uint> {
+        rposition(*self, f)
     }
 
     /// Find the last index containing a matching value
     #[inline]
-    pure fn rposition_elem(t: &T) -> Option<uint> {
-        rposition_elem(self, t)
+    pure fn rposition_elem(&self, t: &T) -> Option<uint> {
+        rposition_elem(*self, t)
     }
 }
 
 pub trait ImmutableCopyableVector<T> {
-    pure fn filter(f: fn(t: &T) -> bool) -> ~[T];
-
-    pure fn rfind(f: fn(t: &T) -> bool) -> Option<T>;
+    pure fn filtered(&self, f: fn(&T) -> bool) -> ~[T];
+    pure fn rfind(&self, f: fn(t: &T) -> bool) -> Option<T>;
+    pure fn partitioned(&self, f: fn(&T) -> bool) -> (~[T], ~[T]);
 }
 
 /// Extension methods for vectors
@@ -1671,8 +1786,8 @@ impl<T: Copy> &[T]: ImmutableCopyableVector<T> {
      * containing only those elements for which `f` returned true.
      */
     #[inline]
-    pure fn filter(f: fn(t: &T) -> bool) -> ~[T] {
-        filter(self, f)
+    pure fn filtered(&self, f: fn(t: &T) -> bool) -> ~[T] {
+        filtered(*self, f)
     }
 
     /**
@@ -1683,10 +1798,21 @@ impl<T: Copy> &[T]: ImmutableCopyableVector<T> {
      * returned. If `f` matches no elements then none is returned.
      */
     #[inline]
-    pure fn rfind(f: fn(t: &T) -> bool) -> Option<T> { rfind(self, f) }
+    pure fn rfind(&self, f: fn(t: &T) -> bool) -> Option<T> {
+        rfind(*self, f)
+    }
+
+    /**
+     * Partitions the vector into those that satisfies the predicate, and
+     * those that do not.
+     */
+    #[inline]
+    pure fn partitioned(&self, f: fn(&T) -> bool) -> (~[T], ~[T]) {
+        partitioned(*self, f)
+    }
 }
 
-pub trait MutableVector<T> {
+pub trait OwnedVector<T> {
     fn push(&mut self, t: T);
     fn push_all_move(&mut self, rhs: ~[T]);
     fn pop(&mut self) -> T;
@@ -1697,86 +1823,122 @@ pub trait MutableVector<T> {
     fn swap_remove(&mut self, index: uint) -> T;
     fn truncate(&mut self, newlen: uint);
     fn retain(&mut self, f: pure fn(t: &T) -> bool);
+    fn consume(self, f: fn(uint, v: T));
+    fn filter(self, f: fn(t: &T) -> bool) -> ~[T];
+    fn partition(self, f: pure fn(&T) -> bool) -> (~[T], ~[T]);
 }
 
-pub trait MutableCopyableVector<T: Copy> {
-    fn push_all(&mut self, rhs: &[const T]);
-    fn grow(&mut self, n: uint, initval: &T);
-    fn grow_fn(&mut self, n: uint, op: iter::InitOp<T>);
-    fn grow_set(&mut self, index: uint, initval: &T, val: T);
-}
-
-trait MutableEqVector<T: Eq> {
-    fn dedup(&mut self);
-}
-
-impl<T> ~[T]: MutableVector<T> {
+impl<T> ~[T]: OwnedVector<T> {
+    #[inline]
     fn push(&mut self, t: T) {
         push(self, t);
     }
 
+    #[inline]
     fn push_all_move(&mut self, rhs: ~[T]) {
         push_all_move(self, rhs);
     }
 
+    #[inline]
     fn pop(&mut self) -> T {
         pop(self)
     }
 
+    #[inline]
     fn shift(&mut self) -> T {
         shift(self)
     }
 
+    #[inline]
     fn unshift(&mut self, x: T) {
         unshift(self, x)
     }
 
+    #[inline]
     fn insert(&mut self, i: uint, x:T) {
         insert(self, i, x)
     }
 
+    #[inline]
     fn remove(&mut self, i: uint) -> T {
         remove(self, i)
     }
 
+    #[inline]
     fn swap_remove(&mut self, index: uint) -> T {
         swap_remove(self, index)
     }
 
+    #[inline]
     fn truncate(&mut self, newlen: uint) {
         truncate(self, newlen);
     }
 
+    #[inline]
     fn retain(&mut self, f: pure fn(t: &T) -> bool) {
         retain(self, f);
     }
+
+    #[inline]
+    fn consume(self, f: fn(uint, v: T)) {
+        consume(self, f)
+    }
+
+    #[inline]
+    fn filter(self, f: fn(&T) -> bool) -> ~[T] {
+        filter(self, f)
+    }
+
+    /**
+     * Partitions the vector into those that satisfies the predicate, and
+     * those that do not.
+     */
+    #[inline]
+    fn partition(self, f: fn(&T) -> bool) -> (~[T], ~[T]) {
+        partition(self, f)
+    }
 }
 
-impl<T: Copy> ~[T]: MutableCopyableVector<T> {
+pub trait OwnedCopyableVector<T: Copy> {
+    fn push_all(&mut self, rhs: &[const T]);
+    fn grow(&mut self, n: uint, initval: &T);
+    fn grow_fn(&mut self, n: uint, op: iter::InitOp<T>);
+    fn grow_set(&mut self, index: uint, initval: &T, val: T);
+}
+
+impl<T: Copy> ~[T]: OwnedCopyableVector<T> {
+    #[inline]
     fn push_all(&mut self, rhs: &[const T]) {
         push_all(self, rhs);
     }
 
+    #[inline]
     fn grow(&mut self, n: uint, initval: &T) {
         grow(self, n, initval);
     }
 
+    #[inline]
     fn grow_fn(&mut self, n: uint, op: iter::InitOp<T>) {
         grow_fn(self, n, op);
     }
 
+    #[inline]
     fn grow_set(&mut self, index: uint, initval: &T, val: T) {
         grow_set(self, index, initval, val);
     }
 }
 
-impl<T: Eq> ~[T]: MutableEqVector<T> {
+trait OwnedEqVector<T: Eq> {
+    fn dedup(&mut self);
+}
+
+impl<T: Eq> ~[T]: OwnedEqVector<T> {
+    #[inline]
     fn dedup(&mut self) {
         dedup(self)
     }
 }
 
-
 /**
 * Constructs a vector from an unsafe pointer to a buffer
 *
@@ -1799,6 +1961,15 @@ pub struct UnboxedVecRepr {
 
 /// Unsafe operations
 pub mod raw {
+    use kinds::Copy;
+    use managed;
+    use option::{None, Some};
+    use option;
+    use ptr::addr_of;
+    use ptr;
+    use sys;
+    use vec::{UnboxedVecRepr, as_const_buf, as_mut_buf, len, with_capacity};
+    use vec::rusti;
 
     /// The internal representation of a (boxed) vector
     pub struct VecRepr {
@@ -1821,7 +1992,7 @@ pub struct VecRepr {
     #[inline(always)]
     pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
         let repr: **VecRepr = ::cast::transmute(v);
-        (**repr).unboxed.fill = new_len * sys::size_of::<T>();
+        (**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>();
     }
 
     /**
@@ -1861,7 +2032,7 @@ pub unsafe fn to_mut_ptr<T>(v: &[mut T]) -> *mut T {
     pub unsafe fn buf_as_slice<T,U>(p: *T,
                                     len: uint,
                                     f: fn(v: &[T]) -> U) -> U {
-        let pair = (p, len * sys::size_of::<T>());
+        let pair = (p, len * sys::nonzero_size_of::<T>());
         let v : *(&blk/[T]) =
             ::cast::reinterpret_cast(&addr_of(&pair));
         f(*v)
@@ -1904,7 +2075,7 @@ pub unsafe fn init_elem<T>(v: &[mut T], i: uint, val: T) {
     pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
         let mut dst = with_capacity(elts);
         set_len(&mut dst, elts);
-        as_mut_buf(dst, |p_dst, _len_dst| ptr::memcpy(p_dst, ptr, elts));
+        as_mut_buf(dst, |p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts));
         dst
     }
 
@@ -1914,10 +2085,14 @@ pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
       * Copies `count` bytes from `src` to `dst`. The source and destination
       * may overlap.
       */
-    pub unsafe fn memcpy<T>(dst: &[mut T], src: &[const T], count: uint) {
+    pub unsafe fn copy_memory<T>(dst: &[mut T], src: &[const T],
+                                 count: uint) {
+        assert dst.len() >= count;
+        assert src.len() >= count;
+
         do as_mut_buf(dst) |p_dst, _len_dst| {
             do as_const_buf(src) |p_src, _len_src| {
-                ptr::memcpy(p_dst, p_src, count)
+                ptr::copy_memory(p_dst, p_src, count)
             }
         }
     }
@@ -1928,10 +2103,14 @@ pub unsafe fn memcpy<T>(dst: &[mut T], src: &[const T], count: uint) {
       * Copies `count` bytes from `src` to `dst`. The source and destination
       * may overlap.
       */
-    pub unsafe fn memmove<T>(dst: &[mut T], src: &[const T], count: uint) {
+    pub unsafe fn copy_overlapping_memory<T>(dst: &[mut T], src: &[const T],
+                                             count: uint) {
+        assert dst.len() >= count;
+        assert src.len() >= count;
+
         do as_mut_buf(dst) |p_dst, _len_dst| {
             do as_const_buf(src) |p_src, _len_src| {
-                ptr::memmove(p_dst, p_src, count)
+                ptr::copy_overlapping_memory(p_dst, p_src, count)
             }
         }
     }
@@ -1939,6 +2118,11 @@ pub unsafe fn memmove<T>(dst: &[mut T], src: &[const T], count: uint) {
 
 /// Operations on `[u8]`
 pub mod bytes {
+    use libc;
+    use uint;
+    use vec::len;
+    use vec::raw;
+    use vec;
 
     /// Bytewise string comparison
     pub pure fn cmp(a: &~[u8], b: &~[u8]) -> int {
@@ -1985,11 +2169,9 @@ pub mod bytes {
       * Copies `count` bytes from `src` to `dst`. The source and destination
       * may not overlap.
       */
-    pub fn memcpy(dst: &[mut u8], src: &[const u8], count: uint) {
-        assert dst.len() >= count;
-        assert src.len() >= count;
-
-        unsafe { vec::raw::memcpy(dst, src, count) }
+    pub fn copy_memory(dst: &[mut u8], src: &[const u8], count: uint) {
+        // Bound checks are done at vec::raw::copy_memory.
+        unsafe { vec::raw::copy_memory(dst, src, count) }
     }
 
     /**
@@ -1998,11 +2180,10 @@ pub fn memcpy(dst: &[mut u8], src: &[const u8], count: uint) {
       * Copies `count` bytes from `src` to `dst`. The source and destination
       * may overlap.
       */
-    pub fn memmove(dst: &[mut u8], src: &[const u8], count: uint) {
-        assert dst.len() >= count;
-        assert src.len() >= count;
-
-        unsafe { vec::raw::memmove(dst, src, count) }
+    pub fn copy_overlapping_memory(dst: &[mut u8], src: &[const u8],
+                                   count: uint) {
+        // Bound checks are done at vec::raw::copy_overlapping_memory.
+        unsafe { vec::raw::copy_overlapping_memory(dst, src, count) }
     }
 }
 
@@ -2229,6 +2410,9 @@ impl<A:Copy> @[A] : iter::CopyableNonstrictIter<A> {
 
 #[cfg(test)]
 mod tests {
+    use option::{None, Option, Some};
+    use option;
+    use vec::*;
 
     fn square(n: uint) -> uint { return n * n; }
 
@@ -2320,6 +2504,18 @@ fn test_is_not_empty() {
         assert (!is_not_empty::<int>(~[]));
     }
 
+    #[test]
+    fn test_len_divzero() {
+        type Z = [i8 * 0];
+        let v0 : &[Z] = &[];
+        let v1 : &[Z] = &[[]];
+        let v2 : &[Z] = &[[], []];
+        assert(sys::size_of::<Z>() == 0);
+        assert(len(v0) == 0);
+        assert(len(v1) == 1);
+        assert(len(v2) == 2);
+    }
+
     #[test]
     fn test_head() {
         let a = ~[11, 12];
@@ -2581,7 +2777,9 @@ fn test_filter_map() {
         fn halve(i: &int) -> Option<int> {
             if *i % 2 == 0 {
                 return option::Some::<int>(*i / 2);
-            } else { return option::None::<int>; }
+            } else {
+                return option::None::<int>;
+            }
         }
         fn halve_for_sure(i: &int) -> int { return *i / 2; }
         let all_even: ~[int] = ~[0, 2, 8, 6];
@@ -3005,6 +3203,26 @@ fn f(x: &int) -> bool { *x == 3 }
                        ~[~[1, 2, 3, 4], ~[5]];
     }
 
+    #[test]
+    fn test_partition() {
+        // FIXME (#4355 maybe): using v.partition here crashes
+        assert partition(~[], |x: &int| *x < 3) == (~[], ~[]);
+        assert partition(~[1, 2, 3], |x: &int| *x < 4) == (~[1, 2, 3], ~[]);
+        assert partition(~[1, 2, 3], |x: &int| *x < 2) == (~[1], ~[2, 3]);
+        assert partition(~[1, 2, 3], |x: &int| *x < 0) == (~[], ~[1, 2, 3]);
+    }
+
+    #[test]
+    fn test_partitioned() {
+        assert (~[]).partitioned(|x: &int| *x < 3) == (~[], ~[]);
+        assert (~[1, 2, 3]).partitioned(|x: &int| *x < 4) ==
+               (~[1, 2, 3], ~[]);
+        assert (~[1, 2, 3]).partitioned(|x: &int| *x < 2) ==
+               (~[1], ~[2, 3]);
+        assert (~[1, 2, 3]).partitioned(|x: &int| *x < 0) ==
+               (~[], ~[1, 2, 3]);
+    }
+
     #[test]
     #[should_fail]
     #[ignore(cfg(windows))]
@@ -3441,7 +3659,7 @@ fn test_filter_map_fail() {
     fn test_filter_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
         let mut i = 0;
-        do filter(v) |_elt| {
+        do v.filtered |_elt| {
             if i == 2 {
                 fail
             }
@@ -3669,7 +3887,7 @@ fn test_as_const_buf_fail() {
     }
 
     #[test]
-    #[ignore(windows)]
+    #[ignore(cfg(windows))]
     #[should_fail]
     fn test_as_mut_buf_fail() {
         let v = [mut (~0, @0), (~0, @0), (~0, @0), (~0, @0)];
@@ -3677,6 +3895,16 @@ fn test_as_mut_buf_fail() {
             fail
         }
     }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_copy_memory_oob() unsafe {
+        let a = [mut 1, 2, 3, 4];
+        let b = [1, 2, 3, 4, 5];
+        raw::copy_memory(a, b, 5);
+    }
+
 }
 
 // Local Variables:
index cf242ddd8e219a87c6a099adfe6149db52ddd2ce..fd36c1d770158581e1ba45d2a042584ba1fcf2f8 100644 (file)
@@ -81,7 +81,7 @@ fn common_exprs() -> ~[ast::expr] {
     }
 
     fn dsl(l: ast::lit_) -> ast::lit {
-        { node: l, span: ast_util::dummy_sp() }
+        ast::spanned { node: l, span: ast_util::dummy_sp() }
     }
 
     ~[dse(ast::expr_break(option::None)),
@@ -167,7 +167,7 @@ type stolen_stuff = {exprs: ~[ast::expr], tys: ~[ast::Ty]};
 fn steal(crate: ast::crate, tm: test_mode) -> stolen_stuff {
     let exprs = @mut ~[];
     let tys = @mut ~[];
-    let v = visit::mk_simple_visitor(@{
+    let v = visit::mk_simple_visitor(@visit::SimpleVisitor {
         visit_expr: |a| stash_expr_if(safe_to_steal_expr, exprs, a, tm),
         visit_ty: |a| stash_ty_if(safe_to_steal_ty, tys, a, tm),
         .. *visit::default_simple_visitor()
@@ -216,7 +216,7 @@ fn replace_expr_in_crate(crate: ast::crate, i: uint,
             fold::noop_fold_expr(original, fld)
         }
     }
-    let afp = @{
+    let afp = @fold::AstFoldFns {
         fold_expr: fold::wrap(|a,b| {
             fold_expr_rep(j, i, newexpr.node, a, b, tm)
         }),
@@ -241,7 +241,7 @@ fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::Ty,
             newty_
         } else { fold::noop_fold_ty(original, fld) }
     }
-    let afp = @{
+    let afp = @fold::AstFoldFns {
         fold_ty: fold::wrap(|a,b| fold_ty_rep(j, i, newty.node, a, b, tm) ),
         .. *fold::default_ast_fold()
     };
@@ -262,8 +262,9 @@ fn as_str(f: fn@(+x: io::Writer)) -> ~str {
 fn check_variants_of_ast(crate: ast::crate, codemap: @codemap::CodeMap,
                          filename: &Path, cx: context) {
     let stolen = steal(crate, cx.mode);
-    let extra_exprs = vec::filter(common_exprs(),
-                                  |a| safe_to_use_expr(*a, cx.mode) );
+    let extra_exprs = do common_exprs().filtered |a| {
+        safe_to_use_expr(*a, cx.mode)
+    };
     check_variants_T(crate, codemap, filename, ~"expr",
                      extra_exprs + stolen.exprs, pprust::expr_to_str,
                      replace_expr_in_crate, cx);
@@ -485,8 +486,9 @@ fn has_raw_pointers(c: ast::crate) -> bool {
         }
     }
     let v =
-        visit::mk_simple_visitor(@{visit_ty: |a| visit_ty(has_rp, a),
-                                      .. *visit::default_simple_visitor()});
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_ty: |a| visit_ty(has_rp, a),
+            .. *visit::default_simple_visitor()});
     visit::visit_crate(c, (), v);
     return *has_rp;
 }
diff --git a/src/librustc/back/arm.rs b/src/librustc/back/arm.rs
new file mode 100644 (file)
index 0000000..2c4e0af
--- /dev/null
@@ -0,0 +1,85 @@
+// 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 driver::session;
+use session::sess_os_to_meta_os;
+use metadata::loader::meta_section_name;
+
+fn get_target_strs(target_os: session::os) -> target_strs::t {
+    return {
+        module_asm: ~"",
+
+        meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)),
+
+        data_layout: match target_os {
+          session::os_macos => {
+            ~"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"
+          }
+
+          session::os_win32 => {
+            ~"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"
+          }
+
+          session::os_linux => {
+            ~"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"
+          }
+
+          session::os_android => {
+            ~"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"
+          }
+
+          session::os_freebsd => {
+            ~"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"
+          }
+        },
+
+        target_triple: match target_os {
+          session::os_macos => ~"arm-apple-darwin",
+          session::os_win32 => ~"arm-pc-mingw32",
+          session::os_linux => ~"arm-unknown-linux",
+          session::os_android => ~"arm-unknown-android",
+          session::os_freebsd => ~"arm-unknown-freebsd"
+        },
+
+        cc_args: ~[~"-marm"]
+    };
+}
+
+
+//
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
+//
index 52b94b76fe614f0ff43f5d60218a0370d9576ac6..e49d9da335569de39198341687d38b050ee6b145 100644 (file)
@@ -8,24 +8,40 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use libc::{c_int, c_uint, c_char};
+use core::prelude::*;
+
+use back::rpath;
 use driver::session;
-use session::Session;
 use lib::llvm::llvm;
-use syntax::attr;
-use middle::ty;
+use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False};
+use lib::llvm::{PassManagerRef, FileType};
+use lib;
+use metadata::common::link_meta;
+use metadata::filesearch;
 use metadata::{encoder, cstore};
 use middle::trans::common::crate_ctxt;
-use metadata::common::link_meta;
+use middle::ty;
+use session::Session;
+use session;
+use util::ppaux;
+
+use core::char;
+use core::cmp;
+use core::hash;
+use core::io::{Writer, WriterUtil};
+use core::libc::{c_int, c_uint, c_char};
+use core::os::consts::{macos, freebsd, linux, android, win32};
+use core::os;
+use core::ptr;
+use core::run;
+use core::str;
+use core::vec;
 use std::map::HashMap;
 use std::sha1::sha1;
 use syntax::ast;
-use syntax::print::pprust;
-use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False,
-        PassManagerRef, FileType};
-use metadata::filesearch;
 use syntax::ast_map::{path, path_mod, path_name};
-use io::{Writer, WriterUtil};
+use syntax::attr;
+use syntax::print::pprust;
 
 enum output_type {
     output_type_none,
@@ -43,14 +59,16 @@ impl output_type : cmp::Eq {
     pure fn ne(&self, other: &output_type) -> bool { !(*self).eq(other) }
 }
 
-fn llvm_err(sess: Session, msg: ~str) -> ! unsafe {
+pub fn llvm_err(sess: Session, +msg: ~str) -> ! unsafe {
     let cstr = llvm::LLVMRustGetLastError();
     if cstr == ptr::null() {
         sess.fatal(msg);
-    } else { sess.fatal(msg + ~": " + str::raw::from_c_str(cstr)); }
+    } else {
+        sess.fatal(msg + ~": " + str::raw::from_c_str(cstr));
+    }
 }
 
-fn WriteOutputFile(sess: Session,
+pub fn WriteOutputFile(sess: Session,
         PM: lib::llvm::PassManagerRef, M: ModuleRef,
         Triple: *c_char,
         // FIXME: When #2334 is fixed, change
@@ -58,15 +76,35 @@ fn WriteOutputFile(sess: Session,
         Output: *c_char, FileType: c_uint,
         OptLevel: c_int,
         EnableSegmentedStacks: bool) {
-    let result = llvm::LLVMRustWriteOutputFile(
-            PM, M, Triple, Output, FileType, OptLevel, EnableSegmentedStacks);
-    if (!result) {
-        llvm_err(sess, ~"Could not write output");
+    unsafe {
+        let result = llvm::LLVMRustWriteOutputFile(
+                PM,
+                M,
+                Triple,
+                Output,
+                FileType,
+                OptLevel,
+                EnableSegmentedStacks);
+        if (!result) {
+            llvm_err(sess, ~"Could not write output");
+        }
     }
 }
 
-mod jit {
+pub mod jit {
     #[legacy_exports];
+
+    use back::link::llvm_err;
+    use lib::llvm::llvm;
+    use lib::llvm::{ModuleRef, PassManagerRef, mk_target_data};
+    use metadata::cstore;
+    use session::Session;
+
+    use core::cast;
+    use core::libc::c_int;
+    use core::ptr;
+    use core::str;
+
     #[nolink]
     #[abi = "rust-intrinsic"]
     extern mod rusti {
@@ -126,13 +164,31 @@ fn exec(sess: Session,
             };
             let func: fn(++argv: ~[~str]) = cast::transmute(move closure);
 
-            func(~[sess.opts.binary]);
+            func(~[/*bad*/copy sess.opts.binary]);
         }
     }
 }
 
 mod write {
     #[legacy_exports];
+
+    use back::link::jit;
+    use back::link::{ModuleRef, WriteOutputFile, output_type};
+    use back::link::{output_type_assembly, output_type_bitcode};
+    use back::link::{output_type_exe, output_type_llvm_assembly};
+    use back::link::{output_type_object};
+    use driver::session;
+    use lib::llvm::llvm;
+    use lib::llvm::{False, True, mk_pass_manager, mk_target_data};
+    use lib;
+    use session::Session;
+
+    use core::char;
+    use core::libc::{c_char, c_int, c_uint};
+    use core::path::Path;
+    use core::str;
+    use core::vec;
+
     fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
         if ot == output_type_assembly || ot == output_type_object ||
                ot == output_type_exe {
@@ -142,146 +198,170 @@ fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
     }
 
     fn run_passes(sess: Session, llmod: ModuleRef, output: &Path) {
-        let opts = sess.opts;
-        if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
-        let mut pm = mk_pass_manager();
-        let td = mk_target_data(
-            sess.targ_cfg.target_strs.data_layout);
-        llvm::LLVMAddTargetData(td.lltd, pm.llpm);
-        // FIXME (#2812): run the linter here also, once there are llvm-c
-        // bindings for it.
-
-        // Generate a pre-optimization intermediate file if -save-temps was
-        // specified.
-
-
-        if opts.save_temps {
-            match opts.output_type {
-              output_type_bitcode => {
-                if opts.optimize != session::No {
-                    let filename = output.with_filetype("no-opt.bc");
+        unsafe {
+            let opts = sess.opts;
+            if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
+            let mut pm = mk_pass_manager();
+            let td = mk_target_data(
+                /*bad*/copy sess.targ_cfg.target_strs.data_layout);
+            llvm::LLVMAddTargetData(td.lltd, pm.llpm);
+            // FIXME (#2812): run the linter here also, once there are llvm-c
+            // bindings for it.
+
+            // Generate a pre-optimization intermediate file if -save-temps
+            // was specified.
+
+
+            if opts.save_temps {
+                match opts.output_type {
+                  output_type_bitcode => {
+                    if opts.optimize != session::No {
+                        let filename = output.with_filetype("no-opt.bc");
+                        str::as_c_str(filename.to_str(), |buf| {
+                            llvm::LLVMWriteBitcodeToFile(llmod, buf)
+                        });
+                    }
+                  }
+                  _ => {
+                    let filename = output.with_filetype("bc");
                     str::as_c_str(filename.to_str(), |buf| {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf)
                     });
+                  }
                 }
-              }
-              _ => {
-                let filename = output.with_filetype("bc");
-                str::as_c_str(filename.to_str(), |buf| {
-                    llvm::LLVMWriteBitcodeToFile(llmod, buf)
-                });
-              }
-            }
-        }
-        if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
-        // FIXME (#2396): This is mostly a copy of the bits of opt's -O2 that
-        // are available in the C api.
-        // Also: We might want to add optimization levels like -O1, -O2,
-        // -Os, etc
-        // Also: Should we expose and use the pass lists used by the opt
-        // tool?
-
-        if opts.optimize != session::No {
-            let fpm = mk_pass_manager();
-            llvm::LLVMAddTargetData(td.lltd, fpm.llpm);
-
-            let FPMB = llvm::LLVMPassManagerBuilderCreate();
-            llvm::LLVMPassManagerBuilderSetOptLevel(FPMB, 2u as c_uint);
-            llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(FPMB,
-                                                                    fpm.llpm);
-            llvm::LLVMPassManagerBuilderDispose(FPMB);
-
-            llvm::LLVMRunPassManager(fpm.llpm, llmod);
-            let mut threshold = 225;
-            if opts.optimize == session::Aggressive { threshold = 275; }
-
-            let MPMB = llvm::LLVMPassManagerBuilderCreate();
-            llvm::LLVMPassManagerBuilderSetOptLevel(MPMB,
-                                                    opts.optimize as c_uint);
-            llvm::LLVMPassManagerBuilderSetSizeLevel(MPMB, False);
-            llvm::LLVMPassManagerBuilderSetDisableUnitAtATime(MPMB, False);
-            llvm::LLVMPassManagerBuilderSetDisableUnrollLoops(MPMB, False);
-            llvm::LLVMPassManagerBuilderSetDisableSimplifyLibCalls(MPMB,
-                                                                   False);
-
-            if threshold != 0u {
-                llvm::LLVMPassManagerBuilderUseInlinerWithThreshold
-                    (MPMB, threshold as c_uint);
             }
-            llvm::LLVMPassManagerBuilderPopulateModulePassManager(MPMB,
-                                                                  pm.llpm);
+            if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
+            // FIXME (#2396): This is mostly a copy of the bits of opt's -O2
+            // that are available in the C api.
+            // Also: We might want to add optimization levels like -O1, -O2,
+            // -Os, etc
+            // Also: Should we expose and use the pass lists used by the opt
+            // tool?
+
+            if opts.optimize != session::No {
+                let fpm = mk_pass_manager();
+                llvm::LLVMAddTargetData(td.lltd, fpm.llpm);
+
+                let FPMB = llvm::LLVMPassManagerBuilderCreate();
+                llvm::LLVMPassManagerBuilderSetOptLevel(FPMB, 2u as c_uint);
+                llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(
+                    FPMB, fpm.llpm);
+                llvm::LLVMPassManagerBuilderDispose(FPMB);
+
+                llvm::LLVMRunPassManager(fpm.llpm, llmod);
+                let mut threshold = 225;
+                if opts.optimize == session::Aggressive { threshold = 275; }
+
+                let MPMB = llvm::LLVMPassManagerBuilderCreate();
+                llvm::LLVMPassManagerBuilderSetOptLevel(MPMB,
+                                                        opts.optimize as
+                                                            c_uint);
+                llvm::LLVMPassManagerBuilderSetSizeLevel(MPMB, False);
+                llvm::LLVMPassManagerBuilderSetDisableUnitAtATime(MPMB,
+                                                                  False);
+                llvm::LLVMPassManagerBuilderSetDisableUnrollLoops(MPMB,
+                                                                  False);
+                llvm::LLVMPassManagerBuilderSetDisableSimplifyLibCalls(MPMB,
+                                                                       False);
+
+                if threshold != 0u {
+                    llvm::LLVMPassManagerBuilderUseInlinerWithThreshold
+                        (MPMB, threshold as c_uint);
+                }
+                llvm::LLVMPassManagerBuilderPopulateModulePassManager(
+                    MPMB, pm.llpm);
 
-            llvm::LLVMPassManagerBuilderDispose(MPMB);
-        }
-        if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
-        if is_object_or_assembly_or_exe(opts.output_type) || opts.jit {
-            let LLVMOptNone       = 0 as c_int; // -O0
-            let LLVMOptLess       = 1 as c_int; // -O1
-            let LLVMOptDefault    = 2 as c_int; // -O2, -Os
-            let LLVMOptAggressive = 3 as c_int; // -O3
-
-            let mut CodeGenOptLevel = match opts.optimize {
-              session::No => LLVMOptNone,
-              session::Less => LLVMOptLess,
-              session::Default => LLVMOptDefault,
-              session::Aggressive => LLVMOptAggressive
-            };
+                llvm::LLVMPassManagerBuilderDispose(MPMB);
+            }
+            if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
+            if is_object_or_assembly_or_exe(opts.output_type) || opts.jit {
+                let LLVMOptNone       = 0 as c_int; // -O0
+                let LLVMOptLess       = 1 as c_int; // -O1
+                let LLVMOptDefault    = 2 as c_int; // -O2, -Os
+                let LLVMOptAggressive = 3 as c_int; // -O3
+
+                let mut CodeGenOptLevel = match opts.optimize {
+                  session::No => LLVMOptNone,
+                  session::Less => LLVMOptLess,
+                  session::Default => LLVMOptDefault,
+                  session::Aggressive => LLVMOptAggressive
+                };
 
-            if opts.jit {
-                // If we are using JIT, go ahead and create and
-                // execute the engine now.
-                // JIT execution takes ownership of the module,
-                // so don't dispose and return.
+                if opts.jit {
+                    // If we are using JIT, go ahead and create and
+                    // execute the engine now.
+                    // JIT execution takes ownership of the module,
+                    // so don't dispose and return.
 
-                jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
+                    jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
 
-                if sess.time_llvm_passes() {
-                    llvm::LLVMRustPrintPassTimings();
+                    if sess.time_llvm_passes() {
+                        llvm::LLVMRustPrintPassTimings();
+                    }
+                    return;
                 }
-                return;
-            }
 
-            let mut FileType;
-            if opts.output_type == output_type_object ||
-                   opts.output_type == output_type_exe {
-               FileType = lib::llvm::ObjectFile;
-            } else { FileType = lib::llvm::AssemblyFile; }
-            // Write optimized bitcode if --save-temps was on.
+                let mut FileType;
+                if opts.output_type == output_type_object ||
+                       opts.output_type == output_type_exe {
+                   FileType = lib::llvm::ObjectFile;
+                } else { FileType = lib::llvm::AssemblyFile; }
+                // Write optimized bitcode if --save-temps was on.
 
-            if opts.save_temps {
-                // Always output the bitcode file with --save-temps
+                if opts.save_temps {
+                    // Always output the bitcode file with --save-temps
 
-                let filename = output.with_filetype("opt.bc");
-                llvm::LLVMRunPassManager(pm.llpm, llmod);
-                str::as_c_str(filename.to_str(), |buf| {
-                    llvm::LLVMWriteBitcodeToFile(llmod, buf)
-                });
-                pm = mk_pass_manager();
-                // Save the assembly file if -S is used
+                    let filename = output.with_filetype("opt.bc");
+                    llvm::LLVMRunPassManager(pm.llpm, llmod);
+                    str::as_c_str(filename.to_str(), |buf| {
+                        llvm::LLVMWriteBitcodeToFile(llmod, buf)
+                    });
+                    pm = mk_pass_manager();
+                    // Save the assembly file if -S is used
+
+                    if opts.output_type == output_type_assembly {
+                        let _: () = str::as_c_str(
+                            sess.targ_cfg.target_strs.target_triple,
+                            |buf_t| {
+                                str::as_c_str(output.to_str(), |buf_o| {
+                                    WriteOutputFile(
+                                        sess,
+                                        pm.llpm,
+                                        llmod,
+                                        buf_t,
+                                        buf_o,
+                                        lib::llvm::AssemblyFile as c_uint,
+                                        CodeGenOptLevel,
+                                        true)
+                                })
+                            });
+                    }
 
-                if opts.output_type == output_type_assembly {
-                    let _: () = str::as_c_str(
-                        sess.targ_cfg.target_strs.target_triple,
-                        |buf_t| {
-                            str::as_c_str(output.to_str(), |buf_o| {
-                                WriteOutputFile(
-                                    sess,
-                                    pm.llpm,
-                                    llmod,
-                                    buf_t,
-                                    buf_o,
-                                    lib::llvm::AssemblyFile as c_uint,
-                                    CodeGenOptLevel,
-                                    true)
-                            })
-                        });
-                }
 
+                    // Save the object file for -c or --save-temps alone
+                    // This .o is needed when an exe is built
+                    if opts.output_type == output_type_object ||
+                           opts.output_type == output_type_exe {
+                        let _: () = str::as_c_str(
+                            sess.targ_cfg.target_strs.target_triple,
+                            |buf_t| {
+                                str::as_c_str(output.to_str(), |buf_o| {
+                                    WriteOutputFile(
+                                        sess,
+                                        pm.llpm,
+                                        llmod,
+                                        buf_t,
+                                        buf_o,
+                                        lib::llvm::ObjectFile as c_uint,
+                                        CodeGenOptLevel,
+                                        true)
+                                })
+                            });
+                    }
+                } else {
+                    // If we aren't saving temps then just output the file
+                    // type corresponding to the '-c' or '-S' flag used
 
-                // Save the object file for -c or --save-temps alone
-                // This .o is needed when an exe is built
-                if opts.output_type == output_type_object ||
-                       opts.output_type == output_type_exe {
                     let _: () = str::as_c_str(
                         sess.targ_cfg.target_strs.target_triple,
                         |buf_t| {
@@ -292,53 +372,36 @@ fn run_passes(sess: Session, llmod: ModuleRef, output: &Path) {
                                     llmod,
                                     buf_t,
                                     buf_o,
-                                    lib::llvm::ObjectFile as c_uint,
+                                    FileType as c_uint,
                                     CodeGenOptLevel,
                                     true)
                             })
                         });
                 }
+                // Clean up and return
+
+                llvm::LLVMDisposeModule(llmod);
+                if sess.time_llvm_passes() {
+                    llvm::LLVMRustPrintPassTimings();
+                }
+                return;
+            }
+
+            if opts.output_type == output_type_llvm_assembly {
+                // Given options "-S --emit-llvm": output LLVM assembly
+                str::as_c_str(output.to_str(), |buf_o| {
+                    llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)});
             } else {
-                // If we aren't saving temps then just output the file
-                // type corresponding to the '-c' or '-S' flag used
-
-                let _: () = str::as_c_str(
-                    sess.targ_cfg.target_strs.target_triple,
-                    |buf_t| {
-                        str::as_c_str(output.to_str(), |buf_o| {
-                            WriteOutputFile(
-                                sess,
-                                pm.llpm,
-                                llmod,
-                                buf_t,
-                                buf_o,
-                                FileType as c_uint,
-                                CodeGenOptLevel,
-                                true)
-                        })
-                    });
+                // If only a bitcode file is asked for by using the
+                // '--emit-llvm' flag, then output it here
+                llvm::LLVMRunPassManager(pm.llpm, llmod);
+                str::as_c_str(output.to_str(),
+                            |buf| llvm::LLVMWriteBitcodeToFile(llmod, buf) );
             }
-            // Clean up and return
 
             llvm::LLVMDisposeModule(llmod);
             if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
-            return;
         }
-
-        if opts.output_type == output_type_llvm_assembly {
-            // Given options "-S --emit-llvm": output LLVM assembly
-            str::as_c_str(output.to_str(), |buf_o| {
-                llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)});
-        } else {
-            // If only a bitcode file is asked for by using the '--emit-llvm'
-            // flag, then output it here
-            llvm::LLVMRunPassManager(pm.llpm, llmod);
-            str::as_c_str(output.to_str(),
-                        |buf| llvm::LLVMWriteBitcodeToFile(llmod, buf) );
-        }
-
-        llvm::LLVMDisposeModule(llmod);
-        if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
     }
 }
 
@@ -407,17 +470,19 @@ fn provided_link_metas(sess: Session, c: ast::crate) ->
         let mut name: Option<~str> = None;
         let mut vers: Option<~str> = None;
         let mut cmh_items: ~[@ast::meta_item] = ~[];
-        let linkage_metas = attr::find_linkage_metas(c.node.attrs);
-        attr::require_unique_names(sess.diagnostic(), linkage_metas);
+        let linkage_metas =
+            attr::find_linkage_metas(/*bad*/copy c.node.attrs);
+        // XXX: Bad copy.
+        attr::require_unique_names(sess.diagnostic(), copy linkage_metas);
         for linkage_metas.each |meta| {
             if attr::get_meta_item_name(*meta) == ~"name" {
                 match attr::get_meta_item_value_str(*meta) {
-                  Some(ref v) => { name = Some((*v)); }
+                  Some(ref v) => { name = Some((/*bad*/copy *v)); }
                   None => cmh_items.push(*meta)
                 }
             } else if attr::get_meta_item_name(*meta) == ~"vers" {
                 match attr::get_meta_item_value_str(*meta) {
-                  Some(ref v) => { vers = Some((*v)); }
+                  Some(ref v) => { vers = Some((/*bad*/copy *v)); }
                   None => cmh_items.push(*meta)
                 }
             } else { cmh_items.push(*meta); }
@@ -438,7 +503,7 @@ fn len_and_str_lit(l: ast::lit) -> ~str {
             return len_and_str(pprust::lit_to_str(@l));
         }
 
-        let cmh_items = attr::sort_meta_items(metas.cmh_items);
+        let cmh_items = attr::sort_meta_items(/*bad*/copy metas.cmh_items);
 
         symbol_hasher.reset();
         for cmh_items.each |m| {
@@ -473,15 +538,16 @@ fn warn_missing(sess: Session, name: ~str, default: ~str) {
     fn crate_meta_name(sess: Session, _crate: ast::crate,
                        output: &Path, metas: provided_metas) -> ~str {
         return match metas.name {
-              Some(ref v) => (*v),
+              Some(ref v) => (/*bad*/copy *v),
               None => {
                 let name = match output.filestem() {
                   None => sess.fatal(fmt!("output file name `%s` doesn't\
                                            appear to have a stem",
                                           output.to_str())),
-                  Some(ref s) => (*s)
+                  Some(ref s) => (/*bad*/copy *s)
                 };
-                warn_missing(sess, ~"name", name);
+                // XXX: Bad copy.
+                warn_missing(sess, ~"name", copy name);
                 name
               }
             };
@@ -490,10 +556,11 @@ fn crate_meta_name(sess: Session, _crate: ast::crate,
     fn crate_meta_vers(sess: Session, _crate: ast::crate,
                        metas: provided_metas) -> ~str {
         return match metas.vers {
-              Some(ref v) => (*v),
+              Some(ref v) => (/*bad*/copy *v),
               None => {
                 let vers = ~"0.0";
-                warn_missing(sess, ~"vers", vers);
+                // Bad copy.
+                warn_missing(sess, ~"vers", copy vers);
                 vers
               }
             };
@@ -534,10 +601,11 @@ fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t,
 
 fn get_symbol_hash(ccx: @crate_ctxt, t: ty::t) -> ~str {
     match ccx.type_hashcodes.find(t) {
-      Some(ref h) => return (*h),
+      Some(ref h) => return (/*bad*/copy *h),
       None => {
         let hash = symbol_hash(ccx.tcx, ccx.symbol_hasher, t, ccx.link_meta);
-        ccx.type_hashcodes.insert(t, hash);
+        // XXX: Bad copy. Prefer `@str`?
+        ccx.type_hashcodes.insert(t, copy hash);
         return hash;
       }
     }
@@ -594,22 +662,27 @@ fn mangle(sess: Session, ss: path) -> ~str {
     n
 }
 
-fn exported_name(sess: Session, path: path, hash: ~str, vers: ~str) -> ~str {
+fn exported_name(sess: Session,
+                 +path: path,
+                 +hash: ~str,
+                 +vers: ~str) -> ~str {
     return mangle(sess,
                   vec::append_one(
                       vec::append_one(path, path_name(sess.ident_of(hash))),
                       path_name(sess.ident_of(vers))));
 }
 
-fn mangle_exported_name(ccx: @crate_ctxt, path: path, t: ty::t) -> ~str {
+fn mangle_exported_name(ccx: @crate_ctxt, +path: path, t: ty::t) -> ~str {
     let hash = get_symbol_hash(ccx, t);
-    return exported_name(ccx.sess, path, hash, ccx.link_meta.vers);
+    return exported_name(ccx.sess, path,
+                         hash,
+                         /*bad*/copy ccx.link_meta.vers);
 }
 
 fn mangle_internal_name_by_type_only(ccx: @crate_ctxt,
-                                     t: ty::t, name: ~str) ->
-   ~str {
-    let s = util::ppaux::ty_to_short_str(ccx.tcx, t);
+                                     t: ty::t,
+                                     +name: ~str) -> ~str {
+    let s = ppaux::ty_to_short_str(ccx.tcx, t);
     let hash = get_symbol_hash(ccx, t);
     return mangle(ccx.sess,
                   ~[path_name(ccx.sess.ident_of(name)),
@@ -617,20 +690,35 @@ fn mangle_internal_name_by_type_only(ccx: @crate_ctxt,
                     path_name(ccx.sess.ident_of(hash))]);
 }
 
-fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt, path: path,
-                                        flav: ~str) -> ~str {
+fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt,
+                                        +path: path,
+                                        +flav: ~str) -> ~str {
     return mangle(ccx.sess,
                   vec::append_one(path, path_name((ccx.names)(flav))));
 }
 
-fn mangle_internal_name_by_path(ccx: @crate_ctxt, path: path) -> ~str {
+fn mangle_internal_name_by_path(ccx: @crate_ctxt, +path: path) -> ~str {
     return mangle(ccx.sess, path);
 }
 
-fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: ~str) -> ~str {
+fn mangle_internal_name_by_seq(ccx: @crate_ctxt, +flav: ~str) -> ~str {
     return fmt!("%s_%u", flav, (ccx.names)(flav).repr);
 }
 
+
+fn output_dll_filename(os: session::os, lm: &link_meta) -> ~str {
+    let libname = fmt!("%s-%s-%s", lm.name, lm.extras_hash, lm.vers);
+    let (dll_prefix, dll_suffix) = match os {
+        session::os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
+        session::os_macos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
+        session::os_linux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
+        session::os_android => (android::DLL_PREFIX, android::DLL_SUFFIX),
+        session::os_freebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
+    };
+    return str::from_slice(dll_prefix) + libname +
+           str::from_slice(dll_suffix);
+}
+
 // If the user wants an exe generated we need to invoke
 // cc to link the object file with some libs
 fn link_binary(sess: Session,
@@ -638,7 +726,7 @@ fn link_binary(sess: Session,
                out_filename: &Path,
                lm: link_meta) {
     // Converts a library file-stem into a cc -l argument
-    fn unlib(config: @session::config, stem: ~str) -> ~str {
+    fn unlib(config: @session::config, +stem: ~str) -> ~str {
         if stem.starts_with("lib") &&
             config.os != session::os_win32 {
             stem.slice(3, stem.len())
@@ -648,9 +736,7 @@ fn unlib(config: @session::config, stem: ~str) -> ~str {
     }
 
     let output = if sess.building_library {
-        let long_libname =
-            os::dll_filename(fmt!("%s-%s-%s",
-                                  lm.name, lm.extras_hash, lm.vers));
+        let long_libname = output_dll_filename(sess.targ_cfg.os, &lm);
         debug!("link_meta.name:  %s", lm.name);
         debug!("long_libname: %s", long_libname);
         debug!("out_filename: %s", out_filename.to_str());
@@ -658,7 +744,7 @@ fn unlib(config: @session::config, stem: ~str) -> ~str {
 
         out_filename.dir_path().push(long_libname)
     } else {
-        *out_filename
+        /*bad*/copy *out_filename
     };
 
     log(debug, ~"output: " + output.to_str());
@@ -673,7 +759,10 @@ fn unlib(config: @session::config, stem: ~str) -> ~str {
     // For win32, there is no cc command,
     // so we add a condition to make it use gcc.
     let cc_prog: ~str =
-        if sess.targ_cfg.os == session::os_win32 { ~"gcc" } else { ~"cc" };
+        if sess.targ_cfg.os == session::os_android {
+            ~"arm-linux-androideabi-g++"
+        } else if sess.targ_cfg.os == session::os_win32 { ~"gcc" }
+        else { ~"cc" };
     // The invocations of cc share some flags across platforms
 
     let mut cc_args =
@@ -705,7 +794,7 @@ fn unlib(config: @session::config, stem: ~str) -> ~str {
     }
 
     let ula = cstore::get_used_link_args(cstore);
-    for ula.each |arg| { cc_args.push(*arg); }
+    for ula.each |arg| { cc_args.push(/*bad*/copy *arg); }
 
     // # Extern library linking
 
@@ -715,7 +804,7 @@ fn unlib(config: @session::config, stem: ~str) -> ~str {
     // to be found at compile time so it is still entirely up to outside
     // forces to make sure that library can be found at runtime.
 
-    let addl_paths = sess.opts.addl_lib_search_paths;
+    let addl_paths = /*bad*/copy sess.opts.addl_lib_search_paths;
     for addl_paths.each |path| { cc_args.push(~"-L" + path.to_str()); }
 
     // The names of the extern libraries
@@ -746,6 +835,11 @@ fn unlib(config: @session::config, stem: ~str) -> ~str {
         // have to be explicit about linking to it. See #2510
         cc_args.push(~"-lm");
     }
+    else if sess.targ_cfg.os == session::os_android {
+        cc_args.push_all(~[~"-ldl", ~"-llog",  ~"-lsupc++",
+                           ~"-lgnustl_shared"]);
+        cc_args.push(~"-lm");
+    }
 
     if sess.targ_cfg.os == session::os_freebsd {
         cc_args.push_all(~[~"-pthread", ~"-lrt",
@@ -766,7 +860,9 @@ fn unlib(config: @session::config, stem: ~str) -> ~str {
     }
 
     // Stack growth requires statically linking a __morestack function
+    if sess.targ_cfg.os != session::os_android {
     cc_args.push(~"-lmorestack");
+    }
 
     // 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
index c12458c3f2805913f2005436b39818c085888544..005a5404b37e6a9eb6dfbc6ee71b1f5dd4d453b2 100644 (file)
@@ -8,13 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::map;
-use std::map::HashMap;
-use metadata::cstore;
+use core::prelude::*;
+
 use driver::session;
+use metadata::cstore;
 use metadata::filesearch;
 
+use core::os;
+use core::uint;
+use core::util;
+use core::vec;
+use std::map::HashMap;
+use std::map;
+
+export get_absolute_rpath;
+export get_install_prefix_rpath;
+export get_relative_to;
 export get_rpath_flags;
+export get_rpath_relative_to_output;
+export minimize_rpaths;
+export rpaths_to_flags;
 
 pure fn not_win32(os: session::os) -> bool {
   match os {
@@ -40,7 +53,7 @@ fn get_rpath_flags(sess: session::Session, out_filename: &Path) -> ~[~str] {
     // where rustrt is and we know every rust program needs it
     let libs = vec::append_one(libs, get_sysroot_absolute_rt_lib(sess));
 
-    let target_triple = sess.opts.target_triple;
+    let target_triple = /*bad*/copy sess.opts.target_triple;
     let rpaths = get_rpaths(os, &sysroot, output, libs, target_triple);
     rpaths_to_flags(rpaths)
 }
@@ -109,14 +122,18 @@ fn get_rpaths_relative_to_output(os: session::os,
 
 fn get_rpath_relative_to_output(os: session::os,
                                 output: &Path,
-                                lib: &Path) -> Path {
+                                lib: &Path)
+                             -> Path {
+    use core::os;
+
     assert not_win32(os);
 
     // Mac doesn't appear to support $ORIGIN
     let prefix = match os {
-        session::os_linux | session::os_freebsd => "$ORIGIN",
+        session::os_android |session::os_linux | session::os_freebsd
+                          => "$ORIGIN",
         session::os_macos => "@executable_path",
-        session::os_win32 => core::util::unreachable()
+        session::os_win32 => util::unreachable()
     };
 
     Path(prefix).push_rel(&get_relative_to(&os::make_absolute(output),
@@ -131,8 +148,8 @@ fn get_relative_to(abs1: &Path, abs2: &Path) -> Path {
     let abs2 = abs2.normalize();
     debug!("finding relative path from %s to %s",
            abs1.to_str(), abs2.to_str());
-    let split1 = abs1.components;
-    let split2 = abs2.components;
+    let split1 = /*bad*/copy abs1.components;
+    let split2 = /*bad*/copy abs2.components;
     let len1 = vec::len(split1);
     let len2 = vec::len(split2);
     assert len1 > 0;
@@ -182,7 +199,7 @@ fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
     for rpaths.each |rpath| {
         let s = rpath.to_str();
         if !set.contains_key(s) {
-            minimized.push(*rpath);
+            minimized.push(/*bad*/copy *rpath);
             set.insert(s, ());
         }
     }
@@ -192,6 +209,17 @@ fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
 #[cfg(unix)]
 mod test {
     #[legacy_exports];
+
+    use core::prelude::*;
+
+    use back::rpath::{get_absolute_rpath, get_install_prefix_rpath};
+    use back::rpath::{get_relative_to, get_rpath_relative_to_output};
+    use back::rpath::{minimize_rpaths, rpaths_to_flags};
+    use driver::session;
+
+    use core::os;
+    use core::str;
+
     #[test]
     fn test_rpaths_to_flags() {
         let flags = rpaths_to_flags(~[Path("path1"),
@@ -304,6 +332,7 @@ fn test_relative_to8() {
 
     #[test]
     #[cfg(target_os = "linux")]
+    #[cfg(target_os = "andorid")]
     fn test_rpath_relative() {
       let o = session::os_linux;
       let res = get_rpath_relative_to_output(o,
index 709375dc62f2529ca2dde6ed3fd795fb7ced2600..490ba574c5325a7b1e67cfbdc9cd55c55331e00a 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 type t = {
     module_asm: ~str,
     meta_sect_name: ~str,
index 1d992683faabeaead1e7053cd7a03afd82c6e388..5c9bdcf14eca8df74122962c209b4099a92d8d7f 100644 (file)
@@ -36,8 +36,10 @@ fn decl(llmod: ModuleRef, prefix: ~str, name: ~str,
     fn nothrow(f: ValueRef) -> ValueRef {
         base::set_no_unwind(f); f
     }
-    let d = |a,b,c| decl(llmod, ~"upcall_", a, b, c);
-    let dv = |a,b| decl(llmod, ~"upcall_", a, b, T_void());
+    let d: &fn(+a: ~str, +b: ~[TypeRef], +c: TypeRef) -> ValueRef =
+        |a,b,c| decl(llmod, ~"upcall_", a, b, c);
+    let dv: &fn(+a: ~str, +b: ~[TypeRef]) -> ValueRef =
+        |a,b| decl(llmod, ~"upcall_", a, b, T_void());
 
     let int_t = T_int(targ_cfg);
 
index 5d8109b9c08dbe5419fab08407a1e45c96fcc2c2..7ac2bb73ebb854bee8c2bb7b44e9195855254e50 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
+use back::target_strs;
 use driver::session;
-use session::sess_os_to_meta_os;
 use metadata::loader::meta_section_name;
+use session::sess_os_to_meta_os;
 
 fn get_target_strs(target_os: session::os) -> target_strs::t {
     return {
@@ -33,6 +35,9 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
           session::os_linux => {
             ~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"
           }
+          session::os_android => {
+            ~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"
+          }
 
           session::os_freebsd => {
             ~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"
@@ -43,6 +48,7 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
           session::os_macos => ~"i686-apple-darwin",
           session::os_win32 => ~"i686-pc-mingw32",
           session::os_linux => ~"i686-unknown-linux-gnu",
+          session::os_android => ~"i686-unknown-android-gnu",
           session::os_freebsd => ~"i686-unknown-freebsd"
         },
 
index ffc598c3a07530990e2f9aed46255ad43dd934dd..aaf9758781301b255169a729433edc9775f6a6b6 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
+use back::target_strs;
 use driver::session;
-use session::sess_os_to_meta_os;
 use metadata::loader::meta_section_name;
+use session::sess_os_to_meta_os;
 
 fn get_target_strs(target_os: session::os) -> target_strs::t {
     return {
@@ -37,6 +39,11 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
                 ~"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"
           }
+          session::os_android => {
+            ~"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"
+          }
 
           session::os_freebsd => {
             ~"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"+
@@ -49,6 +56,7 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
           session::os_macos => ~"x86_64-apple-darwin",
           session::os_win32 => ~"x86_64-pc-mingw32",
           session::os_linux => ~"x86_64-unknown-linux-gnu",
+          session::os_android => ~"x86_64-unknown-android-gnu",
           session::os_freebsd => ~"x86_64-unknown-freebsd",
         },
 
index 91c0d03657724a818bb5293ce47057884bdd8a23..030856539a5e86cf29fbffae304a0972c482573d 100644 (file)
@@ -9,27 +9,51 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use back::link;
+use back::{arm, x86, x86_64};
+use front;
+use lib::llvm::llvm;
 use metadata::{creader, cstore, filesearch};
-use session::{Session, Session_, OptLevel, No, Less, Default, Aggressive};
-use syntax::parse;
-use syntax::{ast, codemap};
-use syntax::attr;
+use metadata;
 use middle::{trans, freevars, kind, ty, typeck, lint};
-use syntax::print::{pp, pprust};
+use middle;
+use session::{Session, Session_, OptLevel, No, Less, Default, Aggressive};
+use session;
 use util::ppaux;
-use back::link;
-use result::{Ok, Err};
-use std::getopts;
-use std::getopts::{opt_present};
-use std::getopts::groups;
+
+use core::cmp;
+use core::int;
+use core::io::WriterUtil;
+use core::io;
+use core::option;
+use core::os;
+use core::result::{Ok, Err};
+use core::str;
+use core::vec;
 use std::getopts::groups::{optopt, optmulti, optflag, optflagopt, getopts};
-use io::WriterUtil;
-use back::{x86, x86_64};
+use std::getopts::groups;
+use std::getopts::{opt_present};
+use std::getopts;
 use std::map::HashMap;
-use lib::llvm::llvm;
-
-enum pp_mode {ppm_normal, ppm_expanded, ppm_typed, ppm_identified,
-              ppm_expanded_identified }
+use std;
+use syntax::ast;
+use syntax::ast_map;
+use syntax::attr;
+use syntax::codemap;
+use syntax::diagnostic;
+use syntax::parse;
+use syntax::print::{pp, pprust};
+use syntax;
+
+enum pp_mode {
+    ppm_normal,
+    ppm_expanded,
+    ppm_typed,
+    ppm_identified,
+    ppm_expanded_identified
+}
 
 /**
  * The name used for source code that doesn't originate in a file
@@ -44,15 +68,24 @@ fn source_name(input: input) -> ~str {
     }
 }
 
-fn default_configuration(sess: Session, argv0: ~str, input: input) ->
+fn default_configuration(sess: Session, +argv0: ~str, input: input) ->
    ast::crate_cfg {
     let libc = match sess.targ_cfg.os {
       session::os_win32 => ~"msvcrt.dll",
       session::os_macos => ~"libc.dylib",
       session::os_linux => ~"libc.so.6",
+      session::os_android => ~"libc.so",
       session::os_freebsd => ~"libc.so.7"
       // _ { "libc.so" }
     };
+    let tos = match sess.targ_cfg.os {
+      session::os_win32 => ~"win32",
+      session::os_macos => ~"macos",
+      session::os_linux => ~"linux",
+      session::os_android => ~"android",
+      session::os_freebsd => ~"freebsd"
+      // _ { "libc.so" }
+    };
 
     let mk = attr::mk_name_value_item_str;
 
@@ -63,9 +96,9 @@ fn default_configuration(sess: Session, argv0: ~str, input: input) ->
     };
 
     return ~[ // Target bindings.
-         attr::mk_word_item(os::family()),
-         mk(~"target_os", os::sysname()),
-         mk(~"target_family", os::family()),
+         attr::mk_word_item(str::from_slice(os::FAMILY)),
+         mk(~"target_os", tos),
+         mk(~"target_family", str::from_slice(os::FAMILY)),
          mk(~"target_arch", arch),
          mk(~"target_word_size", wordsz),
          mk(~"target_libc", libc),
@@ -74,20 +107,21 @@ fn default_configuration(sess: Session, argv0: ~str, input: input) ->
          mk(~"build_input", source_name(input))];
 }
 
-fn append_configuration(cfg: ast::crate_cfg, name: ~str) -> ast::crate_cfg {
-    if attr::contains_name(cfg, name) {
+fn append_configuration(+cfg: ast::crate_cfg, +name: ~str) -> ast::crate_cfg {
+    // XXX: Bad copy.
+    if attr::contains_name(copy cfg, copy name) {
         return cfg;
     } else {
         return vec::append_one(cfg, attr::mk_word_item(name));
     }
 }
 
-fn build_configuration(sess: Session, argv0: ~str, input: input) ->
+fn build_configuration(sess: Session, +argv0: ~str, input: input) ->
    ast::crate_cfg {
     // Combine the configuration requested by the session (command line) with
     // some default and generated configuration items
     let default_cfg = default_configuration(sess, argv0, input);
-    let user_cfg = sess.opts.cfg;
+    let user_cfg = /*bad*/copy sess.opts.cfg;
     // If the user wants a test runner, then add the test cfg
     let user_cfg = append_configuration(
         user_cfg,
@@ -106,7 +140,7 @@ fn parse_cfgspecs(cfgspecs: ~[~str]) -> ast::crate_cfg {
     // meta_word variant.
     let mut words = ~[];
     for cfgspecs.each |s| {
-        words.push(attr::mk_word_item(*s));
+        words.push(attr::mk_word_item(/*bad*/copy *s));
     }
     return words;
 }
@@ -118,7 +152,7 @@ enum input {
     str_input(~str)
 }
 
-fn parse_input(sess: Session, cfg: ast::crate_cfg, input: input)
+fn parse_input(sess: Session, +cfg: ast::crate_cfg, input: input)
     -> @ast::crate {
     match input {
       file_input(ref file) => {
@@ -127,7 +161,7 @@ fn parse_input(sess: Session, cfg: ast::crate_cfg, input: input)
       str_input(ref src) => {
         // FIXME (#2319): Don't really want to box the source string
         parse::parse_crate_from_source_str(
-            anon_src(), @(*src), cfg, sess.parse_sess)
+            anon_src(), @(/*bad*/copy *src), cfg, sess.parse_sess)
       }
     }
 }
@@ -163,7 +197,7 @@ fn compile_upto(sess: Session, cfg: ast::crate_cfg,
     -> {crate: @ast::crate, tcx: Option<ty::ctxt>} {
     let time_passes = sess.time_passes();
     let mut crate = time(time_passes, ~"parsing",
-                         ||parse_input(sess, cfg, input) );
+                         || parse_input(sess, copy cfg, input) );
     if upto == cu_parse { return {crate: crate, tcx: None}; }
 
     sess.building_library = session::building_library(
@@ -176,7 +210,7 @@ fn compile_upto(sess: Session, cfg: ast::crate_cfg,
         front::test::modify_for_testing(sess, crate));
 
     crate = time(time_passes, ~"expansion", ||
-        syntax::ext::expand::expand_crate(sess.parse_sess, cfg,
+        syntax::ext::expand::expand_crate(sess.parse_sess, copy cfg,
                                           crate));
 
     if upto == cu_expand { return {crate: crate, tcx: None}; }
@@ -251,8 +285,8 @@ fn compile_upto(sess: Session, cfg: ast::crate_cfg,
         time(time_passes, ~"mode computation", ||
              middle::mode::compute_modes(ty_cx, method_map, crate));
 
-        time(time_passes, ~"alt checking", ||
-             middle::check_alt::check_crate(ty_cx, method_map, crate));
+        time(time_passes, ~"match checking", ||
+             middle::check_match::check_crate(ty_cx, method_map, crate));
 
         let last_use_map =
             time(time_passes, ~"liveness checking", ||
@@ -304,7 +338,7 @@ fn compile_upto(sess: Session, cfg: ast::crate_cfg,
     return {crate: crate, tcx: None};
 }
 
-fn compile_input(sess: Session, cfg: ast::crate_cfg, input: input,
+fn compile_input(sess: Session, +cfg: ast::crate_cfg, input: input,
                  outdir: &Option<Path>, output: &Option<Path>) {
 
     let upto = if sess.opts.parse_only { cu_parse }
@@ -314,7 +348,7 @@ fn compile_input(sess: Session, cfg: ast::crate_cfg, input: input,
     compile_upto(sess, cfg, input, upto, Some(outputs));
 }
 
-fn pretty_print_input(sess: Session, cfg: ast::crate_cfg, input: input,
+fn pretty_print_input(sess: Session, +cfg: ast::crate_cfg, input: input,
                       ppm: pp_mode) {
     fn ann_paren_for_expr(node: pprust::ann_node) {
         match node {
@@ -370,13 +404,16 @@ fn ann_identified_post(node: pprust::ann_node) {
 
     let ann = match ppm {
       ppm_typed => {
-        {pre: ann_paren_for_expr,
-         post: |a| ann_typed_post(tcx.get(), a) }
+          pprust::pp_ann {pre: ann_paren_for_expr,
+                          post: |a| ann_typed_post(tcx.get(), a) }
       }
       ppm_identified | ppm_expanded_identified => {
-        {pre: ann_paren_for_expr, post: ann_identified_post}
+          pprust::pp_ann {pre: ann_paren_for_expr,
+                          post: ann_identified_post}
+      }
+      ppm_expanded | ppm_normal => {
+          pprust::no_ann()
       }
-      ppm_expanded | ppm_normal => pprust::no_ann()
     };
     let is_expanded = upto != cu_parse;
     let src = sess.codemap.get_filemap(source_name(input)).src;
@@ -396,6 +433,8 @@ fn get_os(triple: ~str) -> Option<session::os> {
             Some(session::os_macos)
         } else if str::contains(triple, ~"linux") {
             Some(session::os_linux)
+        } else if str::contains(triple, ~"android") {
+            Some(session::os_android)
         } else if str::contains(triple, ~"freebsd") {
             Some(session::os_freebsd)
         } else { None }
@@ -435,7 +474,7 @@ fn build_target_config(sopts: @session::options,
     let target_strs = match arch {
       session::arch_x86 => x86::get_target_strs(os),
       session::arch_x86_64 => x86_64::get_target_strs(os),
-      session::arch_arm => x86::get_target_strs(os)
+      session::arch_arm => arm::get_target_strs(os)
     };
     let target_cfg: @session::config =
         @{os: os, arch: arch, target_strs: target_strs, int_type: int_type,
@@ -460,7 +499,7 @@ fn host_triple() -> ~str {
         };
 }
 
-fn build_session_options(binary: ~str,
+fn build_session_options(+binary: ~str,
                          matches: &getopts::Matches,
                          demitter: diagnostic::emitter) -> @session::options {
     let crate_type = if opt_present(matches, ~"lib") {
@@ -505,7 +544,7 @@ fn build_session_options(binary: ~str,
     for debug_flags.each |debug_flag| {
         let mut this_bit = 0u;
         for debug_map.each |pair| {
-            let (name, _, bit) = *pair;
+            let (name, _, bit) = /*bad*/copy *pair;
             if name == *debug_flag { this_bit = bit; break; }
         }
         if this_bit == 0u {
@@ -514,7 +553,9 @@ fn build_session_options(binary: ~str,
         debugging_opts |= this_bit;
     }
     if debugging_opts & session::debug_llvm != 0 {
-        llvm::LLVMSetDebug(1);
+        unsafe {
+            llvm::LLVMSetDebug(1);
+        }
     }
 
     let jit = opt_present(matches, ~"jit");
@@ -566,7 +607,7 @@ fn build_session_options(binary: ~str,
     let target =
         match target_opt {
             None => host_triple(),
-            Some(ref s) => (*s)
+            Some(ref s) => (/*bad*/copy *s)
         };
 
     let addl_lib_search_paths =
@@ -619,7 +660,7 @@ fn build_session_(sopts: @session::options,
     let filesearch = filesearch::mk_filesearch(
         sopts.maybe_sysroot,
         sopts.target_triple,
-        sopts.addl_lib_search_paths);
+        /*bad*/copy sopts.addl_lib_search_paths);
     let lint_settings = lint::mk_lint_settings();
     Session_(@{targ_cfg: target_cfg,
                opts: sopts,
@@ -746,7 +787,7 @@ fn build_output_filenames(input: input,
         // have to make up a name
         // We want to toss everything after the final '.'
         let dirpath = match *odir {
-          Some(ref d) => (*d),
+          Some(ref d) => (/*bad*/copy *d),
           None => match input {
             str_input(_) => os::getcwd(),
             file_input(ref ifile) => (*ifile).dir_path()
@@ -768,9 +809,9 @@ fn build_output_filenames(input: input,
       }
 
       Some(ref out_file) => {
-        out_path = (*out_file);
+        out_path = (/*bad*/copy *out_file);
         obj_path = if stop_after_codegen {
-            (*out_file)
+            (/*bad*/copy *out_file)
         } else {
             (*out_file).with_filetype(obj_suffix)
         };
@@ -806,6 +847,17 @@ fn list_metadata(sess: Session, path: &Path, out: io::Writer) {
 mod test {
     #[legacy_exports];
 
+    use core::prelude::*;
+
+    use driver::driver::{build_configuration, build_session};
+    use driver::driver::{build_session_options, optgroups, str_input};
+
+    use core::vec;
+    use std::getopts::groups::getopts;
+    use std::getopts;
+    use syntax::attr;
+    use syntax::diagnostic;
+
     // When the user supplies --test we should implicitly supply --cfg test
     #[test]
     fn test_switch_implies_cfg_test() {
index b2cb6da78ddc283accb5ca76645fca1f5bf6eb9c..b2b6cb25dbb7b46c4136e9749e5986872007b1b7 100644 (file)
@@ -8,20 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
 
 use back::link;
 use back::target_strs;
+use back;
+use driver;
+use driver::session;
 use metadata::filesearch;
+use metadata;
 use middle::lint;
 
+use core::cmp;
+use core::option;
 use syntax::ast::node_id;
 use syntax::ast::{int_ty, uint_ty, float_ty};
 use syntax::codemap::span;
+use syntax::diagnostic;
 use syntax::parse::parse_sess;
 use syntax::{ast, codemap};
+use syntax;
 
-
-enum os { os_win32, os_macos, os_linux, os_freebsd, }
+enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, }
 
 impl os : cmp::Eq {
     pure fn eq(&self, other: &os) -> bool {
@@ -201,8 +209,7 @@ fn span_unimpl(sp: span, msg: ~str) -> ! {
     fn unimpl(msg: ~str) -> ! {
         self.span_diagnostic.handler().unimpl(msg)
     }
-    fn span_lint_level(level: lint::level,
-                       sp: span, msg: ~str) {
+    fn span_lint_level(level: lint::level, sp: span, +msg: ~str) {
         match level {
           lint::allow => { },
           lint::warn => self.span_warn(sp, msg),
@@ -212,8 +219,10 @@ fn span_lint_level(level: lint::level,
         }
     }
     fn span_lint(lint_mode: lint::lint,
-                 expr_id: ast::node_id, item_id: ast::node_id,
-                 span: span, msg: ~str) {
+                 expr_id: ast::node_id,
+                 item_id: ast::node_id,
+                 span: span,
+                 +msg: ~str) {
         let level = lint::get_lint_settings_level(
             self.lint_settings, lint_mode, expr_id, item_id);
         self.span_lint_level(level, span, msg);
@@ -251,9 +260,9 @@ fn no_monomorphic_collapse() -> bool {
     }
 
     fn str_of(id: ast::ident) -> ~str {
-        *self.parse_sess.interner.get(id)
+        /*bad*/copy *self.parse_sess.interner.get(id)
     }
-    fn ident_of(st: ~str) -> ast::ident {
+    fn ident_of(+st: ~str) -> ast::ident {
         self.parse_sess.interner.intern(@st)
     }
     fn intr() -> @syntax::parse::token::ident_interner {
@@ -317,6 +326,7 @@ fn sess_os_to_meta_os(os: os) -> metadata::loader::os {
     match os {
       os_win32 => loader::os_win32,
       os_linux => loader::os_linux,
+      os_android => loader::os_android,
       os_macos => loader::os_macos,
       os_freebsd => loader::os_freebsd
     }
@@ -325,9 +335,16 @@ fn sess_os_to_meta_os(os: os) -> metadata::loader::os {
 #[cfg(test)]
 mod test {
     #[legacy_exports];
+
+    use core::prelude::*;
+
+    use driver::session::{bin_crate, building_library, lib_crate};
+    use driver::session::{unknown_crate};
+
+    use syntax::ast;
     use syntax::ast_util;
 
-    fn make_crate_type_attr(t: ~str) -> ast::attribute {
+    fn make_crate_type_attr(+t: ~str) -> ast::attribute {
         ast_util::respan(ast_util::dummy_sp(), {
             style: ast::attr_outer,
             value: ast_util::respan(ast_util::dummy_sp(),
index 22054b6a8d27d214f223c068faf087873b53ead6..307698af03710eb6facf7ba2b4eaea456a7f7a09 100644 (file)
@@ -8,13 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use syntax::{ast, fold, attr};
 
+use core::option;
+use core::vec;
+
 export strip_unconfigured_items;
 export metas_in_cfg;
 export strip_items;
 
-type in_cfg_pred = fn@(~[ast::attribute]) -> bool;
+type in_cfg_pred = fn@(+attrs: ~[ast::attribute]) -> bool;
 
 type ctxt = @{
     in_cfg: in_cfg_pred
@@ -24,7 +29,7 @@
 // any items that do not belong in the current configuration
 fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate {
     do strip_items(crate) |attrs| {
-        in_cfg(crate.node.config, attrs)
+        in_cfg(/*bad*/copy crate.node.config, attrs)
     }
 }
 
@@ -33,11 +38,14 @@ fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred)
 
     let ctxt = @{in_cfg: in_cfg};
 
-    let precursor =
-        @{fold_mod: |a,b| fold_mod(ctxt, a, b),
+    let precursor = @fold::AstFoldFns {
+          fold_mod: |a,b| fold_mod(ctxt, a, b),
           fold_block: fold::wrap(|a,b| fold_block(ctxt, a, b) ),
           fold_foreign_mod: |a,b| fold_foreign_mod(ctxt, a, b),
-          fold_item_underscore: |a,b| fold_item_underscore(ctxt, a, b),
+          fold_item_underscore: |a,b| {
+            // Bad copy.
+            fold_item_underscore(ctxt, copy a, b)
+          },
           .. *fold::default_ast_fold()};
 
     let fold = fold::make_fold(precursor);
@@ -91,18 +99,18 @@ fn fold_foreign_mod(cx: ctxt, nm: ast::foreign_mod,
     };
 }
 
-fn fold_item_underscore(cx: ctxt, item: ast::item_,
+fn fold_item_underscore(cx: ctxt, +item: ast::item_,
                         fld: fold::ast_fold) -> ast::item_ {
     let item = match item {
         ast::item_impl(a, b, c, methods) => {
-            let methods = methods.filter(|m| method_in_cfg(cx, *m) );
+            let methods = methods.filtered(|m| method_in_cfg(cx, *m) );
             ast::item_impl(a, b, c, methods)
         }
-        ast::item_trait(a, b, ref methods) => {
-            let methods = methods.filter(|m| trait_method_in_cfg(cx, m) );
-            ast::item_trait(a, b, methods)
+        ast::item_trait(ref a, ref b, ref methods) => {
+            let methods = methods.filtered(|m| trait_method_in_cfg(cx, m) );
+            ast::item_trait(/*bad*/copy *a, /*bad*/copy *b, methods)
         }
-        _ => item
+        item => item
     };
 
     fold::noop_fold_item_underscore(item, fld)
@@ -128,7 +136,7 @@ fn filter_stmt(cx: ctxt, &&stmt: @ast::stmt) ->
 fn fold_block(cx: ctxt, b: ast::blk_, fld: fold::ast_fold) ->
    ast::blk_ {
     let filtered_stmts = vec::filter_map(b.stmts, |a| filter_stmt(cx, *a));
-    return {view_items: b.view_items,
+    return {view_items: /*bad*/copy b.view_items,
          stmts: vec::map(filtered_stmts, |x| fld.fold_stmt(*x)),
          expr: option::map(&b.expr, |x| fld.fold_expr(*x)),
          id: b.id,
@@ -136,36 +144,35 @@ fn fold_block(cx: ctxt, b: ast::blk_, fld: fold::ast_fold) ->
 }
 
 fn item_in_cfg(cx: ctxt, item: @ast::item) -> bool {
-    return (cx.in_cfg)(item.attrs);
+    return (cx.in_cfg)(/*bad*/copy item.attrs);
 }
 
 fn foreign_item_in_cfg(cx: ctxt, item: @ast::foreign_item) -> bool {
-    return (cx.in_cfg)(item.attrs);
+    return (cx.in_cfg)(/*bad*/copy item.attrs);
 }
 
 fn view_item_in_cfg(cx: ctxt, item: @ast::view_item) -> bool {
-    return (cx.in_cfg)(item.attrs);
+    return (cx.in_cfg)(/*bad*/copy item.attrs);
 }
 
 fn method_in_cfg(cx: ctxt, meth: @ast::method) -> bool {
-    return (cx.in_cfg)(meth.attrs);
+    return (cx.in_cfg)(/*bad*/copy meth.attrs);
 }
 
 fn trait_method_in_cfg(cx: ctxt, meth: &ast::trait_method) -> bool {
     match *meth {
-        ast::required(ref meth) => (cx.in_cfg)(meth.attrs),
-        ast::provided(@ref meth) => (cx.in_cfg)(meth.attrs)
+        ast::required(ref meth) => (cx.in_cfg)(/*bad*/copy meth.attrs),
+        ast::provided(@ref meth) => (cx.in_cfg)(/*bad*/copy meth.attrs)
     }
 }
 
 // Determine if an item should be translated in the current crate
 // configuration based on the item's attributes
-fn in_cfg(cfg: ast::crate_cfg, attrs: ~[ast::attribute]) -> bool {
+fn in_cfg(+cfg: ast::crate_cfg, +attrs: ~[ast::attribute]) -> bool {
     metas_in_cfg(cfg, attr::attr_metas(attrs))
 }
 
-fn metas_in_cfg(cfg: ast::crate_cfg, metas: ~[@ast::meta_item]) -> bool {
-
+fn metas_in_cfg(cfg: ast::crate_cfg, +metas: ~[@ast::meta_item]) -> bool {
     // The "cfg" attributes on the item
     let cfg_metas = attr::find_meta_items_by_name(metas, ~"cfg");
 
@@ -179,7 +186,7 @@ fn metas_in_cfg(cfg: ast::crate_cfg, metas: ~[@ast::meta_item]) -> bool {
     if !has_cfg_metas { return true; }
 
     for cfg_metas.each |cfg_mi| {
-        if attr::contains(cfg, *cfg_mi) { return true; }
+        if attr::contains(/*bad*/copy cfg, *cfg_mi) { return true; }
     }
 
     return false;
index 0d01bdbd33654d796108ba30c15e85056cf6e52f..045e60052a4d5ce5d9594ea7b4d66c9883e25a77 100644 (file)
@@ -8,14 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use driver::session::Session;
-use syntax::codemap;
+
+use core::vec;
 use syntax::ast;
 use syntax::ast_util::*;
 use syntax::attr;
+use syntax::codemap;
+use syntax::fold;
 
 export maybe_inject_libcore_ref;
 
+const CORE_VERSION: &static/str = "0.6";
+
 fn maybe_inject_libcore_ref(sess: Session,
                             crate: @ast::crate) -> @ast::crate {
     if use_core(crate) {
@@ -31,29 +38,70 @@ fn use_core(crate: @ast::crate) -> bool {
 
 fn inject_libcore_ref(sess: Session,
                       crate: @ast::crate) -> @ast::crate {
-
-    fn spanned<T: Copy>(x: T) -> @ast::spanned<T> {
-        return @{node: x,
-            span: dummy_sp()};
+    fn spanned<T: Copy>(x: T) -> ast::spanned<T> {
+        ast::spanned { node: x, span: dummy_sp() }
     }
 
-    let n1 = sess.next_node_id();
-    let n2 = sess.next_node_id();
-
-    let vi1 = @{node: ast::view_item_use(sess.ident_of(~"core"), ~[], n1),
-                attrs: ~[],
-                vis: ast::private,
-                span: dummy_sp()};
-    let vp = spanned(ast::view_path_glob(
-        ident_to_path(dummy_sp(), sess.ident_of(~"core")),
-        n2));
-    let vi2 = @{node: ast::view_item_import(~[vp]),
-                attrs: ~[],
-                vis: ast::private,
-                span: dummy_sp()};
-
-    let vis = vec::append(~[vi1, vi2], crate.node.module.view_items);
-
-    return @{node: {module: { view_items: vis,.. crate.node.module },
-                 .. crate.node},.. *crate }
+    let precursor = @fold::AstFoldFns {
+        fold_crate: |crate, span, fld| {
+            let n1 = sess.next_node_id();
+            let vi1 = @{node: ast::view_item_use(sess.ident_of(~"core"),
+                                                 ~[],
+                                                 n1),
+                        attrs: ~[
+                            spanned({
+                                style: ast::attr_inner,
+                                value: spanned(ast::meta_name_value(
+                                    ~"vers",
+                                    spanned(ast::lit_str(
+                                        @CORE_VERSION.to_str()))
+                                )),
+                                is_sugared_doc: false
+                            })
+                        ],
+                        vis: ast::private,
+                        span: dummy_sp()};
+
+            let vis = vec::append(~[vi1], crate.module.view_items);
+            let mut new_module = {
+                view_items: vis,
+                ../*bad*/copy crate.module
+            };
+            new_module = fld.fold_mod(new_module);
+
+            // XXX: Bad copy.
+            let new_crate = { module: new_module, ..copy crate };
+            (new_crate, span)
+        },
+        fold_mod: |module, fld| {
+            let n2 = sess.next_node_id();
+
+            let prelude_path = @{
+                span: dummy_sp(),
+                global: false,
+                idents: ~[
+                    sess.ident_of(~"core"),
+                    sess.ident_of(~"prelude")
+                ],
+                rp: None,
+                types: ~[]
+            };
+
+            let vp = @spanned(ast::view_path_glob(prelude_path, n2));
+            let vi2 = @{node: ast::view_item_import(~[vp]),
+                        attrs: ~[],
+                        vis: ast::private,
+                        span: dummy_sp()};
+
+            let vis = vec::append(~[vi2], module.view_items);
+
+            // XXX: Bad copy.
+            let new_module = { view_items: vis, ..copy module };
+            fold::noop_fold_mod(new_module, fld)
+        },
+        ..*fold::default_ast_fold()
+    };
+
+    let fold = fold::make_fold(precursor);
+    @fold.fold_crate(*crate)
 }
index f8a94fff67820483c134352574a3e1bef469f902..14d31e2f841ca77e02c4165ceefa2d9df269f669 100644 (file)
@@ -8,20 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use driver::session::Session;
 use syntax::parse;
 use syntax::ast;
 
-export inject_intrinsic;
+use core::vec;
 
-fn inject_intrinsic(sess: Session,
-                    crate: @ast::crate) -> @ast::crate {
+export inject_intrinsic;
 
+fn inject_intrinsic(sess: Session, crate: @ast::crate) -> @ast::crate {
     let intrinsic_module = @(include_str!("intrinsic.rs").to_owned());
 
     let item = parse::parse_item_from_source_str(~"<intrinsic>",
                                                  intrinsic_module,
-                                                 sess.opts.cfg,
+                                                 /*bad*/copy sess.opts.cfg,
                                                  ~[],
                                                  sess.parse_sess);
     let item =
@@ -34,6 +36,9 @@ fn inject_intrinsic(sess: Session,
 
     let items = vec::append(~[item], crate.node.module.items);
 
-    return @{node: {module: { items: items ,.. crate.node.module }
-                 ,.. crate.node} ,.. *crate }
+    @ast::spanned {
+        node: { module: { items: items ,.. /*bad*/copy crate.node.module },
+                .. /*bad*/copy crate.node},
+        .. /*bad*/copy *crate
+    }
 }
index 27e9e35b7ec47910d8021e58c60c7552da45e0d9..870a7d6c59377d2570a9ee7e668eb443090f04df 100644 (file)
 
 // Code that generates a test runner to run all the tests in a crate
 
-use syntax::{ast, ast_util};
-use syntax::ast_util::*;
-//import syntax::ast_util::dummy_sp;
-use syntax::fold;
-use syntax::print::pprust;
-use syntax::codemap::span;
+use core::prelude::*;
+
 use driver::session;
+use front::config;
 use session::Session;
+
+use core::dvec::DVec;
+use core::option;
+use core::vec;
+use syntax::ast_util::*;
 use syntax::attr;
-use dvec::DVec;
+use syntax::codemap::span;
+use syntax::fold;
+use syntax::print::pprust;
+use syntax::{ast, ast_util};
 
 export modify_for_testing;
 
@@ -42,7 +47,7 @@ fn modify_for_testing(sess: session::Session,
     // We generate the test harness when building in the 'test'
     // configuration, either with the '--test' or '--cfg test'
     // command line options.
-    let should_test = attr::contains(crate.node.config,
+    let should_test = attr::contains(/*bad*/copy crate.node.config,
                                      attr::mk_word_item(~"test"));
 
     if should_test {
@@ -60,10 +65,10 @@ fn generate_test_harness(sess: session::Session,
           mut path: ~[],
           testfns: DVec()};
 
-    let precursor =
-        @{fold_crate: fold::wrap(|a,b| fold_crate(cx, a, b) ),
-          fold_item: |a,b| fold_item(cx, a, b),
-          fold_mod: |a,b| fold_mod(cx, a, b),.. *fold::default_ast_fold()};
+    let precursor = @fold::AstFoldFns {
+        fold_crate: fold::wrap(|a,b| fold_crate(cx, a, b) ),
+        fold_item: |a,b| fold_item(cx, a, b),
+        fold_mod: |a,b| fold_mod(cx, a, b),.. *fold::default_ast_fold()};
 
     let fold = fold::make_fold(precursor);
     let res = @fold.fold_crate(*crate);
@@ -98,7 +103,7 @@ fn nomain(cx: test_ctxt, item: @ast::item) -> Option<@ast::item> {
     }
 
     let mod_nomain =
-        {view_items: m.view_items,
+        {view_items: /*bad*/copy m.view_items,
          items: vec::filter_map(m.items, |i| nomain(cx, *i))};
     return fold::noop_fold_mod(mod_nomain, fld);
 }
@@ -109,7 +114,7 @@ fn fold_crate(cx: test_ctxt, c: ast::crate_, fld: fold::ast_fold) ->
 
     // Add a special __test module to the crate that will contain code
     // generated for the test harness
-    return {module: add_test_module(cx, folded.module),.. folded};
+    return {module: add_test_module(cx, /*bad*/copy folded.module),.. folded};
 }
 
 
@@ -130,7 +135,7 @@ fn fold_item(cx: test_ctxt, &&i: @ast::item, fld: fold::ast_fold) ->
           _ => {
             debug!("this is a test function");
             let test = {span: i.span,
-                        path: cx.path, ignore: is_ignored(cx, i),
+                        path: /*bad*/copy cx.path, ignore: is_ignored(cx, i),
                         should_fail: should_fail(i)};
             cx.testfns.push(test);
             debug!("have %u test functions", cx.testfns.len());
@@ -148,7 +153,7 @@ fn is_test_fn(i: @ast::item) -> bool {
         vec::len(attr::find_attrs_by_name(i.attrs, ~"test")) > 0u;
 
     fn has_test_signature(i: @ast::item) -> bool {
-        match i.node {
+        match /*bad*/copy i.node {
           ast::item_fn(decl, _, tps, _) => {
             let input_cnt = vec::len(decl.inputs);
             let no_output = match decl.output.node {
@@ -166,12 +171,12 @@ fn has_test_signature(i: @ast::item) -> bool {
 }
 
 fn is_ignored(cx: test_ctxt, i: @ast::item) -> bool {
-    let ignoreattrs = attr::find_attrs_by_name(i.attrs, ~"ignore");
+    let ignoreattrs = attr::find_attrs_by_name(i.attrs, "ignore");
     let ignoreitems = attr::attr_metas(ignoreattrs);
     let cfg_metas = vec::concat(vec::filter_map(ignoreitems,
         |i| attr::get_meta_item_list(*i)));
     return if vec::is_not_empty(ignoreitems) {
-        config::metas_in_cfg(cx.crate.node.config, cfg_metas)
+        config::metas_in_cfg(/*bad*/copy cx.crate.node.config, cfg_metas)
     } else {
         false
     }
@@ -181,9 +186,9 @@ fn should_fail(i: @ast::item) -> bool {
     vec::len(attr::find_attrs_by_name(i.attrs, ~"should_fail")) > 0u
 }
 
-fn add_test_module(cx: test_ctxt, m: ast::_mod) -> ast::_mod {
+fn add_test_module(cx: test_ctxt, +m: ast::_mod) -> ast::_mod {
     let testmod = mk_test_module(cx);
-    return {items: vec::append_one(m.items, testmod),.. m};
+    return {items: vec::append_one(/*bad*/copy m.items, testmod),.. m};
 }
 
 /*
@@ -205,13 +210,18 @@ fn tests() -> ~[std::test::test_desc] {
 */
 
 fn mk_test_module(cx: test_ctxt) -> @ast::item {
+    // Link to std
+    let std = mk_std(cx);
+    let view_items = if is_std(cx) { ~[] } else { ~[std] };
     // A function that generates a vector of test descriptors to feed to the
     // test runner
     let testsfn = mk_tests(cx);
     // The synthesized main function which will call the console test runner
     // with our list of tests
     let mainfn = mk_main(cx);
-    let testmod: ast::_mod = {view_items: ~[], items: ~[mainfn, testsfn]};
+    let testmod: ast::_mod = {
+        view_items: view_items, items: ~[mainfn, testsfn]
+    };
     let item_ = ast::item_mod(testmod);
     // This attribute tells resolve to let us call unexported functions
     let resolve_unexported_attr =
@@ -225,19 +235,41 @@ fn mk_test_module(cx: test_ctxt) -> @ast::item {
          span: dummy_sp()};
 
     debug!("Synthetic test module:\n%s\n",
-           pprust::item_to_str(@item, cx.sess.intr()));
+           pprust::item_to_str(@copy item, cx.sess.intr()));
 
     return @item;
 }
 
 fn nospan<T: Copy>(t: T) -> ast::spanned<T> {
-    return {node: t, span: dummy_sp()};
+    ast::spanned { node: t, span: dummy_sp() }
 }
 
-fn path_node(ids: ~[ast::ident]) -> @ast::path {
+fn path_node(+ids: ~[ast::ident]) -> @ast::path {
     @{span: dummy_sp(), global: false, idents: ids, rp: None, types: ~[]}
 }
 
+fn path_node_global(+ids: ~[ast::ident]) -> @ast::path {
+    @{span: dummy_sp(), global: true, idents: ids, rp: None, types: ~[]}
+}
+
+fn mk_std(cx: test_ctxt) -> @ast::view_item {
+    let vers = ast::lit_str(@~"0.6");
+    let vers = nospan(vers);
+    let mi = ast::meta_name_value(~"vers", vers);
+    let mi = nospan(mi);
+    let vi = ast::view_item_use(cx.sess.ident_of(~"std"),
+                                ~[@mi],
+                                cx.sess.next_node_id());
+    let vi = {
+        node: vi,
+        attrs: ~[],
+        vis: ast::private,
+        span: dummy_sp()
+    };
+
+    return @vi;
+}
+
 fn mk_tests(cx: test_ctxt) -> @ast::item {
     let ret_ty = mk_test_desc_vec_ty(cx);
 
@@ -264,25 +296,34 @@ fn mk_tests(cx: test_ctxt) -> @ast::item {
     return @item;
 }
 
-fn mk_path(cx: test_ctxt, path: ~[ast::ident]) -> ~[ast::ident] {
-    // For tests that are inside of std we don't want to prefix
-    // the paths with std::
+fn is_std(cx: test_ctxt) -> bool {
     let is_std = {
-        let items = attr::find_linkage_metas(cx.crate.node.attrs);
+        let items = attr::find_linkage_metas(/*bad*/copy cx.crate.node.attrs);
         match attr::last_meta_item_value_str_by_name(items, ~"name") {
           Some(~"std") => true,
           _ => false
         }
     };
-    if is_std { path }
-    else { vec::append(~[cx.sess.ident_of(~"std")], path) }
+    return is_std;
+}
+
+fn mk_path(cx: test_ctxt, +path: ~[ast::ident]) -> @ast::path {
+    // For tests that are inside of std we don't want to prefix
+    // the paths with std::
+    if is_std(cx) { path_node_global(path) }
+    else {
+        path_node(
+            ~[cx.sess.ident_of(~"self"),
+              cx.sess.ident_of(~"std")]
+            + path)
+    }
 }
 
 // The ast::Ty of ~[std::test::test_desc]
 fn mk_test_desc_vec_ty(cx: test_ctxt) -> @ast::Ty {
     let test_desc_ty_path =
-        path_node(mk_path(cx, ~[cx.sess.ident_of(~"test"),
-                                cx.sess.ident_of(~"TestDesc")]));
+        mk_path(cx, ~[cx.sess.ident_of(~"test"),
+                      cx.sess.ident_of(~"TestDesc")]);
 
     let test_desc_ty: ast::Ty =
         {id: cx.sess.next_node_id(),
@@ -318,14 +359,14 @@ fn mk_test_desc_vec(cx: test_ctxt) -> @ast::expr {
 
 fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
     let span = test.span;
-    let path = test.path;
+    let path = /*bad*/copy test.path;
 
     debug!("encoding %s", ast_util::path_name_i(path,
                                                 cx.sess.parse_sess.interner));
 
     let name_lit: ast::lit =
-        nospan(ast::lit_str(@ast_util::path_name_i(path, cx.sess.parse_sess
-                                                   .interner)));
+        nospan(ast::lit_str(@ast_util::path_name_i(
+            path, cx.sess.parse_sess.interner)));
     let name_expr_inner: @ast::expr =
         @{id: cx.sess.next_node_id(),
           callee_id: cx.sess.next_node_id(),
@@ -342,7 +383,7 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
         nospan({mutbl: ast::m_imm, ident: cx.sess.ident_of(~"name"),
                 expr: @name_expr});
 
-    let fn_path = path_node(path);
+    let fn_path = path_node_global(path);
 
     let fn_expr: ast::expr =
         {id: cx.sess.next_node_id(),
@@ -381,8 +422,14 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
                 ident: cx.sess.ident_of(~"should_fail"),
                 expr: @fail_expr});
 
+    let test_desc_path =
+        mk_path(cx, ~[cx.sess.ident_of(~"test"),
+                      cx.sess.ident_of(~"TestDesc")]);
+
     let desc_rec_: ast::expr_ =
-        ast::expr_rec(~[name_field, fn_field, ignore_field, fail_field],
+        ast::expr_struct(
+            test_desc_path,
+            ~[name_field, fn_field, ignore_field, fail_field],
             option::None);
     let desc_rec: ast::expr =
         {id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
@@ -394,7 +441,7 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
 
 // FIXME (#1281): This can go away once fn is the type of bare function.
 fn mk_test_wrapper(cx: test_ctxt,
-                   fn_path_expr: ast::expr,
+                   +fn_path_expr: ast::expr,
                    span: span) -> @ast::expr {
     let call_expr: ast::expr = {
         id: cx.sess.next_node_id(),
@@ -446,7 +493,7 @@ fn mk_main(cx: test_ctxt) -> @ast::item {
     let body_: ast::blk_ =
         default_block(~[], option::Some(test_main_call_expr),
                       cx.sess.next_node_id());
-    let body = {node: body_, span: dummy_sp()};
+    let body = ast::spanned { node: body_, span: dummy_sp() };
 
     let item_ = ast::item_fn(decl, ast::impure_fn, ~[], body);
     let item: ast::item =
@@ -461,7 +508,7 @@ fn mk_main(cx: test_ctxt) -> @ast::item {
 
 fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
     // Call os::args to generate the vector of test_descs
-    let args_path = path_node(~[
+    let args_path = path_node_global(~[
         cx.sess.ident_of(~"os"),
         cx.sess.ident_of(~"args")
     ]);
@@ -494,9 +541,9 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
          node: test_call_expr_, span: dummy_sp()};
 
     // Call std::test::test_main
-    let test_main_path = path_node(
+    let test_main_path =
         mk_path(cx, ~[cx.sess.ident_of(~"test"),
-                      cx.sess.ident_of(~"test_main")]));
+                      cx.sess.ident_of(~"test_main")]);
 
     let test_main_path_expr_: ast::expr_ = ast::expr_path(test_main_path);
 
index 3f24d28043799b684a8a925d3823ecc5a083fcca..047268e080fc6f05d0eea3bc787ad076c5d449bb 100644 (file)
@@ -8,12 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use core::cast;
+use core::cmp;
+use core::int;
+use core::io;
+use core::libc::{c_char, c_int, c_uint, c_longlong, c_ulonglong};
+use core::option;
+use core::ptr;
+use core::str;
+use core::uint;
+use core::vec;
 use std::map::HashMap;
 
-use libc::{c_char, c_int, c_uint, c_longlong, c_ulonglong};
-
 type Opcode = u32;
 type Bool = c_uint;
+
 const True: Bool = 1 as Bool;
 const False: Bool = 0 as Bool;
 
@@ -246,754 +257,930 @@ enum SectionIterator_opaque {}
 extern mod llvm {
     #[legacy_exports];
     /* Create and destroy contexts. */
-    fn LLVMContextCreate() -> ContextRef;
-    fn LLVMGetGlobalContext() -> ContextRef;
-    fn LLVMContextDispose(C: ContextRef);
-    fn LLVMGetMDKindIDInContext(C: ContextRef, Name: *c_char, SLen: c_uint) ->
-       c_uint;
-    fn LLVMGetMDKindID(Name: *c_char, SLen: c_uint) -> c_uint;
+    unsafe fn LLVMContextCreate() -> ContextRef;
+    unsafe fn LLVMGetGlobalContext() -> ContextRef;
+    unsafe fn LLVMContextDispose(C: ContextRef);
+    unsafe fn LLVMGetMDKindIDInContext(C: ContextRef,
+                                       Name: *c_char,
+                                       SLen: c_uint)
+                                    -> c_uint;
+    unsafe fn LLVMGetMDKindID(Name: *c_char, SLen: c_uint) -> c_uint;
 
     /* Create and destroy modules. */
-    fn LLVMModuleCreateWithNameInContext(ModuleID: *c_char, C: ContextRef) ->
-       ModuleRef;
-    fn LLVMDisposeModule(M: ModuleRef);
+    unsafe fn LLVMModuleCreateWithNameInContext(ModuleID: *c_char,
+                                                C: ContextRef)
+                                             -> ModuleRef;
+    unsafe fn LLVMDisposeModule(M: ModuleRef);
 
     /** Data layout. See Module::getDataLayout. */
-    fn LLVMGetDataLayout(M: ModuleRef) -> *c_char;
-    fn LLVMSetDataLayout(M: ModuleRef, Triple: *c_char);
+    unsafe fn LLVMGetDataLayout(M: ModuleRef) -> *c_char;
+    unsafe fn LLVMSetDataLayout(M: ModuleRef, Triple: *c_char);
 
     /** Target triple. See Module::getTargetTriple. */
-    fn LLVMGetTarget(M: ModuleRef) -> *c_char;
-    fn LLVMSetTarget(M: ModuleRef, Triple: *c_char);
+    unsafe fn LLVMGetTarget(M: ModuleRef) -> *c_char;
+    unsafe fn LLVMSetTarget(M: ModuleRef, Triple: *c_char);
 
     /** See Module::dump. */
-    fn LLVMDumpModule(M: ModuleRef);
+    unsafe fn LLVMDumpModule(M: ModuleRef);
 
     /** See Module::setModuleInlineAsm. */
-    fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *c_char);
+    unsafe fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *c_char);
 
     /** See llvm::LLVMTypeKind::getTypeID. */
-    fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
+    unsafe fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
 
     /** See llvm::LLVMType::getContext. */
-    fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
+    unsafe fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
 
     /* Operations on integer types */
-    fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint) -> TypeRef;
-
-    fn LLVMInt1Type() -> TypeRef;
-    fn LLVMInt8Type() -> TypeRef;
-    fn LLVMInt16Type() -> TypeRef;
-    fn LLVMInt32Type() -> TypeRef;
-    fn LLVMInt64Type() -> TypeRef;
-    fn LLVMIntType(NumBits: c_uint) -> TypeRef;
-    fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
+    unsafe fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint) -> TypeRef;
+
+    unsafe fn LLVMInt1Type() -> TypeRef;
+    unsafe fn LLVMInt8Type() -> TypeRef;
+    unsafe fn LLVMInt16Type() -> TypeRef;
+    unsafe fn LLVMInt32Type() -> TypeRef;
+    unsafe fn LLVMInt64Type() -> TypeRef;
+    unsafe fn LLVMIntType(NumBits: c_uint) -> TypeRef;
+    unsafe fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
 
     /* Operations on real types */
-    fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
-
-    fn LLVMFloatType() -> TypeRef;
-    fn LLVMDoubleType() -> TypeRef;
-    fn LLVMX86FP80Type() -> TypeRef;
-    fn LLVMFP128Type() -> TypeRef;
-    fn LLVMPPCFP128Type() -> TypeRef;
+    unsafe fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
+
+    unsafe fn LLVMFloatType() -> TypeRef;
+    unsafe fn LLVMDoubleType() -> TypeRef;
+    unsafe fn LLVMX86FP80Type() -> TypeRef;
+    unsafe fn LLVMFP128Type() -> TypeRef;
+    unsafe fn LLVMPPCFP128Type() -> TypeRef;
 
     /* Operations on function types */
-    fn LLVMFunctionType(ReturnType: TypeRef, ParamTypes: *TypeRef,
+    unsafe fn LLVMFunctionType(ReturnType: TypeRef, ParamTypes: *TypeRef,
                         ParamCount: c_uint, IsVarArg: Bool) -> TypeRef;
-    fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
-    fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
-    fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
-    fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *TypeRef);
+    unsafe fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
+    unsafe fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
+    unsafe fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
+    unsafe fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *TypeRef);
 
     /* Operations on struct types */
-    fn LLVMStructTypeInContext(C: ContextRef, ElementTypes: *TypeRef,
+    unsafe fn LLVMStructTypeInContext(C: ContextRef, ElementTypes: *TypeRef,
                                ElementCount: c_uint,
                                Packed: Bool) -> TypeRef;
-    fn LLVMStructType(ElementTypes: *TypeRef, ElementCount: c_uint,
+    unsafe fn LLVMStructType(ElementTypes: *TypeRef, ElementCount: c_uint,
                       Packed: Bool) -> TypeRef;
-    fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
-    fn LLVMGetStructElementTypes(StructTy: TypeRef, Dest: *mut TypeRef);
-    fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
+    unsafe fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
+    unsafe fn LLVMGetStructElementTypes(StructTy: TypeRef,
+                                        Dest: *mut TypeRef);
+    unsafe fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
 
     /* Operations on array, pointer, and vector types (sequence types) */
-    fn LLVMArrayType(ElementType: TypeRef,
+    unsafe fn LLVMArrayType(ElementType: TypeRef,
                      ElementCount: c_uint) -> TypeRef;
-    fn LLVMPointerType(ElementType: TypeRef,
+    unsafe fn LLVMPointerType(ElementType: TypeRef,
                        AddressSpace: c_uint) -> TypeRef;
-    fn LLVMVectorType(ElementType: TypeRef,
+    unsafe fn LLVMVectorType(ElementType: TypeRef,
                       ElementCount: c_uint) -> TypeRef;
 
-    fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
-    fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
-    fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
-    fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
+    unsafe fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
+    unsafe fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
+    unsafe fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
+    unsafe fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
 
     /* Operations on other types */
-    fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
-    fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
+    unsafe fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
 
-    fn LLVMVoidType() -> TypeRef;
-    fn LLVMLabelType() -> TypeRef;
-    fn LLVMMetadataType() -> TypeRef;
+    unsafe fn LLVMVoidType() -> TypeRef;
+    unsafe fn LLVMLabelType() -> TypeRef;
+    unsafe fn LLVMMetadataType() -> TypeRef;
 
     /* Operations on all values */
-    fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
-    fn LLVMGetValueName(Val: ValueRef) -> *c_char;
-    fn LLVMSetValueName(Val: ValueRef, Name: *c_char);
-    fn LLVMDumpValue(Val: ValueRef);
-    fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
-    fn LLVMHasMetadata(Val: ValueRef) -> c_int;
-    fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
-    fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
+    unsafe fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
+    unsafe fn LLVMGetValueName(Val: ValueRef) -> *c_char;
+    unsafe fn LLVMSetValueName(Val: ValueRef, Name: *c_char);
+    unsafe fn LLVMDumpValue(Val: ValueRef);
+    unsafe fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
+    unsafe fn LLVMHasMetadata(Val: ValueRef) -> c_int;
+    unsafe fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
+    unsafe fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
 
     /* Operations on Uses */
-    fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
-    fn LLVMGetNextUse(U: UseRef) -> UseRef;
-    fn LLVMGetUser(U: UseRef) -> ValueRef;
-    fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
+    unsafe fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
+    unsafe fn LLVMGetNextUse(U: UseRef) -> UseRef;
+    unsafe fn LLVMGetUser(U: UseRef) -> ValueRef;
+    unsafe fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
 
     /* Operations on Users */
-    fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
-    fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
+    unsafe fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
+    unsafe fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
 
     /* Operations on constants of any type */
-    fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
+    unsafe fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
     /* all zeroes */
-    fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
+    unsafe fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
     /* only for int/vector */
-    fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
-    fn LLVMIsConstant(Val: ValueRef) -> Bool;
-    fn LLVMIsNull(Val: ValueRef) -> Bool;
-    fn LLVMIsUndef(Val: ValueRef) -> Bool;
-    fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
+    unsafe fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
+    unsafe fn LLVMIsConstant(Val: ValueRef) -> Bool;
+    unsafe fn LLVMIsNull(Val: ValueRef) -> Bool;
+    unsafe fn LLVMIsUndef(Val: ValueRef) -> Bool;
+    unsafe fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
 
     /* Operations on metadata */
-    fn LLVMMDStringInContext(C: ContextRef, Str: *c_char, SLen: c_uint) ->
-       ValueRef;
-    fn LLVMMDString(Str: *c_char, SLen: c_uint) -> ValueRef;
-    fn LLVMMDNodeInContext(C: ContextRef, Vals: *ValueRef, Count: c_uint) ->
-       ValueRef;
-    fn LLVMMDNode(Vals: *ValueRef, Count: c_uint) -> ValueRef;
-    fn LLVMAddNamedMetadataOperand(M: ModuleRef, Str: *c_char,
+    unsafe fn LLVMMDStringInContext(C: ContextRef,
+                                    Str: *c_char,
+                                    SLen: c_uint)
+                                 -> ValueRef;
+    unsafe fn LLVMMDString(Str: *c_char, SLen: c_uint) -> ValueRef;
+    unsafe fn LLVMMDNodeInContext(C: ContextRef,
+                                  Vals: *ValueRef,
+                                  Count: c_uint)
+                               -> ValueRef;
+    unsafe fn LLVMMDNode(Vals: *ValueRef, Count: c_uint) -> ValueRef;
+    unsafe fn LLVMAddNamedMetadataOperand(M: ModuleRef, Str: *c_char,
                                    Val: ValueRef);
 
     /* Operations on scalar constants */
-    fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) ->
-       ValueRef;
-    fn LLVMConstIntOfString(IntTy: TypeRef, Text: *c_char, Radix: u8) ->
-       ValueRef;
-    fn LLVMConstIntOfStringAndSize(IntTy: TypeRef, Text: *c_char,
+    unsafe fn LLVMConstInt(IntTy: TypeRef,
+                           N: c_ulonglong,
+                           SignExtend: Bool)
+                        -> ValueRef;
+    unsafe fn LLVMConstIntOfString(IntTy: TypeRef,
+                                   Text: *c_char,
+                                   Radix: u8)
+                                -> ValueRef;
+    unsafe fn LLVMConstIntOfStringAndSize(IntTy: TypeRef, Text: *c_char,
                                    SLen: c_uint,
                                    Radix: u8) -> ValueRef;
-    fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
-    fn LLVMConstRealOfString(RealTy: TypeRef, Text: *c_char) -> ValueRef;
-    fn LLVMConstRealOfStringAndSize(RealTy: TypeRef, Text: *c_char,
+    unsafe fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
+    unsafe fn LLVMConstRealOfString(RealTy: TypeRef,
+                                    Text: *c_char)
+                                 -> ValueRef;
+    unsafe fn LLVMConstRealOfStringAndSize(RealTy: TypeRef, Text: *c_char,
                                     SLen: c_uint) -> ValueRef;
-    fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
-    fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
+    unsafe fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
+    unsafe fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
 
 
     /* Operations on composite constants */
-    fn LLVMConstStringInContext(C: ContextRef, Str: *c_char, Length: c_uint,
-                                DontNullTerminate: Bool) -> ValueRef;
-    fn LLVMConstStructInContext(C: ContextRef, ConstantVals: *ValueRef,
+    unsafe fn LLVMConstStringInContext(C: ContextRef,
+                                       Str: *c_char,
+                                       Length: c_uint,
+                                       DontNullTerminate: Bool)
+                                    -> ValueRef;
+    unsafe fn LLVMConstStructInContext(C: ContextRef, ConstantVals: *ValueRef,
                                 Count: c_uint, Packed: Bool) -> ValueRef;
 
-    fn LLVMConstString(Str: *c_char, Length: c_uint,
+    unsafe fn LLVMConstString(Str: *c_char, Length: c_uint,
                        DontNullTerminate: Bool) -> ValueRef;
-    fn LLVMConstArray(ElementTy: TypeRef, ConstantVals: *ValueRef,
+    unsafe fn LLVMConstArray(ElementTy: TypeRef, ConstantVals: *ValueRef,
                       Length: c_uint) -> ValueRef;
-    fn LLVMConstStruct(ConstantVals: *ValueRef,
+    unsafe fn LLVMConstStruct(ConstantVals: *ValueRef,
                        Count: c_uint, Packed: Bool) -> ValueRef;
-    fn LLVMConstVector(ScalarConstantVals: *ValueRef,
+    unsafe fn LLVMConstVector(ScalarConstantVals: *ValueRef,
                        Size: c_uint) -> ValueRef;
 
     /* Constant expressions */
-    fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
-    fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
-    fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
-    fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
-    fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
-    fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
-    fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
-    fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
-    fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstNUWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
-    fn LLVMConstNSWSub(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstNUWSub(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
-    fn LLVMConstNSWMul(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstNUWMul(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstExactSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
-       ValueRef;
-    fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
+    unsafe fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
+    unsafe fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
+    unsafe fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
+    unsafe fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
+    unsafe fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
+    unsafe fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
+    unsafe fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
+    unsafe fn LLVMConstAdd(LHSConstant: ValueRef,
+                           RHSConstant: ValueRef)
+                        -> ValueRef;
+    unsafe fn LLVMConstNSWAdd(LHSConstant: ValueRef,
+                              RHSConstant: ValueRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstNUWAdd(LHSConstant: ValueRef,
+                              RHSConstant: ValueRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstFAdd(LHSConstant: ValueRef,
+                            RHSConstant: ValueRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstSub(LHSConstant: ValueRef,
+                           RHSConstant: ValueRef)
+                        -> ValueRef;
+    unsafe fn LLVMConstNSWSub(LHSConstant: ValueRef,
+                              RHSConstant: ValueRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstNUWSub(LHSConstant: ValueRef,
+                              RHSConstant: ValueRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
        ValueRef;
-    fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
-    fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
-    fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
-    fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
-    fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
+    unsafe fn LLVMConstMul(LHSConstant: ValueRef,
+                           RHSConstant: ValueRef)
+                        -> ValueRef;
+    unsafe fn LLVMConstNSWMul(LHSConstant: ValueRef,
+                              RHSConstant: ValueRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstNUWMul(LHSConstant: ValueRef,
+                              RHSConstant: ValueRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstFMul(LHSConstant: ValueRef,
+                            RHSConstant: ValueRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstUDiv(LHSConstant: ValueRef,
+                            RHSConstant: ValueRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstSDiv(LHSConstant: ValueRef,
+                            RHSConstant: ValueRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstExactSDiv(LHSConstant: ValueRef,
+                                 RHSConstant: ValueRef)
+                              -> ValueRef;
+    unsafe fn LLVMConstFDiv(LHSConstant: ValueRef,
+                            RHSConstant: ValueRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstURem(LHSConstant: ValueRef,
+                            RHSConstant: ValueRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstSRem(LHSConstant: ValueRef,
+                            RHSConstant: ValueRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstFRem(LHSConstant: ValueRef,
+                            RHSConstant: ValueRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstAnd(LHSConstant: ValueRef,
+                           RHSConstant: ValueRef)
+                        -> ValueRef;
+    unsafe fn LLVMConstOr(LHSConstant: ValueRef,
+                          RHSConstant: ValueRef)
+                       -> ValueRef;
+    unsafe fn LLVMConstXor(LHSConstant: ValueRef,
+                           RHSConstant: ValueRef)
+                        -> ValueRef;
+    unsafe fn LLVMConstShl(LHSConstant: ValueRef,
+                           RHSConstant: ValueRef)
+                        -> ValueRef;
+    unsafe fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
        ValueRef;
-    fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
+    unsafe fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
        ValueRef;
-    fn LLVMConstGEP(ConstantVal: ValueRef,
+    unsafe fn LLVMConstGEP(ConstantVal: ValueRef,
                     ConstantIndices: *ValueRef,
                     NumIndices: c_uint) -> ValueRef;
-    fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
-                            ConstantIndices: *ValueRef,
-                            NumIndices: c_uint) -> ValueRef;
-    fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstFPTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstFPExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef) ->
-       ValueRef;
-    fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef) ->
-       ValueRef;
-    fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef, ToType: TypeRef) ->
-       ValueRef;
-    fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef) ->
-       ValueRef;
-    fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: TypeRef,
+    unsafe fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
+                                   ConstantIndices: *ValueRef,
+                                   NumIndices: c_uint)
+                                -> ValueRef;
+    unsafe fn LLVMConstTrunc(ConstantVal: ValueRef,
+                             ToType: TypeRef)
+                          -> ValueRef;
+    unsafe fn LLVMConstSExt(ConstantVal: ValueRef,
+                            ToType: TypeRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstZExt(ConstantVal: ValueRef,
+                            ToType: TypeRef)
+                         -> ValueRef;
+    unsafe fn LLVMConstFPTrunc(ConstantVal: ValueRef,
+                               ToType: TypeRef)
+                            -> ValueRef;
+    unsafe fn LLVMConstFPExt(ConstantVal: ValueRef,
+                             ToType: TypeRef)
+                          -> ValueRef;
+    unsafe fn LLVMConstUIToFP(ConstantVal: ValueRef,
+                              ToType: TypeRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstSIToFP(ConstantVal: ValueRef,
+                              ToType: TypeRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstFPToUI(ConstantVal: ValueRef,
+                              ToType: TypeRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstFPToSI(ConstantVal: ValueRef,
+                              ToType: TypeRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstPtrToInt(ConstantVal: ValueRef,
+                                ToType: TypeRef)
+                             -> ValueRef;
+    unsafe fn LLVMConstIntToPtr(ConstantVal: ValueRef,
+                                ToType: TypeRef)
+                             -> ValueRef;
+    unsafe fn LLVMConstBitCast(ConstantVal: ValueRef,
+                               ToType: TypeRef)
+                            -> ValueRef;
+    unsafe fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef,
+                                     ToType: TypeRef)
+                                  -> ValueRef;
+    unsafe fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef,
+                                     ToType: TypeRef)
+                                  -> ValueRef;
+    unsafe fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef,
+                                      ToType: TypeRef)
+                                   -> ValueRef;
+    unsafe fn LLVMConstPointerCast(ConstantVal: ValueRef,
+                                   ToType: TypeRef)
+                                -> ValueRef;
+    unsafe fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: TypeRef,
                         isSigned: Bool) -> ValueRef;
-    fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
-    fn LLVMConstSelect(ConstantCondition: ValueRef, ConstantIfTrue: ValueRef,
-                       ConstantIfFalse: ValueRef) -> ValueRef;
-    fn LLVMConstExtractElement(VectorConstant: ValueRef,
+    unsafe fn LLVMConstFPCast(ConstantVal: ValueRef,
+                              ToType: TypeRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstSelect(ConstantCondition: ValueRef,
+                              ConstantIfTrue: ValueRef,
+                              ConstantIfFalse: ValueRef)
+                           -> ValueRef;
+    unsafe fn LLVMConstExtractElement(VectorConstant: ValueRef,
                                IndexConstant: ValueRef) -> ValueRef;
-    fn LLVMConstInsertElement(VectorConstant: ValueRef,
+    unsafe fn LLVMConstInsertElement(VectorConstant: ValueRef,
                               ElementValueConstant: ValueRef,
                               IndexConstant: ValueRef) -> ValueRef;
-    fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
+    unsafe fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
                               VectorBConstant: ValueRef,
                               MaskConstant: ValueRef) -> ValueRef;
-    fn LLVMConstExtractValue(AggConstant: ValueRef, IdxList: *c_uint,
+    unsafe fn LLVMConstExtractValue(AggConstant: ValueRef, IdxList: *c_uint,
                              NumIdx: c_uint) -> ValueRef;
-    fn LLVMConstInsertValue(AggConstant: ValueRef,
+    unsafe fn LLVMConstInsertValue(AggConstant: ValueRef,
                             ElementValueConstant: ValueRef, IdxList: *c_uint,
                             NumIdx: c_uint) -> ValueRef;
-    fn LLVMConstInlineAsm(Ty: TypeRef, AsmString: *c_char,
+    unsafe fn LLVMConstInlineAsm(Ty: TypeRef, AsmString: *c_char,
                           Constraints: *c_char, HasSideEffects: Bool,
                           IsAlignStack: Bool) -> ValueRef;
-    fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
+    unsafe fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
 
 
 
     /* Operations on global variables, functions, and aliases (globals) */
-    fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
-    fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
-    fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
-    fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
-    fn LLVMGetSection(Global: ValueRef) -> *c_char;
-    fn LLVMSetSection(Global: ValueRef, Section: *c_char);
-    fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
-    fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
-    fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
-    fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
+    unsafe fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
+    unsafe fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
+    unsafe fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
+    unsafe fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
+    unsafe fn LLVMGetSection(Global: ValueRef) -> *c_char;
+    unsafe fn LLVMSetSection(Global: ValueRef, Section: *c_char);
+    unsafe fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
+    unsafe fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
+    unsafe fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
+    unsafe fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
 
 
     /* Operations on global variables */
-    fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *c_char) -> ValueRef;
-    fn LLVMAddGlobalInAddressSpace(M: ModuleRef, Ty: TypeRef, Name: *c_char,
-                                   AddressSpace: c_uint) -> ValueRef;
-    fn LLVMGetNamedGlobal(M: ModuleRef, Name: *c_char) -> ValueRef;
-    fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
-    fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
-    fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
-    fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
-    fn LLVMDeleteGlobal(GlobalVar: ValueRef);
-    fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
-    fn LLVMSetInitializer(GlobalVar: ValueRef, ConstantVal: ValueRef);
-    fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
-    fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
-    fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
-    fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
+    unsafe fn LLVMAddGlobal(M: ModuleRef,
+                            Ty: TypeRef,
+                            Name: *c_char)
+                         -> ValueRef;
+    unsafe fn LLVMAddGlobalInAddressSpace(M: ModuleRef,
+                                          Ty: TypeRef,
+                                          Name: *c_char,
+                                          AddressSpace: c_uint)
+                                       -> ValueRef;
+    unsafe fn LLVMGetNamedGlobal(M: ModuleRef, Name: *c_char) -> ValueRef;
+    unsafe fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
+    unsafe fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
+    unsafe fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
+    unsafe fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
+    unsafe fn LLVMDeleteGlobal(GlobalVar: ValueRef);
+    unsafe fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
+    unsafe fn LLVMSetInitializer(GlobalVar: ValueRef, ConstantVal: ValueRef);
+    unsafe fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
+    unsafe fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
+    unsafe fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
+    unsafe fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
 
     /* Operations on aliases */
-    fn LLVMAddAlias(M: ModuleRef, Ty: TypeRef, Aliasee: ValueRef,
+    unsafe fn LLVMAddAlias(M: ModuleRef, Ty: TypeRef, Aliasee: ValueRef,
                     Name: *c_char) -> ValueRef;
 
     /* Operations on functions */
-    fn LLVMAddFunction(M: ModuleRef, Name: *c_char, FunctionTy: TypeRef) ->
-       ValueRef;
-    fn LLVMGetNamedFunction(M: ModuleRef, Name: *c_char) -> ValueRef;
-    fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
-    fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
-    fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
-    fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
-    fn LLVMDeleteFunction(Fn: ValueRef);
-    fn LLVMGetOrInsertFunction(M: ModuleRef, Name: *c_char,
+    unsafe fn LLVMAddFunction(M: ModuleRef,
+                              Name: *c_char,
+                              FunctionTy: TypeRef)
+                           -> ValueRef;
+    unsafe fn LLVMGetNamedFunction(M: ModuleRef, Name: *c_char) -> ValueRef;
+    unsafe fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
+    unsafe fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
+    unsafe fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
+    unsafe fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
+    unsafe fn LLVMDeleteFunction(Fn: ValueRef);
+    unsafe fn LLVMGetOrInsertFunction(M: ModuleRef, Name: *c_char,
                                FunctionTy: TypeRef) -> ValueRef;
-    fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
-    fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
-    fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
-    fn LLVMGetGC(Fn: ValueRef) -> *c_char;
-    fn LLVMSetGC(Fn: ValueRef, Name: *c_char);
-    fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_ulonglong, HighPA:
+    unsafe fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
+    unsafe fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
+    unsafe fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
+    unsafe fn LLVMGetGC(Fn: ValueRef) -> *c_char;
+    unsafe fn LLVMSetGC(Fn: ValueRef, Name: *c_char);
+    unsafe fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_ulonglong, HighPA:
                            c_ulonglong);
-    fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
-    fn LLVMRemoveFunctionAttr(Fn: ValueRef, PA: c_ulonglong, HighPA:
+    unsafe fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
+    unsafe fn LLVMRemoveFunctionAttr(Fn: ValueRef, PA: c_ulonglong, HighPA:
                               c_ulonglong);
 
     /* Operations on parameters */
-    fn LLVMCountParams(Fn: ValueRef) -> c_uint;
-    fn LLVMGetParams(Fn: ValueRef, Params: *ValueRef);
-    fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
-    fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
-    fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
-    fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
-    fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
-    fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
-    fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
-    fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
-    fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
-    fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
+    unsafe fn LLVMCountParams(Fn: ValueRef) -> c_uint;
+    unsafe fn LLVMGetParams(Fn: ValueRef, Params: *ValueRef);
+    unsafe fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
+    unsafe fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
+    unsafe fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
+    unsafe fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
+    unsafe fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
+    unsafe fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
+    unsafe fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
+    unsafe fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
+    unsafe fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
+    unsafe fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
 
     /* Operations on basic blocks */
-    fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
-    fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
-    fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
-    fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
-    fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
-    fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *ValueRef);
-    fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-    fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-    fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
-    fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
-    fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-
-    fn LLVMAppendBasicBlockInContext(C: ContextRef, Fn: ValueRef,
+    unsafe fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
+    unsafe fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
+    unsafe fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
+    unsafe fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
+    unsafe fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
+    unsafe fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *ValueRef);
+    unsafe fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+    unsafe fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+    unsafe fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+    unsafe fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+    unsafe fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+
+    unsafe fn LLVMAppendBasicBlockInContext(C: ContextRef, Fn: ValueRef,
                                      Name: *c_char) -> BasicBlockRef;
-    fn LLVMInsertBasicBlockInContext(C: ContextRef, BB: BasicBlockRef,
+    unsafe fn LLVMInsertBasicBlockInContext(C: ContextRef, BB: BasicBlockRef,
                                      Name: *c_char) -> BasicBlockRef;
 
-    fn LLVMAppendBasicBlock(Fn: ValueRef, Name: *c_char) -> BasicBlockRef;
-    fn LLVMInsertBasicBlock(InsertBeforeBB: BasicBlockRef, Name: *c_char) ->
-       BasicBlockRef;
-    fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
+    unsafe fn LLVMAppendBasicBlock(Fn: ValueRef,
+                                   Name: *c_char)
+                                -> BasicBlockRef;
+    unsafe fn LLVMInsertBasicBlock(InsertBeforeBB: BasicBlockRef,
+                                   Name: *c_char)
+                                -> BasicBlockRef;
+    unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
 
     /* Operations on instructions */
-    fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
-    fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
-    fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
-    fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
-    fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
+    unsafe fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
+    unsafe fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
+    unsafe fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
+    unsafe fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
+    unsafe fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
 
     /* Operations on call sites */
-    fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
-    fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
-    fn LLVMAddInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
-    fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: c_uint,
+    unsafe fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
+    unsafe fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
+    unsafe fn LLVMAddInstrAttribute(Instr: ValueRef,
+                                    index: c_uint,
+                                    IA: c_uint);
+    unsafe fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: c_uint,
                                 IA: c_uint);
-    fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint,
+    unsafe fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint,
                                   align: c_uint);
 
     /* Operations on call instructions (only) */
-    fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
-    fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
+    unsafe fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
+    unsafe fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
 
     /* Operations on phi nodes */
-    fn LLVMAddIncoming(PhiNode: ValueRef, IncomingValues: *ValueRef,
+    unsafe fn LLVMAddIncoming(PhiNode: ValueRef, IncomingValues: *ValueRef,
                        IncomingBlocks: *BasicBlockRef, Count: c_uint);
-    fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
-    fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint) -> ValueRef;
-    fn LLVMGetIncomingBlock(PhiNode: ValueRef,
+    unsafe fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
+    unsafe fn LLVMGetIncomingValue(PhiNode: ValueRef,
+                                   Index: c_uint)
+                                -> ValueRef;
+    unsafe fn LLVMGetIncomingBlock(PhiNode: ValueRef,
                             Index: c_uint) -> BasicBlockRef;
 
     /* Instruction builders */
-    fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
-    fn LLVMCreateBuilder() -> BuilderRef;
-    fn LLVMPositionBuilder(Builder: BuilderRef, Block: BasicBlockRef,
+    unsafe fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
+    unsafe fn LLVMCreateBuilder() -> BuilderRef;
+    unsafe fn LLVMPositionBuilder(Builder: BuilderRef, Block: BasicBlockRef,
                            Instr: ValueRef);
-    fn LLVMPositionBuilderBefore(Builder: BuilderRef, Instr: ValueRef);
-    fn LLVMPositionBuilderAtEnd(Builder: BuilderRef, Block: BasicBlockRef);
-    fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
-    fn LLVMClearInsertionPosition(Builder: BuilderRef);
-    fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
-    fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef, Instr: ValueRef,
-                                     Name: *c_char);
-    fn LLVMDisposeBuilder(Builder: BuilderRef);
+    unsafe fn LLVMPositionBuilderBefore(Builder: BuilderRef, Instr: ValueRef);
+    unsafe fn LLVMPositionBuilderAtEnd(Builder: BuilderRef,
+                                       Block: BasicBlockRef);
+    unsafe fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
+    unsafe fn LLVMClearInsertionPosition(Builder: BuilderRef);
+    unsafe fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
+    unsafe fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
+                                            Instr: ValueRef,
+                                            Name: *c_char);
+    unsafe fn LLVMDisposeBuilder(Builder: BuilderRef);
 
     /* Metadata */
-    fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
-    fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
-    fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
+    unsafe fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
+    unsafe fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
+    unsafe fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
 
     /* Terminators */
-    fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
-    fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
-    fn LLVMBuildAggregateRet(B: BuilderRef, RetVals: *ValueRef,
+    unsafe fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
+    unsafe fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
+    unsafe fn LLVMBuildAggregateRet(B: BuilderRef, RetVals: *ValueRef,
                              N: c_uint) -> ValueRef;
-    fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
-    fn LLVMBuildCondBr(B: BuilderRef, If: ValueRef, Then: BasicBlockRef,
-                       Else: BasicBlockRef) -> ValueRef;
-    fn LLVMBuildSwitch(B: BuilderRef, V: ValueRef, Else: BasicBlockRef,
+    unsafe fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
+    unsafe fn LLVMBuildCondBr(B: BuilderRef,
+                              If: ValueRef,
+                              Then: BasicBlockRef,
+                              Else: BasicBlockRef)
+                           -> ValueRef;
+    unsafe fn LLVMBuildSwitch(B: BuilderRef, V: ValueRef, Else: BasicBlockRef,
                        NumCases: c_uint) -> ValueRef;
-    fn LLVMBuildIndirectBr(B: BuilderRef, Addr: ValueRef,
+    unsafe fn LLVMBuildIndirectBr(B: BuilderRef, Addr: ValueRef,
                            NumDests: c_uint) -> ValueRef;
-    fn LLVMBuildInvoke(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
+    unsafe fn LLVMBuildInvoke(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
                        NumArgs: c_uint, Then: BasicBlockRef,
                        Catch: BasicBlockRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildLandingPad(B: BuilderRef, Ty: TypeRef, PersFn: ValueRef,
-                           NumClauses: c_uint, Name: *c_char) -> ValueRef;
-    fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
-    fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
+    unsafe fn LLVMBuildLandingPad(B: BuilderRef,
+                                  Ty: TypeRef,
+                                  PersFn: ValueRef,
+                                  NumClauses: c_uint,
+                                  Name: *c_char)
+                               -> ValueRef;
+    unsafe fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
+    unsafe fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
 
     /* Add a case to the switch instruction */
-    fn LLVMAddCase(Switch: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef);
+    unsafe fn LLVMAddCase(Switch: ValueRef,
+                          OnVal: ValueRef,
+                          Dest: BasicBlockRef);
 
     /* Add a destination to the indirectbr instruction */
-    fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
+    unsafe fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
 
     /* Add a clause to the landing pad instruction */
-    fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
+    unsafe fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
 
     /* Set the cleanup on a landing pad instruction */
-    fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
+    unsafe fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
 
     /* Arithmetic */
-    fn LLVMBuildAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                     Name: *c_char) -> ValueRef;
-    fn LLVMBuildNSWAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildNSWAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildNUWAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildNUWAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildFAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildFAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                     Name: *c_char) -> ValueRef;
-    fn LLVMBuildNSWSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildNSWSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildNUWSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildNUWSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildFSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildFSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                     Name: *c_char) -> ValueRef;
-    fn LLVMBuildNSWMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildNSWMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildNUWMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildNUWMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildFMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildFMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildUDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildUDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildSDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildSDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildExactSDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildExactSDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                           Name: *c_char) -> ValueRef;
-    fn LLVMBuildFDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildFDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildURem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildURem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildSRem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildSRem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildFRem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildFRem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildShl(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildShl(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                     Name: *c_char) -> ValueRef;
-    fn LLVMBuildLShr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildLShr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildAShr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildAShr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildAnd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildAnd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                     Name: *c_char) -> ValueRef;
-    fn LLVMBuildOr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildOr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                    Name: *c_char) -> ValueRef;
-    fn LLVMBuildXor(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildXor(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                     Name: *c_char) -> ValueRef;
-    fn LLVMBuildBinOp(B: BuilderRef, Op: Opcode, LHS: ValueRef, RHS: ValueRef,
-                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
+    unsafe fn LLVMBuildBinOp(B: BuilderRef,
+                             Op: Opcode,
+                             LHS: ValueRef,
+                             RHS: ValueRef,
+                             Name: *c_char)
+                          -> ValueRef;
+    unsafe fn LLVMBuildNeg(B: BuilderRef,
+                           V: ValueRef,
+                           Name: *c_char)
+                        -> ValueRef;
+    unsafe fn LLVMBuildNSWNeg(B: BuilderRef,
+                              V: ValueRef,
+                              Name: *c_char)
+                           -> ValueRef;
+    unsafe fn LLVMBuildNUWNeg(B: BuilderRef,
+                              V: ValueRef,
+                              Name: *c_char)
+                           -> ValueRef;
+    unsafe fn LLVMBuildFNeg(B: BuilderRef,
+                            V: ValueRef,
+                            Name: *c_char)
+                         -> ValueRef;
+    unsafe fn LLVMBuildNot(B: BuilderRef,
+                           V: ValueRef,
+                           Name: *c_char)
+                        -> ValueRef;
 
     /* Memory */
-    fn LLVMBuildMalloc(B: BuilderRef, Ty: TypeRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildArrayMalloc(B: BuilderRef, Ty: TypeRef, Val: ValueRef,
+    unsafe fn LLVMBuildMalloc(B: BuilderRef,
+                              Ty: TypeRef,
+                              Name: *c_char)
+                           -> ValueRef;
+    unsafe fn LLVMBuildArrayMalloc(B: BuilderRef, Ty: TypeRef, Val: ValueRef,
                             Name: *c_char) -> ValueRef;
-    fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildArrayAlloca(B: BuilderRef, Ty: TypeRef, Val: ValueRef,
+    unsafe fn LLVMBuildAlloca(B: BuilderRef,
+                              Ty: TypeRef,
+                              Name: *c_char)
+                           -> ValueRef;
+    unsafe fn LLVMBuildArrayAlloca(B: BuilderRef, Ty: TypeRef, Val: ValueRef,
                             Name: *c_char) -> ValueRef;
-    fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
-    fn LLVMBuildLoad(B: BuilderRef, PointerVal: ValueRef, Name: *c_char) ->
-       ValueRef;
-    fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef) ->
+    unsafe fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
+    unsafe fn LLVMBuildLoad(B: BuilderRef,
+                            PointerVal: ValueRef,
+                            Name: *c_char)
+                         -> ValueRef;
+    unsafe fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef) ->
        ValueRef;
-    fn LLVMBuildGEP(B: BuilderRef, Pointer: ValueRef, Indices: *ValueRef,
-                    NumIndices: c_uint, Name: *c_char) -> ValueRef;
-    fn LLVMBuildInBoundsGEP(B: BuilderRef, Pointer: ValueRef,
+    unsafe fn LLVMBuildGEP(B: BuilderRef,
+                           Pointer: ValueRef,
+                           Indices: *ValueRef,
+                           NumIndices: c_uint,
+                           Name: *c_char)
+                        -> ValueRef;
+    unsafe fn LLVMBuildInBoundsGEP(B: BuilderRef, Pointer: ValueRef,
                             Indices: *ValueRef, NumIndices: c_uint,
                             Name: *c_char)
        -> ValueRef;
-    fn LLVMBuildStructGEP(B: BuilderRef, Pointer: ValueRef, Idx: c_uint,
-                          Name: *c_char) -> ValueRef;
-    fn LLVMBuildGlobalString(B: BuilderRef, Str: *c_char, Name: *c_char) ->
-       ValueRef;
-    fn LLVMBuildGlobalStringPtr(B: BuilderRef, Str: *c_char, Name: *c_char) ->
-       ValueRef;
+    unsafe fn LLVMBuildStructGEP(B: BuilderRef,
+                                 Pointer: ValueRef,
+                                 Idx: c_uint,
+                                 Name: *c_char)
+                              -> ValueRef;
+    unsafe fn LLVMBuildGlobalString(B: BuilderRef,
+                                    Str: *c_char,
+                                    Name: *c_char)
+                                 -> ValueRef;
+    unsafe fn LLVMBuildGlobalStringPtr(B: BuilderRef,
+                                       Str: *c_char,
+                                       Name: *c_char)
+                                    -> ValueRef;
 
     /* Casts */
-    fn LLVMBuildTrunc(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildTrunc(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                       Name: *c_char) -> ValueRef;
-    fn LLVMBuildZExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildZExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildSExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildSExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                      Name: *c_char) -> ValueRef;
-    fn LLVMBuildFPToUI(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildFPToUI(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildFPToSI(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildFPToSI(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildUIToFP(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildUIToFP(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildSIToFP(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildSIToFP(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                        Name: *c_char) -> ValueRef;
-    fn LLVMBuildFPTrunc(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildFPTrunc(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                         Name: *c_char) -> ValueRef;
-    fn LLVMBuildFPExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildFPExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                       Name: *c_char) -> ValueRef;
-    fn LLVMBuildPtrToInt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildPtrToInt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                          Name: *c_char) -> ValueRef;
-    fn LLVMBuildIntToPtr(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildIntToPtr(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                          Name: *c_char) -> ValueRef;
-    fn LLVMBuildBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                         Name: *c_char) -> ValueRef;
-    fn LLVMBuildZExtOrBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
-                              Name: *c_char) -> ValueRef;
-    fn LLVMBuildSExtOrBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
-                              Name: *c_char) -> ValueRef;
-    fn LLVMBuildTruncOrBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
-                               Name: *c_char) -> ValueRef;
-    fn LLVMBuildCast(B: BuilderRef, Op: Opcode, Val: ValueRef,
+    unsafe fn LLVMBuildZExtOrBitCast(B: BuilderRef,
+                                     Val: ValueRef,
+                                     DestTy: TypeRef,
+                                     Name: *c_char)
+                                  -> ValueRef;
+    unsafe fn LLVMBuildSExtOrBitCast(B: BuilderRef,
+                                     Val: ValueRef,
+                                     DestTy: TypeRef,
+                                     Name: *c_char)
+                                  -> ValueRef;
+    unsafe fn LLVMBuildTruncOrBitCast(B: BuilderRef,
+                                      Val: ValueRef,
+                                      DestTy: TypeRef,
+                                      Name: *c_char)
+                                   -> ValueRef;
+    unsafe fn LLVMBuildCast(B: BuilderRef, Op: Opcode, Val: ValueRef,
                      DestTy: TypeRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildPointerCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
-                            Name: *c_char) -> ValueRef;
-    fn LLVMBuildIntCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildPointerCast(B: BuilderRef,
+                                   Val: ValueRef,
+                                   DestTy: TypeRef,
+                                   Name: *c_char)
+                                -> ValueRef;
+    unsafe fn LLVMBuildIntCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                         Name: *c_char) -> ValueRef;
-    fn LLVMBuildFPCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
+    unsafe fn LLVMBuildFPCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
                        Name: *c_char) -> ValueRef;
 
     /* Comparisons */
-    fn LLVMBuildICmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
+    unsafe fn LLVMBuildICmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
                      RHS: ValueRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildFCmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
+    unsafe fn LLVMBuildFCmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
                      RHS: ValueRef, Name: *c_char) -> ValueRef;
 
     /* Miscellaneous instructions */
-    fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildCall(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
+    unsafe fn LLVMBuildPhi(B: BuilderRef,
+                           Ty: TypeRef,
+                           Name: *c_char)
+                        -> ValueRef;
+    unsafe fn LLVMBuildCall(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
                      NumArgs: c_uint, Name: *c_char) -> ValueRef;
-    fn LLVMBuildSelect(B: BuilderRef, If: ValueRef, Then: ValueRef,
+    unsafe fn LLVMBuildSelect(B: BuilderRef, If: ValueRef, Then: ValueRef,
                        Else: ValueRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildVAArg(B: BuilderRef, list: ValueRef, Ty: TypeRef,
+    unsafe fn LLVMBuildVAArg(B: BuilderRef, list: ValueRef, Ty: TypeRef,
                       Name: *c_char)
        -> ValueRef;
-    fn LLVMBuildExtractElement(B: BuilderRef, VecVal: ValueRef,
-                               Index: ValueRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildInsertElement(B: BuilderRef, VecVal: ValueRef,
-                              EltVal: ValueRef, Index: ValueRef,
-                              Name: *c_char)
-       -> ValueRef;
-    fn LLVMBuildShuffleVector(B: BuilderRef, V1: ValueRef, V2: ValueRef,
-                              Mask: ValueRef, Name: *c_char) -> ValueRef;
-    fn LLVMBuildExtractValue(B: BuilderRef, AggVal: ValueRef, Index: c_uint,
-                             Name: *c_char) -> ValueRef;
-    fn LLVMBuildInsertValue(B: BuilderRef, AggVal: ValueRef, EltVal: ValueRef,
-                            Index: c_uint, Name: *c_char) -> ValueRef;
-
-    fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef,
-                       Name: *c_char) -> ValueRef;
-    fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *c_char) ->
-       ValueRef;
-    fn LLVMBuildPtrDiff(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
+    unsafe fn LLVMBuildExtractElement(B: BuilderRef,
+                                      VecVal: ValueRef,
+                                      Index: ValueRef,
+                                      Name: *c_char)
+                                   -> ValueRef;
+    unsafe fn LLVMBuildInsertElement(B: BuilderRef,
+                                     VecVal: ValueRef,
+                                     EltVal: ValueRef,
+                                     Index: ValueRef,
+                                     Name: *c_char)
+                                  -> ValueRef;
+    unsafe fn LLVMBuildShuffleVector(B: BuilderRef,
+                                     V1: ValueRef,
+                                     V2: ValueRef,
+                                     Mask: ValueRef,
+                                     Name: *c_char)
+                                  -> ValueRef;
+    unsafe fn LLVMBuildExtractValue(B: BuilderRef,
+                                    AggVal: ValueRef,
+                                    Index: c_uint,
+                                    Name: *c_char)
+                                 -> ValueRef;
+    unsafe fn LLVMBuildInsertValue(B: BuilderRef,
+                                   AggVal: ValueRef,
+                                   EltVal: ValueRef,
+                                   Index: c_uint,
+                                   Name: *c_char)
+                                -> ValueRef;
+
+    unsafe fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *c_char)
+                           -> ValueRef;
+    unsafe fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *c_char)
+                              -> ValueRef;
+    unsafe fn LLVMBuildPtrDiff(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
                         Name: *c_char) -> ValueRef;
 
     /* Atomic Operations */
-    fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
+    unsafe fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
                               CMP: ValueRef, RHS: ValueRef,
                               ++Order: AtomicOrdering) -> ValueRef;
-    fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
+    unsafe fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
                           LHS: ValueRef, RHS: ValueRef,
                           ++Order: AtomicOrdering) -> ValueRef;
 
     /* Selected entries from the downcasts. */
-    fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
+    unsafe fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
 
     /** Writes a module to the specified path. Returns 0 on success. */
-    fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *c_char) -> c_int;
+    unsafe fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *c_char) -> c_int;
 
     /** Creates target data from a target layout string. */
-    fn LLVMCreateTargetData(StringRep: *c_char) -> TargetDataRef;
+    unsafe fn LLVMCreateTargetData(StringRep: *c_char) -> TargetDataRef;
     /** Adds the target data to the given pass manager. The pass manager
         references the target data only weakly. */
-    fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
+    unsafe fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
     /** Number of bytes clobbered when doing a Store to *T. */
-    fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong;
+    unsafe fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
+        -> c_ulonglong;
 
     /** Number of bytes clobbered when doing a Store to *T. */
-    fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong;
+    unsafe fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
+        -> c_ulonglong;
 
     /** Distance between successive elements in an array of T.
     Includes ABI padding. */
-    fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_uint;
+    unsafe fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_uint;
 
     /** Returns the preferred alignment of a type. */
-    fn LLVMPreferredAlignmentOfType(TD: TargetDataRef,
+    unsafe fn LLVMPreferredAlignmentOfType(TD: TargetDataRef,
                                     Ty: TypeRef) -> c_uint;
     /** Returns the minimum alignment of a type. */
-    fn LLVMABIAlignmentOfType(TD: TargetDataRef,
+    unsafe fn LLVMABIAlignmentOfType(TD: TargetDataRef,
                               Ty: TypeRef) -> c_uint;
     /** Returns the minimum alignment of a type when part of a call frame. */
-    fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef,
+    unsafe fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef,
                                     Ty: TypeRef) -> c_uint;
 
     /** Disposes target data. */
-    fn LLVMDisposeTargetData(TD: TargetDataRef);
+    unsafe fn LLVMDisposeTargetData(TD: TargetDataRef);
 
     /** Creates a pass manager. */
-    fn LLVMCreatePassManager() -> PassManagerRef;
+    unsafe fn LLVMCreatePassManager() -> PassManagerRef;
     /** Disposes a pass manager. */
-    fn LLVMDisposePassManager(PM: PassManagerRef);
+    unsafe fn LLVMDisposePassManager(PM: PassManagerRef);
     /** Runs a pass manager on a module. */
-    fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
+    unsafe fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
 
     /** Adds a verification pass. */
-    fn LLVMAddVerifierPass(PM: PassManagerRef);
-
-    fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
-    fn LLVMAddIPSCCPPass(PM: PassManagerRef);
-    fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
-    fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
-    fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
-    fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
-    fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
-    fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
-    fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
-    fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
-    fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
-    fn LLVMAddReassociatePass(PM: PassManagerRef);
-    fn LLVMAddLoopRotatePass(PM: PassManagerRef);
-    fn LLVMAddLICMPass(PM: PassManagerRef);
-    fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
-    fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
-    fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
-    fn LLVMAddGVNPass(PM: PassManagerRef);
-    fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
-    fn LLVMAddSCCPPass(PM: PassManagerRef);
-    fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
-    fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
-    fn LLVMAddConstantMergePass(PM: PassManagerRef);
-    fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
-    fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
-    fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
-    fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
-    fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
-    fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
-    fn LLVMAddPruneEHPass(PM: PassManagerRef);
-    fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
-    fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
-    fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
-    fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
-    fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
-
-    fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
-    fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
-    fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
+    unsafe fn LLVMAddVerifierPass(PM: PassManagerRef);
+
+    unsafe fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
+    unsafe fn LLVMAddIPSCCPPass(PM: PassManagerRef);
+    unsafe fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
+    unsafe fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
+    unsafe fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
+    unsafe fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
+    unsafe fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
+    unsafe fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
+    unsafe fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
+    unsafe fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
+    unsafe fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
+    unsafe fn LLVMAddReassociatePass(PM: PassManagerRef);
+    unsafe fn LLVMAddLoopRotatePass(PM: PassManagerRef);
+    unsafe fn LLVMAddLICMPass(PM: PassManagerRef);
+    unsafe fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
+    unsafe fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
+    unsafe fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
+    unsafe fn LLVMAddGVNPass(PM: PassManagerRef);
+    unsafe fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
+    unsafe fn LLVMAddSCCPPass(PM: PassManagerRef);
+    unsafe fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
+    unsafe fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
+    unsafe fn LLVMAddConstantMergePass(PM: PassManagerRef);
+    unsafe fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
+    unsafe fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
+    unsafe fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
+    unsafe fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
+    unsafe fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
+    unsafe fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
+    unsafe fn LLVMAddPruneEHPass(PM: PassManagerRef);
+    unsafe fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
+    unsafe fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
+    unsafe fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
+    unsafe fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
+    unsafe fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
+
+    unsafe fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
+    unsafe fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
+    unsafe fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
                                          OptimizationLevel: c_uint);
-    fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
+    unsafe fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
                                           Value: Bool);
-    fn LLVMPassManagerBuilderSetDisableUnitAtATime(PMB: PassManagerBuilderRef,
-                                                   Value: Bool);
-    fn LLVMPassManagerBuilderSetDisableUnrollLoops(PMB: PassManagerBuilderRef,
-                                                   Value: Bool);
-    fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls
+    unsafe fn LLVMPassManagerBuilderSetDisableUnitAtATime(
+        PMB: PassManagerBuilderRef, Value: Bool);
+    unsafe fn LLVMPassManagerBuilderSetDisableUnrollLoops(
+        PMB: PassManagerBuilderRef, Value: Bool);
+    unsafe fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls
         (PMB: PassManagerBuilderRef, Value: Bool);
-    fn LLVMPassManagerBuilderUseInlinerWithThreshold
+    unsafe fn LLVMPassManagerBuilderUseInlinerWithThreshold
         (PMB: PassManagerBuilderRef, threshold: c_uint);
-    fn LLVMPassManagerBuilderPopulateModulePassManager
+    unsafe fn LLVMPassManagerBuilderPopulateModulePassManager
         (PMB: PassManagerBuilderRef, PM: PassManagerRef);
 
-    fn LLVMPassManagerBuilderPopulateFunctionPassManager
+    unsafe fn LLVMPassManagerBuilderPopulateFunctionPassManager
         (PMB: PassManagerBuilderRef, PM: PassManagerRef);
 
     /** Destroys a memory buffer. */
-    fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
+    unsafe fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
 
 
     /* Stuff that's in rustllvm/ because it's not upstream yet. */
 
     /** Opens an object file. */
-    fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
+    unsafe fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
     /** Closes an object file. */
-    fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
+    unsafe fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
 
     /** Enumerates the sections in an object file. */
-    fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
+    unsafe fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
     /** Destroys a section iterator. */
-    fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
+    unsafe fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
     /** Returns true if the section iterator is at the end of the section
         list: */
-    fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
+    unsafe fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
                                   SI: SectionIteratorRef) -> Bool;
     /** Moves the section iterator to point to the next section. */
-    fn LLVMMoveToNextSection(SI: SectionIteratorRef);
+    unsafe fn LLVMMoveToNextSection(SI: SectionIteratorRef);
     /** Returns the current section name. */
-    fn LLVMGetSectionName(SI: SectionIteratorRef) -> *c_char;
+    unsafe fn LLVMGetSectionName(SI: SectionIteratorRef) -> *c_char;
     /** Returns the current section size. */
-    fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
+    unsafe fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
     /** Returns the current section contents as a string buffer. */
-    fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *c_char;
+    unsafe fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *c_char;
 
     /** Reads the given file and returns it as a memory buffer. Use
         LLVMDisposeMemoryBuffer() to get rid of it. */
-    fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *c_char) ->
+    unsafe fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *c_char) ->
        MemoryBufferRef;
 
-    fn LLVMRustWriteOutputFile(PM: PassManagerRef, M: ModuleRef,
+    unsafe fn LLVMRustWriteOutputFile(PM: PassManagerRef, M: ModuleRef,
                                Triple: *c_char,
                                // FIXME: When #2334 is fixed, change
                                // c_uint to FileType
@@ -1003,66 +1190,73 @@ fn LLVMRustWriteOutputFile(PM: PassManagerRef, M: ModuleRef,
 
     /** Returns a string describing the last error caused by an LLVMRust*
         call. */
-    fn LLVMRustGetLastError() -> *c_char;
+    unsafe fn LLVMRustGetLastError() -> *c_char;
 
     /** Prepare the JIT. Returns a memory manager that can load crates. */
-    fn LLVMRustPrepareJIT(__morestack: *()) -> *();
+    unsafe fn LLVMRustPrepareJIT(__morestack: *()) -> *();
 
     /** Load a crate into the memory manager. */
-    fn LLVMRustLoadCrate(MM: *(),
+    unsafe fn LLVMRustLoadCrate(MM: *(),
                          Filename: *c_char) -> bool;
 
     /** Execute the JIT engine. */
-    fn LLVMRustExecuteJIT(MM: *(),
+    unsafe fn LLVMRustExecuteJIT(MM: *(),
                           PM: PassManagerRef,
                           M: ModuleRef,
                           OptLevel: c_int,
                           EnableSegmentedStacks: bool) -> *();
 
     /** Parses the bitcode in the given memory buffer. */
-    fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;
+    unsafe fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;
 
     /** Parses LLVM asm in the given file */
-    fn LLVMRustParseAssemblyFile(Filename: *c_char) -> ModuleRef;
+    unsafe fn LLVMRustParseAssemblyFile(Filename: *c_char) -> ModuleRef;
 
-    fn LLVMRustAddPrintModulePass(PM: PassManagerRef, M: ModuleRef,
+    unsafe fn LLVMRustAddPrintModulePass(PM: PassManagerRef, M: ModuleRef,
                                   Output: *c_char);
 
     /** Turn on LLVM pass-timing. */
-    fn LLVMRustEnableTimePasses();
+    unsafe fn LLVMRustEnableTimePasses();
 
     /** Print the pass timings since static dtors aren't picking them up. */
-    fn LLVMRustPrintPassTimings();
+    unsafe fn LLVMRustPrintPassTimings();
 
-    fn LLVMStructCreateNamed(C: ContextRef, Name: *c_char) -> TypeRef;
+    unsafe fn LLVMStructCreateNamed(C: ContextRef, Name: *c_char) -> TypeRef;
 
-    fn LLVMStructSetBody(StructTy: TypeRef, ElementTypes: *TypeRef,
+    unsafe fn LLVMStructSetBody(StructTy: TypeRef, ElementTypes: *TypeRef,
                          ElementCount: c_uint, Packed: Bool);
 
-    fn LLVMConstNamedStruct(S: TypeRef, ConstantVals: *ValueRef,
+    unsafe fn LLVMConstNamedStruct(S: TypeRef, ConstantVals: *ValueRef,
                             Count: c_uint) -> ValueRef;
 
     /** Enables LLVM debug output. */
-    fn LLVMSetDebug(Enabled: c_int);
+    unsafe fn LLVMSetDebug(Enabled: c_int);
 }
 
 fn SetInstructionCallConv(Instr: ValueRef, CC: CallConv) {
-    llvm::LLVMSetInstructionCallConv(Instr, CC as c_uint);
+    unsafe {
+        llvm::LLVMSetInstructionCallConv(Instr, CC as c_uint);
+    }
 }
 fn SetFunctionCallConv(Fn: ValueRef, CC: CallConv) {
-    llvm::LLVMSetFunctionCallConv(Fn, CC as c_uint);
+    unsafe {
+        llvm::LLVMSetFunctionCallConv(Fn, CC as c_uint);
+    }
 }
 fn SetLinkage(Global: ValueRef, Link: Linkage) {
-    llvm::LLVMSetLinkage(Global, Link as c_uint);
+    unsafe {
+        llvm::LLVMSetLinkage(Global, Link as c_uint);
+    }
 }
 
 /* Memory-managed object interface to type handles. */
 
-type type_names = @{type_names: std::map::HashMap<TypeRef, ~str>,
-                    named_types: std::map::HashMap<~str, TypeRef>};
+type type_names = @{type_names: HashMap<TypeRef, ~str>,
+                    named_types: HashMap<~str, TypeRef>};
 
-fn associate_type(tn: type_names, s: ~str, t: TypeRef) {
-    assert tn.type_names.insert(t, s);
+fn associate_type(tn: type_names, +s: ~str, t: TypeRef) {
+    // XXX: Bad copy, use @str instead?
+    assert tn.type_names.insert(t, copy s);
     assert tn.named_types.insert(s, t);
 }
 
@@ -1070,122 +1264,133 @@ fn type_has_name(tn: type_names, t: TypeRef) -> Option<~str> {
     return tn.type_names.find(t);
 }
 
-fn name_has_type(tn: type_names, s: ~str) -> Option<TypeRef> {
+fn name_has_type(tn: type_names, +s: ~str) -> Option<TypeRef> {
     return tn.named_types.find(s);
 }
 
 fn mk_type_names() -> type_names {
-    @{type_names: std::map::HashMap(),
-      named_types: std::map::HashMap()}
+    @{type_names: HashMap(),
+      named_types: HashMap()}
 }
 
 fn type_to_str(names: type_names, ty: TypeRef) -> ~str {
     return type_to_str_inner(names, ~[], ty);
 }
 
-fn type_to_str_inner(names: type_names, outer0: ~[TypeRef], ty: TypeRef) ->
+fn type_to_str_inner(names: type_names, +outer0: ~[TypeRef], ty: TypeRef) ->
    ~str {
-    match type_has_name(names, ty) {
-      option::Some(ref n) => return (*n),
-      _ => {}
-    }
+    unsafe {
+        match type_has_name(names, ty) {
+          option::Some(ref n) => return (/*bad*/copy *n),
+          _ => {}
+        }
 
-    let outer = vec::append_one(outer0, ty);
+        // XXX: Bad copy.
+        let outer = vec::append_one(copy outer0, ty);
 
-    let kind = llvm::LLVMGetTypeKind(ty);
+        let kind = llvm::LLVMGetTypeKind(ty);
 
-    fn tys_str(names: type_names, outer: ~[TypeRef],
-               tys: ~[TypeRef]) -> ~str {
-        let mut s: ~str = ~"";
-        let mut first: bool = true;
-        for tys.each |t| {
-            if first { first = false; } else { s += ~", "; }
-            s += type_to_str_inner(names, outer, *t);
+        fn tys_str(names: type_names, outer: ~[TypeRef],
+                   tys: ~[TypeRef]) -> ~str {
+            let mut s: ~str = ~"";
+            let mut first: bool = true;
+            for tys.each |t| {
+                if first { first = false; } else { s += ~", "; }
+                s += type_to_str_inner(names, outer, *t);
+            }
+            return s;
         }
-        return s;
-    }
 
-    match kind {
-      Void => return ~"Void",
-      Half => return ~"Half",
-      Float => return ~"Float",
-      Double => return ~"Double",
-      X86_FP80 => return ~"X86_FP80",
-      FP128 => return ~"FP128",
-      PPC_FP128 => return ~"PPC_FP128",
-      Label => return ~"Label",
-      Integer => {
-        return ~"i" + int::str(llvm::LLVMGetIntTypeWidth(ty) as int);
-      }
-      Function => {
-        let mut s = ~"fn(";
-        let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
-        let n_args = llvm::LLVMCountParamTypes(ty) as uint;
-        let args = vec::from_elem(n_args, 0 as TypeRef);
-        unsafe {
-            llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
-        }
-        s += tys_str(names, outer, args);
-        s += ~") -> ";
-        s += type_to_str_inner(names, outer, out_ty);
-        return s;
-      }
-      Struct => {
-        let mut s: ~str = ~"{";
-        let n_elts = llvm::LLVMCountStructElementTypes(ty) as uint;
-        let mut elts = vec::from_elem(n_elts, 0 as TypeRef);
-        llvm::LLVMGetStructElementTypes(ty,
-                                        ptr::to_mut_unsafe_ptr(&mut elts[0]));
-        s += tys_str(names, outer, elts);
-        s += ~"}";
-        return s;
-      }
-      Array => {
-        let el_ty = llvm::LLVMGetElementType(ty);
-        return ~"[" + type_to_str_inner(names, outer, el_ty) + ~" x " +
-            uint::str(llvm::LLVMGetArrayLength(ty) as uint) + ~"]";
-      }
-      Pointer => {
-        let mut i: uint = 0u;
-        for outer0.each |tout| {
-            i += 1u;
-            if *tout as int == ty as int {
-                let n: uint = vec::len::<TypeRef>(outer0) - i;
-                return ~"*\\" + int::str(n as int);
+        match kind {
+          Void => return ~"Void",
+          Half => return ~"Half",
+          Float => return ~"Float",
+          Double => return ~"Double",
+          X86_FP80 => return ~"X86_FP80",
+          FP128 => return ~"FP128",
+          PPC_FP128 => return ~"PPC_FP128",
+          Label => return ~"Label",
+          Integer => {
+            return ~"i" + int::str(llvm::LLVMGetIntTypeWidth(ty) as int);
+          }
+          Function => {
+            let mut s = ~"fn(";
+            let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
+            let n_args = llvm::LLVMCountParamTypes(ty) as uint;
+            let args = vec::from_elem(n_args, 0 as TypeRef);
+            unsafe {
+                llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
             }
-        }
-        let addrstr = {
-            let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint;
-            if addrspace == 0u {
-                ~""
-            } else {
-                fmt!("addrspace(%u)", addrspace)
+            s += tys_str(names, outer, args);
+            s += ~") -> ";
+            s += type_to_str_inner(names, outer, out_ty);
+            return s;
+          }
+          Struct => {
+            let mut s: ~str = ~"{";
+            let n_elts = llvm::LLVMCountStructElementTypes(ty) as uint;
+            let mut elts = vec::from_elem(n_elts, 0 as TypeRef);
+            if elts.len() > 0 {
+                llvm::LLVMGetStructElementTypes(
+                    ty, ptr::to_mut_unsafe_ptr(&mut elts[0]));
             }
-        };
-        return addrstr + ~"*" +
-                type_to_str_inner(names, outer, llvm::LLVMGetElementType(ty));
-      }
-      Vector => return ~"Vector",
-      Metadata => return ~"Metadata",
-      X86_MMX => return ~"X86_MMAX"
+            s += tys_str(names, outer, elts);
+            s += ~"}";
+            return s;
+          }
+          Array => {
+            let el_ty = llvm::LLVMGetElementType(ty);
+            return ~"[" + type_to_str_inner(names, outer, el_ty) + ~" x " +
+                uint::str(llvm::LLVMGetArrayLength(ty) as uint) + ~"]";
+          }
+          Pointer => {
+            let mut i: uint = 0u;
+            for outer0.each |tout| {
+                i += 1u;
+                if *tout as int == ty as int {
+                    let n: uint = vec::len::<TypeRef>(outer0) - i;
+                    return ~"*\\" + int::str(n as int);
+                }
+            }
+            let addrstr = {
+                let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint;
+                if addrspace == 0u {
+                    ~""
+                } else {
+                    fmt!("addrspace(%u)", addrspace)
+                }
+            };
+            return addrstr + ~"*" +
+                    type_to_str_inner(names,
+                                      outer,
+                                      llvm::LLVMGetElementType(ty));
+          }
+          Vector => return ~"Vector",
+          Metadata => return ~"Metadata",
+          X86_MMX => return ~"X86_MMAX"
+        }
     }
 }
 
 fn float_width(llt: TypeRef) -> uint {
-    return match llvm::LLVMGetTypeKind(llt) as int {
-          1 => 32u,
-          2 => 64u,
-          3 => 80u,
-          4 | 5 => 128u,
-          _ => fail ~"llvm_float_width called on a non-float type"
-        };
+    unsafe {
+        return match llvm::LLVMGetTypeKind(llt) as int {
+              1 => 32u,
+              2 => 64u,
+              3 => 80u,
+              4 | 5 => 128u,
+              _ => fail ~"llvm_float_width called on a non-float type"
+            };
+    }
 }
 
 fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] unsafe {
-    let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint,
-                             0 as TypeRef);
-    llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args));
-    return args;
+    unsafe {
+        let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint,
+                                 0 as TypeRef);
+        llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args));
+        return args;
+    }
 }
 
 fn struct_element_types(struct_ty: TypeRef) -> ~[TypeRef] {
@@ -1194,8 +1399,10 @@ fn struct_element_types(struct_ty: TypeRef) -> ~[TypeRef] {
         let mut buf: ~[TypeRef] =
             vec::from_elem(count as uint,
                            cast::transmute::<uint,TypeRef>(0));
-        llvm::LLVMGetStructElementTypes(struct_ty,
-                                        ptr::to_mut_unsafe_ptr(&mut buf[0]));
+        if buf.len() > 0 {
+            llvm::LLVMGetStructElementTypes(
+                struct_ty, ptr::to_mut_unsafe_ptr(&mut buf[0]));
+        }
         return move buf;
     }
 }
@@ -1205,7 +1412,11 @@ fn struct_element_types(struct_ty: TypeRef) -> ~[TypeRef] {
 
 struct target_data_res {
     TD: TargetDataRef,
-    drop { llvm::LLVMDisposeTargetData(self.TD); }
+    drop {
+        unsafe {
+            llvm::LLVMDisposeTargetData(self.TD);
+        }
+    }
 }
 
 fn target_data_res(TD: TargetDataRef) -> target_data_res {
@@ -1218,7 +1429,9 @@ fn target_data_res(TD: TargetDataRef) -> target_data_res {
 
 fn mk_target_data(string_rep: ~str) -> target_data {
     let lltd =
-        str::as_c_str(string_rep, |buf| llvm::LLVMCreateTargetData(buf) );
+        str::as_c_str(string_rep, |buf| unsafe {
+            llvm::LLVMCreateTargetData(buf)
+        });
     return {lltd: lltd, dtor: @target_data_res(lltd)};
 }
 
@@ -1226,7 +1439,11 @@ fn mk_target_data(string_rep: ~str) -> target_data {
 
 struct pass_manager_res {
     PM: PassManagerRef,
-    drop { llvm::LLVMDisposePassManager(self.PM); }
+    drop {
+        unsafe {
+            llvm::LLVMDisposePassManager(self.PM);
+        }
+    }
 }
 
 fn pass_manager_res(PM: PassManagerRef) -> pass_manager_res {
@@ -1238,15 +1455,21 @@ fn pass_manager_res(PM: PassManagerRef) -> pass_manager_res {
 type pass_manager = {llpm: PassManagerRef, dtor: @pass_manager_res};
 
 fn mk_pass_manager() -> pass_manager {
-    let llpm = llvm::LLVMCreatePassManager();
-    return {llpm: llpm, dtor: @pass_manager_res(llpm)};
+    unsafe {
+        let llpm = llvm::LLVMCreatePassManager();
+        return {llpm: llpm, dtor: @pass_manager_res(llpm)};
+    }
 }
 
 /* Memory-managed interface to object files. */
 
 struct object_file_res {
     ObjectFile: ObjectFileRef,
-    drop { llvm::LLVMDisposeObjectFile(self.ObjectFile); }
+    drop {
+        unsafe {
+            llvm::LLVMDisposeObjectFile(self.ObjectFile);
+        }
+    }
 }
 
 fn object_file_res(ObjFile: ObjectFileRef) -> object_file_res {
@@ -1258,16 +1481,22 @@ fn object_file_res(ObjFile: ObjectFileRef) -> object_file_res {
 type object_file = {llof: ObjectFileRef, dtor: @object_file_res};
 
 fn mk_object_file(llmb: MemoryBufferRef) -> Option<object_file> {
-    let llof = llvm::LLVMCreateObjectFile(llmb);
-    if llof as int == 0 { return option::None::<object_file>; }
-    return option::Some({llof: llof, dtor: @object_file_res(llof)});
+    unsafe {
+        let llof = llvm::LLVMCreateObjectFile(llmb);
+        if llof as int == 0 { return option::None::<object_file>; }
+        return option::Some({llof: llof, dtor: @object_file_res(llof)});
+    }
 }
 
 /* Memory-managed interface to section iterators. */
 
 struct section_iter_res {
     SI: SectionIteratorRef,
-    drop { llvm::LLVMDisposeSectionIterator(self.SI); }
+    drop {
+        unsafe {
+            llvm::LLVMDisposeSectionIterator(self.SI);
+        }
+    }
 }
 
 fn section_iter_res(SI: SectionIteratorRef) -> section_iter_res {
@@ -1279,8 +1508,10 @@ fn section_iter_res(SI: SectionIteratorRef) -> section_iter_res {
 type section_iter = {llsi: SectionIteratorRef, dtor: @section_iter_res};
 
 fn mk_section_iter(llof: ObjectFileRef) -> section_iter {
-    let llsi = llvm::LLVMGetSections(llof);
-    return {llsi: llsi, dtor: @section_iter_res(llsi)};
+    unsafe {
+        let llsi = llvm::LLVMGetSections(llof);
+        return {llsi: llsi, dtor: @section_iter_res(llsi)};
+    }
 }
 
 //
index 69dcdc389d62a7c37f398436674fef8c2df0f51f..e6a367ac1a863472e6b69b09487146b7c969b67b 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // EBML enum definitions and utils shared by the encoder and decoder
 
 const tag_items: uint = 0x02u;
@@ -139,5 +140,17 @@ enum astencode_tag { // Reserves 0x50 -- 0x6f
 
 const tag_item_impl_type_basename: uint = 0x71;
 
+// Language items are a top-level directory (for speed). Hierarchy:
+//
+// tag_lang_items
+// - tag_lang_items_item
+//   - tag_lang_items_item_id: u32
+//   - tag_lang_items_item_node_id: u32
+
+const tag_lang_items: uint = 0x72;
+const tag_lang_items_item: uint = 0x73;
+const tag_lang_items_item_id: uint = 0x74;
+const tag_lang_items_item_node_id: uint = 0x75;
+
 type link_meta = {name: ~str, vers: ~str, extras_hash: ~str};
 
index e9b820d30db087a6ec86b109df3cb1a49b22e7d3..4627516416214202d664db07361ad6ce1b199c6b 100644 (file)
@@ -8,27 +8,41 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 //! Validates all used crates and extern libraries and loads their metadata
 
-use syntax::diagnostic::span_handler;
-use syntax::{ast, ast_util};
+use core::prelude::*;
+
+use metadata::cstore;
+use metadata::common::*;
+use metadata::decoder;
+use metadata::filesearch::FileSearch;
+use metadata::loader;
+
+use core::dvec::DVec;
+use core::either;
+use core::option;
+use core::vec;
 use syntax::attr;
-use syntax::visit;
 use syntax::codemap::span;
-use std::map::HashMap;
-use syntax::print::pprust;
-use metadata::filesearch::FileSearch;
-use metadata::common::*;
-use dvec::DVec;
+use syntax::diagnostic::span_handler;
 use syntax::parse::token::ident_interner;
+use syntax::print::pprust;
+use syntax::visit;
+use syntax::{ast, ast_util};
+use std::map::HashMap;
 
 export read_crates;
 
 // Traverses an AST, reading all the information about use'd crates and extern
 // libraries necessary for later resolving, typechecking, linking, etc.
-fn read_crates(diag: span_handler, crate: ast::crate,
-               cstore: cstore::CStore, filesearch: FileSearch,
-               os: loader::os, static: bool, intr: @ident_interner) {
+fn read_crates(diag: span_handler,
+               crate: ast::crate,
+               cstore: cstore::CStore,
+               filesearch: FileSearch,
+               os: loader::os,
+               static: bool,
+               intr: @ident_interner) {
     let e = @{diag: diag,
               filesearch: filesearch,
               cstore: cstore,
@@ -38,10 +52,10 @@ fn read_crates(diag: span_handler, crate: ast::crate,
               mut next_crate_num: 1,
               intr: intr};
     let v =
-        visit::mk_simple_visitor(@{visit_view_item:
-                                       |a| visit_view_item(e, a),
-                                   visit_item: |a| visit_item(e, a)
-                                   ,.. *visit::default_simple_visitor()});
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_view_item: |a| visit_view_item(e, a),
+            visit_item: |a| visit_item(e, a),
+            .. *visit::default_simple_visitor()});
     visit::visit_crate(crate, (), v);
     dump_crates(e.crate_cache);
     warn_if_multiple_versions(e, diag, e.crate_cache.get());
@@ -68,10 +82,12 @@ fn warn_if_multiple_versions(e: env, diag: span_handler,
     use either::*;
 
     if crate_cache.len() != 0u {
-        let name = loader::crate_name_from_metas(*crate_cache.last().metas);
+        let name = loader::crate_name_from_metas(
+            /*bad*/copy *crate_cache.last().metas);
         let (matches, non_matches) =
             partition(crate_cache.map_to_vec(|&entry| {
-                let othername = loader::crate_name_from_metas(*entry.metas);
+                let othername = loader::crate_name_from_metas(
+                    copy *entry.metas);
                 if name == othername {
                     Left(entry)
                 } else {
@@ -87,7 +103,8 @@ fn warn_if_multiple_versions(e: env, diag: span_handler,
             for matches.each |match_| {
                 diag.span_note(match_.span, ~"used here");
                 let attrs = ~[
-                    attr::mk_attr(attr::mk_list_item(~"link", *match_.metas))
+                    attr::mk_attr(attr::mk_list_item(
+                        ~"link", /*bad*/copy *match_.metas))
                 ];
                 loader::note_linkage_attrs(e.intr, diag, attrs);
             }
@@ -107,7 +124,7 @@ fn warn_if_multiple_versions(e: env, diag: span_handler,
              intr: @ident_interner};
 
 fn visit_view_item(e: env, i: @ast::view_item) {
-    match i.node {
+    match /*bad*/copy i.node {
       ast::view_item_use(ident, meta_items, id) => {
         debug!("resolving use stmt. ident: %?, meta: %?", ident, meta_items);
         let cnum = resolve_crate(e, ident, meta_items, ~"", i.span);
@@ -118,7 +135,7 @@ fn visit_view_item(e: env, i: @ast::view_item) {
 }
 
 fn visit_item(e: env, i: @ast::item) {
-    match i.node {
+    match /*bad*/copy i.node {
       ast::item_foreign_mod(fm) => {
         match attr::foreign_abi(i.attrs) {
           either::Right(abi) => {
@@ -130,7 +147,7 @@ fn visit_item(e: env, i: @ast::item) {
 
         let cstore = e.cstore;
         let mut already_added = false;
-        let link_args = attr::find_attrs_by_name(i.attrs, ~"link_args");
+        let link_args = attr::find_attrs_by_name(i.attrs, "link_args");
 
         match fm.sort {
           ast::named => {
@@ -143,9 +160,9 @@ fn visit_item(e: env, i: @ast::item) {
                           i.span,
                           ~"empty #[link_name] not allowed; use #[nolink].");
                    }
-                   (*nn)
+                   (/*bad*/copy *nn)
                  }
-                None => *e.intr.get(i.ident)
+                None => /*bad*/copy *e.intr.get(i.ident)
             };
             if attr::find_attrs_by_name(i.attrs, ~"nolink").is_empty() {
                 already_added = !cstore::add_used_library(cstore,
@@ -162,7 +179,7 @@ fn visit_item(e: env, i: @ast::item) {
         for link_args.each |a| {
             match attr::get_meta_item_value_str(attr::attr_meta(*a)) {
               Some(ref linkarg) => {
-                cstore::add_used_link_args(cstore, (*linkarg));
+                cstore::add_used_link_args(cstore, (/*bad*/copy *linkarg));
               }
               None => {/* fallthrough */ }
             }
@@ -172,9 +189,10 @@ fn visit_item(e: env, i: @ast::item) {
     }
 }
 
-fn metas_with(ident: ~str, key: ~str, metas: ~[@ast::meta_item])
+fn metas_with(+ident: ~str, +key: ~str, +metas: ~[@ast::meta_item])
     -> ~[@ast::meta_item] {
-    let name_items = attr::find_meta_items_by_name(metas, key);
+    // XXX: Bad copies.
+    let name_items = attr::find_meta_items_by_name(copy metas, copy key);
     if name_items.is_empty() {
         vec::append_one(metas, attr::mk_name_value_item_str(key, ident))
     } else {
@@ -182,7 +200,7 @@ fn metas_with(ident: ~str, key: ~str, metas: ~[@ast::meta_item])
     }
 }
 
-fn metas_with_ident(ident: ~str, metas: ~[@ast::meta_item])
+fn metas_with_ident(+ident: ~str, +metas: ~[@ast::meta_item])
     -> ~[@ast::meta_item] {
     metas_with(ident, ~"name", metas)
 }
@@ -199,9 +217,9 @@ fn existing_match(e: env, metas: ~[@ast::meta_item], hash: ~str) ->
     return None;
 }
 
-fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item],
-                 hash: ~str, span: span) -> ast::crate_num {
-    let metas = metas_with_ident(*e.intr.get(ident), metas);
+fn resolve_crate(e: env, ident: ast::ident, +metas: ~[@ast::meta_item],
+                 +hash: ~str, span: span) -> ast::crate_num {
+    let metas = metas_with_ident(/*bad*/copy *e.intr.get(ident), metas);
 
     match existing_match(e, metas, hash) {
       None => {
@@ -210,7 +228,7 @@ fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item],
             filesearch: e.filesearch,
             span: span,
             ident: ident,
-            metas: metas,
+            metas: copy metas,  // XXX: Bad copy.
             hash: hash,
             os: e.os,
             static: e.static,
@@ -236,8 +254,8 @@ fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item],
 
         let cname =
             match attr::last_meta_item_value_str_by_name(metas, ~"name") {
-              option::Some(ref v) => (*v),
-              option::None => *e.intr.get(ident)
+              option::Some(ref v) => (/*bad*/copy *v),
+              option::None => /*bad*/copy *e.intr.get(ident)
             };
         let cmeta = @{name: cname, data: cdata,
                       cnum_map: cnum_map, cnum: cnum};
@@ -262,7 +280,7 @@ fn resolve_crate_deps(e: env, cdata: @~[u8]) -> cstore::cnum_map {
     for decoder::get_crate_deps(e.intr, cdata).each |dep| {
         let extrn_cnum = dep.cnum;
         let cname = dep.name;
-        let cmetas = metas_with(dep.vers, ~"vers", ~[]);
+        let cmetas = metas_with(/*bad*/copy dep.vers, ~"vers", ~[]);
         debug!("resolving dep crate %s ver: %s hash: %s",
                *e.intr.get(dep.name), dep.vers, dep.hash);
         match existing_match(e, metas_with_ident(*e.intr.get(cname), cmetas),
@@ -278,8 +296,8 @@ fn resolve_crate_deps(e: env, cdata: @~[u8]) -> cstore::cnum_map {
             // FIXME (#2404): Need better error reporting than just a bogus
             // span.
             let fake_span = ast_util::dummy_sp();
-            let local_cnum = resolve_crate(e, cname, cmetas, dep.hash,
-                                           fake_span);
+            let local_cnum = resolve_crate(e, cname, cmetas,
+                                           /*bad*/copy dep.hash, fake_span);
             cnum_map.insert(extrn_cnum, local_cnum);
           }
         }
index ae56cf45dbcf28d9248d1afbfc48e7c7a1ee7368..2b1c66eb4bbb678711bff7b2dc1c848b5554513b 100644 (file)
@@ -8,13 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // Searching for information from the cstore
 
+use core::prelude::*;
+
 use metadata::common::*;
+use metadata::cstore;
+use metadata::decoder;
+use metadata;
 use middle::ty;
 
 use core::dvec::DVec;
-use core::option::{Some, None};
+use core::vec;
 use reader = std::ebml::reader;
 use std::ebml;
 use std::map::HashMap;
 export get_type_name_if_impl;
 export get_static_methods_if_impl;
 export get_item_attrs;
+export each_lang_item;
 export each_path;
 export get_type;
 export get_impl_traits;
 export get_impl_method;
 export get_item_path;
+export get_lang_items;
 export maybe_get_item_ast, found_ast, found, found_parent, not_found;
 export ProvidedTraitMethodInfo;
 export StaticMethodInfo;
@@ -70,6 +78,14 @@ fn get_type_param_count(cstore: cstore::CStore, def: ast::def_id) -> uint {
     return decoder::get_type_param_count(cdata, def.node);
 }
 
+/// Iterates over all the language items in the given crate.
+fn each_lang_item(cstore: cstore::CStore,
+                  cnum: ast::crate_num,
+                  f: &fn(ast::node_id, uint) -> bool) {
+    let crate_data = cstore::get_crate_data(cstore, cnum);
+    decoder::each_lang_item(crate_data, f)
+}
+
 /// Iterates over all the paths in the given crate.
 fn each_path(cstore: cstore::CStore, cnum: ast::crate_num,
              f: fn(decoder::path_entry) -> bool) {
@@ -87,7 +103,8 @@ fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path {
 
     // FIXME #1920: This path is not always correct if the crate is not linked
     // into the root namespace.
-    vec::append(~[ast_map::path_mod(tcx.sess.ident_of(cdata.name))], path)
+    vec::append(~[ast_map::path_mod(tcx.sess.ident_of(
+        /*bad*/copy cdata.name))], path)
 }
 
 enum found_ast {
index 4f5046e40083c85b52ce96daf532c754590c6525..e9d6711d87b361bd63d87ec00fd3ceb36b6ad163 100644 (file)
@@ -8,11 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // The crate store - a central repo for information collected about external
 // crates and libraries
 
-use std::map;
+use core::prelude::*;
+
+use metadata::creader;
+use metadata::cstore;
+use metadata::decoder;
+
+use core::option;
+use core::str;
+use core::vec;
 use std::map::HashMap;
+use std::map;
+use std;
 use syntax::{ast, attr};
 use syntax::parse::token::ident_interner;
 
@@ -35,7 +46,6 @@
 export add_use_stmt_cnum;
 export find_use_stmt_cnum;
 export get_dep_hashes;
-export get_path;
 
 
 // A map from external crate numbers (as decoded from some crate file) to
 // own crate numbers.
 type cnum_map = map::HashMap<ast::crate_num, ast::crate_num>;
 
-// Multiple items may have the same def_id in crate metadata. They may be
-// renamed imports or reexports. This map keeps the "real" module path
-// and def_id.
-type mod_path_map = map::HashMap<ast::def_id, @~str>;
-
 type crate_metadata = @{name: ~str,
                         data: @~[u8],
                         cnum_map: cnum_map,
@@ -64,7 +69,6 @@ enum CStore { private(cstore_private), }
 type cstore_private =
     @{metas: map::HashMap<ast::crate_num, crate_metadata>,
       use_crate_map: use_crate_map,
-      mod_path_map: mod_path_map,
       mut used_crate_files: ~[Path],
       mut used_libraries: ~[~str],
       mut used_link_args: ~[~str],
@@ -81,10 +85,8 @@ enum CStore { private(cstore_private), }
 fn mk_cstore(intr: @ident_interner) -> CStore {
     let meta_cache = map::HashMap();
     let crate_map = map::HashMap();
-    let mod_path_map = HashMap();
     return private(@{metas: meta_cache,
                      use_crate_map: crate_map,
-                     mod_path_map: mod_path_map,
                      mut used_crate_files: ~[],
                      mut used_libraries: ~[],
                      mut used_link_args: ~[],
@@ -105,18 +107,10 @@ fn get_crate_vers(cstore: CStore, cnum: ast::crate_num) -> ~str {
     return decoder::get_crate_vers(cdata.data);
 }
 
-fn set_crate_data(cstore: CStore, cnum: ast::crate_num,
+fn set_crate_data(cstore: CStore,
+                  cnum: ast::crate_num,
                   data: crate_metadata) {
     p(cstore).metas.insert(cnum, data);
-    let get_crate_data: decoder::GetCrateDataCb = |cnum| {
-        cstore::get_crate_data(cstore, cnum)
-    };
-    for vec::each(decoder::get_crate_module_paths(cstore.intr, data,
-                                                  get_crate_data)) |dp| {
-        let (did, path) = *dp;
-        let d = {crate: cnum, node: did.node};
-        p(cstore).mod_path_map.insert(d, @path);
-    }
 }
 
 fn have_crate_data(cstore: CStore, cnum: ast::crate_num) -> bool {
@@ -134,10 +128,10 @@ fn add_used_crate_file(cstore: CStore, lib: &Path) {
 }
 
 fn get_used_crate_files(cstore: CStore) -> ~[Path] {
-    return p(cstore).used_crate_files;
+    return /*bad*/copy p(cstore).used_crate_files;
 }
 
-fn add_used_library(cstore: CStore, lib: ~str) -> bool {
+fn add_used_library(cstore: CStore, +lib: ~str) -> bool {
     assert lib != ~"";
 
     if vec::contains(p(cstore).used_libraries, &lib) { return false; }
@@ -146,7 +140,7 @@ fn add_used_library(cstore: CStore, lib: ~str) -> bool {
 }
 
 fn get_used_libraries(cstore: CStore) -> ~[~str] {
-    return p(cstore).used_libraries;
+    return /*bad*/copy p(cstore).used_libraries;
 }
 
 fn add_used_link_args(cstore: CStore, args: ~str) {
@@ -154,7 +148,7 @@ fn add_used_link_args(cstore: CStore, args: ~str) {
 }
 
 fn get_used_link_args(cstore: CStore) -> ~[~str] {
-    return p(cstore).used_link_args;
+    return /*bad*/copy p(cstore).used_link_args;
 }
 
 fn add_use_stmt_cnum(cstore: CStore, use_id: ast::node_id,
@@ -177,7 +171,7 @@ fn get_dep_hashes(cstore: CStore) -> ~[~str] {
         let cdata = cstore::get_crate_data(cstore, cnum);
         let hash = decoder::get_crate_hash(cdata.data);
         debug!("Add hash[%s]: %s", cdata.name, hash);
-        result.push({name: cdata.name, hash: hash});
+        result.push({name: /*bad*/copy cdata.name, hash: hash});
     };
     pure fn lteq(a: &crate_hash, b: &crate_hash) -> bool {a.name <= b.name}
     let sorted = std::sort::merge_sort(result, lteq);
@@ -185,14 +179,10 @@ fn get_dep_hashes(cstore: CStore) -> ~[~str] {
     for sorted.each |x| {
         debug!("  hash[%s]: %s", x.name, x.hash);
     }
-    fn mapper(ch: &crate_hash) -> ~str { return ch.hash; }
+    fn mapper(ch: &crate_hash) -> ~str { return /*bad*/copy ch.hash; }
     return vec::map(sorted, mapper);
 }
 
-fn get_path(cstore: CStore, d: ast::def_id) -> ~[~str] {
-    option::map_default(&p(cstore).mod_path_map.find(d), ~[],
-                        |ds| str::split_str(**ds, ~"::"))
-}
 // Local Variables:
 // mode: rust
 // fill-column: 78;
index 726bc5f95902fced3baaa4e1c2542ba76c553642..081a92f686b9a7a80df36bb6c4df067f6700af3f 100644 (file)
@@ -8,20 +8,33 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // Decoding metadata from a single crate's metadata
 
+use core::prelude::*;
+
 use cmd = metadata::cstore::crate_metadata;
 use dvec::DVec;
 use hash::{Hash, HashUtil};
 use io::WriterUtil;
 use metadata::common::*;
 use metadata::csearch::{ProvidedTraitMethodInfo, StaticMethodInfo};
+use metadata::csearch;
+use metadata::cstore;
+use metadata::decoder;
 use metadata::tydecode::{parse_ty_data, parse_def_id, parse_bounds_data};
 use metadata::tydecode::{parse_ident};
 use middle::ty;
 use util::ppaux::ty_to_str;
 
-use reader = std::ebml::reader;
+use core::cmp;
+use core::dvec;
+use core::int;
+use core::io;
+use core::option;
+use core::str;
+use core::vec;
+use std::ebml::reader;
 use std::ebml;
 use std::map::HashMap;
 use std::map;
 export get_method_names_if_trait;
 export get_type_name_if_impl;
 export get_item_attrs;
-export get_crate_module_paths;
 export def_like;
 export dl_def;
 export dl_impl;
 export dl_field;
 export path_entry;
+export each_lang_item;
 export each_path;
 export get_item_path;
 export maybe_find_item; // sketchy
@@ -462,13 +475,30 @@ struct path_entry {
     def_like: def_like,
 }
 
-fn path_entry(path_string: ~str, def_like: def_like) -> path_entry {
+fn path_entry(+path_string: ~str, def_like: def_like) -> path_entry {
     path_entry {
         path_string: path_string,
         def_like: def_like
     }
 }
 
+/// Iterates over the language items in the given crate.
+fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) {
+    let root = reader::Doc(cdata.data);
+    let lang_items = reader::get_doc(root, tag_lang_items);
+    for reader::tagged_docs(lang_items, tag_lang_items_item) |item_doc| {
+        let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
+        let id = reader::doc_as_u32(id_doc) as uint;
+        let node_id_doc = reader::get_doc(item_doc,
+                                          tag_lang_items_item_node_id);
+        let node_id = reader::doc_as_u32(node_id_doc) as ast::node_id;
+
+        if !f(node_id, id) {
+            break;
+        }
+    }
+}
+
 /// Iterates over all the paths in the given crate.
 fn each_path(intr: @ident_interner, cdata: cmd,
              get_crate_data: GetCrateDataCb,
@@ -493,7 +523,8 @@ fn each_path(intr: @ident_interner, cdata: cmd,
                 let def_like = item_to_def_like(item_doc, def_id, cdata.cnum);
 
                 // Hand the information off to the iteratee.
-                let this_path_entry = path_entry(path, def_like);
+                // XXX: Bad copy.
+                let this_path_entry = path_entry(copy path, def_like);
                 if !f(this_path_entry) {
                     broken = true;      // XXX: This is awful.
                 }
@@ -581,7 +612,7 @@ fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt,
     let item_doc = lookup_item(id, cdata.data);
     let path = vec::init(item_path(intr, item_doc));
     match decode_inlined_item(cdata, tcx, path, item_doc) {
-      Some(ref ii) => csearch::found((*ii)),
+      Some(ref ii) => csearch::found((/*bad*/copy *ii)),
       None => {
         match item_parent_item(item_doc) {
           Some(did) => {
@@ -589,7 +620,7 @@ fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt,
             let parent_item = lookup_item(did.node, cdata.data);
             match decode_inlined_item(cdata, tcx, path,
                                                parent_item) {
-              Some(ref ii) => csearch::found_parent(did, (*ii)),
+              Some(ref ii) => csearch::found_parent(did, (/*bad*/copy *ii)),
               None => csearch::not_found
             }
           }
@@ -728,7 +759,7 @@ fn get_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id,
         let ty = doc_type(mth, tcx, cdata);
         let def_id = item_def_id(mth, cdata);
         let fty = match ty::get(ty).sty {
-          ty::ty_fn(ref f) => (*f),
+          ty::ty_fn(ref f) => (/*bad*/copy *f),
           _ => {
             tcx.diag.handler().bug(
                 ~"get_trait_methods: id has non-function type");
@@ -759,7 +790,7 @@ fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
 
         let fty;
         match ty::get(ty).sty {
-            ty::ty_fn(ref f) => fty = (*f),
+            ty::ty_fn(ref f) => fty = (/*bad*/copy *f),
             _ => {
                 tcx.diag.handler().bug(~"get_provided_trait_methods(): id \
                                          has non-function type");
@@ -1000,9 +1031,10 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] {
             assert (vec::len(meta_items) == 1u);
             let meta_item = meta_items[0];
             attrs.push(
-                {node: {style: ast::attr_outer, value: *meta_item,
-                        is_sugared_doc: false},
-                 span: ast_util::dummy_sp()});
+                ast::spanned { node: { style: ast::attr_outer,
+                                       value: /*bad*/copy *meta_item,
+                                       is_sugared_doc: false },
+                               span: ast_util::dummy_sp()});
         };
       }
       option::None => ()
@@ -1075,52 +1107,25 @@ fn get_crate_vers(data: @~[u8]) -> ~str {
     let attrs = decoder::get_crate_attributes(data);
     return match attr::last_meta_item_value_str_by_name(
         attr::find_linkage_metas(attrs), ~"vers") {
-      Some(ref ver) => (*ver),
+      Some(ref ver) => (/*bad*/copy *ver),
       None => ~"0.0"
     };
 }
 
 fn iter_crate_items(intr: @ident_interner, cdata: cmd,
                     get_crate_data: GetCrateDataCb,
-                    proc: fn(~str, ast::def_id)) {
+                    proc: fn(+path: ~str, ast::def_id)) {
     for each_path(intr, cdata, get_crate_data) |path_entry| {
         match path_entry.def_like {
             dl_impl(*) | dl_field => {}
             dl_def(def) => {
-                proc(path_entry.path_string, ast_util::def_id_of_def(def))
+                proc(/*bad*/copy path_entry.path_string,
+                     ast_util::def_id_of_def(def))
             }
         }
     }
 }
 
-fn get_crate_module_paths(intr: @ident_interner, cdata: cmd,
-                          get_crate_data: GetCrateDataCb)
-                                    -> ~[(ast::def_id, ~str)] {
-    fn mod_of_path(p: ~str) -> ~str {
-        str::connect(vec::init(str::split_str(p, ~"::")), ~"::")
-    }
-
-    // find all module (path, def_ids), which are not
-    // fowarded path due to renamed import or reexport
-    let mut res = ~[];
-    let mods = map::HashMap();
-    do iter_crate_items(intr, cdata, get_crate_data) |path, did| {
-        let m = mod_of_path(path);
-        if str::is_not_empty(m) {
-            // if m has a sub-item, it must be a module
-            mods.insert(m, true);
-        }
-        // Collect everything by now. There might be multiple
-        // paths pointing to the same did. Those will be
-        // unified later by using the mods map
-        res.push((did, path));
-    }
-    return do vec::filter(res) |x| {
-        let (_, xp) = *x;
-        mods.contains_key(xp)
-    }
-}
-
 fn list_crate_metadata(intr: @ident_interner, bytes: @~[u8],
                        out: io::Writer) {
     let hash = get_crate_hash(bytes);
index ab6992c1283bc3f1bbc5b6b3842a016a1cbe02f5..6d131a074eb1616fed6791d2f05ee7c6bb9a693f 100644 (file)
@@ -8,30 +8,47 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // Metadata encoding
 
+use core::prelude::*;
+
+use metadata::common::*;
+use metadata::csearch;
+use metadata::cstore;
+use metadata::decoder;
+use metadata::tyencode;
+use middle::resolve;
+use middle::ty::node_id_to_type;
+use middle::ty;
+use middle;
 use util::ppaux::ty_to_str;
 
-use std::{ebml, map};
+use core::dvec;
+use core::flate;
+use core::float;
+use core::hash::{Hash, HashUtil};
+use core::int;
+use core::io::WriterUtil;
+use core::io;
+use core::str::to_bytes;
+use core::str;
+use core::to_bytes::IterBytes;
+use core::uint;
+use core::vec;
 use std::map::HashMap;
-use io::WriterUtil;
-use writer = std::ebml::writer;
+use std::{ebml, map};
+use std;
 use syntax::ast::*;
-use syntax::print::pprust;
-use syntax::{ast_util, visit};
-use syntax::ast_util::*;
-use metadata::common::*;
-use middle::ty;
-use middle::ty::node_id_to_type;
-use middle::resolve;
+use syntax::ast;
 use syntax::ast_map;
+use syntax::ast_util::*;
 use syntax::attr;
-use str::to_bytes;
-use syntax::ast;
 use syntax::diagnostic::span_handler;
-
-use hash::{Hash, HashUtil};
-use to_bytes::IterBytes;
+use syntax::print::pprust;
+use syntax::{ast_util, visit};
+use syntax;
+use writer = std::ebml::writer;
 
 export encode_parms;
 export encode_metadata;
@@ -70,6 +87,7 @@
     mut inline_bytes: uint,
     mut attr_bytes: uint,
     mut dep_bytes: uint,
+    mut lang_item_bytes: uint,
     mut item_bytes: uint,
     mut index_bytes: uint,
     mut zero_bytes: uint,
@@ -162,11 +180,12 @@ fn def_to_str(did: def_id) -> ~str { fmt!("%d:%d", did.crate, did.node) }
 
 fn encode_ty_type_param_bounds(ebml_w: writer::Encoder, ecx: @encode_ctxt,
                                params: @~[ty::param_bounds]) {
-    let ty_str_ctxt = @{diag: ecx.diag,
-                        ds: def_to_str,
-                        tcx: ecx.tcx,
-                        reachable: |a| reachable(ecx, a),
-                        abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
+    let ty_str_ctxt = @tyencode::ctxt {
+        diag: ecx.diag,
+        ds: def_to_str,
+        tcx: ecx.tcx,
+        reachable: |a| reachable(ecx, a),
+        abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
     for params.each |param| {
         ebml_w.start_tag(tag_items_data_item_ty_param_bounds);
         tyencode::enc_bounds(ebml_w.writer, ty_str_ctxt, *param);
@@ -189,23 +208,23 @@ fn encode_variant_id(ebml_w: writer::Encoder, vid: def_id) {
 }
 
 fn write_type(ecx: @encode_ctxt, ebml_w: writer::Encoder, typ: ty::t) {
-    let ty_str_ctxt =
-        @{diag: ecx.diag,
-          ds: def_to_str,
-          tcx: ecx.tcx,
-          reachable: |a| reachable(ecx, a),
-          abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
+    let ty_str_ctxt = @tyencode::ctxt {
+        diag: ecx.diag,
+        ds: def_to_str,
+        tcx: ecx.tcx,
+        reachable: |a| reachable(ecx, a),
+        abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
     tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
 }
 
 fn write_vstore(ecx: @encode_ctxt, ebml_w: writer::Encoder,
                 vstore: ty::vstore) {
-    let ty_str_ctxt =
-        @{diag: ecx.diag,
-          ds: def_to_str,
-          tcx: ecx.tcx,
-          reachable: |a| reachable(ecx, a),
-          abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
+    let ty_str_ctxt = @tyencode::ctxt {
+        diag: ecx.diag,
+        ds: def_to_str,
+        tcx: ecx.tcx,
+        reachable: |a| reachable(ecx, a),
+        abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
     tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
 }
 
@@ -218,7 +237,7 @@ fn encode_type(ecx: @encode_ctxt, ebml_w: writer::Encoder, typ: ty::t) {
 fn encode_symbol(ecx: @encode_ctxt, ebml_w: writer::Encoder, id: node_id) {
     ebml_w.start_tag(tag_items_data_item_symbol);
     let sym = match ecx.item_symbols.find(id) {
-      Some(ref x) => (*x),
+      Some(ref x) => (/*bad*/copy *x),
       None => {
         ecx.diag.handler().bug(
             fmt!("encode_symbol: id not found %d", id));
@@ -265,7 +284,7 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: writer::Encoder,
         encode_type(ecx, ebml_w,
                     node_id_to_type(ecx.tcx, variant.node.id));
         match variant.node.kind {
-            ast::tuple_variant_kind(args)
+            ast::tuple_variant_kind(ref args)
                     if args.len() > 0 && ty_params.len() == 0 => {
                 encode_symbol(ecx, ebml_w, variant.node.id);
             }
@@ -277,8 +296,9 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: writer::Encoder,
             encode_disr_val(ecx, ebml_w, vi[i].disr_val);
             disr_val = vi[i].disr_val;
         }
-        encode_type_param_bounds(ebml_w, ecx, ty_params);
-        encode_path(ecx, ebml_w, path, ast_map::path_name(variant.node.name));
+        encode_type_param_bounds(ebml_w, ecx, /*bad*/copy ty_params);
+        encode_path(ecx, ebml_w, /*bad*/copy path,
+                    ast_map::path_name(variant.node.name));
         ebml_w.end_tag();
         disr_val += 1;
         i += 1;
@@ -307,7 +327,7 @@ fn encode_path_elt(ecx: @encode_ctxt, ebml_w: writer::Encoder,
 }
 
 fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: writer::Encoder,
-                       md: _mod, id: node_id, path: ast_map::path,
+                       md: _mod, id: node_id, +path: ast_map::path,
                        name: ident) {
     ebml_w.start_tag(tag_items_data_item);
     encode_def_id(ebml_w, local_def(id));
@@ -434,7 +454,8 @@ fn encode_info_for_struct(ecx: @encode_ctxt, ebml_w: writer::Encoder,
                        tcx.sess.str_of(nm), id);
                 encode_visibility(ebml_w, vis);
                 encode_name(ecx, ebml_w, nm);
-                encode_path(ecx, ebml_w, path, ast_map::path_name(nm));
+                encode_path(ecx, ebml_w, /*bad*/copy path,
+                            ast_map::path_name(nm));
                 encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
                 encode_mutability(ebml_w, mt);
                 encode_def_id(ebml_w, local_def(id));
@@ -443,13 +464,13 @@ fn encode_info_for_struct(ecx: @encode_ctxt, ebml_w: writer::Encoder,
             unnamed_field => {}
         }
     }
-    *index
+    /*bad*/copy *index
 }
 
 // This is for encoding info for ctors and dtors
 fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder,
-                        id: node_id, ident: ident, path: ast_map::path,
-                        item: Option<inlined_item>, tps: ~[ty_param]) {
+                        id: node_id, ident: ident, +path: ast_map::path,
+                        item: Option<inlined_item>, +tps: ~[ty_param]) {
         ebml_w.start_tag(tag_items_data_item);
         encode_name(ecx, ebml_w, ident);
         encode_def_id(ebml_w, local_def(id));
@@ -458,9 +479,10 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder,
         let its_ty = node_id_to_type(ecx.tcx, id);
         debug!("fn name = %s ty = %s its node id = %d",
                ecx.tcx.sess.str_of(ident),
-               util::ppaux::ty_to_str(ecx.tcx, its_ty), id);
+               ty_to_str(ecx.tcx, its_ty), id);
         encode_type(ecx, ebml_w, its_ty);
-        encode_path(ecx, ebml_w, path, ast_map::path_name(ident));
+        // XXX: Bad copy.
+        encode_path(ecx, ebml_w, copy path, ast_map::path_name(ident));
         match item {
            Some(ref it) => {
              (ecx.encode_inlined_item)(ecx, ebml_w, path, (*it));
@@ -472,10 +494,13 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: writer::Encoder,
         ebml_w.end_tag();
 }
 
-fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: writer::Encoder,
-                          impl_path: ast_map::path, should_inline: bool,
+fn encode_info_for_method(ecx: @encode_ctxt,
+                          ebml_w: writer::Encoder,
+                          +impl_path: ast_map::path,
+                          should_inline: bool,
                           parent_id: node_id,
-                          m: @method, all_tps: ~[ty_param]) {
+                          m: @method,
+                          +all_tps: ~[ty_param]) {
     debug!("encode_info_for_method: %d %s %u", m.id,
            ecx.tcx.sess.str_of(m.ident), all_tps.len());
     ebml_w.start_tag(tag_items_data_item);
@@ -486,12 +511,14 @@ fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: writer::Encoder,
         }
         _ => encode_family(ebml_w, purity_fn_family(m.purity))
     }
+    let len = all_tps.len();
     encode_type_param_bounds(ebml_w, ecx, all_tps);
     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
     encode_name(ecx, ebml_w, m.ident);
-    encode_path(ecx, ebml_w, impl_path, ast_map::path_name(m.ident));
+    // XXX: Bad copy.
+    encode_path(ecx, ebml_w, copy impl_path, ast_map::path_name(m.ident));
     encode_self_type(ebml_w, m.self_ty.node);
-    if all_tps.len() > 0u || should_inline {
+    if len > 0u || should_inline {
         (ecx.encode_inlined_item)(
            ecx, ebml_w, impl_path,
            ii_method(local_def(parent_id), m));
@@ -529,7 +556,7 @@ fn should_inline(attrs: ~[attribute]) -> bool {
 
 fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
                         item: @item, index: @mut ~[entry<int>],
-                        path: ast_map::path) {
+                        +path: ast_map::path) {
 
     let tcx = ecx.tcx;
     let must_write =
@@ -549,7 +576,7 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
     debug!("encoding info for item at %s",
            ecx.tcx.sess.codemap.span_to_str(item.span));
 
-    match item.node {
+    match /*bad*/copy item.node {
       item_const(_, _) => {
         add_to_index();
         ebml_w.start_tag(tag_items_data_item);
@@ -565,11 +592,13 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, local_def(item.id));
         encode_family(ebml_w, purity_fn_family(purity));
+        let tps_len = tps.len();
         encode_type_param_bounds(ebml_w, ecx, tps);
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
-        encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
-        encode_attributes(ebml_w, item.attrs);
-        if tps.len() > 0u || should_inline(item.attrs) {
+        // XXX: Bad copy.
+        encode_path(ecx, ebml_w, copy path, ast_map::path_name(item.ident));
+        encode_attributes(ebml_w, /*bad*/copy item.attrs);
+        if tps_len > 0u || should_inline(item.attrs) {
             (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
         } else {
             encode_symbol(ecx, ebml_w, item.id);
@@ -601,36 +630,39 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
         encode_region_param(ecx, ebml_w, item);
         ebml_w.end_tag();
       }
-      item_enum(ref enum_definition, tps) => {
+      item_enum(ref enum_definition, ref tps) => {
         add_to_index();
         do ebml_w.wr_tag(tag_items_data_item) {
             encode_def_id(ebml_w, local_def(item.id));
             encode_family(ebml_w, 't');
-            encode_type_param_bounds(ebml_w, ecx, tps);
+            encode_type_param_bounds(ebml_w, ecx, /*bad*/copy *tps);
             encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
             encode_name(ecx, ebml_w, item.ident);
             for (*enum_definition).variants.each |v| {
                 encode_variant_id(ebml_w, local_def(v.node.id));
             }
-            (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
-            encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
+            (ecx.encode_inlined_item)(ecx, ebml_w, /*bad*/copy path,
+                                      ii_item(item));
+            encode_path(ecx, ebml_w, /*bad*/copy path,
+                        ast_map::path_name(item.ident));
             encode_region_param(ecx, ebml_w, item);
         }
         encode_enum_variant_info(ecx,
                                  ebml_w,
                                  item.id,
-                                 (*enum_definition).variants,
+                                 /*bad*/copy (*enum_definition).variants,
                                  path,
                                  index,
-                                 tps);
+                                 /*bad*/copy *tps);
       }
       item_struct(struct_def, tps) => {
         /* First, encode the fields
            These come first because we need to write them to make
            the index, and the index needs to be in the item for the
            class itself */
-        let idx = encode_info_for_struct(ecx, ebml_w, path,
-                                        struct_def.fields, index);
+        // XXX: Bad copy of `path`.
+        let idx = encode_info_for_struct(ecx, ebml_w, copy path,
+                                        /*bad*/copy struct_def.fields, index);
         /* Encode the dtor */
         do struct_def.dtor.iter |dtor| {
             index.push({val: dtor.node.id, pos: ebml_w.writer.tell()});
@@ -638,10 +670,10 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
                                ecx.tcx.sess.ident_of(
                                    ecx.tcx.sess.str_of(item.ident) +
                                    ~"_dtor"),
-                               path, if tps.len() > 0u {
+                               /*bad*/copy path, if tps.len() > 0u {
                                    Some(ii_dtor(*dtor, item.ident, tps,
                                                 local_def(item.id))) }
-                               else { None }, tps);
+                               else { None }, /*bad*/copy tps);
         }
 
         /* Index the class*/
@@ -690,10 +722,11 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
         encode_def_id(ebml_w, local_def(item.id));
         encode_family(ebml_w, 'i');
         encode_region_param(ecx, ebml_w, item);
-        encode_type_param_bounds(ebml_w, ecx, tps);
+        // XXX: Bad copy.
+        encode_type_param_bounds(ebml_w, ecx, copy tps);
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
         encode_name(ecx, ebml_w, item.ident);
-        encode_attributes(ebml_w, item.attrs);
+        encode_attributes(ebml_w, /*bad*/copy item.attrs);
         match ty.node {
             ast::ty_path(path, _) if path.idents.len() == 1 => {
                 encode_impl_type_basename(ecx, ebml_w,
@@ -710,19 +743,21 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
         do opt_trait.iter() |associated_trait| {
            encode_trait_ref(ebml_w, ecx, *associated_trait);
         }
-        encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
+        // XXX: Bad copy.
+        encode_path(ecx, ebml_w, copy path, ast_map::path_name(item.ident));
         ebml_w.end_tag();
 
         let impl_path = vec::append_one(path,
                                         ast_map::path_name(item.ident));
         for methods.each |m| {
             index.push({val: m.id, pos: ebml_w.writer.tell()});
-            encode_info_for_method(ecx, ebml_w, impl_path,
-                                   should_inline(m.attrs), item.id, *m,
-                                   vec::append(tps, m.tps));
+            encode_info_for_method(ecx, ebml_w, /*bad*/copy impl_path,
+                                   should_inline(/*bad*/copy m.attrs),
+                                   item.id, *m,
+                                   vec::append(/*bad*/copy tps, m.tps));
         }
       }
-      item_trait(tps, traits, ref ms) => {
+      item_trait(ref tps, ref traits, ref ms) => {
         let provided_methods = dvec::DVec();
 
         add_to_index();
@@ -730,10 +765,10 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
         encode_def_id(ebml_w, local_def(item.id));
         encode_family(ebml_w, 'I');
         encode_region_param(ecx, ebml_w, item);
-        encode_type_param_bounds(ebml_w, ecx, tps);
+        encode_type_param_bounds(ebml_w, ecx, /*bad*/copy *tps);
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
         encode_name(ecx, ebml_w, item.ident);
-        encode_attributes(ebml_w, item.attrs);
+        encode_attributes(ebml_w, /*bad*/copy item.attrs);
         let mut i = 0u;
         for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| {
             match (*ms)[i] {
@@ -741,8 +776,9 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
                 ebml_w.start_tag(tag_item_trait_method);
                 encode_def_id(ebml_w, local_def((*ty_m).id));
                 encode_name(ecx, ebml_w, mty.ident);
-                encode_type_param_bounds(ebml_w, ecx, (*ty_m).tps);
-                encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
+                encode_type_param_bounds(ebml_w, ecx,
+                                         /*bad*/copy (*ty_m).tps);
+                encode_type(ecx, ebml_w, ty::mk_fn(tcx, /*bad*/copy mty.fty));
                 encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity));
                 encode_self_type(ebml_w, mty.self_ty);
                 encode_method_sort(ebml_w, 'r');
@@ -754,8 +790,8 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
                 ebml_w.start_tag(tag_item_trait_method);
                 encode_def_id(ebml_w, local_def(m.id));
                 encode_name(ecx, ebml_w, mty.ident);
-                encode_type_param_bounds(ebml_w, ecx, m.tps);
-                encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
+                encode_type_param_bounds(ebml_w, ecx, /*bad*/copy m.tps);
+                encode_type(ecx, ebml_w, ty::mk_fn(tcx, /*bad*/copy mty.fty));
                 encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity));
                 encode_self_type(ebml_w, mty.self_ty);
                 encode_method_sort(ebml_w, 'p');
@@ -764,7 +800,8 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
             }
             i += 1u;
         }
-        encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
+        // XXX: Bad copy.
+        encode_path(ecx, ebml_w, copy path, ast_map::path_name(item.ident));
         for traits.each |associated_trait| {
            encode_trait_ref(ebml_w, ecx, *associated_trait)
         }
@@ -790,7 +827,7 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
             let polyty = ecx.tcx.tcache.get(local_def(ty_m.id));
             encode_ty_type_param_bounds(ebml_w, ecx, polyty.bounds);
             encode_type(ecx, ebml_w, polyty.ty);
-            let m_path = vec::append_one(path,
+            let m_path = vec::append_one(/*bad*/copy path,
                                          ast_map::path_name(item.ident));
             encode_path(ecx, ebml_w, m_path, ast_map::path_name(ty_m.ident));
             ebml_w.end_tag();
@@ -799,30 +836,33 @@ fn add_to_index_(item: @item, ebml_w: writer::Encoder,
         // Finally, output all the provided methods as items.
         for provided_methods.each |m| {
             index.push({val: m.id, pos: ebml_w.writer.tell()});
-            encode_info_for_method(ecx, ebml_w, path, true, item.id, *m,
-                                   m.tps);
+            encode_info_for_method(ecx, ebml_w, /*bad*/copy path,
+                                   true, item.id, *m, /*bad*/copy m.tps);
         }
       }
       item_mac(*) => fail ~"item macros unimplemented"
     }
 }
 
-fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
+fn encode_info_for_foreign_item(ecx: @encode_ctxt,
+                                ebml_w: writer::Encoder,
                                 nitem: @foreign_item,
                                 index: @mut ~[entry<int>],
-                                path: ast_map::path, abi: foreign_abi) {
+                                +path: ast_map::path,
+                                abi: foreign_abi) {
     if !reachable(ecx, nitem.id) { return; }
     index.push({val: nitem.id, pos: ebml_w.writer.tell()});
 
     ebml_w.start_tag(tag_items_data_item);
-    match nitem.node {
+    match /*bad*/copy nitem.node {
       foreign_item_fn(_, purity, tps) => {
         encode_def_id(ebml_w, local_def(nitem.id));
         encode_family(ebml_w, purity_fn_family(purity));
         encode_type_param_bounds(ebml_w, ecx, tps);
         encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
         if abi == foreign_abi_rust_intrinsic {
-            (ecx.encode_inlined_item)(ecx, ebml_w, path,
+            // XXX: Bad copy of `path`.
+            (ecx.encode_inlined_item)(ecx, ebml_w, copy path,
                                       ii_foreign(nitem));
         } else {
             encode_symbol(ecx, ebml_w, nitem.id);
@@ -848,13 +888,13 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder,
     encode_info_for_mod(ecx, ebml_w, crate.node.module,
                         crate_node_id, ~[],
                         syntax::parse::token::special_idents::invalid);
-    visit::visit_crate(*crate, (), visit::mk_vt(@{
+    visit::visit_crate(*crate, (), visit::mk_vt(@visit::Visitor {
         visit_expr: |_e, _cx, _v| { },
         visit_item: |i, cx, v, copy ebml_w| {
             visit::visit_item(i, cx, v);
             match ecx.tcx.items.get(i.id) {
               ast_map::node_item(_, pt) => {
-                encode_info_for_item(ecx, ebml_w, i, index, *pt);
+                encode_info_for_item(ecx, ebml_w, i, index, /*bad*/copy *pt);
               }
               _ => fail ~"bad item"
             }
@@ -864,7 +904,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder,
             match ecx.tcx.items.get(ni.id) {
               ast_map::node_foreign_item(_, abi, pt) => {
                 encode_info_for_foreign_item(ecx, ebml_w, ni,
-                                             index, *pt, abi);
+                                             index, /*bad*/copy *pt, abi);
               }
               // case for separate item and foreign-item tables
               _ => fail ~"bad foreign item"
@@ -873,7 +913,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder,
         ,.. *visit::default_visitor()
     }));
     ebml_w.end_tag();
-    return *index;
+    return /*bad*/copy *index;
 }
 
 
@@ -890,7 +930,7 @@ fn create_index<T: Copy Hash IterBytes>(index: ~[entry<T>]) ->
 
     let mut buckets_frozen = ~[];
     for buckets.each |bucket| {
-        buckets_frozen.push(@**bucket);
+        buckets_frozen.push(@/*bad*/copy **bucket);
     }
     return buckets_frozen;
 }
@@ -954,7 +994,7 @@ fn encode_meta_item(ebml_w: writer::Encoder, mi: meta_item) {
           _ => {/* FIXME (#623): encode other variants */ }
         }
       }
-      meta_list(ref name, items) => {
+      meta_list(ref name, ref items) => {
         ebml_w.start_tag(tag_meta_item_list);
         ebml_w.start_tag(tag_meta_item_name);
         ebml_w.writer.write(str::to_bytes((*name)));
@@ -983,16 +1023,18 @@ fn encode_attributes(ebml_w: writer::Encoder, attrs: ~[attribute]) {
 // them in anyway with default values.
 fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] {
 
-    fn synthesize_link_attr(ecx: @encode_ctxt, items: ~[@meta_item]) ->
+    fn synthesize_link_attr(ecx: @encode_ctxt, +items: ~[@meta_item]) ->
        attribute {
 
         assert (ecx.link_meta.name != ~"");
         assert (ecx.link_meta.vers != ~"");
 
         let name_item =
-            attr::mk_name_value_item_str(~"name", ecx.link_meta.name);
+            attr::mk_name_value_item_str(~"name",
+                                         /*bad*/copy ecx.link_meta.name);
         let vers_item =
-            attr::mk_name_value_item_str(~"vers", ecx.link_meta.vers);
+            attr::mk_name_value_item_str(~"vers",
+                                         /*bad*/copy ecx.link_meta.vers);
 
         let other_items =
             {
@@ -1011,14 +1053,14 @@ fn synthesize_link_attr(ecx: @encode_ctxt, items: ~[@meta_item]) ->
     for crate.node.attrs.each |attr| {
         attrs.push(
             if attr::get_attr_name(*attr) != ~"link" {
-                *attr
+                /*bad*/copy *attr
             } else {
-                match attr.node.value.node {
+                match /*bad*/copy attr.node.value.node {
                   meta_list(_, l) => {
                     found_link_attr = true;;
                     synthesize_link_attr(ecx, l)
                   }
-                  _ => *attr
+                  _ => /*bad*/copy *attr
                 }
             });
     }
@@ -1040,7 +1082,8 @@ fn get_ordered_deps(ecx: @encode_ctxt, cstore: cstore::CStore)
         // Pull the cnums and name,vers,hash out of cstore
         let mut deps: ~[numdep] = ~[];
         do cstore::iter_crate_data(cstore) |key, val| {
-            let dep = {cnum: key, name: ecx.tcx.sess.ident_of(val.name),
+            let dep = {cnum: key,
+                       name: ecx.tcx.sess.ident_of(/*bad*/copy val.name),
                        vers: decoder::get_crate_vers(val.data),
                        hash: decoder::get_crate_hash(val.data)};
             deps.push(dep);
@@ -1074,6 +1117,30 @@ fn get_ordered_deps(ecx: @encode_ctxt, cstore: cstore::CStore)
     ebml_w.end_tag();
 }
 
+fn encode_lang_items(ecx: @encode_ctxt, ebml_w: writer::Encoder) {
+    ebml_w.start_tag(tag_lang_items);
+
+    for ecx.tcx.lang_items.each_item |def_id, i| {
+        if def_id.crate != local_crate {
+            loop;
+        }
+
+        ebml_w.start_tag(tag_lang_items_item);
+
+        ebml_w.start_tag(tag_lang_items_item_id);
+        ebml_w.writer.write_be_u32(i as u32);
+        ebml_w.end_tag();   // tag_lang_items_item_id
+
+        ebml_w.start_tag(tag_lang_items_item_node_id);
+        ebml_w.writer.write_be_u32(def_id.node as u32);
+        ebml_w.end_tag();   // tag_lang_items_item_node_id
+
+        ebml_w.end_tag();   // tag_lang_items_item
+    }
+
+    ebml_w.end_tag();   // tag_lang_items
+}
+
 fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: writer::Encoder,
                     dep: decoder::crate_dep) {
     ebml_w.start_tag(tag_crate_dep);
@@ -1108,6 +1175,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
         {mut inline_bytes: 0,
          mut attr_bytes: 0,
          mut dep_bytes: 0,
+         mut lang_item_bytes: 0,
          mut item_bytes: 0,
          mut index_bytes: 0,
          mut zero_bytes: 0,
@@ -1121,7 +1189,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
         reexports2: parms.reexports2,
         item_symbols: parms.item_symbols,
         discrim_symbols: parms.discrim_symbols,
-        link_meta: parms.link_meta,
+        link_meta: /*bad*/copy parms.link_meta,
         cstore: parms.cstore,
         encode_inlined_item: parms.encode_inlined_item,
         type_abbrevs: ty::new_ty_hash()
@@ -1129,7 +1197,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
 
     let ebml_w = writer::Encoder(wr as io::Writer);
 
-    encode_hash(ebml_w, ecx.link_meta.extras_hash);
+    encode_hash(ebml_w, /*bad*/copy ecx.link_meta.extras_hash);
 
     let mut i = wr.pos;
     let crate_attrs = synthesize_crate_attrs(ecx, crate);
@@ -1140,6 +1208,11 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
     encode_crate_deps(ecx, ebml_w, ecx.cstore);
     ecx.stats.dep_bytes = wr.pos - i;
 
+    // Encode the language items.
+    i = wr.pos;
+    encode_lang_items(ecx, ebml_w);
+    ecx.stats.lang_item_bytes = wr.pos - i;
+
     // Encode and index the items.
     ebml_w.start_tag(tag_items);
     i = wr.pos;
@@ -1169,6 +1242,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
         io::println(fmt!("    inline bytes: %u", ecx.stats.inline_bytes));
         io::println(fmt!(" attribute bytes: %u", ecx.stats.attr_bytes));
         io::println(fmt!("       dep bytes: %u", ecx.stats.dep_bytes));
+        io::println(fmt!(" lang item bytes: %u", ecx.stats.lang_item_bytes));
         io::println(fmt!("      item bytes: %u", ecx.stats.item_bytes));
         io::println(fmt!("     index bytes: %u", ecx.stats.index_bytes));
         io::println(fmt!("      zero bytes: %u", ecx.stats.zero_bytes));
@@ -1194,11 +1268,12 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
 
 // Get the encoded string for a type
 fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> ~str {
-    let cx = @{diag: tcx.diag,
-               ds: def_to_str,
-               tcx: tcx,
-               reachable: |_id| false,
-               abbrevs: tyencode::ac_no_abbrevs};
+    let cx = @tyencode::ctxt {
+        diag: tcx.diag,
+        ds: def_to_str,
+        tcx: tcx,
+        reachable: |_id| false,
+        abbrevs: tyencode::ac_no_abbrevs};
     do io::with_str_writer |wr| {
         tyencode::enc_ty(wr, cx, t);
     }
index be4968636f158aa03d2d4b2e1a990df252ebcce2..15c0a1944ea42829bc18564760b44ad8c591b070 100644 (file)
@@ -8,11 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // A module for searching for libraries
 // FIXME (#2658): I'm not happy how this module turned out. Should
 // probably just be folded into cstore.
 
-use result::Result;
+use core::prelude::*;
+
+use core::option;
+use core::os;
+use core::result::Result;
+use core::result;
+use core::str;
+
 export FileSearch;
 export mk_filesearch;
 export pick;
@@ -40,24 +48,24 @@ trait FileSearch {
 
 fn mk_filesearch(maybe_sysroot: Option<Path>,
                  target_triple: &str,
-                 addl_lib_search_paths: ~[Path]) -> FileSearch {
+                 +addl_lib_search_paths: ~[Path]) -> FileSearch {
     type filesearch_impl = {sysroot: Path,
                             addl_lib_search_paths: ~[Path],
                             target_triple: ~str};
     impl filesearch_impl: FileSearch {
-        fn sysroot() -> Path { self.sysroot }
+        fn sysroot() -> Path { /*bad*/copy self.sysroot }
         fn lib_search_paths() -> ~[Path] {
-            let mut paths = self.addl_lib_search_paths;
+            let mut paths = /*bad*/copy self.addl_lib_search_paths;
 
             paths.push(
                 make_target_lib_path(&self.sysroot,
                                      self.target_triple));
             match get_cargo_lib_path_nearest() {
-              result::Ok(ref p) => paths.push((*p)),
+              result::Ok(ref p) => paths.push((/*bad*/copy *p)),
               result::Err(_) => ()
             }
             match get_cargo_lib_path() {
-              result::Ok(ref p) => paths.push((*p)),
+              result::Ok(ref p) => paths.push((/*bad*/copy *p)),
               result::Err(_) => ()
             }
             paths
@@ -108,7 +116,7 @@ fn make_target_lib_path(sysroot: &Path,
     sysroot.push_rel(&relative_target_lib_path(target_triple))
 }
 
-fn get_default_sysroot() -> Path {
+fn get_or_default_sysroot() -> Path {
     match os::self_exe_path() {
       option::Some(ref p) => (*p).pop(),
       option::None => fail ~"can't determine value for sysroot"
@@ -117,13 +125,13 @@ fn get_default_sysroot() -> Path {
 
 fn get_sysroot(maybe_sysroot: Option<Path>) -> Path {
     match maybe_sysroot {
-      option::Some(ref sr) => (*sr),
-      option::None => get_default_sysroot()
+      option::Some(ref sr) => (/*bad*/copy *sr),
+      option::None => get_or_default_sysroot()
     }
 }
 
 fn get_cargo_sysroot() -> Result<Path, ~str> {
-    result::Ok(get_default_sysroot().push_many([libdir(), ~"cargo"]))
+    result::Ok(get_or_default_sysroot().push_many([libdir(), ~"cargo"]))
 }
 
 fn get_cargo_root() -> Result<Path, ~str> {
@@ -141,7 +149,7 @@ fn get_cargo_root_nearest() -> Result<Path, ~str> {
         let cwd = os::getcwd();
         let cwd_cargo = cwd.push(".cargo");
         let mut par_cargo = cwd.pop().push(".cargo");
-        let mut rslt = result::Ok(cwd_cargo);
+        let mut rslt = result::Ok(copy cwd_cargo);  // XXX: Bad copy.
 
         if !os::path_is_dir(&cwd_cargo) && cwd_cargo != p {
             while par_cargo != p {
index 5901e58aeb190afb78116c30366397d0ad4d3c2d..58c9a1b90f247729725b16fb862b73d4d957ccfd 100644 (file)
@@ -8,19 +8,35 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 //! Finds crate binaries and loads their metadata
 
-use syntax::diagnostic::span_handler;
-use syntax::{ast, attr};
-use syntax::print::pprust;
-use syntax::codemap::span;
+use core::prelude::*;
+
 use lib::llvm::{False, llvm, mk_object_file, mk_section_iter};
+use metadata::decoder;
+use metadata::encoder;
 use metadata::filesearch::FileSearch;
-use io::WriterUtil;
+use metadata::filesearch;
+use syntax::codemap::span;
+use syntax::diagnostic::span_handler;
 use syntax::parse::token::ident_interner;
+use syntax::print::pprust;
+use syntax::{ast, attr};
+
+use core::cast;
+use core::flate;
+use core::io::WriterUtil;
+use core::io;
+use core::os::consts::{macos, freebsd, linux, android, win32};
+use core::option;
+use core::ptr;
+use core::str;
+use core::uint;
+use core::vec;
 
 export os;
-export os_macos, os_win32, os_linux, os_freebsd;
+export os_macos, os_win32, os_linux, os_freebsd, os_android;
 export ctxt;
 export load_library_crate;
 export list_file_metadata;
@@ -33,6 +49,7 @@ enum os {
     os_macos,
     os_win32,
     os_linux,
+    os_android,
     os_freebsd
 }
 
@@ -50,7 +67,7 @@ enum os {
 
 fn load_library_crate(cx: ctxt) -> {ident: ~str, data: @~[u8]} {
     match find_library_crate(cx) {
-      Some(ref t) => return (*t),
+      Some(ref t) => return (/*bad*/copy *t),
       None => {
         cx.diag.span_fatal(
             cx.span, fmt!("can't find crate for `%s`",
@@ -60,17 +77,22 @@ fn load_library_crate(cx: ctxt) -> {ident: ~str, data: @~[u8]} {
 }
 
 fn find_library_crate(cx: ctxt) -> Option<{ident: ~str, data: @~[u8]}> {
-    attr::require_unique_names(cx.diag, cx.metas);
+    attr::require_unique_names(cx.diag, /*bad*/copy cx.metas);
     find_library_crate_aux(cx, libname(cx), cx.filesearch)
 }
 
 fn libname(cx: ctxt) -> {prefix: ~str, suffix: ~str} {
     if cx.static { return {prefix: ~"lib", suffix: ~".rlib"}; }
-    match cx.os {
-      os_win32 => return {prefix: ~"", suffix: ~".dll"},
-      os_macos => return {prefix: ~"lib", suffix: ~".dylib"},
-      os_linux => return {prefix: ~"lib", suffix: ~".so"},
-      os_freebsd => return {prefix: ~"lib", suffix: ~".so"}
+    let (dll_prefix, dll_suffix) = match cx.os {
+        os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
+        os_macos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
+        os_linux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
+        os_android => (android::DLL_PREFIX, android::DLL_SUFFIX),
+        os_freebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
+    };
+    return {
+        prefix: str::from_slice(dll_prefix),
+        suffix: str::from_slice(dll_suffix)
     }
 }
 
@@ -78,9 +100,9 @@ fn find_library_crate_aux(cx: ctxt,
                           nn: {prefix: ~str, suffix: ~str},
                           filesearch: filesearch::FileSearch) ->
    Option<{ident: ~str, data: @~[u8]}> {
-    let crate_name = crate_name_from_metas(cx.metas);
+    let crate_name = crate_name_from_metas(/*bad*/copy cx.metas);
     let prefix: ~str = nn.prefix + crate_name + ~"-";
-    let suffix: ~str = nn.suffix;
+    let suffix: ~str = /*bad*/copy nn.suffix;
 
     let mut matches = ~[];
     filesearch::search(filesearch, |path| {
@@ -115,7 +137,7 @@ fn find_library_crate_aux(cx: ctxt,
     if matches.is_empty() {
         None
     } else if matches.len() == 1u {
-        Some(matches[0])
+        Some(/*bad*/copy matches[0])
     } else {
         cx.diag.span_err(
             cx.span, fmt!("multiple matching crates for `%s`", crate_name));
@@ -130,12 +152,12 @@ fn find_library_crate_aux(cx: ctxt,
     }
 }
 
-fn crate_name_from_metas(metas: ~[@ast::meta_item]) -> ~str {
+fn crate_name_from_metas(+metas: ~[@ast::meta_item]) -> ~str {
     let name_items = attr::find_meta_items_by_name(metas, ~"name");
     match vec::last_opt(name_items) {
       Some(i) => {
         match attr::get_meta_item_value_str(i) {
-          Some(ref n) => (*n),
+          Some(ref n) => (/*bad*/copy *n),
           // FIXME (#2406): Probably want a warning here since the user
           // is using the wrong type of meta item.
           _ => fail
@@ -153,7 +175,7 @@ fn note_linkage_attrs(intr: @ident_interner, diag: span_handler,
     }
 }
 
-fn crate_matches(crate_data: @~[u8], metas: ~[@ast::meta_item],
+fn crate_matches(crate_data: @~[u8], +metas: ~[@ast::meta_item],
                  hash: ~str) -> bool {
     let attrs = decoder::get_crate_attributes(crate_data);
     let linkage_metas = attr::find_linkage_metas(attrs);
@@ -231,6 +253,7 @@ fn meta_section_name(os: os) -> ~str {
       os_macos => ~"__DATA,__note.rustc",
       os_win32 => ~".note.rustc",
       os_linux => ~".note.rustc",
+      os_android => ~".note.rustc",
       os_freebsd => ~".note.rustc"
     }
 }
index 4ba6abb03831093ee8fc40895c562d13cfb2b25b..25a73b009a94f478e054dea146dbbf3b54ade698 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #[legacy_exports];
+
 export encoder;
 export creader;
 export cstore;
index c7ee052147f9aa8610955cfe13e2a3f9c8fc62c4..927ef29b04fc26b363066f3c6e45081593930fe9 100644 (file)
@@ -8,14 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // Type decoding
 
 // tjc note: Would be great to have a `match check` macro equivalent
 // for some of these
 
+use core::prelude::*;
+
 use middle::ty;
 use middle::ty::{FnTyBase, FnMeta, FnSig};
 
+use core::io;
+use core::str;
+use core::uint;
+use core::vec;
 use syntax::ast;
 use syntax::ast::*;
 use syntax::ast_util;
@@ -85,13 +92,6 @@ fn parse_arg_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt,
     parse_arg(st, conv)
 }
 
-fn parse_ret_ty(st: @pstate, conv: conv_did) -> (ast::ret_style, ty::t) {
-    match peek(st) {
-      '!' => { next(st); (ast::noreturn, ty::mk_bot(st.tcx)) }
-      _ => (ast::return_val, parse_ty(st, conv))
-    }
-}
-
 fn parse_path(st: @pstate) -> @ast::path {
     let mut idents: ~[ast::ident] = ~[];
     fn is_last(c: char) -> bool { return c == '(' || c == ':'; }
@@ -432,14 +432,13 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy {
         inputs.push({mode: mode, ty: parse_ty(st, conv)});
     }
     st.pos += 1u; // eat the ']'
-    let (ret_style, ret_ty) = parse_ret_ty(st, conv);
+    let ret_ty = parse_ty(st, conv);
     return FnTyBase {
         meta: FnMeta {purity: purity,
                       proto: proto,
                       onceness: onceness,
                       bounds: bounds,
-                      region: region,
-                      ret_style: ret_style},
+                      region: region},
         sig: FnSig {inputs: inputs,
                     output: ret_ty}
     };
index 6ceb592f6c9ddc5141211064f814e21ee336aeaf..154fb8d2de85a7346c9b87c4180196846eaa14b8 100644 (file)
@@ -8,15 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // Type encoding
 
-use io::WriterUtil;
+use core::prelude::*;
+
+use middle::ty;
+use middle::ty::Vid;
+
+use core::io::WriterUtil;
+use core::io;
+use core::uint;
+use core::vec;
 use std::map::HashMap;
 use syntax::ast::*;
 use syntax::diagnostic::span_handler;
-use middle::ty;
-use middle::ty::vid;
 use syntax::print::pprust::*;
+use middle::ty::Vid;
 
 export ctxt;
 export ty_abbrev;
@@ -28,7 +36,7 @@
 export enc_arg;
 export enc_vstore;
 
-type ctxt = {
+struct ctxt {
     diag: span_handler,
     // Def -> str Callback:
     ds: fn@(def_id) -> ~str,
@@ -36,7 +44,7 @@
     tcx: ty::ctxt,
     reachable: fn@(node_id) -> bool,
     abbrevs: abbrev_ctxt
-};
+}
 
 // Compact string representation for ty.t values. API ty_str & parse_from_str.
 // Extra parameters are for converting to/from def_ids in the string rep.
@@ -56,12 +64,12 @@ fn enc_ty(w: io::Writer, cx: @ctxt, t: ty::t) {
     match cx.abbrevs {
       ac_no_abbrevs => {
         let result_str = match cx.tcx.short_names_cache.find(t) {
-            Some(s) => *s,
+            Some(s) => /*bad*/copy *s,
             None => {
                 let s = do io::with_str_writer |wr| {
-                    enc_sty(wr, cx, ty::get(t).sty);
+                    enc_sty(wr, cx, /*bad*/copy ty::get(t).sty);
                 };
-                cx.tcx.short_names_cache.insert(t, @s);
+                cx.tcx.short_names_cache.insert(t, @copy s);
                 s
           }
         };
@@ -85,7 +93,7 @@ fn enc_ty(w: io::Writer, cx: @ctxt, t: ty::t) {
               }
               _ => {}
             }
-            enc_sty(w, cx, ty::get(t).sty);
+            enc_sty(w, cx, /*bad*/copy ty::get(t).sty);
             let end = w.tell();
             let len = end - pos;
             fn estimate_sz(u: uint) -> uint {
@@ -183,6 +191,9 @@ fn enc_bound_region(w: io::Writer, cx: @ctxt, br: ty::bound_region) {
         w.write_char('|');
         enc_bound_region(w, cx, *br);
       }
+      ty::br_fresh(id) => {
+        w.write_uint(id);
+      }
     }
 }
 
@@ -206,7 +217,7 @@ fn enc_vstore(w: io::Writer, cx: @ctxt, v: ty::vstore) {
     }
 }
 
-fn enc_sty(w: io::Writer, cx: @ctxt, st: ty::sty) {
+fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
     match st {
       ty::ty_nil => w.write_char('n'),
       ty::ty_bot => w.write_char('z'),
@@ -383,10 +394,7 @@ fn enc_ty_fn(w: io::Writer, cx: @ctxt, ft: ty::FnTy) {
         enc_arg(w, cx, *arg);
     }
     w.write_char(']');
-    match ft.meta.ret_style {
-      noreturn => w.write_char('!'),
-      _ => enc_ty(w, cx, ft.sig.output)
-    }
+    enc_ty(w, cx, ft.sig.output);
 }
 
 fn enc_bounds(w: io::Writer, cx: @ctxt, bs: @~[ty::param_bound]) {
index 40d4bd61668b05947db692b0cdc89e3f785e67e3..eb9d4ae6a30ad29fab5396497ccaff000a45db05 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use c = metadata::common;
 use cstore = metadata::cstore;
 use driver::session::Session;
 use middle::typeck::{method_origin, method_map_entry, vtable_res};
 use middle::typeck::{vtable_origin};
 use middle::{ty, typeck};
+use middle;
 use util::ppaux::ty_to_str;
 
-use reader = std::ebml::reader;
+use core::{dvec, io, option, vec};
 use std::ebml::reader::get_doc;
+use std::ebml::reader;
 use std::ebml::writer::Encoder;
 use std::ebml;
 use std::map::HashMap;
+use std::prettyprint;
 use std::serialize;
 use std::serialize::{Encodable, EncoderHelpers, DecoderHelpers};
 use std::serialize::Decodable;
@@ -41,6 +46,7 @@
 use syntax::parse;
 use syntax::print::pprust;
 use syntax::visit;
+use syntax;
 use writer = std::ebml::writer;
 
 export maps;
@@ -109,7 +115,7 @@ fn encode_inlined_item(ecx: @e::encode_ctxt,
 fn decode_inlined_item(cdata: cstore::crate_metadata,
                        tcx: ty::ctxt,
                        maps: maps,
-                       path: ast_map::path,
+                       +path: ast_map::path,
                        par_doc: ebml::Doc) -> Option<ast::inlined_item> {
     let dcx = @{cdata: cdata, tcx: tcx, maps: maps};
     match par_doc.opt_child(c::tag_ast) {
@@ -125,8 +131,9 @@ fn decode_inlined_item(cdata: cstore::crate_metadata,
                                           to_id_range: to_id_range});
         let raw_ii = decode_ast(ast_doc);
         let ii = renumber_ast(xcx, raw_ii);
+        // XXX: Bad copy of `path`.
         ast_map::map_decoded_item(tcx.sess.diagnostic(),
-                                  dcx.tcx.items, path, ii);
+                                  dcx.tcx.items, copy path, ii);
         debug!("Fn named: %s", tcx.sess.str_of(ii.ident()));
         decode_side_tables(xcx, ast_doc);
         debug!("< Decoded inlined fn: %s::%s",
@@ -249,19 +256,22 @@ fn encode_ast(ebml_w: writer::Encoder, item: ast::inlined_item) {
 // inlined items.
 fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
     fn drop_nested_items(blk: ast::blk_, fld: fold::ast_fold) -> ast::blk_ {
-        let stmts_sans_items = do vec::filter(blk.stmts) |stmt| {
+        let stmts_sans_items = do blk.stmts.filtered |stmt| {
             match stmt.node {
               ast::stmt_expr(_, _) | ast::stmt_semi(_, _) |
-              ast::stmt_decl(@{node: ast::decl_local(_), span: _}, _) => true,
-              ast::stmt_decl(@{node: ast::decl_item(_), span: _}, _) => false,
+              ast::stmt_decl(@ast::spanned { node: ast::decl_local(_),
+                                             span: _}, _) => true,
+              ast::stmt_decl(@ast::spanned { node: ast::decl_item(_),
+                                             span: _}, _) => false,
               ast::stmt_mac(*) => fail ~"unexpanded macro in astencode"
             }
         };
-        let blk_sans_items = { stmts: stmts_sans_items,.. blk };
+        // XXX: Bad copy.
+        let blk_sans_items = { stmts: stmts_sans_items,.. copy blk };
         fold::noop_fold_block(blk_sans_items, fld)
     }
 
-    let fld = fold::make_fold(@{
+    let fld = fold::make_fold(@fold::AstFoldFns {
         fold_block: fold::wrap(drop_nested_items),
         .. *fold::default_ast_fold()
     });
@@ -276,11 +286,12 @@ fn drop_nested_items(blk: ast::blk_, fld: fold::ast_fold) -> ast::blk_ {
       ast::ii_foreign(i) => {
         ast::ii_foreign(fld.fold_foreign_item(i))
       }
-      ast::ii_dtor(ref dtor, nm, tps, parent_id) => {
+      ast::ii_dtor(ref dtor, nm, ref tps, parent_id) => {
         let dtor_body = fld.fold_block((*dtor).node.body);
-        ast::ii_dtor({node: {body: dtor_body,
-                              .. (*dtor).node},
-            .. (*dtor)}, nm, tps, parent_id)
+        ast::ii_dtor(ast::spanned { node: { body: dtor_body,
+                                            .. /*bad*/copy (*dtor).node },
+                                    .. (/*bad*/copy *dtor) },
+                     nm, /*bad*/copy *tps, parent_id)
       }
     }
 }
@@ -293,7 +304,7 @@ fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item {
 
 fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item)
     -> ast::inlined_item {
-    let fld = fold::make_fold(@{
+    let fld = fold::make_fold(@fold::AstFoldFns{
         new_id: |a| xcx.tr_id(a),
         new_span: |a| xcx.tr_span(a),
         .. *fold::default_ast_fold()
@@ -309,16 +320,18 @@ fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item)
       ast::ii_foreign(i) => {
         ast::ii_foreign(fld.fold_foreign_item(i))
       }
-      ast::ii_dtor(ref dtor, nm, tps, parent_id) => {
+      ast::ii_dtor(ref dtor, nm, ref tps, parent_id) => {
         let dtor_body = fld.fold_block((*dtor).node.body);
-        let dtor_attrs = fld.fold_attributes((*dtor).node.attrs);
-        let new_params = fold::fold_ty_params(tps, fld);
+        let dtor_attrs = fld.fold_attributes(/*bad*/copy (*dtor).node.attrs);
+        let new_params = fold::fold_ty_params(/*bad*/copy *tps, fld);
         let dtor_id = fld.new_id((*dtor).node.id);
         let new_parent = xcx.tr_def_id(parent_id);
         let new_self = fld.new_id((*dtor).node.self_id);
-        ast::ii_dtor({node: {id: dtor_id, attrs: dtor_attrs,
-                self_id: new_self, body: dtor_body},
-                        .. (*dtor)},
+        ast::ii_dtor(ast::spanned { node: { id: dtor_id,
+                                            attrs: dtor_attrs,
+                                            self_id: new_self,
+                                            body: dtor_body },
+                                    .. (/*bad*/copy *dtor)},
           nm, new_params, new_parent)
       }
      }
@@ -411,7 +424,8 @@ fn tr(xcx: extended_decode_ctxt) -> ty::Region {
 impl ty::bound_region: tr {
     fn tr(xcx: extended_decode_ctxt) -> ty::bound_region {
         match self {
-            ty::br_anon(_) | ty::br_named(_) | ty::br_self => self,
+            ty::br_anon(_) | ty::br_named(_) | ty::br_self |
+            ty::br_fresh(_) => self,
             ty::br_cap_avoid(id, br) => ty::br_cap_avoid(xcx.tr_id(id),
                                                          @br.tr(xcx))
         }
@@ -516,7 +530,7 @@ fn encode_vtable_res(ecx: @e::encode_ctxt,
     // ty::t doesn't work, and there is no way (atm) to have
     // hand-written encoding routines combine with auto-generated
     // ones.  perhaps we should fix this.
-    do ebml_w.emit_from_vec(*dr) |vtable_origin| {
+    do ebml_w.emit_from_vec(/*bad*/copy *dr) |vtable_origin| {
         encode_vtable_origin(ecx, ebml_w, *vtable_origin)
     }
 }
@@ -525,14 +539,14 @@ fn encode_vtable_origin(ecx: @e::encode_ctxt,
                       ebml_w: writer::Encoder,
                       vtable_origin: typeck::vtable_origin) {
     do ebml_w.emit_enum(~"vtable_origin") {
-        match vtable_origin {
+        match /*bad*/copy vtable_origin {
           typeck::vtable_static(def_id, tys, vtable_res) => {
             do ebml_w.emit_enum_variant(~"vtable_static", 0u, 3u) {
                 do ebml_w.emit_enum_variant_arg(0u) {
                     ebml_w.emit_def_id(def_id)
                 }
                 do ebml_w.emit_enum_variant_arg(1u) {
-                    ebml_w.emit_tys(ecx, tys);
+                    ebml_w.emit_tys(ecx, /*bad*/copy tys);
                 }
                 do ebml_w.emit_enum_variant_arg(2u) {
                     encode_vtable_res(ecx, ebml_w, vtable_res);
@@ -555,7 +569,7 @@ fn encode_vtable_origin(ecx: @e::encode_ctxt,
                     ebml_w.emit_def_id(def_id)
                 }
                 do ebml_w.emit_enum_variant_arg(1u) {
-                    ebml_w.emit_tys(ecx, tys);
+                    ebml_w.emit_tys(ecx, /*bad*/copy tys);
                 }
             }
           }
@@ -629,11 +643,11 @@ trait get_ty_str_ctxt {
 
 impl @e::encode_ctxt: get_ty_str_ctxt {
     fn ty_str_ctxt() -> @tyencode::ctxt {
-        @{diag: self.tcx.sess.diagnostic(),
-          ds: e::def_to_str,
-          tcx: self.tcx,
-          reachable: |a| encoder::reachable(self, a),
-          abbrevs: tyencode::ac_use_abbrevs(self.type_abbrevs)}
+        @tyencode::ctxt {diag: self.tcx.sess.diagnostic(),
+                        ds: e::def_to_str,
+                        tcx: self.tcx,
+                        reachable: |a| encoder::reachable(self, a),
+                        abbrevs: tyencode::ac_use_abbrevs(self.type_abbrevs)}
     }
 }
 
@@ -666,7 +680,8 @@ fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg) {
     }
 
     fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]) {
-        do self.emit_from_vec(tys) |ty| {
+        // XXX: Bad copy.
+        do self.emit_from_vec(copy tys) |ty| {
             self.emit_ty(ecx, *ty)
         }
     }
@@ -680,7 +695,7 @@ fn emit_bounds(ecx: @e::encode_ctxt, bs: ty::param_bounds) {
     fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty) {
         do self.emit_rec {
             do self.emit_field(~"bounds", 0u) {
-                do self.emit_from_vec(*tpbt.bounds) |bs| {
+                do self.emit_from_vec(/*bad*/copy *tpbt.bounds) |bs| {
                     self.emit_bounds(ecx, *bs);
                 }
             }
@@ -754,7 +769,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
         do ebml_w.tag(c::tag_table_node_type_subst) {
             ebml_w.id(id);
             do ebml_w.tag(c::tag_table_val) {
-                ebml_w.emit_tys(ecx, *tys)
+                ebml_w.emit_tys(ecx, /*bad*/copy *tys)
             }
         }
     }
@@ -763,7 +778,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
         do ebml_w.tag(c::tag_table_freevars) {
             ebml_w.id(id);
             do ebml_w.tag(c::tag_table_val) {
-                do ebml_w.emit_from_vec(**fv) |fv_entry| {
+                do ebml_w.emit_from_vec(/*bad*/copy **fv) |fv_entry| {
                     encode_freevar_entry(ebml_w, *fv_entry)
                 }
             }
@@ -1030,7 +1045,7 @@ trait fake_ext_ctxt {
     fn cfg() -> ast::crate_cfg;
     fn parse_sess() -> parse::parse_sess;
     fn call_site() -> span;
-    fn ident_of(st: ~str) -> ast::ident;
+    fn ident_of(+st: ~str) -> ast::ident;
 }
 
 #[cfg(test)]
@@ -1047,7 +1062,7 @@ fn call_site() -> span {
             expn_info: None
         }
     }
-    fn ident_of(st: ~str) -> ast::ident {
+    fn ident_of(+st: ~str) -> ast::ident {
         self.interner.intern(@st)
     }
 }
@@ -1068,10 +1083,10 @@ fn roundtrip(in_item: Option<@ast::item>) {
     let out_item = decode_item_ast(ebml_doc);
 
     let exp_str = do io::with_str_writer |w| {
-        in_item.encode(&std::prettyprint::Encoder(w))
+        in_item.encode(&prettyprint::Serializer(w))
     };
     let out_str = do io::with_str_writer |w| {
-        out_item.encode(&std::prettyprint::Encoder(w))
+        out_item.encode(&prettyprint::Serializer(w))
     };
 
     debug!("expected string: %s", exp_str);
index 858cfb06d5120b33516e8e8bd7dbac7b9fd9b900..3d5bdac596bc6be7ad16d6e0cedc4db2a7445230 100644 (file)
 // 1. assignments are always made to mutable locations;
 // 2. loans made in overlapping scopes do not conflict
 // 3. assignments do not affect things loaned out as immutable
-// 4. moves to dnot affect things loaned out in any way
+// 4. moves do not affect things loaned out in any way
 
-use middle::ty::{CopyValue, MoveValue, ReadValue};
+use core::prelude::*;
 
-use dvec::DVec;
+use middle::borrowck::{Loan, bckerr, borrowck_ctxt, cmt, inherent_mutability};
+use middle::borrowck::{req_maps, save_and_restore};
+use middle::mem_categorization::{cat_arg, cat_binding, cat_deref, cat_local};
+use middle::mem_categorization::{cat_rvalue, cat_special};
+use middle::mem_categorization::{loan_path, lp_arg, lp_comp, lp_deref};
+use middle::mem_categorization::{lp_local};
+use middle::ty::{CopyValue, MoveValue, ReadValue};
+use middle::ty;
+use util::ppaux::ty_to_str;
+
+use core::cmp;
+use core::dvec::DVec;
+use core::uint;
+use core::vec;
+use std::map::HashMap;
+use syntax::ast::{m_const, m_imm, m_mutbl};
+use syntax::ast;
+use syntax::ast_util;
+use syntax::codemap::span;
+use syntax::print::pprust;
+use syntax::visit;
 
 export check_loans;
 
@@ -72,11 +92,11 @@ fn check_loans(bccx: borrowck_ctxt,
                                  reported: HashMap(),
                                  mut declared_purity: ast::impure_fn,
                                  mut fn_args: @~[]});
-    let vt = visit::mk_vt(@{visit_expr: check_loans_in_expr,
-                            visit_local: check_loans_in_local,
-                            visit_block: check_loans_in_block,
-                            visit_fn: check_loans_in_fn,
-                            .. *visit::default_visitor()});
+    let vt = visit::mk_vt(@visit::Visitor {visit_expr: check_loans_in_expr,
+                                           visit_local: check_loans_in_local,
+                                           visit_block: check_loans_in_block,
+                                           visit_fn: check_loans_in_fn,
+                                           .. *visit::default_visitor()});
     visit::visit_crate(*crate, clcx, vt);
 }
 
@@ -227,13 +247,13 @@ fn check_pure_callee_or_arg(pc: purity_cause,
         let callee_ty = ty::node_id_to_type(tcx, callee_id);
         match ty::get(callee_ty).sty {
           ty::ty_fn(ref fn_ty) => {
-            match (*fn_ty).meta.purity {
+            match fn_ty.meta.purity {
               ast::pure_fn => return, // case (c) above
               ast::impure_fn | ast::unsafe_fn | ast::extern_fn => {
                 self.report_purity_error(
                     pc, callee_span,
                     fmt!("access to %s function",
-                         pprust::purity_to_str((*fn_ty).meta.purity)));
+                         fn_ty.meta.purity.to_str()));
               }
             }
           }
@@ -623,7 +643,7 @@ fn check_loans_in_expr(expr: @ast::expr,
         Some(ReadValue) | Some(CopyValue) | None => {}
     }
 
-    match expr.node {
+    match /*bad*/copy expr.node {
       ast::expr_path(*) if self.bccx.last_use_map.contains_key(expr.id) => {
         self.check_last_use(expr);
       }
index d5809a7389e811770a9ba413f2164c3354e94af1..52cbd1da10c9ddb9d42503303ba6dc5877cca6bb 100644 (file)
 // their associated scopes.  In phase two, checking loans, we will then make
 // sure that all of these loans are honored.
 
-use middle::mem_categorization::{mem_categorization_ctxt, opt_deref_kind};
+use core::prelude::*;
+
 use middle::borrowck::preserve::{preserve_condition, pc_ok, pc_if_pure};
+use middle::borrowck::{Loan, bckres, borrowck_ctxt, err_mutbl, req_maps};
+use middle::mem_categorization::{cat_binding, cat_discr, cmt, comp_variant};
+use middle::mem_categorization::{mem_categorization_ctxt};
+use middle::mem_categorization::{opt_deref_kind};
+use middle::pat_util;
 use middle::ty::{ty_region};
+use middle::ty;
+use util::common::indenter;
+use util::ppaux::{expr_repr, region_to_str};
 
+use core::dvec;
 use core::send_map::linear::LinearMap;
+use core::vec;
+use std::map::HashMap;
+use syntax::ast::{m_const, m_imm, m_mutbl};
+use syntax::ast;
+use syntax::codemap::span;
+use syntax::print::pprust;
+use syntax::visit;
 
 export gather_loans;
 
@@ -65,9 +82,9 @@ fn gather_loans(bccx: borrowck_ctxt, crate: @ast::crate) -> req_maps {
                                   mut item_ub: 0,
                                   mut root_ub: 0,
                                   mut ignore_adjustments: LinearMap()});
-    let v = visit::mk_vt(@{visit_expr: req_loans_in_expr,
-                           visit_fn: req_loans_in_fn,
-                           .. *visit::default_visitor()});
+    let v = visit::mk_vt(@visit::Visitor {visit_expr: req_loans_in_expr,
+                                          visit_fn: req_loans_in_fn,
+                                          .. *visit::default_visitor()});
     visit::visit_crate(*crate, glcx, v);
     return glcx.req_maps;
 }
@@ -115,7 +132,7 @@ fn req_loans_in_expr(ex: @ast::expr,
     }
 
     // Special checks for various kinds of expressions:
-    match ex.node {
+    match /*bad*/copy ex.node {
       ast::expr_addr_of(mutbl, base) => {
         let base_cmt = self.bccx.cat_expr(base);
 
@@ -498,7 +515,7 @@ fn gather_pat(&self,
                   discr_cmt: cmt,
                   root_pat: @ast::pat,
                   arm_id: ast::node_id,
-                  alt_id: ast::node_id) {
+                  match_id: ast::node_id) {
         do self.bccx.cat_pattern(discr_cmt, root_pat) |cmt, pat| {
             match pat.node {
               ast::pat_ident(bm, _, _) if self.pat_is_binding(pat) => {
@@ -506,11 +523,11 @@ fn gather_pat(&self,
                   ast::bind_by_value | ast::bind_by_move => {
                     // copying does not borrow anything, so no check
                     // is required
-                    // as for move, check::alt ensures it's from an rvalue.
+                    // as for move, check::_match ensures it's from an rvalue.
                   }
                   ast::bind_by_ref(mutbl) => {
                     // ref x or ref x @ p --- creates a ptr which must
-                    // remain valid for the scope of the alt
+                    // remain valid for the scope of the match
 
                     // find the region of the resulting pointer (note that
                     // the type of such a pattern will *always* be a
@@ -523,7 +540,7 @@ fn gather_pat(&self,
                     // of the function of this node in method preserve():
                     let arm_scope = ty::re_scope(arm_id);
                     if self.bccx.is_subregion_of(scope_r, arm_scope) {
-                        let cmt_discr = self.bccx.cat_discr(cmt, alt_id);
+                        let cmt_discr = self.bccx.cat_discr(cmt, match_id);
                         self.guarantee_valid(cmt_discr, mutbl, scope_r);
                     } else {
                         self.guarantee_valid(cmt, mutbl, scope_r);
index 7dc68fa0b4b1318c8ab7ea88842605afb737ebe6..92a3ce2458913828b9773c5eda6f0f5c86b87cd7 100644 (file)
 // Loan(Ex, M, S) = Ls holds if ToAddr(Ex) will remain valid for the entirety
 // of the scope S, presuming that the returned set of loans `Ls` are honored.
 
+use core::prelude::*;
+
+use middle::borrowck::{Loan, bckres, borrowck_ctxt, cmt, err_mutbl};
+use middle::borrowck::{err_out_of_scope};
+use middle::mem_categorization::{cat_arg, cat_binding, cat_discr, cat_comp};
+use middle::mem_categorization::{cat_deref, cat_discr, cat_local};
+use middle::mem_categorization::{cat_special, cat_stack_upvar, comp_field};
+use middle::mem_categorization::{comp_index, comp_variant, region_ptr};
+use middle::ty;
+use util::common::indenter;
+
+use core::result::{Err, Ok, Result};
+use syntax::ast::{m_const, m_imm, m_mutbl};
+use syntax::ast;
+
 export public_methods;
-use result::{Result, Ok, Err};
 
 impl borrowck_ctxt {
     fn loan(cmt: cmt,
index 90de32814470ee8e83216066d34c1bcd26ac3b9e..19fc9eb175d6017b167c64bf55c733f89cd862a7 100644 (file)
 
 #[legacy_exports];
 
+use core::prelude::*;
+
+use middle::liveness;
 use middle::mem_categorization::*;
-use middle::ty::to_str;
+use middle::region;
+use middle::ty;
 use util::common::indenter;
 use util::ppaux::{expr_repr, note_and_explain_region};
 use util::ppaux::{ty_to_str, region_to_str, explain_region};
 
+use core::cmp;
 use core::dvec::DVec;
+use core::io;
 use core::result::{Result, Ok, Err};
 use std::list::{List, Cons, Nil};
 use std::list;
 #[legacy_exports]
 pub mod preserve;
 
-export check_crate, root_map, mutbl_map;
-export check_loans, gather_loans, loan, preserve;
-
 fn check_crate(tcx: ty::ctxt,
                method_map: typeck::method_map,
                last_use_map: liveness::last_use_map,
@@ -333,7 +336,7 @@ enum borrowck_ctxt {
 
 // set of ids of local vars / formal arguments that are modified / moved.
 // this is used in trans for optimization purposes.
-type mutbl_map = std::map::HashMap<ast::node_id, ()>;
+type mutbl_map = HashMap<ast::node_id, ()>;
 
 // Errors that can occur"]
 enum bckerr_code {
@@ -405,7 +408,7 @@ impl bckerr : cmp::Eq {
 type bckres<T> = Result<T, bckerr>;
 
 /// a complete record of a loan that was granted
-struct Loan {lp: @loan_path, cmt: cmt, mutbl: ast::mutability}
+pub struct Loan {lp: @loan_path, cmt: cmt, mutbl: ast::mutability}
 
 /// maps computed by `gather_loans` that are then used by `check_loans`
 ///
@@ -413,7 +416,7 @@ struct Loan {lp: @loan_path, cmt: cmt, mutbl: ast::mutability}
 ///   for the duration of that block/expr
 /// - `pure_map`: map from block/expr that must be pure to the error message
 ///   that should be reported if they are not pure
-type req_maps = {
+pub type req_maps = {
     req_loan_map: HashMap<ast::node_id, @DVec<Loan>>,
     pure_map: HashMap<ast::node_id, bckerr>
 };
@@ -489,8 +492,8 @@ fn cat_variant<N: ast_node>(arg: N,
         cat_variant(self.tcx, self.method_map, arg, enum_did, cmt)
     }
 
-    fn cat_discr(cmt: cmt, alt_id: ast::node_id) -> cmt {
-        return @{cat:cat_discr(cmt, alt_id),.. *cmt};
+    fn cat_discr(cmt: cmt, match_id: ast::node_id) -> cmt {
+        return @{cat:cat_discr(cmt, match_id),.. *cmt};
     }
 
     fn cat_pattern(cmt: cmt, pat: @ast::pat, op: fn(cmt, @ast::pat)) {
@@ -514,11 +517,11 @@ fn report(err: bckerr) {
         self.note_and_explain_bckerr(err);
     }
 
-    fn span_err(s: span, m: ~str) {
+    fn span_err(s: span, +m: ~str) {
         self.tcx.sess.span_err(s, m);
     }
 
-    fn span_note(s: span, m: ~str) {
+    fn span_note(s: span, +m: ~str) {
         self.tcx.sess.span_note(s, m);
     }
 
index b1a34bbe2569b9e7f610236c58ec2a39f158d165..600ede8c720ecac699bedec973c843a8e910add2 100644 (file)
 // the scope S.
 //
 
+use core::prelude::*;
+
+use middle::borrowck::{bckerr, bckerr_code, bckres, borrowck_ctxt, cmt};
+use middle::borrowck::{err_mut_uniq, err_mut_variant, err_out_of_root_scope};
+use middle::borrowck::{err_out_of_scope, err_root_not_permitted};
+use middle::mem_categorization::{cat_arg, cat_binding, cat_comp, cat_deref};
+use middle::mem_categorization::{cat_discr, cat_local, cat_special};
+use middle::mem_categorization::{cat_stack_upvar, comp_field, comp_index};
+use middle::mem_categorization::{comp_variant, region_ptr};
+use middle::ty;
+use util::common::indenter;
+
+use syntax::ast::{m_const, m_imm, m_mutbl};
+use syntax::ast;
+
 export public_methods, preserve_condition, pc_ok, pc_if_pure;
 
 enum preserve_condition {
@@ -190,15 +205,15 @@ fn preserve(cmt: cmt) -> bckres<preserve_condition> {
                 self.attempt_root(cmt, base, derefs)
             }
           }
-          cat_discr(base, alt_id) => {
-            // Subtle: in an alt, we must ensure that each binding
+          cat_discr(base, match_id) => {
+            // Subtle: in a match, we must ensure that each binding
             // variable remains valid for the duration of the arm in
             // which it appears, presuming that this arm is taken.
             // But it is inconvenient in trans to root something just
             // for one arm.  Therefore, we insert a cat_discr(),
             // basically a special kind of category that says "if this
             // value must be dynamically rooted, root it for the scope
-            // `alt_id`.
+            // `match_id`.
             //
             // As an example, consider this scenario:
             //
@@ -208,7 +223,7 @@ fn preserve(cmt: cmt) -> bckres<preserve_condition> {
             // Technically, the value `x` need only be rooted
             // in the `some` arm.  However, we evaluate `x` in trans
             // before we know what arm will be taken, so we just
-            // always root it for the duration of the alt.
+            // always root it for the duration of the match.
             //
             // As a second example, consider *this* scenario:
             //
@@ -220,7 +235,7 @@ fn preserve(cmt: cmt) -> bckres<preserve_condition> {
             // found only when checking which pattern matches: but
             // this check is done before entering the arm.  Therefore,
             // even in this case we just choose to keep the value
-            // rooted for the entire alt.  This means the value will be
+            // rooted for the entire match.  This means the value will be
             // rooted even if the none arm is taken.  Oh well.
             //
             // At first, I tried to optimize the second case to only
@@ -242,12 +257,12 @@ fn preserve(cmt: cmt) -> bckres<preserve_condition> {
             // Nonetheless, if you decide to optimize this case in the
             // future, you need only adjust where the cat_discr()
             // node appears to draw the line between what will be rooted
-            // in the *arm* vs the *alt*.
+            // in the *arm* vs the *match*.
 
-            let alt_rooting_ctxt =
-                preserve_ctxt({scope_region: ty::re_scope(alt_id),
+            let match_rooting_ctxt =
+                preserve_ctxt({scope_region: ty::re_scope(match_id),
                                .. **self});
-            (&alt_rooting_ctxt).preserve(base)
+            (&match_rooting_ctxt).preserve(base)
           }
         }
     }
index f9a7459c67176561fdddcdc35e7dc1a621dd2e5b..bd8d1b64906599b1de12a9ac8c8234f7442bb515 100644 (file)
@@ -8,10 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syntax::{ast, ast_util};
-use syntax::codemap::span;
-use std::map;
+use core::prelude::*;
+
+use middle::freevars;
+use middle::ty;
+
+use core::option;
+use core::vec;
 use std::map::HashMap;
+use std::map;
+use syntax::codemap::span;
+use syntax::{ast, ast_util};
 
 export capture_mode;
 export capture_var;
diff --git a/src/librustc/middle/check_alt.rs b/src/librustc/middle/check_alt.rs
deleted file mode 100644 (file)
index ef192a0..0000000
+++ /dev/null
@@ -1,841 +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 middle::const_eval::{compare_const_vals, lookup_const_by_id};
-use middle::const_eval::{eval_const_expr, const_val, const_int, const_bool};
-use middle::pat_util::*;
-use middle::ty::*;
-use middle::ty;
-use middle::typeck::method_map;
-use util::ppaux::ty_to_str;
-
-use std::map::HashMap;
-use syntax::ast::*;
-use syntax::ast_util::{variant_def_ids, dummy_sp, unguarded_pat, walk_pat};
-use syntax::codemap::span;
-use syntax::print::pprust::pat_to_str;
-use syntax::visit;
-use std::sort;
-
-struct AltCheckCtxt {
-    tcx: ty::ctxt,
-    method_map: method_map,
-}
-
-fn check_crate(tcx: ty::ctxt, method_map: method_map, crate: @crate) {
-    let cx = @AltCheckCtxt { tcx: tcx, method_map: method_map };
-    visit::visit_crate(*crate, (), visit::mk_vt(@{
-        visit_expr: |a,b,c| check_expr(cx, a, b, c),
-        visit_local: |a,b,c| check_local(cx, a, b, c),
-        visit_fn: |kind, decl, body, sp, id, e, v|
-            check_fn(cx, kind, decl, body, sp, id, e, v),
-        .. *visit::default_visitor::<()>()
-    }));
-    tcx.sess.abort_if_errors();
-}
-
-fn expr_is_non_moving_lvalue(cx: @AltCheckCtxt, expr: @expr) -> bool {
-    if !ty::expr_is_lval(cx.tcx, cx.method_map, expr) {
-        return false;
-    }
-
-    match cx.tcx.value_modes.find(expr.id) {
-        Some(MoveValue) => return false,
-        Some(CopyValue) | Some(ReadValue) => return true,
-        None => {
-            cx.tcx.sess.span_bug(expr.span, ~"no entry in value mode map");
-        }
-    }
-}
-
-fn check_expr(cx: @AltCheckCtxt, ex: @expr, &&s: (), v: visit::vt<()>) {
-    visit::visit_expr(ex, s, v);
-    match ex.node {
-      expr_match(scrut, ref arms) => {
-        // First, check legality of move bindings.
-        let is_non_moving_lvalue = expr_is_non_moving_lvalue(cx, ex);
-        for arms.each |arm| {
-            check_legality_of_move_bindings(cx,
-                                            is_non_moving_lvalue,
-                                            arm.guard.is_some(),
-                                            arm.pats);
-        }
-
-        check_arms(cx, (*arms));
-        /* Check for exhaustiveness */
-         // Check for empty enum, because is_useful only works on inhabited
-         // types.
-       let pat_ty = node_id_to_type(cx.tcx, scrut.id);
-       if (*arms).is_empty() {
-           if !type_is_empty(cx.tcx, pat_ty) {
-               // We know the type is inhabited, so this must be wrong
-               cx.tcx.sess.span_err(ex.span, fmt!("non-exhaustive patterns: \
-                            type %s is non-empty",
-                            ty_to_str(cx.tcx, pat_ty)));
-           }
-           // If the type *is* empty, it's vacuously exhaustive
-           return;
-       }
-       match ty::get(pat_ty).sty {
-          ty_enum(did, _) => {
-              if (*enum_variants(cx.tcx, did)).is_empty() &&
-                    (*arms).is_empty() {
-
-               return;
-            }
-          }
-          _ => { /* We assume only enum types can be uninhabited */ }
-       }
-       let arms = vec::concat(vec::filter_map((*arms), unguarded_pat));
-       check_exhaustive(cx, ex.span, arms);
-     }
-     _ => ()
-    }
-}
-
-// Check for unreachable patterns
-fn check_arms(cx: @AltCheckCtxt, arms: ~[arm]) {
-    let mut seen = ~[];
-    for arms.each |arm| {
-        for arm.pats.each |pat| {
-            let v = ~[*pat];
-            match is_useful(cx, seen, v) {
-              not_useful => {
-                cx.tcx.sess.span_err(pat.span, ~"unreachable pattern");
-              }
-              _ => ()
-            }
-            if arm.guard.is_none() { seen.push(v); }
-        }
-    }
-}
-
-fn raw_pat(p: @pat) -> @pat {
-    match p.node {
-      pat_ident(_, _, Some(s)) => { raw_pat(s) }
-      _ => { p }
-    }
-}
-
-fn check_exhaustive(cx: @AltCheckCtxt, sp: span, pats: ~[@pat]) {
-    assert(pats.is_not_empty());
-    let ext = match is_useful(cx, vec::map(pats, |p| ~[*p]), ~[wild()]) {
-      not_useful => return, // This is good, wildcard pattern isn't reachable
-      useful_ => None,
-      useful(ty, ref ctor) => {
-        match ty::get(ty).sty {
-          ty::ty_bool => {
-            match (*ctor) {
-              val(const_bool(true)) => Some(~"true"),
-              val(const_bool(false)) => Some(~"false"),
-              _ => None
-            }
-          }
-          ty::ty_enum(id, _) => {
-              let vid = match (*ctor) { variant(id) => id,
-              _ => fail ~"check_exhaustive: non-variant ctor" };
-            match vec::find(*ty::enum_variants(cx.tcx, id),
-                                |v| v.id == vid) {
-                Some(v) => Some(cx.tcx.sess.str_of(v.name)),
-              None => fail ~"check_exhaustive: bad variant in ctor"
-            }
-          }
-          ty::ty_unboxed_vec(*) | ty::ty_evec(*) => {
-            match (*ctor) {
-              vec(n) => Some(fmt!("vectors of length %u", n)),
-              _ => None
-            }
-          }
-          _ => None
-        }
-      }
-    };
-    let msg = ~"non-exhaustive patterns" + match ext {
-      Some(ref s) => ~": " + (*s) + ~" not covered",
-      None => ~""
-    };
-    cx.tcx.sess.span_err(sp, msg);
-}
-
-type matrix = ~[~[@pat]];
-
-enum useful { useful(ty::t, ctor), useful_, not_useful }
-
-enum ctor {
-    single,
-    variant(def_id),
-    val(const_val),
-    range(const_val, const_val),
-    vec(uint)
-}
-
-impl ctor : cmp::Eq {
-    pure fn eq(&self, other: &ctor) -> bool {
-        match ((*self), (*other)) {
-            (single, single) => true,
-            (variant(did_self), variant(did_other)) => did_self == did_other,
-            (val(ref cv_self), val(ref cv_other)) =>
-                (*cv_self) == (*cv_other),
-            (range(ref cv0_self, ref cv1_self),
-             range(ref cv0_other, ref cv1_other)) => {
-                (*cv0_self) == (*cv0_other) && (*cv1_self) == (*cv1_other)
-            }
-            (vec(n_self), vec(n_other)) => n_self == n_other,
-            (single, _) | (variant(_), _) | (val(_), _) |
-            (range(*), _) | (vec(*), _) => {
-                false
-            }
-        }
-    }
-    pure fn ne(&self, other: &ctor) -> bool { !(*self).eq(other) }
-}
-
-// Algorithm from http://moscova.inria.fr/~maranget/papers/warn/index.html
-//
-// Whether a vector `v` of patterns is 'useful' in relation to a set of such
-// vectors `m` is defined as there being a set of inputs that will match `v`
-// but not any of the sets in `m`.
-//
-// This is used both for reachability checking (if a pattern isn't useful in
-// relation to preceding patterns, it is not reachable) and exhaustiveness
-// checking (if a wildcard pattern is useful in relation to a matrix, the
-// matrix isn't exhaustive).
-
-// Note: is_useful doesn't work on empty types, as the paper notes.
-// So it assumes that v is non-empty.
-fn is_useful(cx: @AltCheckCtxt, m: matrix, v: ~[@pat]) -> useful {
-    if m.len() == 0u { return useful_; }
-    if m[0].len() == 0u { return not_useful; }
-    let real_pat = match vec::find(m, |r| r[0].id != 0) {
-      Some(r) => r[0], None => v[0]
-    };
-    let left_ty = if real_pat.id == 0 { ty::mk_nil(cx.tcx) }
-                  else { ty::node_id_to_type(cx.tcx, real_pat.id) };
-
-    match pat_ctor_id(cx, v[0]) {
-      None => {
-        match missing_ctor(cx, m, left_ty) {
-          None => {
-            match ty::get(left_ty).sty {
-              ty::ty_bool => {
-                match is_useful_specialized(cx, m, v,
-                                            val(const_bool(true)),
-                                            0u, left_ty){
-                  not_useful => {
-                    is_useful_specialized(cx, m, v,
-                                          val(const_bool(false)),
-                                          0u, left_ty)
-                  }
-                  ref u => (*u)
-                }
-              }
-              ty::ty_enum(eid, _) => {
-                for (*ty::enum_variants(cx.tcx, eid)).each |va| {
-                    match is_useful_specialized(cx, m, v, variant(va.id),
-                                                va.args.len(), left_ty) {
-                      not_useful => (),
-                      ref u => return (*u)
-                    }
-                }
-                not_useful
-              }
-              ty::ty_unboxed_vec(*) | ty::ty_evec(*) => {
-                let max_len = do m.foldr(0) |r, max_len| {
-                  match r[0].node {
-                    pat_vec(elems, _) => uint::max(elems.len(), max_len),
-                    _ => max_len
-                  }
-                };
-                for uint::range(0, max_len + 1) |n| {
-                  match is_useful_specialized(cx, m, v, vec(n), n, left_ty) {
-                    not_useful => (),
-                    ref u => return (*u)
-                  }
-                }
-                not_useful
-              }
-              _ => {
-                let arity = ctor_arity(cx, single, left_ty);
-                is_useful_specialized(cx, m, v, single, arity, left_ty)
-              }
-            }
-          }
-          Some(ref ctor) => {
-            match is_useful(cx, vec::filter_map(m, |r| default(cx, *r)),
-                            vec::tail(v)) {
-              useful_ => useful(left_ty, (*ctor)),
-              ref u => (*u)
-            }
-          }
-        }
-      }
-      Some(ref v0_ctor) => {
-        let arity = ctor_arity(cx, (*v0_ctor), left_ty);
-        is_useful_specialized(cx, m, v, (*v0_ctor), arity, left_ty)
-      }
-    }
-}
-
-fn is_useful_specialized(cx: @AltCheckCtxt, m: matrix, v: ~[@pat], ctor: ctor,
-                          arity: uint, lty: ty::t) -> useful {
-    let ms = vec::filter_map(m, |r| specialize(cx, *r, ctor, arity, lty));
-    let could_be_useful = is_useful(
-        cx, ms, specialize(cx, v, ctor, arity, lty).get());
-    match could_be_useful {
-      useful_ => useful(lty, ctor),
-      ref u => (*u)
-    }
-}
-
-fn pat_ctor_id(cx: @AltCheckCtxt, p: @pat) -> Option<ctor> {
-    let pat = raw_pat(p);
-    match pat.node {
-      pat_wild => { None }
-      pat_ident(_, _, _) | pat_enum(_, _) => {
-        match cx.tcx.def_map.find(pat.id) {
-          Some(def_variant(_, id)) => Some(variant(id)),
-          Some(def_const(did)) => {
-            let const_expr = lookup_const_by_id(cx.tcx, did).get();
-            Some(val(eval_const_expr(cx.tcx, const_expr)))
-          }
-          _ => None
-        }
-      }
-      pat_lit(expr) => { Some(val(eval_const_expr(cx.tcx, expr))) }
-      pat_range(lo, hi) => {
-        Some(range(eval_const_expr(cx.tcx, lo), eval_const_expr(cx.tcx, hi)))
-      }
-      pat_struct(*) => {
-        match cx.tcx.def_map.find(pat.id) {
-          Some(def_variant(_, id)) => Some(variant(id)),
-          _ => Some(single)
-        }
-      }
-      pat_box(_) | pat_uniq(_) | pat_rec(_, _) | pat_tup(_) |
-      pat_region(*) => {
-        Some(single)
-      }
-      pat_vec(elems, tail) => {
-        match tail {
-          Some(_) => None,
-          None => Some(vec(elems.len()))
-        }
-      }
-    }
-}
-
-fn is_wild(cx: @AltCheckCtxt, p: @pat) -> bool {
-    let pat = raw_pat(p);
-    match pat.node {
-      pat_wild => { true }
-      pat_ident(_, _, _) => {
-        match cx.tcx.def_map.find(pat.id) {
-          Some(def_variant(_, _)) | Some(def_const(*)) => { false }
-          _ => { true }
-        }
-      }
-      _ => { false }
-    }
-}
-
-fn missing_ctor(cx: @AltCheckCtxt,
-                m: matrix,
-                left_ty: ty::t)
-             -> Option<ctor> {
-    match ty::get(left_ty).sty {
-      ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) | ty::ty_tup(_) |
-      ty::ty_rec(_) | ty::ty_struct(*) => {
-        for m.each |r| {
-            if !is_wild(cx, r[0]) { return None; }
-        }
-        return Some(single);
-      }
-      ty::ty_enum(eid, _) => {
-        let mut found = ~[];
-        for m.each |r| {
-            do option::iter(&pat_ctor_id(cx, r[0])) |id| {
-                if !vec::contains(found, id) {
-                    found.push(*id);
-                }
-            }
-        }
-        let variants = ty::enum_variants(cx.tcx, eid);
-        if found.len() != (*variants).len() {
-            for vec::each(*variants) |v| {
-                if !found.contains(&(variant(v.id))) {
-                    return Some(variant(v.id));
-                }
-            }
-            fail;
-        } else { None }
-      }
-      ty::ty_nil => None,
-      ty::ty_bool => {
-        let mut true_found = false, false_found = false;
-        for m.each |r| {
-            match pat_ctor_id(cx, r[0]) {
-              None => (),
-              Some(val(const_bool(true))) => true_found = true,
-              Some(val(const_bool(false))) => false_found = true,
-              _ => fail ~"impossible case"
-            }
-        }
-        if true_found && false_found { None }
-        else if true_found { Some(val(const_bool(false))) }
-        else { Some(val(const_bool(true))) }
-      }
-      ty::ty_unboxed_vec(*) | ty::ty_evec(*) => {
-
-        // Find the lengths and tails of all vector patterns.
-        let vec_pat_lens = do m.filter_map |r| {
-            match r[0].node {
-                pat_vec(elems, tail) => {
-                    Some((elems.len(), tail.is_some()))
-                }
-                _ => None
-            }
-        };
-
-        // Sort them by length such that for patterns of the same length,
-        // those with a destructured tail come first.
-        let mut sorted_vec_lens = sort::merge_sort(vec_pat_lens,
-            |&(len1, tail1), &(len2, tail2)| {
-                if len1 == len2 {
-                    tail1 > tail2
-                } else {
-                    len1 <= len2
-                }
-            }
-        );
-        vec::dedup(&mut sorted_vec_lens);
-
-        let mut found_tail = false;
-        let mut next = 0;
-        let mut missing = None;
-        for sorted_vec_lens.each |&(length, tail)| {
-            if length != next {
-                missing = Some(next);
-                break;
-            }
-            if tail {
-                found_tail = true;
-                break;
-            }
-            next += 1;
-        }
-
-        // We found patterns of all lengths within <0, next), yet there was no
-        // pattern with a tail - therefore, we report vec(next) as missing.
-        if !found_tail {
-            missing = Some(next);
-        }
-        match missing {
-          Some(k) => Some(vec(k)),
-          None => None
-        }
-      }
-      _ => Some(single)
-    }
-}
-
-fn ctor_arity(cx: @AltCheckCtxt, ctor: ctor, ty: ty::t) -> uint {
-    match ty::get(ty).sty {
-      ty::ty_tup(fs) => fs.len(),
-      ty::ty_rec(fs) => fs.len(),
-      ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) => 1u,
-      ty::ty_enum(eid, _) => {
-          let id = match ctor { variant(id) => id,
-          _ => fail ~"impossible case" };
-        match vec::find(*ty::enum_variants(cx.tcx, eid), |v| v.id == id ) {
-            Some(v) => v.args.len(),
-            None => fail ~"impossible case"
-        }
-      }
-      ty::ty_struct(cid, _) => ty::lookup_struct_fields(cx.tcx, cid).len(),
-      ty::ty_unboxed_vec(*) | ty::ty_evec(*) => {
-        match ctor {
-          vec(n) => n,
-          _ => 0u
-        }
-      }
-      _ => 0u
-    }
-}
-
-fn wild() -> @pat {
-    @{id: 0, node: pat_wild, span: syntax::ast_util::dummy_sp()}
-}
-
-fn specialize(cx: @AltCheckCtxt, r: ~[@pat], ctor_id: ctor, arity: uint,
-              left_ty: ty::t) -> Option<~[@pat]> {
-    let r0 = raw_pat(r[0]);
-    match r0.node {
-      pat_wild => Some(vec::append(vec::from_elem(arity, wild()),
-                                   vec::tail(r))),
-      pat_ident(_, _, _) => {
-        match cx.tcx.def_map.find(r0.id) {
-          Some(def_variant(_, id)) => {
-            if variant(id) == ctor_id { Some(vec::tail(r)) }
-            else { None }
-          }
-          Some(def_const(did)) => {
-            let const_expr = lookup_const_by_id(cx.tcx, did).get();
-            let e_v = eval_const_expr(cx.tcx, const_expr);
-            let match_ = match ctor_id {
-                val(ref v) => compare_const_vals(e_v, (*v)) == 0,
-                range(ref c_lo, ref c_hi) => {
-                    compare_const_vals((*c_lo), e_v) >= 0 &&
-                        compare_const_vals((*c_hi), e_v) <= 0
-                }
-                single => true,
-                _ => fail ~"type error"
-            };
-            if match_ { Some(vec::tail(r)) } else { None }
-          }
-          _ => Some(vec::append(vec::from_elem(arity, wild()), vec::tail(r)))
-        }
-      }
-      pat_enum(_, args) => {
-        match cx.tcx.def_map.get(r0.id) {
-          def_variant(_, id) if variant(id) == ctor_id => {
-            let args = match args {
-              Some(args) => args,
-              None => vec::from_elem(arity, wild())
-            };
-            Some(vec::append(args, vec::tail(r)))
-          }
-          def_variant(_, _) => None,
-          def_struct(*) => {
-            // XXX: Is this right? --pcw
-            let new_args;
-            match args {
-              Some(args) => new_args = args,
-              None => new_args = vec::from_elem(arity, wild())
-            }
-            Some(vec::append(new_args, vec::tail(r)))
-          }
-          _ => None
-        }
-      }
-      pat_rec(flds, _) => {
-        let ty_flds = match ty::get(left_ty).sty {
-            ty::ty_rec(flds) => flds,
-            _ => fail ~"bad type for pat_rec"
-        };
-        let args = vec::map(ty_flds, |ty_fld| {
-            match vec::find(flds, |f| f.ident == ty_fld.ident ) {
-              Some(f) => f.pat,
-              _ => wild()
-            }
-        });
-        Some(vec::append(args, vec::tail(r)))
-      }
-      pat_struct(_, flds, _) => {
-        // Is this a struct or an enum variant?
-        match cx.tcx.def_map.get(r0.id) {
-            def_variant(_, variant_id) => {
-                if variant(variant_id) == ctor_id {
-                    // XXX: Is this right? --pcw
-                    let args = flds.map(|ty_field| {
-                        match vec::find(flds, |f| f.ident == ty_field.ident) {
-                            Some(f) => f.pat,
-                            _ => wild()
-                        }
-                    });
-                    Some(vec::append(args, vec::tail(r)))
-                } else {
-                    None
-                }
-            }
-            _ => {
-                // Grab the class data that we care about.
-                let class_fields, class_id;
-                match ty::get(left_ty).sty {
-                    ty::ty_struct(cid, _) => {
-                        class_id = cid;
-                        class_fields = ty::lookup_struct_fields(cx.tcx,
-                                                               class_id);
-                    }
-                    _ => {
-                        cx.tcx.sess.span_bug(r0.span, ~"struct pattern \
-                                                        didn't resolve to a \
-                                                        struct");
-                    }
-                }
-                let args = vec::map(class_fields, |class_field| {
-                    match vec::find(flds, |f| f.ident == class_field.ident ) {
-                      Some(f) => f.pat,
-                      _ => wild()
-                    }
-                });
-                Some(vec::append(args, vec::tail(r)))
-            }
-        }
-      }
-      pat_tup(args) => Some(vec::append(args, vec::tail(r))),
-      pat_box(a) | pat_uniq(a) | pat_region(a) =>
-          Some(vec::append(~[a], vec::tail(r))),
-      pat_lit(expr) => {
-        let e_v = eval_const_expr(cx.tcx, expr);
-        let match_ = match ctor_id {
-          val(ref v) => compare_const_vals(e_v, (*v)) == 0,
-          range(ref c_lo, ref c_hi) => {
-            compare_const_vals((*c_lo), e_v) >= 0 &&
-                compare_const_vals((*c_hi), e_v) <= 0
-          }
-          single => true,
-          _ => fail ~"type error"
-        };
-        if match_ { Some(vec::tail(r)) } else { None }
-      }
-      pat_range(lo, hi) => {
-        let (c_lo, c_hi) = match ctor_id {
-          val(ref v) => ((*v), (*v)),
-          range(ref lo, ref hi) => ((*lo), (*hi)),
-          single => return Some(vec::tail(r)),
-          _ => fail ~"type error"
-        };
-        let v_lo = eval_const_expr(cx.tcx, lo),
-            v_hi = eval_const_expr(cx.tcx, hi);
-        let match_ = compare_const_vals(c_lo, v_lo) >= 0 &&
-                    compare_const_vals(c_hi, v_hi) <= 0;
-        if match_ { Some(vec::tail(r)) } else { None }
-      }
-      pat_vec(elems, tail) => {
-        match ctor_id {
-          vec(_) => {
-            if elems.len() < arity && tail.is_some() {
-              Some(vec::append(
-                vec::append(elems, vec::from_elem(
-                    arity - elems.len(), wild()
-                )),
-                vec::tail(r)
-              ))
-            } else if elems.len() == arity {
-              Some(vec::append(elems, vec::tail(r)))
-            } else {
-              None
-            }
-          }
-          _ => None
-        }
-      }
-    }
-}
-
-fn default(cx: @AltCheckCtxt, r: ~[@pat]) -> Option<~[@pat]> {
-    if is_wild(cx, r[0]) { Some(vec::tail(r)) }
-    else { None }
-}
-
-fn check_local(cx: @AltCheckCtxt, loc: @local, &&s: (), v: visit::vt<()>) {
-    visit::visit_local(loc, s, v);
-    if is_refutable(cx, loc.node.pat) {
-        cx.tcx.sess.span_err(loc.node.pat.span,
-                          ~"refutable pattern in local binding");
-    }
-
-    // Check legality of move bindings.
-    let is_lvalue = match loc.node.init {
-        Some(init) => expr_is_non_moving_lvalue(cx, init),
-        None => true
-    };
-    check_legality_of_move_bindings(cx, is_lvalue, false, [ loc.node.pat ]);
-}
-
-fn check_fn(cx: @AltCheckCtxt,
-            kind: visit::fn_kind,
-            decl: fn_decl,
-            body: blk,
-            sp: span,
-            id: node_id,
-            &&s: (),
-            v: visit::vt<()>) {
-    visit::visit_fn(kind, decl, body, sp, id, s, v);
-    for decl.inputs.each |input| {
-        if is_refutable(cx, input.pat) {
-            cx.tcx.sess.span_err(input.pat.span,
-                              ~"refutable pattern in function argument");
-        }
-    }
-}
-
-fn is_refutable(cx: @AltCheckCtxt, pat: &pat) -> bool {
-    match cx.tcx.def_map.find(pat.id) {
-      Some(def_variant(enum_id, _)) => {
-        if vec::len(*ty::enum_variants(cx.tcx, enum_id)) != 1u {
-            return true;
-        }
-      }
-      Some(def_const(*)) => return true,
-      _ => ()
-    }
-
-    match pat.node {
-      pat_box(sub) | pat_uniq(sub) | pat_region(sub) |
-      pat_ident(_, _, Some(sub)) => {
-        is_refutable(cx, sub)
-      }
-      pat_wild | pat_ident(_, _, None) => { false }
-      pat_lit(@{node: expr_lit(@{node: lit_nil, _}), _}) => { false } // "()"
-      pat_lit(_) | pat_range(_, _) => { true }
-      pat_rec(fields, _) => {
-        fields.any(|f| is_refutable(cx, f.pat))
-      }
-      pat_struct(_, fields, _) => {
-        fields.any(|f| is_refutable(cx, f.pat))
-      }
-      pat_tup(elts) => {
-        elts.any(|elt| is_refutable(cx, *elt))
-      }
-      pat_enum(_, Some(args)) => {
-        args.any(|a| is_refutable(cx, *a))
-      }
-      pat_enum(_,_) => { false }
-      pat_vec(*) => { true }
-    }
-}
-
-// Legality of move bindings checking
-
-fn check_legality_of_move_bindings(cx: @AltCheckCtxt,
-                                   is_lvalue: bool,
-                                   has_guard: bool,
-                                   pats: &[@pat]) {
-    let tcx = cx.tcx;
-    let def_map = tcx.def_map;
-    let mut by_ref_span = None;
-    let mut any_by_move = false;
-    for pats.each |pat| {
-        do pat_bindings(def_map, *pat) |bm, id, span, _path| {
-            match bm {
-                bind_by_ref(_) => {
-                    by_ref_span = Some(span);
-                }
-                bind_by_move => {
-                    any_by_move = true;
-                }
-                bind_by_value => {}
-                bind_infer => {
-                    match cx.tcx.value_modes.find(id) {
-                        Some(MoveValue) => any_by_move = true,
-                        Some(CopyValue) | Some(ReadValue) => {}
-                        None => {
-                            cx.tcx.sess.span_bug(span, ~"no mode for pat \
-                                                         binding");
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    let check_move: &fn(@pat, Option<@pat>) = |p, sub| {
-        // check legality of moving out of the enum
-        if sub.is_some() {
-            tcx.sess.span_err(
-                p.span,
-                ~"cannot bind by-move with sub-bindings");
-        } else if has_guard {
-            tcx.sess.span_err(
-                p.span,
-                ~"cannot bind by-move into a pattern guard");
-        } else if by_ref_span.is_some() {
-            tcx.sess.span_err(
-                p.span,
-                ~"cannot bind by-move and by-ref \
-                  in the same pattern");
-            tcx.sess.span_note(
-                by_ref_span.get(),
-                ~"by-ref binding occurs here");
-        } else if is_lvalue {
-            tcx.sess.span_err(
-                p.span,
-                ~"cannot bind by-move when \
-                  matching an lvalue");
-        }
-    };
-
-    if !any_by_move { return; } // pointless micro-optimization
-    for pats.each |pat| {
-        do walk_pat(*pat) |p| {
-            if pat_is_binding(def_map, p) {
-                match p.node {
-                    pat_ident(bind_by_move, _, sub) => check_move(p, sub),
-                    pat_ident(bind_infer, _, sub) => {
-                        match tcx.value_modes.find(p.id) {
-                            Some(MoveValue) => check_move(p, sub),
-                            Some(CopyValue) | Some(ReadValue) => {}
-                            None => {
-                                cx.tcx.sess.span_bug(
-                                    pat.span, ~"no mode for pat binding");
-                            }
-                        }
-                    }
-                    _ => {}
-                }
-            }
-        }
-
-        // Now check to ensure that any move binding is not behind an @ or &.
-        // This is always illegal.
-        let vt = visit::mk_vt(@{
-            visit_pat: |pat, behind_bad_pointer, v| {
-                let error_out = || {
-                    cx.tcx.sess.span_err(pat.span, ~"by-move pattern \
-                                                     bindings may not occur \
-                                                     behind @ or & bindings");
-                };
-                match pat.node {
-                    pat_ident(binding_mode, _, sub) => {
-                        debug!("(check legality of move) checking pat \
-                                ident with behind_bad_pointer %?",
-                                behind_bad_pointer);
-                        match binding_mode {
-                            bind_by_move if behind_bad_pointer => error_out(),
-                            bind_infer if behind_bad_pointer => {
-                                match cx.tcx.value_modes.find(pat.id) {
-                                    Some(MoveValue) => error_out(),
-                                    Some(CopyValue) |
-                                    Some(ReadValue) => {}
-                                    None => {
-                                        cx.tcx.sess.span_bug(pat.span,
-                                            ~"no mode for pat binding");
-                                    }
-                                }
-                            }
-                            _ => {}
-                        }
-                        match sub {
-                            None => {}
-                            Some(subpat) => {
-                                (v.visit_pat)(subpat, behind_bad_pointer, v);
-                            }
-                        }
-                    }
-                    pat_box(subpat) | pat_region(subpat) => {
-                        (v.visit_pat)(subpat, true, v);
-                    }
-                    _ => visit::visit_pat(pat, behind_bad_pointer, v)
-                }
-            },
-            .. *visit::default_visitor::<bool>()
-        });
-        (vt.visit_pat)(*pat, false, vt);
-    }
-}
-
-// Local Variables:
-// mode: rust
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
index 06dd18b3bf3f40d9fc6c80edc52e1b48a4109104..df937c92d95dbce31af85b56ab6caec9eb0fe49f 100644 (file)
@@ -8,16 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syntax::ast::*;
-use syntax::{visit, ast_util, ast_map};
+use core::prelude::*;
+
 use driver::session::Session;
+use middle::resolve;
+use middle::ty;
+use middle::typeck;
+use util::ppaux;
+
+use core::dvec::DVec;
+use core::option;
 use std::map::HashMap;
-use dvec::DVec;
+use syntax::ast::*;
+use syntax::{visit, ast_util, ast_map};
 
 fn check_crate(sess: Session, crate: @crate, ast_map: ast_map::map,
                def_map: resolve::DefMap,
                 method_map: typeck::method_map, tcx: ty::ctxt) {
-    visit::visit_crate(*crate, false, visit::mk_vt(@{
+    visit::visit_crate(*crate, false, visit::mk_vt(@visit::Visitor {
         visit_item: |a,b,c| check_item(sess, ast_map, def_map, a, b, c),
         visit_pat: check_pat,
         visit_expr: |a,b,c|
@@ -49,7 +57,8 @@ fn check_item(sess: Session, ast_map: ast_map::map,
 fn check_pat(p: @pat, &&_is_const: bool, v: visit::vt<bool>) {
     fn is_str(e: @expr) -> bool {
         match e.node {
-          expr_vstore(@{node: expr_lit(@{node: lit_str(_), _}), _},
+          expr_vstore(@{node: expr_lit(@spanned { node: lit_str(_),
+                                                  _}), _},
                       expr_vstore_uniq) => true,
           _ => false
         }
@@ -76,7 +85,7 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
                           ~"disallowed operator in constant expression");
             return;
           }
-          expr_lit(@{node: lit_str(_), _}) => { }
+          expr_lit(@spanned {node: lit_str(_), _}) => { }
           expr_binary(_, _, _) | expr_unary(_, _) => {
             if method_map.contains_key(e.id) {
                 sess.span_err(e.span, ~"user-defined operators are not \
@@ -88,7 +97,7 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
             let ety = ty::expr_ty(tcx, e);
             if !ty::type_is_numeric(ety) {
                 sess.span_err(e.span, ~"can not cast to `" +
-                              util::ppaux::ty_to_str(tcx, ety) +
+                              ppaux::ty_to_str(tcx, ety) +
                               ~"` in a constant expression");
             }
           }
@@ -129,11 +138,12 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
           expr_call(callee, _, false) => {
             match def_map.find(callee.id) {
                 Some(def_struct(*)) => {}    // OK.
+                Some(def_variant(*)) => {}    // OK.
                 _ => {
                     sess.span_err(
                         e.span,
                         ~"function calls in constants are limited to \
-                          structure constructors");
+                          struct and enum constructors");
                 }
             }
           }
@@ -162,7 +172,7 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
         }
     }
     match e.node {
-      expr_lit(@{node: lit_int(v, t), _}) => {
+      expr_lit(@spanned {node: lit_int(v, t), _}) => {
         if t != ty_char {
             if (v as u64) > ast_util::int_ty_max(
                 if t == ty_i { sess.targ_cfg.int_type } else { t }) {
@@ -170,7 +180,7 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
             }
         }
       }
-      expr_lit(@{node: lit_uint(v, t), _}) => {
+      expr_lit(@spanned {node: lit_uint(v, t), _}) => {
         if v > ast_util::uint_ty_max(
             if t == ty_u { sess.targ_cfg.uint_type } else { t }) {
             sess.span_err(e.span, ~"literal out of range for its type");
@@ -202,7 +212,7 @@ fn check_item_recursion(sess: Session, ast_map: ast_map::map,
         idstack: @DVec()
     };
 
-    let visitor = visit::mk_vt(@{
+    let visitor = visit::mk_vt(@visit::Visitor {
         visit_item: visit_item,
         visit_expr: visit_expr,
         .. *visit::default_visitor()
index 5ff186126fb0c96ce1d159dc982ebddf8156d3ef..0e260c54fe26b4a65cd452bc0d9e36b0816b204f 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
+use middle::ty;
+
 use syntax::ast::*;
 use syntax::visit;
 
@@ -16,7 +19,7 @@
 fn check_crate(tcx: ty::ctxt, crate: @crate) {
     visit::visit_crate(*crate,
                        {in_loop: false, can_ret: true},
-                       visit::mk_vt(@{
+                       visit::mk_vt(@visit::Visitor {
         visit_item: |i, _cx, v| {
             visit::visit_item(i, {in_loop: false, can_ret: true}, v);
         },
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
new file mode 100644 (file)
index 0000000..0a063d1
--- /dev/null
@@ -0,0 +1,853 @@
+// 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 core::prelude::*;
+
+use middle::const_eval::{compare_const_vals, lookup_const_by_id};
+use middle::const_eval::{eval_const_expr, const_val, const_int, const_bool};
+use middle::pat_util::*;
+use middle::ty::*;
+use middle::ty;
+use middle::typeck::method_map;
+use util::ppaux::ty_to_str;
+
+use core::cmp;
+use core::option;
+use core::uint;
+use core::vec;
+use std::map::HashMap;
+use std::sort;
+use syntax::ast::*;
+use syntax::ast_util::{variant_def_ids, dummy_sp, unguarded_pat, walk_pat};
+use syntax::ast_util;
+use syntax::codemap::span;
+use syntax::print::pprust::pat_to_str;
+use syntax::visit;
+
+struct MatchCheckCtxt {
+    tcx: ty::ctxt,
+    method_map: method_map,
+}
+
+fn check_crate(tcx: ty::ctxt, method_map: method_map, crate: @crate) {
+    let cx = @MatchCheckCtxt { tcx: tcx, method_map: method_map };
+    visit::visit_crate(*crate, (), visit::mk_vt(@visit::Visitor {
+        visit_expr: |a,b,c| check_expr(cx, a, b, c),
+        visit_local: |a,b,c| check_local(cx, a, b, c),
+        visit_fn: |kind, decl, body, sp, id, e, v|
+            check_fn(cx, kind, decl, body, sp, id, e, v),
+        .. *visit::default_visitor::<()>()
+    }));
+    tcx.sess.abort_if_errors();
+}
+
+fn expr_is_non_moving_lvalue(cx: @MatchCheckCtxt, expr: @expr) -> bool {
+    if !ty::expr_is_lval(cx.tcx, cx.method_map, expr) {
+        return false;
+    }
+
+    match cx.tcx.value_modes.find(expr.id) {
+        Some(MoveValue) => return false,
+        Some(CopyValue) | Some(ReadValue) => return true,
+        None => {
+            cx.tcx.sess.span_bug(expr.span, ~"no entry in value mode map");
+        }
+    }
+}
+
+fn check_expr(cx: @MatchCheckCtxt, ex: @expr, &&s: (), v: visit::vt<()>) {
+    visit::visit_expr(ex, s, v);
+    match ex.node {
+      expr_match(scrut, ref arms) => {
+        // First, check legality of move bindings.
+        let is_non_moving_lvalue = expr_is_non_moving_lvalue(cx, ex);
+        for arms.each |arm| {
+            check_legality_of_move_bindings(cx,
+                                            is_non_moving_lvalue,
+                                            arm.guard.is_some(),
+                                            arm.pats);
+        }
+
+        check_arms(cx, (/*bad*/copy *arms));
+        /* Check for exhaustiveness */
+         // Check for empty enum, because is_useful only works on inhabited
+         // types.
+       let pat_ty = node_id_to_type(cx.tcx, scrut.id);
+       if (*arms).is_empty() {
+           if !type_is_empty(cx.tcx, pat_ty) {
+               // We know the type is inhabited, so this must be wrong
+               cx.tcx.sess.span_err(ex.span, fmt!("non-exhaustive patterns: \
+                            type %s is non-empty",
+                            ty_to_str(cx.tcx, pat_ty)));
+           }
+           // If the type *is* empty, it's vacuously exhaustive
+           return;
+       }
+       match ty::get(pat_ty).sty {
+          ty_enum(did, _) => {
+              if (*enum_variants(cx.tcx, did)).is_empty() &&
+                    (*arms).is_empty() {
+
+               return;
+            }
+          }
+          _ => { /* We assume only enum types can be uninhabited */ }
+       }
+       let arms = vec::concat(vec::filter_map((*arms), unguarded_pat));
+       check_exhaustive(cx, ex.span, arms);
+     }
+     _ => ()
+    }
+}
+
+// Check for unreachable patterns
+fn check_arms(cx: @MatchCheckCtxt, arms: ~[arm]) {
+    let mut seen = ~[];
+    for arms.each |arm| {
+        for arm.pats.each |pat| {
+            let v = ~[*pat];
+            match is_useful(cx, seen, v) {
+              not_useful => {
+                cx.tcx.sess.span_err(pat.span, ~"unreachable pattern");
+              }
+              _ => ()
+            }
+            if arm.guard.is_none() { seen.push(v); }
+        }
+    }
+}
+
+fn raw_pat(p: @pat) -> @pat {
+    match p.node {
+      pat_ident(_, _, Some(s)) => { raw_pat(s) }
+      _ => { p }
+    }
+}
+
+fn check_exhaustive(cx: @MatchCheckCtxt, sp: span, pats: ~[@pat]) {
+    assert(pats.is_not_empty());
+    let ext = match is_useful(cx, vec::map(pats, |p| ~[*p]), ~[wild()]) {
+      not_useful => return, // This is good, wildcard pattern isn't reachable
+      useful_ => None,
+      useful(ty, ref ctor) => {
+        match ty::get(ty).sty {
+          ty::ty_bool => {
+            match (*ctor) {
+              val(const_bool(true)) => Some(~"true"),
+              val(const_bool(false)) => Some(~"false"),
+              _ => None
+            }
+          }
+          ty::ty_enum(id, _) => {
+              let vid = match (*ctor) { variant(id) => id,
+              _ => fail ~"check_exhaustive: non-variant ctor" };
+            match vec::find(*ty::enum_variants(cx.tcx, id),
+                                |v| v.id == vid) {
+                Some(v) => Some(cx.tcx.sess.str_of(v.name)),
+              None => fail ~"check_exhaustive: bad variant in ctor"
+            }
+          }
+          ty::ty_unboxed_vec(*) | ty::ty_evec(*) => {
+            match (*ctor) {
+              vec(n) => Some(fmt!("vectors of length %u", n)),
+              _ => None
+            }
+          }
+          _ => None
+        }
+      }
+    };
+    let msg = ~"non-exhaustive patterns" + match ext {
+      Some(ref s) => ~": " + (*s) + ~" not covered",
+      None => ~""
+    };
+    cx.tcx.sess.span_err(sp, msg);
+}
+
+type matrix = ~[~[@pat]];
+
+enum useful { useful(ty::t, ctor), useful_, not_useful }
+
+enum ctor {
+    single,
+    variant(def_id),
+    val(const_val),
+    range(const_val, const_val),
+    vec(uint)
+}
+
+impl ctor : cmp::Eq {
+    pure fn eq(&self, other: &ctor) -> bool {
+        match ((*self), (*other)) {
+            (single, single) => true,
+            (variant(did_self), variant(did_other)) => did_self == did_other,
+            (val(ref cv_self), val(ref cv_other)) =>
+                (*cv_self) == (*cv_other),
+            (range(ref cv0_self, ref cv1_self),
+             range(ref cv0_other, ref cv1_other)) => {
+                (*cv0_self) == (*cv0_other) && (*cv1_self) == (*cv1_other)
+            }
+            (vec(n_self), vec(n_other)) => n_self == n_other,
+            (single, _) | (variant(_), _) | (val(_), _) |
+            (range(*), _) | (vec(*), _) => {
+                false
+            }
+        }
+    }
+    pure fn ne(&self, other: &ctor) -> bool { !(*self).eq(other) }
+}
+
+// Algorithm from http://moscova.inria.fr/~maranget/papers/warn/index.html
+//
+// Whether a vector `v` of patterns is 'useful' in relation to a set of such
+// vectors `m` is defined as there being a set of inputs that will match `v`
+// but not any of the sets in `m`.
+//
+// This is used both for reachability checking (if a pattern isn't useful in
+// relation to preceding patterns, it is not reachable) and exhaustiveness
+// checking (if a wildcard pattern is useful in relation to a matrix, the
+// matrix isn't exhaustive).
+
+// Note: is_useful doesn't work on empty types, as the paper notes.
+// So it assumes that v is non-empty.
+fn is_useful(cx: @MatchCheckCtxt, +m: matrix, +v: ~[@pat]) -> useful {
+    if m.len() == 0u { return useful_; }
+    if m[0].len() == 0u { return not_useful; }
+    let real_pat = match vec::find(m, |r| r[0].id != 0) {
+      Some(r) => r[0], None => v[0]
+    };
+    let left_ty = if real_pat.id == 0 { ty::mk_nil(cx.tcx) }
+                  else { ty::node_id_to_type(cx.tcx, real_pat.id) };
+
+    match pat_ctor_id(cx, v[0]) {
+      None => {
+        match missing_ctor(cx, m, left_ty) {
+          None => {
+            match ty::get(left_ty).sty {
+              ty::ty_bool => {
+                match is_useful_specialized(cx, m, v,
+                                            val(const_bool(true)),
+                                            0u, left_ty){
+                  not_useful => {
+                    is_useful_specialized(cx, m, v,
+                                          val(const_bool(false)),
+                                          0u, left_ty)
+                  }
+                  ref u => (/*bad*/copy *u)
+                }
+              }
+              ty::ty_enum(eid, _) => {
+                for (*ty::enum_variants(cx.tcx, eid)).each |va| {
+                    match is_useful_specialized(cx, m, v, variant(va.id),
+                                                va.args.len(), left_ty) {
+                      not_useful => (),
+                      ref u => return (/*bad*/copy *u)
+                    }
+                }
+                not_useful
+              }
+              ty::ty_unboxed_vec(*) | ty::ty_evec(*) => {
+                let max_len = do m.foldr(0) |r, max_len| {
+                  match /*bad*/copy r[0].node {
+                    pat_vec(elems, _) => uint::max(elems.len(), max_len),
+                    _ => max_len
+                  }
+                };
+                for uint::range(0, max_len + 1) |n| {
+                  match is_useful_specialized(cx, m, v, vec(n), n, left_ty) {
+                    not_useful => (),
+                    ref u => return (/*bad*/copy *u)
+                  }
+                }
+                not_useful
+              }
+              _ => {
+                let arity = ctor_arity(cx, single, left_ty);
+                is_useful_specialized(cx, m, v, single, arity, left_ty)
+              }
+            }
+          }
+          Some(ref ctor) => {
+            match is_useful(cx, vec::filter_map(m, |r| default(cx, copy *r)),
+                            vec::tail(v)) {
+              useful_ => useful(left_ty, (/*bad*/copy *ctor)),
+              ref u => (/*bad*/copy *u)
+            }
+          }
+        }
+      }
+      Some(ref v0_ctor) => {
+        let arity = ctor_arity(cx, (*v0_ctor), left_ty);
+        is_useful_specialized(cx, m, v, /*bad*/copy *v0_ctor, arity, left_ty)
+      }
+    }
+}
+
+fn is_useful_specialized(cx: @MatchCheckCtxt, m: matrix, +v: ~[@pat],
+                         +ctor: ctor, arity: uint, lty: ty::t) -> useful {
+    let ms = vec::filter_map(m, |r| specialize(cx, copy *r,
+                                               ctor, arity, lty));
+    let could_be_useful = is_useful(
+        cx, ms, specialize(cx, v, ctor, arity, lty).get());
+    match could_be_useful {
+      useful_ => useful(lty, ctor),
+      ref u => (/*bad*/copy *u)
+    }
+}
+
+fn pat_ctor_id(cx: @MatchCheckCtxt, p: @pat) -> Option<ctor> {
+    let pat = raw_pat(p);
+    match /*bad*/copy pat.node {
+      pat_wild => { None }
+      pat_ident(_, _, _) | pat_enum(_, _) => {
+        match cx.tcx.def_map.find(pat.id) {
+          Some(def_variant(_, id)) => Some(variant(id)),
+          Some(def_const(did)) => {
+            let const_expr = lookup_const_by_id(cx.tcx, did).get();
+            Some(val(eval_const_expr(cx.tcx, const_expr)))
+          }
+          _ => None
+        }
+      }
+      pat_lit(expr) => { Some(val(eval_const_expr(cx.tcx, expr))) }
+      pat_range(lo, hi) => {
+        Some(range(eval_const_expr(cx.tcx, lo), eval_const_expr(cx.tcx, hi)))
+      }
+      pat_struct(*) => {
+        match cx.tcx.def_map.find(pat.id) {
+          Some(def_variant(_, id)) => Some(variant(id)),
+          _ => Some(single)
+        }
+      }
+      pat_box(_) | pat_uniq(_) | pat_rec(_, _) | pat_tup(_) |
+      pat_region(*) => {
+        Some(single)
+      }
+      pat_vec(elems, tail) => {
+        match tail {
+          Some(_) => None,
+          None => Some(vec(elems.len()))
+        }
+      }
+    }
+}
+
+fn is_wild(cx: @MatchCheckCtxt, p: @pat) -> bool {
+    let pat = raw_pat(p);
+    match pat.node {
+      pat_wild => { true }
+      pat_ident(_, _, _) => {
+        match cx.tcx.def_map.find(pat.id) {
+          Some(def_variant(_, _)) | Some(def_const(*)) => { false }
+          _ => { true }
+        }
+      }
+      _ => { false }
+    }
+}
+
+fn missing_ctor(cx: @MatchCheckCtxt,
+                m: matrix,
+                left_ty: ty::t)
+             -> Option<ctor> {
+    match ty::get(left_ty).sty {
+      ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) | ty::ty_tup(_) |
+      ty::ty_rec(_) | ty::ty_struct(*) => {
+        for m.each |r| {
+            if !is_wild(cx, r[0]) { return None; }
+        }
+        return Some(single);
+      }
+      ty::ty_enum(eid, _) => {
+        let mut found = ~[];
+        for m.each |r| {
+            do option::iter(&pat_ctor_id(cx, r[0])) |id| {
+                if !vec::contains(found, id) {
+                    found.push(/*bad*/copy *id);
+                }
+            }
+        }
+        let variants = ty::enum_variants(cx.tcx, eid);
+        if found.len() != (*variants).len() {
+            for vec::each(*variants) |v| {
+                if !found.contains(&(variant(v.id))) {
+                    return Some(variant(v.id));
+                }
+            }
+            fail;
+        } else { None }
+      }
+      ty::ty_nil => None,
+      ty::ty_bool => {
+        let mut true_found = false, false_found = false;
+        for m.each |r| {
+            match pat_ctor_id(cx, r[0]) {
+              None => (),
+              Some(val(const_bool(true))) => true_found = true,
+              Some(val(const_bool(false))) => false_found = true,
+              _ => fail ~"impossible case"
+            }
+        }
+        if true_found && false_found { None }
+        else if true_found { Some(val(const_bool(false))) }
+        else { Some(val(const_bool(true))) }
+      }
+      ty::ty_unboxed_vec(*) | ty::ty_evec(*) => {
+
+        // Find the lengths and tails of all vector patterns.
+        let vec_pat_lens = do m.filter_map |r| {
+            match /*bad*/copy r[0].node {
+                pat_vec(elems, tail) => {
+                    Some((elems.len(), tail.is_some()))
+                }
+                _ => None
+            }
+        };
+
+        // Sort them by length such that for patterns of the same length,
+        // those with a destructured tail come first.
+        let mut sorted_vec_lens = sort::merge_sort(vec_pat_lens,
+            |&(len1, tail1), &(len2, tail2)| {
+                if len1 == len2 {
+                    tail1 > tail2
+                } else {
+                    len1 <= len2
+                }
+            }
+        );
+        vec::dedup(&mut sorted_vec_lens);
+
+        let mut found_tail = false;
+        let mut next = 0;
+        let mut missing = None;
+        for sorted_vec_lens.each |&(length, tail)| {
+            if length != next {
+                missing = Some(next);
+                break;
+            }
+            if tail {
+                found_tail = true;
+                break;
+            }
+            next += 1;
+        }
+
+        // We found patterns of all lengths within <0, next), yet there was no
+        // pattern with a tail - therefore, we report vec(next) as missing.
+        if !found_tail {
+            missing = Some(next);
+        }
+        match missing {
+          Some(k) => Some(vec(k)),
+          None => None
+        }
+      }
+      _ => Some(single)
+    }
+}
+
+fn ctor_arity(cx: @MatchCheckCtxt, ctor: ctor, ty: ty::t) -> uint {
+    match /*bad*/copy ty::get(ty).sty {
+      ty::ty_tup(fs) => fs.len(),
+      ty::ty_rec(fs) => fs.len(),
+      ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) => 1u,
+      ty::ty_enum(eid, _) => {
+          let id = match ctor { variant(id) => id,
+          _ => fail ~"impossible case" };
+        match vec::find(*ty::enum_variants(cx.tcx, eid), |v| v.id == id ) {
+            Some(v) => v.args.len(),
+            None => fail ~"impossible case"
+        }
+      }
+      ty::ty_struct(cid, _) => ty::lookup_struct_fields(cx.tcx, cid).len(),
+      ty::ty_unboxed_vec(*) | ty::ty_evec(*) => {
+        match ctor {
+          vec(n) => n,
+          _ => 0u
+        }
+      }
+      _ => 0u
+    }
+}
+
+fn wild() -> @pat {
+    @{id: 0, node: pat_wild, span: ast_util::dummy_sp()}
+}
+
+fn specialize(cx: @MatchCheckCtxt, r: ~[@pat], ctor_id: ctor, arity: uint,
+              left_ty: ty::t) -> Option<~[@pat]> {
+    let r0 = raw_pat(r[0]);
+    match /*bad*/copy r0.node {
+      pat_wild => Some(vec::append(vec::from_elem(arity, wild()),
+                                   vec::tail(r))),
+      pat_ident(_, _, _) => {
+        match cx.tcx.def_map.find(r0.id) {
+          Some(def_variant(_, id)) => {
+            if variant(id) == ctor_id { Some(vec::tail(r)) }
+            else { None }
+          }
+          Some(def_const(did)) => {
+            let const_expr = lookup_const_by_id(cx.tcx, did).get();
+            let e_v = eval_const_expr(cx.tcx, const_expr);
+            let match_ = match ctor_id {
+                val(ref v) => compare_const_vals(e_v, (*v)) == 0,
+                range(ref c_lo, ref c_hi) => {
+                    compare_const_vals((*c_lo), e_v) >= 0 &&
+                        compare_const_vals((*c_hi), e_v) <= 0
+                }
+                single => true,
+                _ => fail ~"type error"
+            };
+            if match_ { Some(vec::tail(r)) } else { None }
+          }
+          _ => Some(vec::append(vec::from_elem(arity, wild()), vec::tail(r)))
+        }
+      }
+      pat_enum(_, args) => {
+        match cx.tcx.def_map.get(r0.id) {
+          def_variant(_, id) if variant(id) == ctor_id => {
+            let args = match args {
+              Some(args) => args,
+              None => vec::from_elem(arity, wild())
+            };
+            Some(vec::append(args, vec::tail(r)))
+          }
+          def_variant(_, _) => None,
+          def_struct(*) => {
+            // XXX: Is this right? --pcw
+            let new_args;
+            match args {
+              Some(args) => new_args = args,
+              None => new_args = vec::from_elem(arity, wild())
+            }
+            Some(vec::append(new_args, vec::tail(r)))
+          }
+          _ => None
+        }
+      }
+      pat_rec(flds, _) => {
+        let ty_flds = match /*bad*/copy ty::get(left_ty).sty {
+            ty::ty_rec(flds) => flds,
+            _ => fail ~"bad type for pat_rec"
+        };
+        let args = vec::map(ty_flds, |ty_fld| {
+            match vec::find(flds, |f| f.ident == ty_fld.ident ) {
+              Some(f) => f.pat,
+              _ => wild()
+            }
+        });
+        Some(vec::append(args, vec::tail(r)))
+      }
+      pat_struct(_, flds, _) => {
+        // Is this a struct or an enum variant?
+        match cx.tcx.def_map.get(r0.id) {
+            def_variant(_, variant_id) => {
+                if variant(variant_id) == ctor_id {
+                    // XXX: Is this right? --pcw
+                    let args = flds.map(|ty_field| {
+                        match vec::find(flds, |f| f.ident == ty_field.ident) {
+                            Some(f) => f.pat,
+                            _ => wild()
+                        }
+                    });
+                    Some(vec::append(args, vec::tail(r)))
+                } else {
+                    None
+                }
+            }
+            _ => {
+                // Grab the class data that we care about.
+                let class_fields, class_id;
+                match ty::get(left_ty).sty {
+                    ty::ty_struct(cid, _) => {
+                        class_id = cid;
+                        class_fields = ty::lookup_struct_fields(cx.tcx,
+                                                               class_id);
+                    }
+                    _ => {
+                        cx.tcx.sess.span_bug(r0.span, ~"struct pattern \
+                                                        didn't resolve to a \
+                                                        struct");
+                    }
+                }
+                let args = vec::map(class_fields, |class_field| {
+                    match vec::find(flds, |f| f.ident == class_field.ident ) {
+                      Some(f) => f.pat,
+                      _ => wild()
+                    }
+                });
+                Some(vec::append(args, vec::tail(r)))
+            }
+        }
+      }
+      pat_tup(args) => Some(vec::append(args, vec::tail(r))),
+      pat_box(a) | pat_uniq(a) | pat_region(a) =>
+          Some(vec::append(~[a], vec::tail(r))),
+      pat_lit(expr) => {
+        let e_v = eval_const_expr(cx.tcx, expr);
+        let match_ = match ctor_id {
+          val(ref v) => compare_const_vals(e_v, (*v)) == 0,
+          range(ref c_lo, ref c_hi) => {
+            compare_const_vals((*c_lo), e_v) >= 0 &&
+                compare_const_vals((*c_hi), e_v) <= 0
+          }
+          single => true,
+          _ => fail ~"type error"
+        };
+        if match_ { Some(vec::tail(r)) } else { None }
+      }
+      pat_range(lo, hi) => {
+        let (c_lo, c_hi) = match ctor_id {
+          val(ref v) => ((/*bad*/copy *v), (/*bad*/copy *v)),
+          range(ref lo, ref hi) => ((/*bad*/copy *lo), (/*bad*/copy *hi)),
+          single => return Some(vec::tail(r)),
+          _ => fail ~"type error"
+        };
+        let v_lo = eval_const_expr(cx.tcx, lo),
+            v_hi = eval_const_expr(cx.tcx, hi);
+        let match_ = compare_const_vals(c_lo, v_lo) >= 0 &&
+                    compare_const_vals(c_hi, v_hi) <= 0;
+        if match_ { Some(vec::tail(r)) } else { None }
+      }
+      pat_vec(elems, tail) => {
+        match ctor_id {
+          vec(_) => {
+            if elems.len() < arity && tail.is_some() {
+              // XXX: Bad copy.
+              Some(vec::append(
+                vec::append(copy elems, vec::from_elem(
+                    arity - elems.len(), wild()
+                )),
+                vec::tail(r)
+              ))
+            } else if elems.len() == arity {
+              Some(vec::append(elems, vec::tail(r)))
+            } else {
+              None
+            }
+          }
+          _ => None
+        }
+      }
+    }
+}
+
+fn default(cx: @MatchCheckCtxt, r: ~[@pat]) -> Option<~[@pat]> {
+    if is_wild(cx, r[0]) { Some(vec::tail(r)) }
+    else { None }
+}
+
+fn check_local(cx: @MatchCheckCtxt, loc: @local, &&s: (), v: visit::vt<()>) {
+    visit::visit_local(loc, s, v);
+    if is_refutable(cx, loc.node.pat) {
+        cx.tcx.sess.span_err(loc.node.pat.span,
+                          ~"refutable pattern in local binding");
+    }
+
+    // Check legality of move bindings.
+    let is_lvalue = match loc.node.init {
+        Some(init) => expr_is_non_moving_lvalue(cx, init),
+        None => true
+    };
+    check_legality_of_move_bindings(cx, is_lvalue, false, [ loc.node.pat ]);
+}
+
+fn check_fn(cx: @MatchCheckCtxt,
+            kind: visit::fn_kind,
+            decl: fn_decl,
+            body: blk,
+            sp: span,
+            id: node_id,
+            &&s: (),
+            v: visit::vt<()>) {
+    visit::visit_fn(kind, decl, body, sp, id, s, v);
+    for decl.inputs.each |input| {
+        if is_refutable(cx, input.pat) {
+            cx.tcx.sess.span_err(input.pat.span,
+                              ~"refutable pattern in function argument");
+        }
+    }
+}
+
+fn is_refutable(cx: @MatchCheckCtxt, pat: &pat) -> bool {
+    match cx.tcx.def_map.find(pat.id) {
+      Some(def_variant(enum_id, _)) => {
+        if vec::len(*ty::enum_variants(cx.tcx, enum_id)) != 1u {
+            return true;
+        }
+      }
+      Some(def_const(*)) => return true,
+      _ => ()
+    }
+
+    match /*bad*/copy pat.node {
+      pat_box(sub) | pat_uniq(sub) | pat_region(sub) |
+      pat_ident(_, _, Some(sub)) => {
+        is_refutable(cx, sub)
+      }
+      pat_wild | pat_ident(_, _, None) => { false }
+      pat_lit(@{node: expr_lit(@spanned { node: lit_nil, _}), _}) => {
+        // "()"
+        false
+      }
+      pat_lit(_) | pat_range(_, _) => { true }
+      pat_rec(fields, _) => {
+        fields.any(|f| is_refutable(cx, f.pat))
+      }
+      pat_struct(_, fields, _) => {
+        fields.any(|f| is_refutable(cx, f.pat))
+      }
+      pat_tup(elts) => {
+        elts.any(|elt| is_refutable(cx, *elt))
+      }
+      pat_enum(_, Some(args)) => {
+        args.any(|a| is_refutable(cx, *a))
+      }
+      pat_enum(_,_) => { false }
+      pat_vec(*) => { true }
+    }
+}
+
+// Legality of move bindings checking
+
+fn check_legality_of_move_bindings(cx: @MatchCheckCtxt,
+                                   is_lvalue: bool,
+                                   has_guard: bool,
+                                   pats: &[@pat]) {
+    let tcx = cx.tcx;
+    let def_map = tcx.def_map;
+    let mut by_ref_span = None;
+    let mut any_by_move = false;
+    for pats.each |pat| {
+        do pat_bindings(def_map, *pat) |bm, id, span, _path| {
+            match bm {
+                bind_by_ref(_) => {
+                    by_ref_span = Some(span);
+                }
+                bind_by_move => {
+                    any_by_move = true;
+                }
+                bind_by_value => {}
+                bind_infer => {
+                    match cx.tcx.value_modes.find(id) {
+                        Some(MoveValue) => any_by_move = true,
+                        Some(CopyValue) | Some(ReadValue) => {}
+                        None => {
+                            cx.tcx.sess.span_bug(span, ~"no mode for pat \
+                                                         binding");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    let check_move: &fn(@pat, Option<@pat>) = |p, sub| {
+        // check legality of moving out of the enum
+        if sub.is_some() {
+            tcx.sess.span_err(
+                p.span,
+                ~"cannot bind by-move with sub-bindings");
+        } else if has_guard {
+            tcx.sess.span_err(
+                p.span,
+                ~"cannot bind by-move into a pattern guard");
+        } else if by_ref_span.is_some() {
+            tcx.sess.span_err(
+                p.span,
+                ~"cannot bind by-move and by-ref \
+                  in the same pattern");
+            tcx.sess.span_note(
+                by_ref_span.get(),
+                ~"by-ref binding occurs here");
+        } else if is_lvalue {
+            tcx.sess.span_err(
+                p.span,
+                ~"cannot bind by-move when \
+                  matching an lvalue");
+        }
+    };
+
+    if !any_by_move { return; } // pointless micro-optimization
+    for pats.each |pat| {
+        do walk_pat(*pat) |p| {
+            if pat_is_binding(def_map, p) {
+                match p.node {
+                    pat_ident(bind_by_move, _, sub) => check_move(p, sub),
+                    pat_ident(bind_infer, _, sub) => {
+                        match tcx.value_modes.find(p.id) {
+                            Some(MoveValue) => check_move(p, sub),
+                            Some(CopyValue) | Some(ReadValue) => {}
+                            None => {
+                                cx.tcx.sess.span_bug(
+                                    pat.span, ~"no mode for pat binding");
+                            }
+                        }
+                    }
+                    _ => {}
+                }
+            }
+        }
+
+        // Now check to ensure that any move binding is not behind an @ or &.
+        // This is always illegal.
+        let vt = visit::mk_vt(@visit::Visitor {
+            visit_pat: |pat, behind_bad_pointer, v| {
+                let error_out = || {
+                    cx.tcx.sess.span_err(pat.span, ~"by-move pattern \
+                                                     bindings may not occur \
+                                                     behind @ or & bindings");
+                };
+                match pat.node {
+                    pat_ident(binding_mode, _, sub) => {
+                        debug!("(check legality of move) checking pat \
+                                ident with behind_bad_pointer %?",
+                                behind_bad_pointer);
+                        match binding_mode {
+                            bind_by_move if behind_bad_pointer => error_out(),
+                            bind_infer if behind_bad_pointer => {
+                                match cx.tcx.value_modes.find(pat.id) {
+                                    Some(MoveValue) => error_out(),
+                                    Some(CopyValue) |
+                                    Some(ReadValue) => {}
+                                    None => {
+                                        cx.tcx.sess.span_bug(pat.span,
+                                            ~"no mode for pat binding");
+                                    }
+                                }
+                            }
+                            _ => {}
+                        }
+                        match sub {
+                            None => {}
+                            Some(subpat) => {
+                                (v.visit_pat)(subpat, behind_bad_pointer, v);
+                            }
+                        }
+                    }
+                    pat_box(subpat) | pat_region(subpat) => {
+                        (v.visit_pat)(subpat, true, v);
+                    }
+                    _ => visit::visit_pat(pat, behind_bad_pointer, v)
+                }
+            },
+            .. *visit::default_visitor::<bool>()
+        });
+        (vt.visit_pat)(*pat, false, vt);
+    }
+}
+
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
index a51885b1fc7eb35e72128605ca6c505cb66aa28e..530e63acf5710fa59633aefaed356afd78c80770 100644 (file)
@@ -8,6 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use middle::resolve;
+use middle::ty;
+use middle;
+
+use core::cmp;
+use core::float;
+use core::vec;
 use syntax::{ast, ast_map, ast_util, visit};
 use syntax::ast::*;
 
@@ -38,7 +47,7 @@
 //        & and * pointers
 //        copies of general constants
 //
-//        (in theory, probably not at first: if/alt on integer-const
+//        (in theory, probably not at first: if/match on integer-const
 //         conditions / descriminants)
 //
 //   - Non-constants: everything else.
@@ -72,7 +81,7 @@ fn classify(e: @expr,
       Some(x) => x,
       None => {
         let cn =
-            match e.node {
+            match /*bad*/copy e.node {
               ast::expr_lit(lit) => {
                 match lit.node {
                   ast::lit_str(*) |
@@ -198,7 +207,7 @@ fn lookup_constness(tcx: ty::ctxt, e: @expr) -> constness {
 fn process_crate(crate: @ast::crate,
                  def_map: resolve::DefMap,
                  tcx: ty::ctxt) {
-    let v = visit::mk_simple_visitor(@{
+    let v = visit::mk_simple_visitor(@visit::SimpleVisitor {
         visit_expr_post: |e| { classify(e, def_map, tcx); },
         .. *visit::default_simple_visitor()
     });
@@ -234,8 +243,8 @@ impl const_val : cmp::Eq {
 
 fn eval_const_expr(tcx: middle::ty::ctxt, e: @expr) -> const_val {
     match eval_const_expr_partial(tcx, e) {
-        Ok(ref r) => (*r),
-        Err(ref s) => fail (*s)
+        Ok(ref r) => (/*bad*/copy *r),
+        Err(ref s) => fail (/*bad*/copy *s)
     }
 }
 
@@ -251,7 +260,7 @@ fn fromb(b: bool) -> Result<const_val, ~str> { Ok(const_int(b as i64)) }
           Ok(const_uint(i)) => Ok(const_uint(-i)),
           Ok(const_str(_)) => Err(~"Negate on string"),
           Ok(const_bool(_)) => Err(~"Negate on boolean"),
-          ref err => (*err)
+          ref err => (/*bad*/copy *err)
         }
       }
       expr_unary(not, inner) => {
@@ -398,7 +407,7 @@ fn fromb(b: bool) -> Result<const_val, ~str> { Ok(const_int(b as i64)) }
 
 fn lit_to_const(lit: @lit) -> const_val {
     match lit.node {
-      lit_str(s) => const_str(*s),
+      lit_str(s) => const_str(/*bad*/copy *s),
       lit_int(n, _) => const_int(n),
       lit_uint(n, _) => const_uint(n),
       lit_int_unsuffixed(n) => const_int(n),
index 38ec7dd5eb07113c5fac9495d14a861e6982842e..3c1f261c1f8af56c51921b67c19d583e91f7d708 100644 (file)
@@ -8,14 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // A pass that annotates for each loops and functions with the free
 // variables that they contain.
 
-use syntax::print::pprust::path_to_str;
+use middle::resolve;
+use middle::ty;
+
+use core::int;
+use core::option::*;
+use core::vec;
 use std::map::*;
-use option::*;
-use syntax::{ast, ast_util, visit};
 use syntax::codemap::span;
+use syntax::print::pprust::path_to_str;
+use syntax::{ast, ast_util, visit};
 
 export annotate_freevars;
 export freevar_map;
@@ -84,10 +90,11 @@ fn ignore_item(_i: @ast::item, &&_depth: int, _v: visit::vt<int>) { }
             }
         };
 
-    let v = visit::mk_vt(@{visit_item: ignore_item, visit_expr: walk_expr,
-                           .. *visit::default_visitor()});
+    let v = visit::mk_vt(@visit::Visitor {visit_item: ignore_item,
+                                          visit_expr: walk_expr,
+                                          .. *visit::default_visitor()});
     (v.visit_block)(blk, 1, v);
-    return @*refs;
+    return @/*bad*/copy *refs;
 }
 
 // Build a map from every function and for-each body to a set of the
@@ -106,8 +113,9 @@ fn annotate_freevars(def_map: resolve::DefMap, crate: @ast::crate) ->
     };
 
     let visitor =
-        visit::mk_simple_visitor(@{visit_fn: walk_fn,
-                                   .. *visit::default_simple_visitor()});
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_fn: walk_fn,
+            .. *visit::default_simple_visitor()});
     visit::visit_crate(*crate, (), visitor);
 
     return freevars;
index e35377c5cdd9377b3a96818a2588197e7d2207bf..eee0a48ec67f9fa187eb66ced47af6cb0e8ef5c5 100644 (file)
@@ -8,12 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use middle::freevars::freevar_entry;
+use middle::freevars;
 use middle::lint::{non_implicitly_copyable_typarams, implicit_copies};
+use middle::liveness;
+use middle::pat_util;
 use middle::ty::{CopyValue, MoveValue, ReadValue};
 use middle::ty::{Kind, kind_copyable, kind_noncopyable, kind_const};
+use middle::ty;
+use middle::typeck;
+use middle;
 use util::ppaux::{ty_to_str, tys_to_str};
 
+use core::option;
+use core::str;
+use core::vec;
 use std::map::HashMap;
 use syntax::ast::*;
 use syntax::codemap::span;
@@ -65,13 +76,13 @@ fn kind_to_str(k: Kind) -> ~str {
     if ty::kind_can_be_sent(k) {
         kinds.push(~"owned");
     } else if ty::kind_is_durable(k) {
-        kinds.push(~"durable");
+        kinds.push(~"&static");
     }
 
     str::connect(kinds, ~" ")
 }
 
-type rval_map = std::map::HashMap<node_id, ()>;
+type rval_map = HashMap<node_id, ()>;
 
 type ctx = {tcx: ty::ctxt,
             method_map: typeck::method_map,
@@ -86,7 +97,7 @@ fn check_crate(tcx: ty::ctxt,
                method_map: method_map,
                last_use_map: last_use_map,
                current_item: -1};
-    let visit = visit::mk_vt(@{
+    let visit = visit::mk_vt(@visit::Visitor {
         visit_arm: check_arm,
         visit_expr: check_expr,
         visit_stmt: check_stmt,
@@ -287,7 +298,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
         }
     }
 
-    match e.node {
+    match /*bad*/copy e.node {
       expr_assign(_, ex) |
       expr_unary(box(_), ex) | expr_unary(uniq(_), ex) |
       expr_ret(Some(ex)) => {
@@ -320,7 +331,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
           Some(ex) => {
             // All noncopyable fields must be overridden
             let t = ty::expr_ty(cx.tcx, ex);
-            let ty_fields = match ty::get(t).sty {
+            let ty_fields = match /*bad*/copy ty::get(t).sty {
               ty::ty_rec(f) => f,
               ty::ty_struct(did, ref substs) =>
                   ty::struct_fields(cx.tcx, did, &(*substs)),
@@ -398,7 +409,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
 
 fn check_stmt(stmt: @stmt, cx: ctx, v: visit::vt<ctx>) {
     match stmt.node {
-      stmt_decl(@{node: decl_local(locals), _}, _) => {
+      stmt_decl(@spanned {node: decl_local(ref locals), _}, _) => {
         for locals.each |local| {
             match local.node.init {
               Some(expr) =>
@@ -560,7 +571,7 @@ fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: span) -> bool {
         match ty::get(ty).sty {
           ty::ty_param(*) => {
             tcx.sess.span_err(sp, ~"value may contain borrowed \
-                                    pointers; use `durable` bound");
+                                    pointers; use `&static` bound");
           }
           _ => {
             tcx.sess.span_err(sp, ~"value may contain borrowed \
@@ -605,7 +616,7 @@ fn check_cast_for_escaping_regions(
     // worries.
     let target_ty = ty::expr_ty(cx.tcx, target);
     let target_substs = match ty::get(target_ty).sty {
-      ty::ty_trait(_, ref substs, _) => {(*substs)}
+      ty::ty_trait(_, ref substs, _) => {(/*bad*/copy *substs)}
       _ => { return; /* not a cast to a trait */ }
     };
 
index 1f65ee8ae83243fdab2ad2fd712fa562693822d2..ae56fb7f717dad13e1660738190be6284e74e141 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // Detecting language items.
 //
 // Language items are items that represent concepts intrinsic to the language
 //
 // * Functions called by the compiler itself.
 
+use core::prelude::*;
+
 use driver::session::Session;
-use metadata::csearch::{each_path, get_item_attrs};
+use metadata::csearch::{each_lang_item, get_item_attrs};
 use metadata::cstore::{iter_crate_data};
 use metadata::decoder::{dl_def, dl_field, dl_impl};
 use syntax::ast::{crate, def_fn, def_id, def_ty, lit_str, meta_item};
 use syntax::ast::{meta_list, meta_name_value, meta_word};
 use syntax::ast_util::{local_def};
-use syntax::visit::{default_simple_visitor, mk_simple_visitor};
+use syntax::visit::{default_simple_visitor, mk_simple_visitor, SimpleVisitor};
 use syntax::visit::{visit_crate, visit_item};
 
+use core::ptr;
 use std::map::HashMap;
 use str_eq = str::eq;
 
+pub enum LangItem {
+    ConstTraitLangItem,         // 0
+    CopyTraitLangItem,          // 1
+    OwnedTraitLangItem,         // 2
+    DurableTraitLangItem,       // 3
+
+    DropTraitLangItem,          // 4
+
+    AddTraitLangItem,           // 5
+    SubTraitLangItem,           // 6
+    MulTraitLangItem,           // 7
+    DivTraitLangItem,           // 8
+    ModuloTraitLangItem,        // 9
+    NegTraitLangItem,           // 10
+    NotTraitLangItem,           // 11
+    BitXorTraitLangItem,        // 12
+    BitAndTraitLangItem,        // 13
+    BitOrTraitLangItem,         // 14
+    ShlTraitLangItem,           // 15
+    ShrTraitLangItem,           // 16
+    IndexTraitLangItem,         // 17
+
+    EqTraitLangItem,            // 18
+    OrdTraitLangItem,           // 19
+
+    StrEqFnLangItem,            // 20
+    UniqStrEqFnLangItem,        // 21
+    AnnihilateFnLangItem,       // 22
+    LogTypeFnLangItem,          // 23
+    FailFnLangItem,             // 24
+    FailBoundsCheckFnLangItem,  // 25
+    ExchangeMallocFnLangItem,   // 26
+    ExchangeFreeFnLangItem,     // 27
+    MallocFnLangItem,           // 28
+    FreeFnLangItem,             // 29
+}
+
 struct LanguageItems {
-    mut const_trait: Option<def_id>,
-    mut copy_trait: Option<def_id>,
-    mut owned_trait: Option<def_id>,
-    mut durable_trait: Option<def_id>,
-
-    mut drop_trait: Option<def_id>,
-
-    mut add_trait: Option<def_id>,
-    mut sub_trait: Option<def_id>,
-    mut mul_trait: Option<def_id>,
-    mut div_trait: Option<def_id>,
-    mut modulo_trait: Option<def_id>,
-    mut neg_trait: Option<def_id>,
-    mut bitxor_trait: Option<def_id>,
-    mut bitand_trait: Option<def_id>,
-    mut bitor_trait: Option<def_id>,
-    mut shl_trait: Option<def_id>,
-    mut shr_trait: Option<def_id>,
-    mut index_trait: Option<def_id>,
-
-    mut eq_trait: Option<def_id>,
-    mut ord_trait: Option<def_id>,
-
-    mut str_eq_fn: Option<def_id>,
-    mut uniq_str_eq_fn: Option<def_id>,
-    mut annihilate_fn: Option<def_id>,
-    mut log_type_fn: Option<def_id>
+    items: [ Option<def_id> * 30 ]
 }
 
-mod language_items {
-    #[legacy_exports];
-    fn make() -> LanguageItems {
+impl LanguageItems {
+    static pub fn new() -> LanguageItems {
         LanguageItems {
-            const_trait: None,
-            copy_trait: None,
-            owned_trait: None,
-            durable_trait: None,
-
-            drop_trait: None,
-
-            add_trait: None,
-            sub_trait: None,
-            mul_trait: None,
-            div_trait: None,
-            modulo_trait: None,
-            neg_trait: None,
-            bitxor_trait: None,
-            bitand_trait: None,
-            bitor_trait: None,
-            shl_trait: None,
-            shr_trait: None,
-            index_trait: None,
-
-            eq_trait: None,
-            ord_trait: None,
-
-            str_eq_fn: None,
-            uniq_str_eq_fn: None,
-            annihilate_fn: None,
-            log_type_fn: None
+            items: [ None, ..30 ]
+        }
+    }
+
+    fn each_item(&self, f: &fn(def_id: def_id, i: uint) -> bool) {
+        for self.items.eachi |i, &item| {
+            if !f(item.get(), i) {
+                break;
+            }
         }
     }
-}
 
-fn LanguageItemCollector(crate: @crate, session: Session,
-                         items: &r/LanguageItems)
-    -> LanguageItemCollector/&r {
+    static pub fn item_name(index: uint) -> &static/str {
+        match index {
+            0  => "const",
+            1  => "copy",
+            2  => "owned",
+            3  => "durable",
+
+            4  => "drop",
+
+            5  => "add",
+            6  => "sub",
+            7  => "mul",
+            8  => "div",
+            9  => "modulo",
+            10 => "neg",
+            11 => "not",
+            12 => "bitxor",
+            13 => "bitand",
+            14 => "bitor",
+            15 => "shl",
+            16 => "shr",
+            17 => "index",
+            18 => "eq",
+            19 => "ord",
+
+            20 => "str_eq",
+            21 => "uniq_str_eq",
+            22 => "annihilate",
+            23 => "log_type",
+            24 => "fail_",
+            25 => "fail_bounds_check",
+            26 => "exchange_malloc",
+            27 => "exchange_free",
+            28 => "malloc",
+            29 => "free",
+
+            _ => "???"
+        }
+    }
+
+    // XXX: Method macros sure would be nice here.
+
+    pub fn const_trait(&const self) -> def_id {
+        self.items[ConstTraitLangItem as uint].get()
+    }
+    pub fn copy_trait(&const self) -> def_id {
+        self.items[CopyTraitLangItem as uint].get()
+    }
+    pub fn owned_trait(&const self) -> def_id {
+        self.items[OwnedTraitLangItem as uint].get()
+    }
+    pub fn durable_trait(&const self) -> def_id {
+        self.items[DurableTraitLangItem as uint].get()
+    }
+
+    pub fn drop_trait(&const self) -> def_id {
+        self.items[DropTraitLangItem as uint].get()
+    }
+
+    pub fn add_trait(&const self) -> def_id {
+        self.items[AddTraitLangItem as uint].get()
+    }
+    pub fn sub_trait(&const self) -> def_id {
+        self.items[SubTraitLangItem as uint].get()
+    }
+    pub fn mul_trait(&const self) -> def_id {
+        self.items[MulTraitLangItem as uint].get()
+    }
+    pub fn div_trait(&const self) -> def_id {
+        self.items[DivTraitLangItem as uint].get()
+    }
+    pub fn modulo_trait(&const self) -> def_id {
+        self.items[ModuloTraitLangItem as uint].get()
+    }
+    pub fn neg_trait(&const self) -> def_id {
+        self.items[NegTraitLangItem as uint].get()
+    }
+    pub fn not_trait(&const self) -> def_id {
+        self.items[NotTraitLangItem as uint].get()
+    }
+    pub fn bitxor_trait(&const self) -> def_id {
+        self.items[BitXorTraitLangItem as uint].get()
+    }
+    pub fn bitand_trait(&const self) -> def_id {
+        self.items[BitAndTraitLangItem as uint].get()
+    }
+    pub fn bitor_trait(&const self) -> def_id {
+        self.items[BitOrTraitLangItem as uint].get()
+    }
+    pub fn shl_trait(&const self) -> def_id {
+        self.items[ShlTraitLangItem as uint].get()
+    }
+    pub fn shr_trait(&const self) -> def_id {
+        self.items[ShrTraitLangItem as uint].get()
+    }
+    pub fn index_trait(&const self) -> def_id {
+        self.items[IndexTraitLangItem as uint].get()
+    }
 
+    pub fn eq_trait(&const self) -> def_id {
+        self.items[EqTraitLangItem as uint].get()
+    }
+    pub fn ord_trait(&const self) -> def_id {
+        self.items[OrdTraitLangItem as uint].get()
+    }
+
+    pub fn str_eq_fn(&const self) -> def_id {
+        self.items[StrEqFnLangItem as uint].get()
+    }
+    pub fn uniq_str_eq_fn(&const self) -> def_id {
+        self.items[UniqStrEqFnLangItem as uint].get()
+    }
+    pub fn annihilate_fn(&const self) -> def_id {
+        self.items[AnnihilateFnLangItem as uint].get()
+    }
+    pub fn log_type_fn(&const self) -> def_id {
+        self.items[LogTypeFnLangItem as uint].get()
+    }
+    pub fn fail_fn(&const self) -> def_id {
+        self.items[FailFnLangItem as uint].get()
+    }
+    pub fn fail_bounds_check_fn(&const self) -> def_id {
+        self.items[FailBoundsCheckFnLangItem as uint].get()
+    }
+    pub fn exchange_malloc_fn(&const self) -> def_id {
+        self.items[ExchangeMallocFnLangItem as uint].get()
+    }
+    pub fn exchange_free_fn(&const self) -> def_id {
+        self.items[ExchangeFreeFnLangItem as uint].get()
+    }
+    pub fn malloc_fn(&const self) -> def_id {
+        self.items[MallocFnLangItem as uint].get()
+    }
+    pub fn free_fn(&const self) -> def_id {
+        self.items[FreeFnLangItem as uint].get()
+    }
+}
+
+fn LanguageItemCollector(crate: @crate,
+                         session: Session,
+                         items: &r/mut LanguageItems)
+                      -> LanguageItemCollector/&r {
     let item_refs = HashMap();
 
-    item_refs.insert(~"const", &mut items.const_trait);
-    item_refs.insert(~"copy", &mut items.copy_trait);
-    item_refs.insert(~"owned", &mut items.owned_trait);
-    item_refs.insert(~"durable", &mut items.durable_trait);
-
-    item_refs.insert(~"drop", &mut items.drop_trait);
-
-    item_refs.insert(~"add", &mut items.add_trait);
-    item_refs.insert(~"sub", &mut items.sub_trait);
-    item_refs.insert(~"mul", &mut items.mul_trait);
-    item_refs.insert(~"div", &mut items.div_trait);
-    item_refs.insert(~"modulo", &mut items.modulo_trait);
-    item_refs.insert(~"neg", &mut items.neg_trait);
-    item_refs.insert(~"bitxor", &mut items.bitxor_trait);
-    item_refs.insert(~"bitand", &mut items.bitand_trait);
-    item_refs.insert(~"bitor", &mut items.bitor_trait);
-    item_refs.insert(~"shl", &mut items.shl_trait);
-    item_refs.insert(~"shr", &mut items.shr_trait);
-    item_refs.insert(~"index", &mut items.index_trait);
-
-    item_refs.insert(~"eq", &mut items.eq_trait);
-    item_refs.insert(~"ord", &mut items.ord_trait);
-
-    item_refs.insert(~"str_eq", &mut items.str_eq_fn);
-    item_refs.insert(~"uniq_str_eq", &mut items.uniq_str_eq_fn);
-    item_refs.insert(~"annihilate", &mut items.annihilate_fn);
-    item_refs.insert(~"log_type", &mut items.log_type_fn);
+    item_refs.insert(~"const", ConstTraitLangItem as uint);
+    item_refs.insert(~"copy", CopyTraitLangItem as uint);
+    item_refs.insert(~"owned", OwnedTraitLangItem as uint);
+    item_refs.insert(~"durable", DurableTraitLangItem as uint);
+
+    item_refs.insert(~"drop", DropTraitLangItem as uint);
+
+    item_refs.insert(~"add", AddTraitLangItem as uint);
+    item_refs.insert(~"sub", SubTraitLangItem as uint);
+    item_refs.insert(~"mul", MulTraitLangItem as uint);
+    item_refs.insert(~"div", DivTraitLangItem as uint);
+    item_refs.insert(~"modulo", ModuloTraitLangItem as uint);
+    item_refs.insert(~"neg", NegTraitLangItem as uint);
+    item_refs.insert(~"not", NotTraitLangItem as uint);
+    item_refs.insert(~"bitxor", BitXorTraitLangItem as uint);
+    item_refs.insert(~"bitand", BitAndTraitLangItem as uint);
+    item_refs.insert(~"bitor", BitOrTraitLangItem as uint);
+    item_refs.insert(~"shl", ShlTraitLangItem as uint);
+    item_refs.insert(~"shr", ShrTraitLangItem as uint);
+    item_refs.insert(~"index", IndexTraitLangItem as uint);
+
+    item_refs.insert(~"eq", EqTraitLangItem as uint);
+    item_refs.insert(~"ord", OrdTraitLangItem as uint);
+
+    item_refs.insert(~"str_eq", StrEqFnLangItem as uint);
+    item_refs.insert(~"uniq_str_eq", UniqStrEqFnLangItem as uint);
+    item_refs.insert(~"annihilate", AnnihilateFnLangItem as uint);
+    item_refs.insert(~"log_type", LogTypeFnLangItem as uint);
+    item_refs.insert(~"fail_", FailFnLangItem as uint);
+    item_refs.insert(~"fail_bounds_check", FailBoundsCheckFnLangItem as uint);
+    item_refs.insert(~"exchange_malloc", ExchangeMallocFnLangItem as uint);
+    item_refs.insert(~"exchange_free", ExchangeFreeFnLangItem as uint);
+    item_refs.insert(~"malloc", MallocFnLangItem as uint);
+    item_refs.insert(~"free", FreeFnLangItem as uint);
 
     LanguageItemCollector {
         crate: crate,
@@ -140,16 +280,15 @@ fn LanguageItemCollector(crate: @crate, session: Session,
 }
 
 struct LanguageItemCollector {
-    items: &LanguageItems,
+    items: &mut LanguageItems,
 
     crate: @crate,
     session: Session,
 
-    item_refs: HashMap<~str,&mut Option<def_id>>,
+    item_refs: HashMap<~str,uint>,
 }
 
 impl LanguageItemCollector {
-
     fn match_and_collect_meta_item(item_def_id: def_id,
                                    meta_item: meta_item) {
         match meta_item.node {
@@ -157,8 +296,8 @@ fn match_and_collect_meta_item(item_def_id: def_id,
                 match literal.node {
                     lit_str(value) => {
                         self.match_and_collect_item(item_def_id,
-                                                    (*key),
-                                                    *value);
+                                                    (/*bad*/copy *key),
+                                                    /*bad*/copy *value);
                     }
                     _ => {} // Skip.
                 }
@@ -167,6 +306,22 @@ fn match_and_collect_meta_item(item_def_id: def_id,
         }
     }
 
+    fn collect_item(item_index: uint, item_def_id: def_id) {
+        // Check for duplicates.
+        match self.items.items[item_index] {
+            Some(original_def_id) if original_def_id != item_def_id => {
+                self.session.err(fmt!("duplicate entry for `%s`",
+                                      LanguageItems::item_name(item_index)));
+            }
+            Some(_) | None => {
+                // OK.
+            }
+        }
+
+        // Matched.
+        self.items.items[item_index] = Some(item_def_id);
+    }
+
     fn match_and_collect_item(item_def_id: def_id, key: ~str, value: ~str) {
         if key != ~"lang" {
             return;    // Didn't match.
@@ -176,29 +331,15 @@ fn match_and_collect_item(item_def_id: def_id, key: ~str, value: ~str) {
             None => {
                 // Didn't match.
             }
-            Some(item_ref) => {
-                // Check for duplicates.
-                match copy *item_ref {
-                    Some(original_def_id)
-                            if original_def_id != item_def_id => {
-
-                        self.session.err(fmt!("duplicate entry for `%s`",
-                                              value));
-                    }
-                    Some(_) | None => {
-                        // OK.
-                    }
-                }
-
-                // Matched.
-                *item_ref = Some(item_def_id);
+            Some(item_index) => {
+                self.collect_item(item_index, item_def_id)
             }
         }
     }
 
     fn collect_local_language_items() {
         let this = unsafe { ptr::addr_of(&self) };
-        visit_crate(*self.crate, (), mk_simple_visitor(@{
+        visit_crate(*self.crate, (), mk_simple_visitor(@SimpleVisitor {
             visit_item: |item| {
                 for item.attrs.each |attribute| {
                     unsafe {
@@ -216,30 +357,17 @@ fn collect_local_language_items() {
     fn collect_external_language_items() {
         let crate_store = self.session.cstore;
         do iter_crate_data(crate_store) |crate_number, _crate_metadata| {
-            for each_path(crate_store, crate_number) |path_entry| {
-                let def_id;
-                match path_entry.def_like {
-                    dl_def(def_ty(did)) | dl_def(def_fn(did, _)) => {
-                        def_id = did;
-                    }
-                    dl_def(_) | dl_impl(_) | dl_field => {
-                        // Skip this.
-                        loop;
-                    }
-                }
-
-                do get_item_attrs(crate_store, def_id) |meta_items| {
-                    for meta_items.each |meta_item| {
-                        self.match_and_collect_meta_item(def_id, **meta_item);
-                    }
-                }
+            for each_lang_item(crate_store, crate_number)
+                    |node_id, item_index| {
+                let def_id = { crate: crate_number, node: node_id };
+                self.collect_item(item_index, def_id);
             }
         }
     }
 
     fn check_completeness() {
         for self.item_refs.each |key, item_ref| {
-            match *item_ref {
+            match self.items.items[item_ref] {
                 None => {
                     self.session.err(fmt!("no item found for `%s`", key));
                 }
@@ -258,8 +386,8 @@ fn collect() {
 }
 
 fn collect_language_items(crate: @crate, session: Session) -> LanguageItems {
-    let items = language_items::make();
-    let collector = LanguageItemCollector(crate, session, &items);
+    let mut items = LanguageItems::new();
+    let collector = LanguageItemCollector(crate, session, &mut items);
     collector.collect();
     copy items
 }
index f2ab93478c4b78d7c36abf8debf2298971034110..02264d1ea93b9a9f9ad945c784dd7d44d18d5a9b 100644 (file)
@@ -8,19 +8,40 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use driver::session;
+use core::prelude::*;
+
 use driver::session::Session;
+use driver::session;
+use middle::pat_util::{pat_bindings};
 use middle::ty;
-use syntax::{ast, ast_util, visit};
-use syntax::attr;
-use syntax::codemap::span;
-use std::map::{Map,HashMap};
-use std::smallintmap::{Map,SmallIntMap};
-use io::WriterUtil;
 use util::ppaux::{ty_to_str};
-use middle::pat_util::{pat_bindings};
+
+use core::char;
+use core::cmp;
+use core::either;
+use core::i8;
+use core::i16;
+use core::i32;
+use core::i64;
+use core::int;
+use core::io::WriterUtil;
+use core::str;
+use core::u8;
+use core::u16;
+use core::u32;
+use core::u64;
+use core::uint;
+use core::vec;
+use std::map::{Map, HashMap};
+use std::map;
+use std::smallintmap::{Map, SmallIntMap};
+use std::smallintmap;
 use syntax::ast_util::{path_to_ident};
+use syntax::attr;
+use syntax::codemap::span;
 use syntax::print::pprust::{expr_to_str, mode_to_str, pat_to_str};
+use syntax::{ast, ast_util, visit};
+
 export lint, ctypes, unused_imports, while_true, path_statement, old_vecs;
 export unrecognized_lint, non_implicitly_copyable_typarams;
 export vecs_implicitly_copyable, implicit_copies, legacy_modes;
@@ -86,12 +107,12 @@ impl lint : cmp::Eq {
     pure fn ne(&self, other: &lint) -> bool { !(*self).eq(other) }
 }
 
-fn level_to_str(lv: level) -> ~str {
+fn level_to_str(lv: level) -> &static/str {
     match lv {
-      allow => ~"allow",
-      warn => ~"warn",
-      deny => ~"deny",
-      forbid => ~"forbid"
+      allow => "allow",
+      warn => "warn",
+      deny => "deny",
+      forbid => "forbid"
     }
 }
 
@@ -107,7 +128,7 @@ impl level : cmp::Eq {
 }
 
 type lint_spec = @{lint: lint,
-                   desc: ~str,
+                   desc: &static/str,
                    default: level};
 
 type lint_dict = HashMap<~str,lint_spec>;
@@ -120,113 +141,113 @@ fn get_lint_dict() -> lint_dict {
     let v = ~[
         (~"ctypes",
          @{lint: ctypes,
-           desc: ~"proper use of core::libc types in foreign modules",
+           desc: "proper use of core::libc types in foreign modules",
            default: warn}),
 
         (~"unused_imports",
          @{lint: unused_imports,
-           desc: ~"imports that are never used",
+           desc: "imports that are never used",
            default: allow}),
 
         (~"while_true",
          @{lint: while_true,
-           desc: ~"suggest using loop { } instead of while(true) { }",
+           desc: "suggest using loop { } instead of while(true) { }",
            default: warn}),
 
         (~"path_statement",
          @{lint: path_statement,
-           desc: ~"path statements with no effect",
+           desc: "path statements with no effect",
            default: warn}),
 
         (~"unrecognized_lint",
          @{lint: unrecognized_lint,
-           desc: ~"unrecognized lint attribute",
+           desc: "unrecognized lint attribute",
            default: warn}),
 
         (~"non_implicitly_copyable_typarams",
          @{lint: non_implicitly_copyable_typarams,
-           desc: ~"passing non implicitly copyable types as copy type params",
+           desc: "passing non implicitly copyable types as copy type params",
            default: warn}),
 
         (~"vecs_implicitly_copyable",
          @{lint: vecs_implicitly_copyable,
-           desc: ~"make vecs and strs not implicitly copyable \
+           desc: "make vecs and strs not implicitly copyable \
                   (only checked at top level)",
            default: warn}),
 
         (~"implicit_copies",
          @{lint: implicit_copies,
-           desc: ~"implicit copies of non implicitly copyable data",
+           desc: "implicit copies of non implicitly copyable data",
            default: warn}),
 
         (~"deprecated_mode",
          @{lint: deprecated_mode,
-           desc: ~"warn about deprecated uses of modes",
+           desc: "warn about deprecated uses of modes",
            default: warn}),
 
         (~"deprecated_pattern",
          @{lint: deprecated_pattern,
-           desc: ~"warn about deprecated uses of pattern bindings",
+           desc: "warn about deprecated uses of pattern bindings",
            default: allow}),
 
         (~"non_camel_case_types",
          @{lint: non_camel_case_types,
-           desc: ~"types, variants and traits should have camel case names",
+           desc: "types, variants and traits should have camel case names",
            default: allow}),
 
         (~"managed_heap_memory",
          @{lint: managed_heap_memory,
-           desc: ~"use of managed (@ type) heap memory",
+           desc: "use of managed (@ type) heap memory",
            default: allow}),
 
         (~"owned_heap_memory",
          @{lint: owned_heap_memory,
-           desc: ~"use of owned (~ type) heap memory",
+           desc: "use of owned (~ type) heap memory",
            default: allow}),
 
         (~"heap_memory",
          @{lint: heap_memory,
-           desc: ~"use of any (~ type or @ type) heap memory",
+           desc: "use of any (~ type or @ type) heap memory",
            default: allow}),
 
         (~"structural_records",
          @{lint: structural_records,
-           desc: ~"use of any structural records",
+           desc: "use of any structural records",
            default: allow}),
 
         (~"legacy modes",
          @{lint: legacy_modes,
-           desc: ~"allow legacy modes",
+           desc: "allow legacy modes",
            default: forbid}),
 
         (~"type_limits",
          @{lint: type_limits,
-           desc: ~"comparisons made useless by limits of the types involved",
+           desc: "comparisons made useless by limits of the types involved",
            default: warn}),
 
         (~"default_methods",
          @{lint: default_methods,
-           desc: ~"allow default methods",
+           desc: "allow default methods",
            default: deny}),
 
         (~"deprecated_self",
          @{lint: deprecated_self,
-           desc: ~"warn about deprecated uses of `self`",
+           desc: "warn about deprecated uses of `self`",
            default: allow}),
 
         /* FIXME(#3266)--make liveness warnings lintable
         (~"unused_variable",
          @{lint: unused_variable,
-           desc: ~"detect variables which are not used in any way",
+           desc: "detect variables which are not used in any way",
            default: warn}),
 
         (~"dead_assignment",
          @{lint: dead_assignment,
-           desc: ~"detect assignments that will never be read",
+           desc: "detect assignments that will never be read",
            default: warn}),
         */
     ];
-    std::map::hash_from_vec(v)
+    map::hash_from_vec(v)
 }
 
 // This is a highly not-optimal set of data structure decisions.
@@ -242,7 +263,7 @@ fn get_lint_dict() -> lint_dict {
 };
 
 fn mk_lint_settings() -> lint_settings {
-    {default_settings: std::smallintmap::mk(),
+    {default_settings: smallintmap::mk(),
      settings_map: HashMap()}
 }
 
@@ -266,7 +287,7 @@ fn get_lint_settings_level(settings: lint_settings,
 // This is kind of unfortunate. It should be somewhere else, or we should use
 // a persistent data structure...
 fn clone_lint_modes(modes: lint_modes) -> lint_modes {
-    std::smallintmap::SmallIntMap_(@{v: copy modes.v})
+    smallintmap::SmallIntMap_(@{v: copy modes.v})
 }
 
 type ctxt_ = {dict: lint_dict,
@@ -291,7 +312,7 @@ fn set_level(lint: lint, level: level) {
         }
     }
 
-    fn span_lint(level: level, span: span, msg: ~str) {
+    fn span_lint(level: level, span: span, +msg: ~str) {
         self.sess.span_lint_level(level, span, msg);
     }
 
@@ -308,15 +329,16 @@ fn with_lint_attrs(attrs: ~[ast::attribute], f: fn(ctxt)) {
         for [allow, warn, deny, forbid].each |level| {
             let level_name = level_to_str(*level);
             let metas =
-                attr::attr_metas(attr::find_attrs_by_name(attrs,
-                                                          level_name));
+                attr::attr_metas(attr::find_attrs_by_name(attrs, level_name));
             for metas.each |meta| {
-                match meta.node {
+                match /*bad*/copy meta.node {
                   ast::meta_list(_, metas) => {
                     for metas.each |meta| {
                         match meta.node {
                           ast::meta_word(ref lintname) => {
-                            triples.push((*meta, *level, *lintname));
+                            triples.push((*meta,
+                                          *level,
+                                          /*bad*/copy *lintname));
                           }
                           _ => {
                             self.sess.span_err(
@@ -335,7 +357,7 @@ fn with_lint_attrs(attrs: ~[ast::attribute], f: fn(ctxt)) {
         }
 
         for triples.each |pair| {
-            let (meta, level, lintname) = *pair;
+            let (meta, level, lintname) = /*bad*/copy *pair;
             match self.dict.find(lintname) {
               None => {
                 self.span_lint(
@@ -375,7 +397,7 @@ fn with_lint_attrs(attrs: ~[ast::attribute], f: fn(ctxt)) {
 
 
 fn build_settings_item(i: @ast::item, &&cx: ctxt, v: visit::vt<ctxt>) {
-    do cx.with_lint_attrs(i.attrs) |cx| {
+    do cx.with_lint_attrs(/*bad*/copy i.attrs) |cx| {
         if !cx.is_default {
             cx.sess.lint_settings.settings_map.insert(i.id, cx.curr);
         }
@@ -386,7 +408,7 @@ fn build_settings_item(i: @ast::item, &&cx: ctxt, v: visit::vt<ctxt>) {
 fn build_settings_crate(sess: session::Session, crate: @ast::crate) {
 
     let cx = ctxt_({dict: get_lint_dict(),
-                    curr: std::smallintmap::mk(),
+                    curr: smallintmap::mk(),
                     is_default: true,
                     sess: sess});
 
@@ -399,7 +421,7 @@ fn build_settings_crate(sess: session::Session, crate: @ast::crate) {
         cx.set_level(lint, level);
     }
 
-    do cx.with_lint_attrs(crate.node.attrs) |cx| {
+    do cx.with_lint_attrs(/*bad*/copy crate.node.attrs) |cx| {
         // Copy out the default settings
         for cx.curr.each |k, v| {
             sess.lint_settings.default_settings.insert(k, v);
@@ -407,7 +429,7 @@ fn build_settings_crate(sess: session::Session, crate: @ast::crate) {
 
         let cx = ctxt_({is_default: true,.. *cx});
 
-        let visit = visit::mk_vt(@{
+        let visit = visit::mk_vt(@visit::Visitor {
             visit_item: build_settings_item,
             .. *visit::default_visitor()
         });
@@ -435,29 +457,33 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
 // not traverse into subitems, since that is handled by the outer
 // lint visitor.
 fn item_stopping_visitor<E>(v: visit::vt<E>) -> visit::vt<E> {
-    visit::mk_vt(@{visit_item: |_i, _e, _v| { },.. **v})
+    visit::mk_vt(@visit::Visitor {visit_item: |_i, _e, _v| { },.. **v})
 }
 
 fn check_item_while_true(cx: ty::ctxt, it: @ast::item) {
-    let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
-        visit_expr: fn@(e: @ast::expr) {
-           match e.node {
-             ast::expr_while(cond, _) => {
-                match cond.node {
-                    ast::expr_lit(@{node: ast::lit_bool(true),_}) => {
-                            cx.sess.span_lint(
-                                while_true, e.id, it.id,
-                                e.span,
-                                ~"denote infinite loops with loop { ... }");
+    let visit = item_stopping_visitor(
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_expr: |e: @ast::expr| {
+                match e.node {
+                    ast::expr_while(cond, _) => {
+                        match cond.node {
+                            ast::expr_lit(@ast::spanned {
+                                node: ast::lit_bool(true), _}) =>
+                            {
+                                cx.sess.span_lint(
+                                    while_true, e.id, it.id,
+                                    e.span,
+                                    ~"denote infinite loops \
+                                      with loop { ... }");
+                            }
+                            _ => ()
+                        }
                     }
                     _ => ()
                 }
-             }
-             _ => ()
-          }
-        },
-        .. *visit::default_simple_visitor()
-    }));
+            },
+            .. *visit::default_simple_visitor()
+        }));
     visit::visit_item(it, (), visit);
 }
 
@@ -519,7 +545,7 @@ fn check_limits(cx: ty::ctxt, binop: ast::binop, l: &ast::expr,
         } else {
             binop
         };
-        match ty::get(ty::expr_ty(cx, @*expr)).sty {
+        match ty::get(ty::expr_ty(cx, @/*bad*/copy *expr)).sty {
             ty::ty_int(int_ty) => {
                 let (min, max) = int_ty_range(int_ty);
                 let lit_val: i64 = match lit.node {
@@ -558,27 +584,30 @@ fn check_limits(cx: ty::ctxt, binop: ast::binop, l: &ast::expr,
         }
     }
 
-    let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
-        visit_expr: fn@(e: @ast::expr) {
-            match e.node {
-                ast::expr_binary(ref binop, @ref l, @ref r) => {
-                    if is_comparison(*binop)
-                       && !check_limits(cx, *binop, l, r) {
-                        cx.sess.span_lint(
-                            type_limits, e.id, it.id, e.span,
-                            ~"comparison is useless due to type limits");
-                    }
+    let visit_expr: @fn(@ast::expr) = |e| {
+        match e.node {
+            ast::expr_binary(ref binop, @ref l, @ref r) => {
+                if is_comparison(*binop)
+                    && !check_limits(cx, *binop, l, r) {
+                    cx.sess.span_lint(
+                        type_limits, e.id, it.id, e.span,
+                        ~"comparison is useless due to type limits");
                 }
-                _ => ()
             }
-        },
-        .. *visit::default_simple_visitor()
-    }));
+            _ => ()
+        }
+    };
+
+    let visit = item_stopping_visitor(
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_expr: visit_expr,
+            .. *visit::default_simple_visitor()
+        }));
     visit::visit_item(it, (), visit);
 }
 
 fn check_item_default_methods(cx: ty::ctxt, item: @ast::item) {
-    match item.node {
+    match /*bad*/copy item.node {
         ast::item_trait(_, _, methods) => {
             for methods.each |method| {
                 match *method {
@@ -611,10 +640,10 @@ fn maybe_warn(cx: ty::ctxt,
               parameter or mark the method as static");
     }
 
-    match item.node {
+    match /*bad*/copy item.node {
         ast::item_trait(_, _, methods) => {
             for methods.each |method| {
-                match *method {
+                match /*bad*/copy *method {
                     ast::required(ty_method) => {
                         maybe_warn(cx, item, ty_method.self_ty);
                     }
@@ -634,19 +663,20 @@ fn maybe_warn(cx: ty::ctxt,
 }
 
 fn check_item_structural_records(cx: ty::ctxt, it: @ast::item) {
-    let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
-        visit_expr: fn@(e: @ast::expr) {
-           match e.node {
-             ast::expr_rec(*) =>
-                 cx.sess.span_lint(
-                                structural_records, e.id, it.id,
-                                e.span,
-                                ~"structural records are deprecated"),
-               _ => ()
-           }
-        },
-        .. *visit::default_simple_visitor()
-    }));
+    let visit = item_stopping_visitor(
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_expr: |e: @ast::expr| {
+                match e.node {
+                    ast::expr_rec(*) =>
+                    cx.sess.span_lint(
+                        structural_records, e.id, it.id,
+                        e.span,
+                        ~"structural records are deprecated"),
+                    _ => ()
+                }
+            },
+            .. *visit::default_simple_visitor()
+        }));
     visit::visit_item(it, (), visit);
 }
 
@@ -682,10 +712,11 @@ fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id,
     }
 
     match it.node {
-      ast::item_foreign_mod(nmod) if attr::foreign_abi(it.attrs) !=
-      either::Right(ast::foreign_abi_rust_intrinsic) => {
+      ast::item_foreign_mod(ref nmod)
+      if attr::foreign_abi(it.attrs) !=
+            either::Right(ast::foreign_abi_rust_intrinsic) => {
         for nmod.items.each |ni| {
-            match ni.node {
+            match /*bad*/copy ni.node {
               ast::foreign_item_fn(decl, _, _) => {
                 check_foreign_fn(cx, it.id, decl);
               }
@@ -752,34 +783,36 @@ fn check_type(cx: ty::ctxt,
       _ => ()
     }
 
-    let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
-        visit_expr: fn@(e: @ast::expr) {
-            let ty = ty::expr_ty(cx, e);
-            check_type(cx, e.id, it.id, e.span, ty);
-        },
-        .. *visit::default_simple_visitor()
-    }));
+    let visit = item_stopping_visitor(
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_expr: |e: @ast::expr| {
+                let ty = ty::expr_ty(cx, e);
+                check_type(cx, e.id, it.id, e.span, ty);
+            },
+            .. *visit::default_simple_visitor()
+        }));
     visit::visit_item(it, (), visit);
 }
 
 fn check_item_path_statement(cx: ty::ctxt, it: @ast::item) {
-    let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
-        visit_stmt: fn@(s: @ast::stmt) {
-            match s.node {
-              ast::stmt_semi(@{id: id,
-                               callee_id: _,
-                               node: ast::expr_path(_),
-                               span: _}, _) => {
-                cx.sess.span_lint(
-                    path_statement, id, it.id,
-                    s.span,
-                    ~"path statement with no effect");
-              }
-              _ => ()
-            }
-        },
-        .. *visit::default_simple_visitor()
-    }));
+    let visit = item_stopping_visitor(
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_stmt: |s: @ast::stmt| {
+                match s.node {
+                    ast::stmt_semi(@{id: id,
+                                     callee_id: _,
+                                     node: ast::expr_path(_),
+                                     span: _}, _) => {
+                        cx.sess.span_lint(
+                            path_statement, id, it.id,
+                            s.span,
+                            ~"path statement with no effect");
+                    }
+                    _ => ()
+                }
+            },
+            .. *visit::default_simple_visitor()
+        }));
     visit::visit_item(it, (), visit);
 }
 
@@ -793,14 +826,14 @@ fn is_camel_case(cx: ty::ctxt, ident: ast::ident) -> bool {
             !ident.contains_char('_')
     }
 
-    fn ident_without_trailing_underscores(ident: ~str) -> ~str {
+    fn ident_without_trailing_underscores(+ident: ~str) -> ~str {
         match str::rfind(ident, |c| c != '_') {
             Some(idx) => (ident).slice(0, idx + 1),
             None => { ident } // all underscores
         }
     }
 
-    fn ident_without_leading_underscores(ident: ~str) -> ~str {
+    fn ident_without_leading_underscores(+ident: ~str) -> ~str {
         match str::find(ident, |c| c != '_') {
           Some(idx) => ident.slice(idx, ident.len()),
           None => {
@@ -948,7 +981,7 @@ fn check_item_deprecated_modes(tcx: ty::ctxt, it: @ast::item) {
 
 fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
 
-    let v = visit::mk_simple_visitor(@{
+    let v = visit::mk_simple_visitor(@visit::SimpleVisitor {
         visit_item: |it|
             check_item(it, tcx),
         visit_fn: |fk, decl, body, span, id|
index c481ef81477bb700c9145dc3e6a2e88b779fec60..bfcd809594b2b635e42d7046a06f97ef699c350e 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 /*!
  * A classic liveness analysis based on dataflow over the AST.  Computes,
  * for each local variable in a function, whether that variable is live
  *   to return explicitly.
  */
 
+use core::prelude::*;
+
 use middle::capture::{cap_move, cap_drop, cap_copy, cap_ref};
+use middle::capture;
+use middle::pat_util;
 use middle::ty::MoveValue;
+use middle::ty;
+use middle::typeck;
 
+use core::cmp;
 use core::dvec::DVec;
 use core::io::WriterUtil;
+use core::io;
+use core::ptr;
+use core::to_str;
+use core::uint;
+use core::vec;
 use std::map::HashMap;
 use syntax::ast::*;
 use syntax::codemap::span;
@@ -194,7 +207,7 @@ fn live_node_kind_to_str(lnk: LiveNodeKind, cx: ty::ctxt) -> ~str {
 fn check_crate(tcx: ty::ctxt,
                method_map: typeck::method_map,
                crate: @crate) -> last_use_map {
-    let visitor = visit::mk_vt(@{
+    let visitor = visit::mk_vt(@visit::Visitor {
         visit_fn: visit_fn,
         visit_local: visit_local,
         visit_expr: visit_expr,
@@ -414,7 +427,7 @@ fn add_last_use(expr_id: node_id, var: Variable) {
 fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
             sp: span, id: node_id, &&self: @IrMaps, v: vt<@IrMaps>) {
     debug!("visit_fn: id=%d", id);
-    let _i = util::common::indenter();
+    let _i = ::util::common::indenter();
 
     // swap in a new set of IR maps for this function body:
     let fn_maps = @IrMaps(self.tcx, self.method_map,
@@ -476,7 +489,7 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
     let entry_ln = (*lsets).compute(decl, body);
 
     // check for various error conditions
-    let check_vt = visit::mk_vt(@{
+    let check_vt = visit::mk_vt(@visit::Visitor {
         visit_fn: check_fn,
         visit_local: check_local,
         visit_expr: check_expr,
@@ -1022,7 +1035,7 @@ fn propagate_through_stmt(stmt: @stmt, succ: LiveNode) -> LiveNode {
     }
 
     fn propagate_through_decl(decl: @decl, succ: LiveNode) -> LiveNode {
-        match decl.node {
+        match /*bad*/copy decl.node {
           decl_local(locals) => {
             do locals.foldr(succ) |local, succ| {
                 self.propagate_through_local(*local, succ)
@@ -1071,7 +1084,7 @@ fn propagate_through_expr(expr: @expr, succ: LiveNode) -> LiveNode {
         debug!("propagate_through_expr: %s",
              expr_to_str(expr, self.tcx.sess.intr()));
 
-        match expr.node {
+        match /*bad*/copy expr.node {
           // Interesting cases with control flow or which gen/kill
 
           expr_path(_) => {
@@ -1552,7 +1565,7 @@ fn check_call(args: &[@expr],
 }
 
 fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
-    match expr.node {
+    match /*bad*/copy expr.node {
       expr_path(_) => {
         for self.variable_from_def_map(expr.id, expr.span).each |var| {
             let ln = self.live_node(expr.id, expr.span);
index 8962a1494e50d70c03190b2b6884c5d0b84a39c0..b72950cbf4b1b3ef1a264420b58a596b24e2e5eb 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 /*!
  * # Categorization
  *
  * then an index to jump forward to the relevant item.
  */
 
-use syntax::ast;
+use core::prelude::*;
+
+use middle::ty;
+use middle::typeck;
+use util::ppaux::{ty_to_str, region_to_str};
+use util::common::indenter;
+
+use core::cmp;
+use core::to_bytes;
+use core::uint;
 use syntax::ast::{m_imm, m_const, m_mutbl};
+use syntax::ast;
 use syntax::codemap::span;
 use syntax::print::pprust;
-use util::ppaux::{ty_to_str, region_to_str};
-use util::common::indenter;
 
 enum categorization {
     cat_rvalue,                     // result of eval'ing some misc expr
@@ -129,7 +138,7 @@ impl categorization : cmp::Eq {
 }
 
 // different kinds of pointers:
-enum ptr_kind {
+pub enum ptr_kind {
     uniq_ptr,
     gc_ptr,
     region_ptr(ty::Region),
@@ -170,7 +179,7 @@ impl ptr_kind : cmp::Eq {
 
 // I am coining the term "components" to mean "pieces of a data
 // structure accessible without a dereference":
-enum comp_kind {
+pub enum comp_kind {
     comp_tuple,                  // elt in a tuple
     comp_anon_field,             // anonymous field (in e.g.
                                  // struct Foo(int, int);
@@ -262,7 +271,7 @@ impl cmt_ : cmp::Eq {
 // a loan path is like a category, but it exists only when the data is
 // interior to the stack frame.  loan paths are used as the key to a
 // map indicating what is borrowed at any point in time.
-enum loan_path {
+pub enum loan_path {
     lp_local(ast::node_id),
     lp_arg(ast::node_id),
     lp_deref(@loan_path, ptr_kind),
@@ -897,7 +906,7 @@ fn cat_pattern(cmt: cmt, pat: @ast::pat, op: fn(cmt, @ast::pat)) {
         //     local(x)->@->@
         //
         // where the id of `local(x)` is the id of the `x` that appears
-        // in the alt, the id of `local(x)->@` is the `@y` pattern,
+        // in the match, the id of `local(x)->@` is the `@y` pattern,
         // and the id of `local(x)->@->@` is the id of the `y` pattern.
 
 
@@ -907,7 +916,7 @@ fn cat_pattern(cmt: cmt, pat: @ast::pat, op: fn(cmt, @ast::pat)) {
                pat.id, pprust::pat_to_str(pat, tcx.sess.intr()),
                self.cmt_to_repr(cmt));
 
-        match pat.node {
+        match /*bad*/copy pat.node {
           ast::pat_wild => {
             // _
           }
@@ -1111,7 +1120,7 @@ fn field_mutbl(tcx: ty::ctxt,
                f_name: ast::ident,
                node_id: ast::node_id) -> Option<ast::mutability> {
     // Need to refactor so that records/class fields can be treated uniformly.
-    match ty::get(base_ty).sty {
+    match /*bad*/copy ty::get(base_ty).sty {
       ty::ty_rec(fields) => {
         for fields.each |f| {
             if f.ident == f_name {
index 28fa77d625d93f86652bbd73f26f01ae10fae4b7..7c2b518dbe9ed295d90b10bc1fc13bfb585f627e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use middle::pat_util;
 use middle::ty;
 use middle::ty::{CopyValue, MoveValue, ReadValue, ValueMode, ctxt};
 use syntax::ast::{expr_match, expr_method_call, expr_paren, expr_path};
 use syntax::ast::{expr_swap, expr_unary, neg, node_id, not, pat, pat_ident};
 use syntax::ast::{sty_uniq, sty_value, uniq};
+use syntax::ast::{fn_decl, blk};
 use syntax::visit;
-use syntax::visit::vt;
+use syntax::visit::{fn_kind, vt};
+use syntax::print::pprust;
+use syntax::codemap::span;
 
 struct VisitContext {
     tcx: ctxt,
@@ -30,6 +35,17 @@ struct VisitContext {
     mode: ValueMode,
 }
 
+fn compute_modes_for_fn(fk: fn_kind,
+                        decl: fn_decl,
+                        body: blk,
+                        sp: span,
+                        id: node_id,
+                        &&cx: VisitContext,
+                        v: vt<VisitContext>) {
+    let body_cx = VisitContext { mode: MoveValue, ..cx };
+    visit::visit_fn(fk, decl, body, sp, id, body_cx, v);
+}
+
 fn compute_modes_for_fn_args(callee_id: node_id,
                              args: &[@expr],
                              last_arg_is_block: bool,
@@ -77,6 +93,10 @@ fn record_mode_for_expr(expr: @expr, &&cx: VisitContext) {
 fn compute_modes_for_expr(expr: @expr,
                           &&cx: VisitContext,
                           v: vt<VisitContext>) {
+    debug!("compute_modes_for_expr(expr=%?/%s, mode=%?)",
+           expr.id, pprust::expr_to_str(expr, cx.tcx.sess.intr()),
+           cx.mode);
+
     // Adjust the mode if there was an implicit reference here.
     let cx = match cx.tcx.adjustments.find(expr.id) {
         None => cx,
@@ -89,7 +109,7 @@ fn compute_modes_for_expr(expr: @expr,
         }
     };
 
-    match expr.node {
+    match copy expr.node {
         expr_call(callee, args, is_block) => {
             let callee_cx = VisitContext { mode: ReadValue, ..cx };
             compute_modes_for_expr(callee, callee_cx, v);
@@ -232,7 +252,8 @@ fn compute_modes_for_pat(pat: @pat,
 }
 
 pub fn compute_modes(tcx: ctxt, method_map: method_map, crate: @crate) {
-    let visitor = visit::mk_vt(@{
+    let visitor = visit::mk_vt(@visit::Visitor {
+        visit_fn: compute_modes_for_fn,
         visit_expr: compute_modes_for_expr,
         visit_pat: compute_modes_for_pat,
         .. *visit::default_visitor()
index b1bd42758f19ad84ab61ecfa782a939ba2282608..5a4d36f1d10a9e794a51f11d82db0a30632759d0 100644 (file)
@@ -8,7 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use middle::resolve;
 use middle::ty::{CopyValue, MoveValue, ReadValue};
+use middle::ty;
 
 use syntax::ast::*;
 use syntax::ast_util;
 export pat_is_const;
 export arms_have_by_move_bindings;
 
-type PatIdMap = std::map::HashMap<ident, node_id>;
+type PatIdMap = HashMap<ident, node_id>;
 
 // This is used because same-named variables in alternative patterns need to
 // use the node_id of their namesake in the first pattern.
 fn pat_id_map(dm: resolve::DefMap, pat: @pat) -> PatIdMap {
-    let map = std::map::HashMap();
+    let map = HashMap();
     do pat_bindings(dm, pat) |_bm, p_id, _s, n| {
       map.insert(path_to_ident(n), p_id);
     };
index 5819db17f58a842eea6a82224ff5ae68040746b2..745e3f6086f65afcbae312f6656190bd9087c365 100644 (file)
@@ -8,25 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 // A pass that checks to make sure private fields and methods aren't used
 // outside their scopes.
 
+use core::prelude::*;
+
 use middle::ty::{ty_struct, ty_enum};
+use middle::ty;
 use middle::typeck::{method_map, method_origin, method_param, method_self};
 use middle::typeck::{method_static, method_trait};
-use /*mod*/ syntax::ast;
-use /*mod*/ syntax::visit;
-use syntax::ast_map;
+
+use core::dvec::DVec;
+use core::util::ignore;
 use syntax::ast::{def_variant, expr_field, expr_method_call, expr_struct};
 use syntax::ast::{expr_unary, ident, item_struct, item_enum, item_impl};
 use syntax::ast::{item_trait, local_crate, node_id, pat_struct, private};
 use syntax::ast::{provided, required};
+use syntax::ast;
 use syntax::ast_map::{node_item, node_method};
+use syntax::ast_map;
 use syntax::ast_util::{Private, Public, has_legacy_export_attr, is_local};
 use syntax::ast_util::{visibility_to_privacy};
-
-use core::util::ignore;
-use dvec::DVec;
+use syntax::visit;
 
 fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
     let privileged_items = @DVec();
@@ -186,7 +190,7 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
         }
     };
 
-    let visitor = visit::mk_vt(@{
+    let visitor = visit::mk_vt(@visit::Visitor {
         visit_mod: |the_module, span, node_id, method_map, visitor| {
             let n_added = add_privileged_items(the_module.items);
 
@@ -310,7 +314,7 @@ struct variant \
             visit::visit_expr(expr, method_map, visitor);
         },
         visit_pat: |pattern, method_map, visitor| {
-            match pattern.node {
+            match /*bad*/copy pattern.node {
                 pat_struct(_, fields, _) => {
                     match ty::get(ty::pat_ty(tcx, pattern)).sty {
                         ty_struct(id, _) => {
index f746e0236807ed3daa6f980a25768d027a70fd4b..ae6a6d67c1d4aa53114ad2e786fe009323313006 100644 (file)
 
 */
 
+use core::prelude::*;
+
 use driver::session::Session;
 use metadata::csearch;
+use middle::resolve;
 use middle::ty::{region_variance, rv_covariant, rv_invariant};
 use middle::ty::{rv_contravariant};
 use middle::ty;
 
+use core::cmp;
 use core::dvec::DVec;
+use core::vec;
 use std::list;
 use std::list::list;
 use std::map::HashMap;
@@ -67,7 +72,7 @@ struct ctxt {
     // that when we visit it we can view it as a parent.
     root_exprs: HashMap<ast::node_id, ()>,
 
-    // The parent scope is the innermost block, statement, call, or alt
+    // The parent scope is the innermost block, statement, call, or match
     // expression during the execution of which the current expression
     // will be evaluated.  Generally speaking, the innermost parent
     // scope is also the closest suitable ancestor in the AST tree.
@@ -347,7 +352,7 @@ fn resolve_crate(sess: Session, def_map: resolve::DefMap,
                          region_map: HashMap(),
                          root_exprs: HashMap(),
                          parent: None};
-    let visitor = visit::mk_vt(@{
+    let visitor = visit::mk_vt(@visit::Visitor {
         visit_block: resolve_block,
         visit_item: resolve_item,
         visit_fn: resolve_fn,
@@ -564,7 +569,7 @@ fn with(item_id: ast::node_id,
         self.item_id = item_id;
         self.anon_implies_rp = anon_implies_rp;
         debug!("with_item_id(%d, %b)", item_id, anon_implies_rp);
-        let _i = util::common::indenter();
+        let _i = ::util::common::indenter();
         f();
         self.item_id = old_item_id;
         self.anon_implies_rp = old_anon_implies_rp;
@@ -777,7 +782,7 @@ fn determine_rp_in_crate(sess: Session,
                                   mut ambient_variance: rv_covariant});
 
     // Gather up the base set, worklist and dep_map
-    let visitor = visit::mk_vt(@{
+    let visitor = visit::mk_vt(@visit::Visitor {
         visit_fn: determine_rp_in_fn,
         visit_item: determine_rp_in_item,
         visit_ty: determine_rp_in_ty,
index f8138dc6d325fc583210c70738bbcd4a7322aa88..a7c579127f95478d9d3e165c72a3199470dff681 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use driver::session::Session;
 use metadata::csearch::{each_path, get_method_names_if_trait};
 use metadata::csearch::{get_static_methods_if_impl, get_type_name_if_impl};
 use middle::lang_items::LanguageItems;
 use middle::lint::{deny, allow, forbid, level, unused_imports, warn};
 use middle::pat_util::{pat_bindings};
-use syntax::ast::{_mod, add, arm, binding_mode, bitand, bitor, bitxor, blk};
-use syntax::ast::{capture_clause};
+
+use core::cmp;
+use core::str;
+use core::vec;
+use syntax::ast::{RegionTyParamBound, TraitTyParamBound, _mod, add, arm};
+use syntax::ast::{binding_mode, bitand, bitor, bitxor, blk, capture_clause};
 use syntax::ast::{crate, crate_num, decl_item, def, def_arg, def_binding};
 use syntax::ast::{def_const, def_foreign_mod, def_fn, def_id, def_label};
 use syntax::ast::{def_local, def_mod, def_prim_ty, def_region, def_self};
 use syntax::ast::{gt, ident, impure_fn, inherited, item, item_struct};
 use syntax::ast::{item_const, item_enum, item_fn, item_foreign_mod};
 use syntax::ast::{item_impl, item_mac, item_mod, item_trait, item_ty, le};
-use syntax::ast::{local, local_crate, lt, method, mode, module_ns, mul, ne};
-use syntax::ast::{neg, node_id, pat, pat_enum, pat_ident, path, prim_ty};
-use syntax::ast::{pat_box, pat_lit, pat_range, pat_rec, pat_struct};
-use syntax::ast::{pat_tup, pat_uniq, pat_wild, private, provided, public};
-use syntax::ast::{required, rem, self_ty_, shl, shr, stmt_decl, struct_dtor};
-use syntax::ast::{struct_field, struct_variant_kind, sty_by_ref, sty_static};
-use syntax::ast::{subtract, trait_ref, tuple_variant_kind, Ty, ty_bool};
-use syntax::ast::{ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i, ty_i16};
-use syntax::ast::{ty_i32, ty_i64, ty_i8, ty_int, ty_param, ty_path, ty_str};
-use syntax::ast::{ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint};
+use syntax::ast::{local, local_crate, lt, method, mode, module_ns, mul};
+use syntax::ast::{named_field, ne, neg, node_id, pat, pat_enum, pat_ident};
+use syntax::ast::{path, pat_box, pat_lit, pat_range, pat_rec, pat_struct};
+use syntax::ast::{pat_tup, pat_uniq, pat_wild, prim_ty, private, provided};
+use syntax::ast::{public, required, rem, self_ty_, shl, shr, stmt_decl};
+use syntax::ast::{struct_dtor, struct_field, struct_variant_kind, sty_by_ref};
+use syntax::ast::{sty_static, subtract, trait_ref, tuple_variant_kind, Ty};
+use syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i};
+use syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, ty_param, ty_path};
+use syntax::ast::{ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint};
 use syntax::ast::{type_value_ns, ty_param_bound, unnamed_field};
 use syntax::ast::{variant, view_item, view_item_export, view_item_import};
 use syntax::ast::{view_item_use, view_path_glob, view_path_list};
-use syntax::ast::{view_path_simple, visibility, anonymous, named};
+use syntax::ast::{view_path_simple, visibility, anonymous, named, not};
 use syntax::ast_util::{def_id_of_def, dummy_sp, local_def};
 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
 use syntax::ast_util::{Privacy, Public, Private, visibility_to_privacy};
 use syntax::ast_util::has_legacy_export_attr;
 use syntax::attr::{attr_metas, contains_name};
+use syntax::parse::token::ident_interner;
+use syntax::parse::token::special_idents;
 use syntax::print::pprust::{pat_to_str, path_to_str};
 use syntax::codemap::span;
-use syntax::visit::{default_visitor, fk_method, mk_vt, visit_block};
+use syntax::visit::{default_visitor, fk_method, mk_vt, Visitor, visit_block};
 use syntax::visit::{visit_crate, visit_expr, visit_expr_opt, visit_fn};
 use syntax::visit::{visit_foreign_item, visit_item, visit_method_helper};
 use syntax::visit::{visit_mod, visit_ty, vt};
@@ -66,7 +74,6 @@
 use option::{Some, get, is_some, is_none};
 use str::{connect, split_str};
 use vec::pop;
-use syntax::parse::token::ident_interner;
 
 use std::list::{Cons, List, Nil};
 use std::map::HashMap;
@@ -317,9 +324,14 @@ enum UseLexicalScopeFlag {
     UseLexicalScope
 }
 
-struct ModulePrefixResult {
-    result: ResolveResult<@Module>,
-    prefix_len: uint
+enum SearchThroughModulesFlag {
+    DontSearchThroughModules,
+    SearchThroughModules
+}
+
+enum ModulePrefixResult {
+    NoPrefixFound,
+    PrefixFound(@Module, uint)
 }
 
 impl XrayFlag : cmp::Eq {
@@ -475,10 +487,19 @@ enum ParentLink {
     BlockParentLink(@Module, node_id)
 }
 
+/// The type of module this is.
+enum ModuleKind {
+    NormalModuleKind,
+    ExternModuleKind,
+    TraitModuleKind,
+    AnonymousModuleKind,
+}
+
 /// One node in the tree of modules.
 struct Module {
     parent_link: ParentLink,
     mut def_id: Option<def_id>,
+    kind: ModuleKind,
 
     children: HashMap<ident,@NameBindings>,
     imports: DVec<@ImportDirective>,
@@ -527,10 +548,12 @@ struct Module {
 
 fn Module(parent_link: ParentLink,
           def_id: Option<def_id>,
+          kind: ModuleKind,
           legacy_exports: bool) -> Module {
     Module {
         parent_link: parent_link,
         def_id: def_id,
+        kind: kind,
         children: HashMap(),
         imports: DVec(),
         anonymous_children: HashMap(),
@@ -589,10 +612,11 @@ impl NameBindings {
     fn define_module(privacy: Privacy,
                      parent_link: ParentLink,
                      def_id: Option<def_id>,
+                     kind: ModuleKind,
                      legacy_exports: bool,
                      sp: span) {
         // Merges the module with the existing type def or creates a new one.
-        let module_ = @Module(parent_link, def_id, legacy_exports);
+        let module_ = @Module(parent_link, def_id, kind, legacy_exports);
         match self.type_def {
             None => {
                 self.type_def = Some(TypeNsDef {
@@ -794,6 +818,7 @@ fn Resolver(session: Session, lang_items: LanguageItems,
     (*graph_root).define_module(Public,
                                 NoParentLink,
                                 Some({ crate: 0, node: 0 }),
+                                NormalModuleKind,
                                 has_legacy_export_attr(crate.node.attrs),
                                 crate.span);
 
@@ -824,7 +849,9 @@ fn Resolver(session: Session, lang_items: LanguageItems,
         xray_context: NoXray,
         current_trait_refs: None,
 
-        self_ident: syntax::parse::token::special_idents::self_,
+        self_ident: special_idents::self_,
+        type_self_ident: special_idents::type_self,
+
         primitive_type_table: @PrimitiveTypeTable(session.
                                                   parse_sess.interner),
 
@@ -880,6 +907,8 @@ struct Resolver {
 
     // The ident for the keyword "self".
     self_ident: ident,
+    // The ident for the non-keyword "Self".
+    type_self_ident: ident,
 
     // The idents for the primitive types.
     primitive_type_table: @PrimitiveTypeTable,
@@ -922,7 +951,7 @@ fn resolve(@self, this: @Resolver) {
     fn build_reduced_graph(this: @Resolver) {
         let initial_parent =
             ModuleReducedGraphParent((*self.graph_root).get_module());
-        visit_crate(*self.crate, initial_parent, mk_vt(@{
+        visit_crate(*self.crate, initial_parent, mk_vt(@Visitor {
             visit_item: |item, context, visitor|
                 (*this).build_reduced_graph_for_item(item, context, visitor),
 
@@ -1103,7 +1132,7 @@ fn build_reduced_graph_for_item(item: @item,
         };
         let privacy = visibility_to_privacy(item.vis, legacy);
 
-        match item.node {
+        match /*bad*/copy item.node {
             item_mod(module_) => {
                 let legacy = has_legacy_export_attr(item.attrs);
                 let (name_bindings, new_parent) =
@@ -1111,8 +1140,12 @@ fn build_reduced_graph_for_item(item: @item,
 
                 let parent_link = self.get_parent_link(new_parent, ident);
                 let def_id = { crate: 0, node: item.id };
-                (*name_bindings).define_module(privacy, parent_link,
-                                               Some(def_id), legacy, sp);
+                (*name_bindings).define_module(privacy,
+                                               parent_link,
+                                               Some(def_id),
+                                               NormalModuleKind,
+                                               legacy,
+                                               sp);
 
                 let new_parent =
                     ModuleReducedGraphParent((*name_bindings).get_module());
@@ -1134,6 +1167,7 @@ fn build_reduced_graph_for_item(item: @item,
                         (*name_bindings).define_module(privacy,
                                                        parent_link,
                                                        Some(def_id),
+                                                       ExternModuleKind,
                                                        legacy,
                                                        sp);
 
@@ -1251,8 +1285,12 @@ fn build_reduced_graph_for_item(item: @item,
                         let parent_link = self.get_parent_link(new_parent,
                                                                ident);
                         let def_id = local_def(item.id);
-                        name_bindings.define_module(privacy, parent_link,
-                                                    Some(def_id), false, sp);
+                        name_bindings.define_module(privacy,
+                                                    parent_link,
+                                                    Some(def_id),
+                                                    TraitModuleKind,
+                                                    false,
+                                                    sp);
 
                         let new_parent = ModuleReducedGraphParent(
                             name_bindings.get_module());
@@ -1313,6 +1351,7 @@ fn build_reduced_graph_for_item(item: @item,
                     name_bindings.define_module(privacy,
                                                 parent_link,
                                                 Some(local_def(item.id)),
+                                                TraitModuleKind,
                                                 false,
                                                 sp);
                     module_parent_opt = Some(ModuleReducedGraphParent(
@@ -1425,7 +1464,7 @@ fn build_reduced_graph_for_view_item(view_item: @view_item,
           ModuleReducedGraphParent(m) => m.legacy_exports
         };
         let privacy = visibility_to_privacy(view_item.vis, legacy);
-        match view_item.node {
+        match /*bad*/copy view_item.node {
             view_item_import(view_paths) => {
                 for view_paths.each |view_path| {
                     // Extract and intern the module part of the path. For
@@ -1568,6 +1607,7 @@ fn build_reduced_graph_for_view_item(view_item: @view_item,
                         (*child_name_bindings).define_module(privacy,
                                                              parent_link,
                                                              Some(def_id),
+                                                             NormalModuleKind,
                                                              false,
                                                              view_item.span);
                         self.build_reduced_graph_for_external_crate
@@ -1592,7 +1632,7 @@ fn build_reduced_graph_for_foreign_item(foreign_item: @foreign_item,
             self.add_child(name, parent, ForbidDuplicateValues,
                            foreign_item.span);
 
-        match foreign_item.node {
+        match /*bad*/copy foreign_item.node {
             foreign_item_fn(_, purity, type_parameters) => {
                 let def = def_fn(local_def(foreign_item.id), purity);
                 (*name_bindings).define_value(Public, def, foreign_item.span);
@@ -1626,7 +1666,9 @@ fn build_reduced_graph_for_block(block: blk,
 
             let parent_module = self.get_module_from_parent(parent);
             let new_module = @Module(BlockParentLink(parent_module, block_id),
-                                     None, false);
+                                     None,
+                                     AnonymousModuleKind,
+                                     false);
             parent_module.anonymous_children.insert(block_id, new_module);
             new_parent = ModuleReducedGraphParent(new_module);
         } else {
@@ -1660,6 +1702,7 @@ fn handle_external_def(def: def, modules: HashMap<def_id, @Module>,
                     child_name_bindings.define_module(Public,
                                                       parent_link,
                                                       Some(def_id),
+                                                      NormalModuleKind,
                                                       false,
                                                       dummy_sp());
                     modules.insert(def_id,
@@ -1772,7 +1815,7 @@ fn build_reduced_graph_for_external_crate(root: @Module) {
 
             let mut current_module = root;
             for pieces.each |ident_str| {
-                let ident = self.session.ident_of(*ident_str);
+                let ident = self.session.ident_of(/*bad*/copy *ident_str);
                 // Create or reuse a graph node for the child.
                 let (child_name_bindings, new_parent) =
                     self.add_child(ident,
@@ -1791,6 +1834,7 @@ fn build_reduced_graph_for_external_crate(root: @Module) {
                         (*child_name_bindings).define_module(Public,
                                                              parent_link,
                                                              None,
+                                                             NormalModuleKind,
                                                              false,
                                                              dummy_sp());
                     }
@@ -1804,6 +1848,7 @@ fn build_reduced_graph_for_external_crate(root: @Module) {
                         (*child_name_bindings).define_module(Public,
                                                              parent_link,
                                                              None,
+                                                             NormalModuleKind,
                                                              false,
                                                              dummy_sp());
                     }
@@ -1830,9 +1875,6 @@ fn build_reduced_graph_for_external_crate(root: @Module) {
                 }
                 dl_impl(def) => {
                     // We only process static methods of impls here.
-                    debug!("(building reduced graph for external crate) \
-                            processing impl %s", final_ident_str);
-
                     match get_type_name_if_impl(self.session.cstore, def) {
                         None => {}
                         Some(final_ident) => {
@@ -1840,7 +1882,7 @@ fn build_reduced_graph_for_external_crate(root: @Module) {
                                 get_static_methods_if_impl(
                                     self.session.cstore, def);
                             match static_methods_opt {
-                                Some(static_methods) if
+                                Some(ref static_methods) if
                                     static_methods.len() >= 1 => {
                                     debug!("(building reduced graph for \
                                             external crate) processing \
@@ -1874,6 +1916,7 @@ fn build_reduced_graph_for_external_crate(root: @Module) {
                                                 Public,
                                                 parent_link,
                                                 Some(def),
+                                                NormalModuleKind,
                                                 false,
                                                 dummy_sp());
                                             type_module =
@@ -1915,7 +1958,7 @@ fn build_reduced_graph_for_external_crate(root: @Module) {
                 }
                 dl_field => {
                     debug!("(building reduced graph for external crate) \
-                            ignoring field %s", final_ident_str);
+                            ignoring field");
                 }
             }
         }
@@ -2046,8 +2089,11 @@ fn resolve_imports_for_module(module_: @Module) {
             match self.resolve_import_for_module(module_, import_directive) {
                 Failed => {
                     // We presumably emitted an error. Continue.
-                    self.session.span_err(import_directive.span,
-                                          ~"failed to resolve import");
+                    let idents = import_directive.module_path.get();
+                    let msg = fmt!("failed to resolve import: %s",
+                                   self.import_path_to_str(idents,
+                                   *import_directive.subclass));
+                    self.session.span_err(import_directive.span, msg);
                 }
                 Indeterminate => {
                     // Bail out. We'll come around next time.
@@ -2063,20 +2109,29 @@ fn resolve_imports_for_module(module_: @Module) {
     }
 
     fn idents_to_str(idents: ~[ident]) -> ~str {
-        // XXX: str::connect should do this.
-        let mut result = ~"";
-        let mut first = true;
-        for idents.each() |ident| {
-            if first {
-                first = false;
-            } else {
-                result += ~"::";
-            }
-            result += self.session.str_of(*ident);
-        }
-        // XXX: Shouldn't copy here. We need string builder functionality.
-        return result;
+        let ident_strs = idents.map(|&ident| self.session.str_of(ident));
+        return str::connect(ident_strs, "::");
+    }
+
+    fn import_directive_subclass_to_str(subclass: ImportDirectiveSubclass)
+                                                                     -> ~str {
+        match subclass {
+            SingleImport(_target, source, _ns) => self.session.str_of(source),
+            GlobImport => ~"*"
+        }
     }
+
+    fn import_path_to_str(idents: ~[ident], subclass: ImportDirectiveSubclass)
+                                                                     -> ~str {
+        if idents.is_empty() {
+            self.import_directive_subclass_to_str(subclass)
+        } else {
+            fmt!("%s::%s",
+                 self.idents_to_str(idents),
+                 self.import_directive_subclass_to_str(subclass))
+        }
+    }
+
     /**
      * Attempts to resolve the given import. The return value indicates
      * failure if we're certain the name does not exist, indeterminate if we
@@ -2722,23 +2777,13 @@ fn resolve_module_path_for_import(module_: @Module,
                self.idents_to_str((*module_path).get()),
                self.module_to_str(module_));
 
-        // The first element of the module path must be in the current scope
-        // chain.
-
-        let resolve_result = match use_lexical_scope {
-            DontUseLexicalScope => {
-                self.resolve_module_prefix(module_, module_path)
-            }
-            UseLexicalScope => {
-                let result = self.resolve_module_in_lexical_scope(
-                    module_,
-                    module_path.get_elt(0));
-                ModulePrefixResult { result: result, prefix_len: 1 }
-            }
-        };
+        // Resolve the module prefix, if any.
+        let module_prefix_result = self.resolve_module_prefix(module_,
+                                                              module_path);
 
         let mut search_module;
-        match resolve_result.result {
+        let mut start_index;
+        match module_prefix_result {
             Failed => {
                 self.session.span_err(span, ~"unresolved name");
                 return Failed;
@@ -2748,21 +2793,61 @@ fn resolve_module_path_for_import(module_: @Module,
                         bailing");
                 return Indeterminate;
             }
-            Success(resulting_module) => {
-                search_module = resulting_module;
+            Success(NoPrefixFound) => {
+                // There was no prefix, so we're considering the first element
+                // of the path. How we handle this depends on whether we were
+                // instructed to use lexical scope or not.
+                match use_lexical_scope {
+                    DontUseLexicalScope => {
+                        // This is a crate-relative path. We will start the
+                        // resolution process at index zero.
+                        search_module = self.graph_root.get_module();
+                        start_index = 0;
+                    }
+                    UseLexicalScope => {
+                        // This is not a crate-relative path. We resolve the
+                        // first component of the path in the current lexical
+                        // scope and then proceed to resolve below that.
+                        let result = self.resolve_module_in_lexical_scope(
+                            module_,
+                            module_path.get_elt(0));
+                        match result {
+                            Failed => {
+                                self.session.span_err(span,
+                                                      ~"unresolved name");
+                                return Failed;
+                            }
+                            Indeterminate => {
+                                debug!("(resolving module path for import) \
+                                        indeterminate; bailing");
+                                return Indeterminate;
+                            }
+                            Success(containing_module) => {
+                                search_module = containing_module;
+                                start_index = 1;
+                            }
+                        }
+                    }
+                }
+            }
+            Success(PrefixFound(containing_module, index)) => {
+                search_module = containing_module;
+                start_index = index;
             }
         }
 
         return self.resolve_module_path_from_root(search_module,
                                                   module_path,
-                                                  resolve_result.prefix_len,
+                                                  start_index,
                                                   xray,
                                                   span);
     }
 
     fn resolve_item_in_lexical_scope(module_: @Module,
                                      name: ident,
-                                     namespace: Namespace)
+                                     namespace: Namespace,
+                                     search_through_modules:
+                                        SearchThroughModulesFlag)
                                   -> ResolveResult<Target> {
 
         debug!("(resolving item in lexical scope) resolving `%s` in \
@@ -2818,7 +2903,30 @@ fn resolve_item_in_lexical_scope(module_: @Module,
                             module");
                     return Failed;
                 }
-                ModuleParentLink(parent_module_node, _) |
+                ModuleParentLink(parent_module_node, _) => {
+                    match search_through_modules {
+                        DontSearchThroughModules => {
+                            match search_module.kind {
+                                NormalModuleKind => {
+                                    // We stop the search here.
+                                    debug!("(resolving item in lexical \
+                                            scope) unresolved module: not \
+                                            searching through module \
+                                            parents");
+                                    return Failed;
+                                }
+                                ExternModuleKind |
+                                TraitModuleKind |
+                                AnonymousModuleKind => {
+                                    search_module = parent_module_node;
+                                }
+                            }
+                        }
+                        SearchThroughModules => {
+                            search_module = parent_module_node;
+                        }
+                    }
+                }
                 BlockParentLink(parent_module_node, _) => {
                     search_module = parent_module_node;
                 }
@@ -2854,9 +2962,8 @@ fn resolve_module_in_lexical_scope(module_: @Module, name: ident)
                                     -> ResolveResult<@Module> {
         // If this module is an anonymous module, resolve the item in the
         // lexical scope. Otherwise, resolve the item from the crate root.
-        let resolve_result = self.resolve_item_in_lexical_scope(module_,
-                                                                name,
-                                                                TypeNS);
+        let resolve_result = self.resolve_item_in_lexical_scope(
+            module_, name, TypeNS, DontSearchThroughModules);
         match resolve_result {
             Success(target) => {
                 match target.bindings.type_def {
@@ -2894,99 +3001,85 @@ fn resolve_module_in_lexical_scope(module_: @Module, name: ident)
     }
 
     /**
-     * Resolves a "module prefix". A module prefix is one of (a) the name of a
-     * module; (b) "self::"; (c) some chain of "super::".
+     * Returns the nearest normal module parent of the given module.
      */
-    fn resolve_module_prefix(module_: @Module,
-                             module_path: @DVec<ident>)
-                          -> ModulePrefixResult {
-        let interner = self.session.parse_sess.interner;
-
-        let mut containing_module = self.graph_root.get_module();
-        let mut i = 0;
+    fn get_nearest_normal_module_parent(module_: @Module) -> Option<@Module> {
+        let mut module_ = module_;
         loop {
-            if *interner.get(module_path.get_elt(i)) == ~"self" {
-                containing_module = module_;
-                i += 1;
-                break;
-            }
-            if *interner.get(module_path.get_elt(i)) == ~"super" {
-                match containing_module.parent_link {
-                    NoParentLink => {
-                        return ModulePrefixResult {
-                            result: Failed,
-                            prefix_len: i
-                        };
-                    }
-                    BlockParentLink(new_module, _) |
-                    ModuleParentLink(new_module, _) => {
-                        containing_module = new_module;
+            match module_.parent_link {
+                NoParentLink => return None,
+                ModuleParentLink(new_module, _) |
+                BlockParentLink(new_module, _) => {
+                    match new_module.kind {
+                        NormalModuleKind => return Some(new_module),
+                        ExternModuleKind |
+                        TraitModuleKind |
+                        AnonymousModuleKind => module_ = new_module,
                     }
                 }
-                i += 1;
-            } else {
-                break;
             }
         }
+    }
 
-        // Is the containing module the current module? If so, we allow
-        // globs to be unresolved.
-        let allow_globs = core::managed::ptr_eq(containing_module, module_);
-
-        let name = module_path.get_elt(i);
-        let resolve_result = self.resolve_name_in_module(containing_module,
-                                                         name,
-                                                         TypeNS,
-                                                         Xray,
-                                                         allow_globs);
-        match resolve_result {
-            Success(target) => {
-                match target.bindings.type_def {
-                    Some(ref type_def) => {
-                        match (*type_def).module_def {
-                            None => {
-                                error!("!!! (resolving crate-relative \
-                                        module) module wasn't actually a \
-                                        module!");
-                                return ModulePrefixResult {
-                                    result: Failed,
-                                    prefix_len: i + 1
-                                };
-                            }
-                            Some(module_def) => {
-                                return ModulePrefixResult {
-                                    result: Success(module_def),
-                                    prefix_len: i + 1
-                                };
-                            }
-                        }
-                    }
-                    None => {
-                        error!("!!! (resolving crate-relative module) module
-                                wasn't actually a module!");
-                        return ModulePrefixResult {
-                            result: Failed,
-                            prefix_len: i + 1
-                        };
-                    }
+    /**
+     * Returns the nearest normal module parent of the given module, or the
+     * module itself if it is a normal module.
+     */
+    fn get_nearest_normal_module_parent_or_self(module_: @Module) -> @Module {
+        match module_.kind {
+            NormalModuleKind => return module_,
+            ExternModuleKind | TraitModuleKind | AnonymousModuleKind => {
+                match self.get_nearest_normal_module_parent(module_) {
+                    None => module_,
+                    Some(new_module) => new_module
                 }
             }
-            Indeterminate => {
-                debug!("(resolving crate-relative module) indeterminate; \
-                        bailing");
-                return ModulePrefixResult {
-                    result: Indeterminate,
-                    prefix_len: i + 1
-                };
-            }
-            Failed => {
-                debug!("(resolving crate-relative module) failed to resolve");
-                return ModulePrefixResult {
-                    result: Failed,
-                    prefix_len: i + 1
-                };
+        }
+    }
+
+    /**
+     * Resolves a "module prefix". A module prefix is one of (a) `self::`;
+     * (b) some chain of `super::`.
+     */
+    fn resolve_module_prefix(module_: @Module,
+                             module_path: @DVec<ident>)
+                          -> ResolveResult<ModulePrefixResult> {
+        let interner = self.session.parse_sess.interner;
+
+        // Start at the current module if we see `self` or `super`, or at the
+        // top of the crate otherwise.
+        let mut containing_module;
+        let mut i;
+        if *interner.get(module_path.get_elt(0)) == ~"self" {
+            containing_module =
+                self.get_nearest_normal_module_parent_or_self(module_);
+            i = 1;
+        } else if *interner.get(module_path.get_elt(0)) == ~"super" {
+            containing_module =
+                self.get_nearest_normal_module_parent_or_self(module_);
+            i = 0;  // We'll handle `super` below.
+        } else {
+            return Success(NoPrefixFound);
+        }
+
+        // Now loop through all the `super`s we find.
+        while i < module_path.len() &&
+                *interner.get(module_path.get_elt(i)) == ~"super" {
+            debug!("(resolving module prefix) resolving `super` at %s",
+                   self.module_to_str(containing_module));
+            match self.get_nearest_normal_module_parent(containing_module) {
+                None => return Failed,
+                Some(new_module) => {
+                    containing_module = new_module;
+                    i += 1;
+                }
             }
         }
+
+        debug!("(resolving module prefix) finished resolving prefix at %s",
+               self.module_to_str(containing_module));
+
+        return Success(PrefixFound(containing_module, i));
     }
 
     fn name_is_exported(module_: @Module, name: ident) -> bool {
@@ -3006,7 +3099,6 @@ fn resolve_name_in_module(module_: @Module,
                               xray: XrayFlag,
                               allow_globs: bool)
                            -> ResolveResult<Target> {
-
         debug!("(resolving name in module) resolving `%s` in `%s`",
                self.session.str_of(name),
                self.module_to_str(module_));
@@ -3109,7 +3201,8 @@ fn resolve_one_level_renaming_import(module_: @Module,
         debug!("(resolving one-level naming result) searching for module");
         match self.resolve_item_in_lexical_scope(module_,
                                                  source_name,
-                                                 TypeNS) {
+                                                 TypeNS,
+                                                 SearchThroughModules) {
             Failed => {
                 debug!("(resolving one-level renaming import) didn't find \
                         module result");
@@ -3135,8 +3228,9 @@ fn resolve_one_level_renaming_import(module_: @Module,
         } else {
             debug!("(resolving one-level naming result) searching for value");
             match self.resolve_item_in_lexical_scope(module_,
-                                                   source_name,
-                                                   ValueNS) {
+                                                     source_name,
+                                                     ValueNS,
+                                                     SearchThroughModules) {
 
                 Failed => {
                     debug!("(resolving one-level renaming import) didn't \
@@ -3157,8 +3251,9 @@ fn resolve_one_level_renaming_import(module_: @Module,
 
             debug!("(resolving one-level naming result) searching for type");
             match self.resolve_item_in_lexical_scope(module_,
-                                                   source_name,
-                                                   TypeNS) {
+                                                     source_name,
+                                                     TypeNS,
+                                                     SearchThroughModules) {
 
                 Failed => {
                     debug!("(resolving one-level renaming import) didn't \
@@ -3628,7 +3723,7 @@ fn search_ribs(ribs: @DVec<@Rib>, name: ident, span: span,
     fn resolve_crate(@self) {
         debug!("(resolving crate) starting");
 
-        visit_crate(*self.crate, (), mk_vt(@{
+        visit_crate(*self.crate, (), mk_vt(@Visitor {
             visit_item: |item, _context, visitor|
                 self.resolve_item(item, visitor),
             visit_arm: |arm, _context, visitor|
@@ -3652,15 +3747,16 @@ fn resolve_item(item: @item, visitor: ResolveVisitor) {
         // Items with the !resolve_unexported attribute are X-ray contexts.
         // This is used to allow the test runner to run unexported tests.
         let orig_xray_flag = self.xray_context;
-        if contains_name(attr_metas(item.attrs), ~"!resolve_unexported") {
+        if contains_name(attr_metas(/*bad*/copy item.attrs),
+                         ~"!resolve_unexported") {
             self.xray_context = Xray;
         }
 
-        match item.node {
+        match /*bad*/copy item.node {
 
             // enum item: resolve all the variants' discrs,
             // then resolve the ty params
-            item_enum(ref enum_def, type_parameters) => {
+            item_enum(ref enum_def, ref type_parameters) => {
 
                 for (*enum_def).variants.each() |variant| {
                     do variant.node.disr_expr.iter() |dis_expr| {
@@ -3675,11 +3771,9 @@ fn resolve_item(item: @item, visitor: ResolveVisitor) {
                 // n.b. the discr expr gets visted twice.
                 // but maybe it's okay since the first time will signal an
                 // error if there is one? -- tjc
-                do self.with_type_parameter_rib
-                        (HasTypeParameters(&type_parameters, item.id, 0,
-                                           NormalRibKind))
-                        || {
-
+                do self.with_type_parameter_rib(
+                    HasTypeParameters(
+                        type_parameters, item.id, 0, NormalRibKind)) {
                     visit_item(item, (), visitor);
                 }
             }
@@ -3707,19 +3801,22 @@ fn resolve_item(item: @item, visitor: ResolveVisitor) {
                                             visitor);
             }
 
-            item_trait(type_parameters, traits, ref methods) => {
+            item_trait(ref type_parameters, ref traits, ref methods) => {
                 // Create a new rib for the self type.
                 let self_type_rib = @Rib(NormalRibKind);
                 (*self.type_ribs).push(self_type_rib);
                 self_type_rib.bindings.insert(self.self_ident,
                                               dl_def(def_self_ty(item.id)));
+                self_type_rib.bindings.insert(self.type_self_ident,
+                                              dl_def(def_self_ty(item.id)));
 
                 // Create a new rib for the trait-wide type parameters.
                 do self.with_type_parameter_rib
-                        (HasTypeParameters(&type_parameters, item.id, 0,
+                        (HasTypeParameters(type_parameters, item.id, 0,
                                            NormalRibKind)) {
 
-                    self.resolve_type_parameters(type_parameters, visitor);
+                    self.resolve_type_parameters(/*bad*/copy *type_parameters,
+                                                 visitor);
 
                     // Resolve derived traits.
                     for traits.each |trt| {
@@ -3758,8 +3855,9 @@ fn resolve_item(item: @item, visitor: ResolveVisitor) {
 
                                 // Resolve the method-specific type
                                 // parameters.
-                                self.resolve_type_parameters((*ty_m).tps,
-                                                             visitor);
+                                self.resolve_type_parameters(
+                                    /*bad*/copy (*ty_m).tps,
+                                    visitor);
 
                                 for (*ty_m).decl.inputs.each |argument| {
                                     self.resolve_type(argument.ty, visitor);
@@ -3785,7 +3883,7 @@ fn resolve_item(item: @item, visitor: ResolveVisitor) {
             item_struct(struct_def, ty_params) => {
                 self.resolve_struct(item.id,
                                    @copy ty_params,
-                                   struct_def.fields,
+                                   /*bad*/copy struct_def.fields,
                                    struct_def.dtor,
                                    visitor);
             }
@@ -3800,7 +3898,7 @@ fn resolve_item(item: @item, visitor: ResolveVisitor) {
             item_foreign_mod(foreign_module) => {
                 do self.with_scope(Some(item.ident)) {
                     for foreign_module.items.each |foreign_item| {
-                        match foreign_item.node {
+                        match /*bad*/copy foreign_item.node {
                             foreign_item_fn(_, _, type_parameters) => {
                                 do self.with_type_parameter_rib
                                     (HasTypeParameters(&type_parameters,
@@ -3822,7 +3920,7 @@ fn resolve_item(item: @item, visitor: ResolveVisitor) {
                 }
             }
 
-            item_fn(fn_decl, _, ty_params, ref block) => {
+            item_fn(ref fn_decl, _, ref ty_params, ref block) => {
                 // If this is the main function, we must record it in the
                 // session.
                 //
@@ -3831,15 +3929,15 @@ fn resolve_item(item: @item, visitor: ResolveVisitor) {
 
                 if !self.session.building_library &&
                     is_none(&self.session.main_fn) &&
-                    item.ident == syntax::parse::token::special_idents::main {
+                    item.ident == special_idents::main {
 
                     self.session.main_fn = Some((item.id, item.span));
                 }
 
                 self.resolve_function(OpaqueFunctionRibKind,
-                                      Some(@fn_decl),
+                                      Some(@/*bad*/copy *fn_decl),
                                       HasTypeParameters
-                                        (&ty_params,
+                                        (ty_params,
                                          item.id,
                                          0,
                                          OpaqueFunctionRibKind),
@@ -3964,7 +4062,8 @@ fn resolve_function(rib_kind: RibKind,
                     // Continue.
                 }
                 HasTypeParameters(type_parameters, _, _, _) => {
-                    self.resolve_type_parameters(*type_parameters, visitor);
+                    self.resolve_type_parameters(/*bad*/copy *type_parameters,
+                                                 visitor);
                 }
             }
 
@@ -4018,8 +4117,11 @@ fn resolve_function(rib_kind: RibKind,
     fn resolve_type_parameters(type_parameters: ~[ty_param],
                                visitor: ResolveVisitor) {
         for type_parameters.each |type_parameter| {
-            for type_parameter.bounds.each |bound| {
-                self.resolve_type(**bound, visitor);
+            for type_parameter.bounds.each |&bound| {
+                match bound {
+                    TraitTyParamBound(ty) => self.resolve_type(ty, visitor),
+                    RegionTyParamBound => {}
+                }
             }
         }
     }
@@ -4036,7 +4138,8 @@ fn resolve_struct(id: node_id,
                                          OpaqueFunctionRibKind)) {
 
             // Resolve the type parameters.
-            self.resolve_type_parameters(*type_parameters, visitor);
+            self.resolve_type_parameters(/*bad*/copy *type_parameters,
+                                         visitor);
 
             // Resolve fields.
             for fields.each |field| {
@@ -4083,7 +4186,7 @@ fn resolve_method(rib_kind: RibKind,
         };
 
         self.resolve_function(rib_kind,
-                              Some(@method.decl),
+                              Some(@/*bad*/copy method.decl),
                               type_parameters,
                               method.body,
                               self_binding,
@@ -4105,7 +4208,8 @@ fn resolve_implementation(id: node_id,
                                         (borrowed_type_parameters, id, 0,
                                          NormalRibKind)) {
             // Resolve the type parameters.
-            self.resolve_type_parameters(type_parameters, visitor);
+            self.resolve_type_parameters(/*bad*/copy type_parameters,
+                                         visitor);
 
             // Resolve the trait reference, if necessary.
             let original_trait_refs = self.current_trait_refs;
@@ -4349,17 +4453,14 @@ fn resolve_type(ty: @Ty, visitor: ResolveVisitor) {
                         // Write the result into the def map.
                         debug!("(resolving type) writing resolution for `%s` \
                                 (id %d)",
-                               connect(path.idents.map(
-                                   |x| self.session.str_of(*x)), ~"::"),
+                               self.idents_to_str(path.idents),
                                path_id);
                         self.record_def(path_id, def);
                     }
                     None => {
                         self.session.span_err
                             (ty.span, fmt!("use of undeclared type name `%s`",
-                                           connect(path.idents.map(
-                                               |x| self.session.str_of(*x)),
-                                                   ~"::")));
+                                           self.idents_to_str(path.idents)));
                     }
                 }
             }
@@ -4553,9 +4654,7 @@ struct in scope",
                             self.session.span_err(
                                 path.span,
                                 fmt!("`%s` does not name a structure",
-                                     connect(path.idents.map(
-                                         |x| self.session.str_of(*x)),
-                                             ~"::")));
+                                     self.idents_to_str(path.idents)));
                         }
                     }
                 }
@@ -4571,7 +4670,8 @@ fn resolve_bare_identifier_pattern(name: ident)
                                     -> BareIdentifierPatternResolution {
         match self.resolve_item_in_lexical_scope(self.current_module,
                                                  name,
-                                                 ValueNS) {
+                                                 ValueNS,
+                                                 SearchThroughModules) {
             Success(target) => {
                 match target.bindings.value_def {
                     None => {
@@ -4608,10 +4708,11 @@ fn resolve_bare_identifier_pattern(name: ident)
      * If `check_ribs` is true, checks the local definitions first; i.e.
      * doesn't skip straight to the containing module.
      */
-    fn resolve_path(path: @path, namespace: Namespace, check_ribs: bool,
+    fn resolve_path(path: @path,
+                    namespace: Namespace,
+                    check_ribs: bool,
                     visitor: ResolveVisitor)
                  -> Option<def> {
-
         // First, resolve the types.
         for path.types.each |ty| {
             self.resolve_type(*ty, visitor);
@@ -4625,8 +4726,8 @@ fn resolve_path(path: @path, namespace: Namespace, check_ribs: bool,
 
         if path.idents.len() > 1 {
             return self.resolve_module_relative_path(path,
-                                                  self.xray_context,
-                                                  namespace);
+                                                     self.xray_context,
+                                                     namespace);
         }
 
         return self.resolve_identifier(path.idents.last(),
@@ -4655,7 +4756,7 @@ fn resolve_identifier(identifier: ident,
         }
 
         return self.resolve_item_by_identifier_in_lexical_scope(identifier,
-                                                             namespace);
+                                                                namespace);
     }
 
     // XXX: Merge me with resolve_name_in_module?
@@ -4797,10 +4898,10 @@ fn resolve_crate_relative_path(path: @path,
 
         let mut containing_module;
         match self.resolve_module_path_from_root(root_module,
-                                               module_path_idents,
-                                               0,
-                                               xray,
-                                               path.span) {
+                                                 module_path_idents,
+                                                 0,
+                                                 xray,
+                                                 path.span) {
 
             Failed => {
                 self.session.span_err(path.span,
@@ -4821,9 +4922,9 @@ fn resolve_crate_relative_path(path: @path,
 
         let name = path.idents.last();
         match self.resolve_definition_of_name_in_module(containing_module,
-                                                      name,
-                                                      namespace,
-                                                      xray) {
+                                                        name,
+                                                        namespace,
+                                                        xray) {
             NoNameDefinition => {
                 // We failed to resolve the name. Report an error.
                 return None;
@@ -4870,8 +4971,9 @@ fn resolve_item_by_identifier_in_lexical_scope(ident: ident,
                                                 -> Option<def> {
         // Check the items.
         match self.resolve_item_in_lexical_scope(self.current_module,
-                                               ident,
-                                               namespace) {
+                                                 ident,
+                                                 namespace,
+                                                 DontSearchThroughModules) {
             Success(target) => {
                 match (*target.bindings).def_for_namespace(namespace) {
                     None => {
@@ -4909,10 +5011,8 @@ fn name_exists_in_scope_struct(name: &str) -> bool {
                     item_struct(class_def, _) => {
                       for vec::each(class_def.fields) |field| {
                         match field.node.kind {
-                          syntax::ast::unnamed_field
-                            => {},
-                          syntax::ast::named_field(ident, _, _)
-                            => {
+                          unnamed_field => {},
+                          named_field(ident, _, _) => {
                               if str::eq_slice(self.session.str_of(ident),
                                                name) {
                                 return true
@@ -4950,14 +5050,12 @@ fn resolve_expr(expr: @expr, visitor: ResolveVisitor) {
                     Some(def) => {
                         // Write the result into the def map.
                         debug!("(resolving expr) resolved `%s`",
-                               connect(path.idents.map(
-                                   |x| self.session.str_of(*x)), ~"::"));
+                               self.idents_to_str(path.idents));
                         self.record_def(expr.id, def);
                     }
                     None => {
-                        let wrong_name =
-                            connect(path.idents.map(
-                                |x| self.session.str_of(*x)), ~"::") ;
+                        let wrong_name = self.idents_to_str(
+                            /*bad*/copy path.idents);
                         if self.name_exists_in_scope_struct(wrong_name) {
                             self.session.span_err(expr.span,
                                         fmt!("unresolved name: `%s`. \
@@ -4976,10 +5074,10 @@ fn resolve_expr(expr: @expr, visitor: ResolveVisitor) {
                 visit_expr(expr, (), visitor);
             }
 
-            expr_fn(_, fn_decl, ref block, capture_clause) |
-            expr_fn_block(fn_decl, ref block, capture_clause) => {
+            expr_fn(_, ref fn_decl, ref block, capture_clause) |
+            expr_fn_block(ref fn_decl, ref block, capture_clause) => {
                 self.resolve_function(FunctionRibKind(expr.id, block.node.id),
-                                      Some(@fn_decl),
+                                      Some(@/*bad*/copy *fn_decl),
                                       NoTypeParameters,
                                       (*block),
                                       NoSelfBinding,
@@ -5017,9 +5115,7 @@ fn resolve_expr(expr: @expr, visitor: ResolveVisitor) {
                         self.session.span_err(
                             path.span,
                             fmt!("`%s` does not name a structure",
-                                 connect(path.idents.map(
-                                     |x| self.session.str_of(*x)),
-                                         ~"::")));
+                                 self.idents_to_str(path.idents)));
                     }
                 }
 
@@ -5070,60 +5166,64 @@ fn record_candidate_traits_for_expr_if_necessary(expr: @expr) {
             }
             expr_binary(add, _, _) | expr_assign_op(add, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.add_trait);
+                                              self.lang_items.add_trait());
             }
             expr_binary(subtract, _, _) | expr_assign_op(subtract, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.sub_trait);
+                                              self.lang_items.sub_trait());
             }
             expr_binary(mul, _, _) | expr_assign_op(mul, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.mul_trait);
+                                              self.lang_items.mul_trait());
             }
             expr_binary(div, _, _) | expr_assign_op(div, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.div_trait);
+                                              self.lang_items.div_trait());
             }
             expr_binary(rem, _, _) | expr_assign_op(rem, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.modulo_trait);
+                                              self.lang_items.modulo_trait());
             }
             expr_binary(bitxor, _, _) | expr_assign_op(bitxor, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.bitxor_trait);
+                                              self.lang_items.bitxor_trait());
             }
             expr_binary(bitand, _, _) | expr_assign_op(bitand, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.bitand_trait);
+                                              self.lang_items.bitand_trait());
             }
             expr_binary(bitor, _, _) | expr_assign_op(bitor, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.bitor_trait);
+                                              self.lang_items.bitor_trait());
             }
             expr_binary(shl, _, _) | expr_assign_op(shl, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.shl_trait);
+                                              self.lang_items.shl_trait());
             }
             expr_binary(shr, _, _) | expr_assign_op(shr, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.shr_trait);
+                                              self.lang_items.shr_trait());
             }
             expr_binary(lt, _, _) | expr_binary(le, _, _) |
             expr_binary(ge, _, _) | expr_binary(gt, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.ord_trait);
+                                              self.lang_items.ord_trait());
             }
             expr_binary(eq, _, _) | expr_binary(ne, _, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.eq_trait);
+                                              self.lang_items.eq_trait());
             }
             expr_unary(neg, _) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.neg_trait);
+                                              self.lang_items.neg_trait());
+            }
+            expr_unary(not, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.not_trait());
             }
             expr_index(*) => {
                 self.add_fixed_trait_for_expr(expr.id,
-                                              self.lang_items.index_trait);
+                                              self.lang_items.index_trait());
             }
             _ => {
                 // Nothing to do.
@@ -5242,9 +5342,9 @@ fn add_trait_info_if_containing_method(found_traits: @DVec<def_id>,
         }
     }
 
-    fn add_fixed_trait_for_expr(expr_id: node_id, +trait_id: Option<def_id>) {
+    fn add_fixed_trait_for_expr(expr_id: node_id, +trait_id: def_id) {
         let traits = @DVec();
-        traits.push(trait_id.get());
+        traits.push(trait_id);
         self.trait_map.insert(expr_id, traits);
     }
 
@@ -5338,7 +5438,7 @@ fn check_for_unused_imports_in_module(module_: @Module) {
     // hit.
     //
 
-    /// A somewhat inefficient routine to print out the name of a module.
+    /// A somewhat inefficient routine to obtain the name of a module.
     fn module_to_str(module_: @Module) -> ~str {
         let idents = DVec();
         let mut current_module = module_;
@@ -5352,7 +5452,7 @@ fn module_to_str(module_: @Module) -> ~str {
                     current_module = module_;
                 }
                 BlockParentLink(module_, _) => {
-                    idents.push(syntax::parse::token::special_idents::opaque);
+                    idents.push(special_idents::opaque);
                     current_module = module_;
                 }
             }
@@ -5361,22 +5461,7 @@ fn module_to_str(module_: @Module) -> ~str {
         if idents.len() == 0 {
             return ~"???";
         }
-
-        let mut string = ~"";
-        let mut i = idents.len() - 1;
-        loop {
-            if i < idents.len() - 1 {
-                string += ~"::";
-            }
-            string += self.session.str_of(idents.get_elt(i));
-
-            if i == 0 {
-                break;
-            }
-            i -= 1;
-        }
-
-        return string;
+        return self.idents_to_str(vec::reversed(idents.get()));
     }
 
     fn dump_module(module_: @Module) {
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
new file mode 100644 (file)
index 0000000..cc2a0eb
--- /dev/null
@@ -0,0 +1,1805 @@
+// 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.
+
+/*!
+ *
+ * # Compilation of match statements
+ *
+ * I will endeavor to explain the code as best I can.  I have only a loose
+ * understanding of some parts of it.
+ *
+ * ## Matching
+ *
+ * The basic state of the code is maintained in an array `m` of `@Match`
+ * objects.  Each `@Match` describes some list of patterns, all of which must
+ * match against the current list of values.  If those patterns match, then
+ * the arm listed in the match is the correct arm.  A given arm may have
+ * multiple corresponding match entries, one for each alternative that
+ * remains.  As we proceed these sets of matches are adjusted by the various
+ * `enter_XXX()` functions, each of which adjusts the set of options given
+ * some information about the value which has been matched.
+ *
+ * So, initially, there is one value and N matches, each of which have one
+ * constituent pattern.  N here is usually the number of arms but may be
+ * greater, if some arms have multiple alternatives.  For example, here:
+ *
+ *     enum Foo { A, B(int), C(uint, uint) }
+ *     match foo {
+ *         A => ...,
+ *         B(x) => ...,
+ *         C(1u, 2) => ...,
+ *         C(_) => ...
+ *     }
+ *
+ * The value would be `foo`.  There would be four matches, each of which
+ * contains one pattern (and, in one case, a guard).  We could collect the
+ * various options and then compile the code for the case where `foo` is an
+ * `A`, a `B`, and a `C`.  When we generate the code for `C`, we would (1)
+ * drop the two matches that do not match a `C` and (2) expand the other two
+ * into two patterns each.  In the first case, the two patterns would be `1u`
+ * and `2`, and the in the second case the _ pattern would be expanded into
+ * `_` and `_`.  The two values are of course the arguments to `C`.
+ *
+ * Here is a quick guide to the various functions:
+ *
+ * - `compile_submatch()`: The main workhouse.  It takes a list of values and
+ *   a list of matches and finds the various possibilities that could occur.
+ *
+ * - `enter_XXX()`: modifies the list of matches based on some information
+ *   about the value that has been matched.  For example,
+ *   `enter_rec_or_struct()` adjusts the values given that a record or struct
+ *   has been matched.  This is an infallible pattern, so *all* of the matches
+ *   must be either wildcards or record/struct patterns.  `enter_opt()`
+ *   handles the fallible cases, and it is correspondingly more complex.
+ *
+ * ## Bindings
+ *
+ * We store information about the bound variables for each arm as part of the
+ * per-arm `ArmData` struct.  There is a mapping from identifiers to
+ * `BindingInfo` structs.  These structs contain the mode/id/type of the
+ * binding, but they also contain up to two LLVM values, called `llmatch` and
+ * `llbinding` respectively (the `llbinding`, as will be described shortly, is
+ * optional and only present for by-value bindings---therefore it is bundled
+ * up as part of the `TransBindingMode` type).  Both point at allocas.
+ *
+ * The `llmatch` binding always stores a pointer into the value being matched
+ * which points at the data for the binding.  If the value being matched has
+ * type `T`, then, `llmatch` will point at an alloca of type `T*` (and hence
+ * `llmatch` has type `T**`).  So, if you have a pattern like:
+ *
+ *    let a: A = ...;
+ *    let b: B = ...;
+ *    match (a, b) { (ref c, copy d) => { ... } }
+ *
+ * For `c` and `d`, we would generate allocas of type `C*` and `D*`
+ * respectively.  These are called the `llmatch`.  As we match, when we come
+ * up against an identifier, we store the current pointer into the
+ * corresponding alloca.
+ *
+ * In addition, for each by-value binding (copy or move), we will create a
+ * second alloca (`llbinding`) that will hold the final value.  In this
+ * example, that means that `d` would have this second alloca of type `D` (and
+ * hence `llbinding` has type `D*`).
+ *
+ * Once a pattern is completely matched, and assuming that there is no guard
+ * pattern, we will branch to a block that leads to the body itself.  For any
+ * by-value bindings, this block will first load the ptr from `llmatch` (the
+ * one of type `D*`) and copy/move the value into `llbinding` (the one of type
+ * `D`).  The second alloca then becomes the value of the local variable.  For
+ * by ref bindings, the value of the local variable is simply the first
+ * alloca.
+ *
+ * So, for the example above, we would generate a setup kind of like this:
+ *
+ *        +-------+
+ *        | Entry |
+ *        +-------+
+ *            |
+ *        +-------------------------------------------+
+ *        | llmatch_c = (addr of first half of tuple) |
+ *        | llmatch_d = (addr of first half of tuple) |
+ *        +-------------------------------------------+
+ *            |
+ *        +--------------------------------------+
+ *        | *llbinding_d = **llmatch_dlbinding_d |
+ *        +--------------------------------------+
+ *
+ * If there is a guard, the situation is slightly different, because we must
+ * execute the guard code.  Moreover, we need to do so once for each of the
+ * alternatives that lead to the arm, because if the guard fails, they may
+ * have different points from which to continue the search. Therefore, in that
+ * case, we generate code that looks more like:
+ *
+ *        +-------+
+ *        | Entry |
+ *        +-------+
+ *            |
+ *        +-------------------------------------------+
+ *        | llmatch_c = (addr of first half of tuple) |
+ *        | llmatch_d = (addr of first half of tuple) |
+ *        +-------------------------------------------+
+ *            |
+ *        +-------------------------------------------------+
+ *        | *llbinding_d = **llmatch_dlbinding_d            |
+ *        | check condition                                 |
+ *        | if false { free *llbinding_d, goto next case }  |
+ *        | if true { goto body }                           |
+ *        +-------------------------------------------------+
+ *
+ * The handling for the cleanups is a bit... sensitive.  Basically, the body
+ * is the one that invokes `add_clean()` for each binding.  During the guard
+ * evaluation, we add temporary cleanups and revoke them after the guard is
+ * evaluated (it could fail, after all).  Presuming the guard fails, we drop
+ * the various values we copied explicitly.  Note that guards and moves are
+ * just plain incompatible.
+ *
+ */
+
+use core::prelude::*;
+
+use back::abi;
+use lib::llvm::llvm;
+use lib::llvm::{ValueRef, BasicBlockRef};
+use middle::const_eval;
+use middle::pat_util::*;
+use middle::resolve::DefMap;
+use middle::trans::base::*;
+use middle::trans::build::*;
+use middle::trans::callee;
+use middle::trans::common::*;
+use middle::trans::consts;
+use middle::trans::controlflow;
+use middle::trans::datum::*;
+use middle::trans::expr::Dest;
+use middle::trans::expr;
+use middle::trans::glue;
+use middle::ty::{CopyValue, MoveValue, ReadValue};
+use util::common::indenter;
+
+use core::dvec::DVec;
+use core::dvec;
+use std::map::HashMap;
+use syntax::ast::def_id;
+use syntax::ast;
+use syntax::ast_util::{dummy_sp, path_to_ident};
+use syntax::ast_util;
+use syntax::codemap::span;
+use syntax::print::pprust::pat_to_str;
+
+fn macros() { include!("macros.rs"); } // FIXME(#3114): Macro import/export.
+
+// An option identifying a literal: either a unit-like struct or an
+// expression.
+enum Lit {
+    UnitLikeStructLit(ast::node_id),    // the node ID of the pattern
+    ExprLit(@ast::expr),
+    ConstLit(ast::def_id),              // the def ID of the constant
+}
+
+// An option identifying a branch (either a literal, a enum variant or a
+// range)
+enum Opt {
+    lit(Lit),
+    var(/* disr val */int, /* variant dids */{enm: def_id, var: def_id}),
+    range(@ast::expr, @ast::expr),
+    vec_len_eq(uint),
+    vec_len_ge(uint)
+}
+
+fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool {
+    match (*a, *b) {
+      (lit(a), lit(b)) => {
+        match (a, b) {
+            (UnitLikeStructLit(a), UnitLikeStructLit(b)) => a == b,
+            _ => {
+                let a_expr;
+                match a {
+                    ExprLit(existing_a_expr) => a_expr = existing_a_expr,
+                    ConstLit(a_const) => {
+                        let e = const_eval::lookup_const_by_id(tcx, a_const);
+                        a_expr = e.get();
+                    }
+                    UnitLikeStructLit(_) => {
+                        fail ~"UnitLikeStructLit should have been handled \
+                               above"
+                    }
+                }
+
+                let b_expr;
+                match b {
+                    ExprLit(existing_b_expr) => b_expr = existing_b_expr,
+                    ConstLit(b_const) => {
+                        let e = const_eval::lookup_const_by_id(tcx, b_const);
+                        b_expr = e.get();
+                    }
+                    UnitLikeStructLit(_) => {
+                        fail ~"UnitLikeStructLit should have been handled \
+                               above"
+                    }
+                }
+
+                const_eval::compare_lit_exprs(tcx, a_expr, b_expr) == 0
+            }
+        }
+      }
+      (range(a1, a2), range(b1, b2)) => {
+        const_eval::compare_lit_exprs(tcx, a1, b1) == 0 &&
+        const_eval::compare_lit_exprs(tcx, a2, b2) == 0
+      }
+      (var(a, _), var(b, _)) => a == b,
+      (vec_len_eq(a), vec_len_eq(b)) => a == b,
+      (vec_len_ge(a), vec_len_ge(b)) => a == b,
+      _ => false
+    }
+}
+
+enum opt_result {
+    single_result(Result),
+    lower_bound(Result),
+    range_result(Result, Result),
+}
+fn trans_opt(bcx: block, o: &Opt) -> opt_result {
+    let _icx = bcx.insn_ctxt("match::trans_opt");
+    let ccx = bcx.ccx();
+    let mut bcx = bcx;
+    match *o {
+        lit(ExprLit(lit_expr)) => {
+            let datumblock = expr::trans_to_datum(bcx, lit_expr);
+            return single_result(datumblock.to_result());
+        }
+        lit(UnitLikeStructLit(pat_id)) => {
+            let struct_ty = ty::node_id_to_type(bcx.tcx(), pat_id);
+            let datumblock = datum::scratch_datum(bcx, struct_ty, true);
+            return single_result(datumblock.to_result(bcx));
+        }
+        lit(ConstLit(lit_id)) => {
+            let llval = consts::get_const_val(bcx.ccx(), lit_id);
+            return single_result(rslt(bcx, llval));
+        }
+        var(disr_val, _) => {
+            return single_result(rslt(bcx, C_int(ccx, disr_val)));
+        }
+        range(l1, l2) => {
+            return range_result(rslt(bcx, consts::const_expr(ccx, l1)),
+                                rslt(bcx, consts::const_expr(ccx, l2)));
+        }
+        vec_len_eq(n) => {
+            return single_result(rslt(bcx, C_int(ccx, n as int)));
+        }
+        vec_len_ge(n) => {
+            return lower_bound(rslt(bcx, C_int(ccx, n as int)));
+        }
+    }
+}
+
+fn variant_opt(tcx: ty::ctxt, pat_id: ast::node_id) -> Opt {
+    match tcx.def_map.get(pat_id) {
+        ast::def_variant(enum_id, var_id) => {
+            let variants = ty::enum_variants(tcx, enum_id);
+            for vec::each(*variants) |v| {
+                if var_id == v.id {
+                    return var(v.disr_val, {enm: enum_id, var: var_id});
+                }
+            }
+            ::core::util::unreachable();
+        }
+        ast::def_struct(_) => {
+            return lit(UnitLikeStructLit(pat_id));
+        }
+        _ => {
+            tcx.sess.bug(~"non-variant or struct in variant_opt()");
+        }
+    }
+}
+
+enum TransBindingMode {
+    TrByValue(/*ismove:*/ bool, /*llbinding:*/ ValueRef),
+    TrByRef,
+    TrByImplicitRef
+}
+
+/**
+ * Information about a pattern binding:
+ * - `llmatch` is a pointer to a stack slot.  The stack slot contains a
+ *   pointer into the value being matched.  Hence, llmatch has type `T**`
+ *   where `T` is the value being matched.
+ * - `trmode` is the trans binding mode
+ * - `id` is the node id of the binding
+ * - `ty` is the Rust type of the binding */
+struct BindingInfo {
+    llmatch: ValueRef,
+    trmode: TransBindingMode,
+    id: ast::node_id,
+    ty: ty::t,
+}
+
+type BindingsMap = HashMap<ident, BindingInfo>;
+
+struct ArmData {
+    bodycx: block,
+    arm: &ast::arm,
+    bindings_map: BindingsMap
+}
+
+struct Match {
+    pats: ~[@ast::pat],
+    data: @ArmData
+}
+
+fn match_to_str(bcx: block, m: &Match) -> ~str {
+    if bcx.sess().verbose() {
+        // for many programs, this just take too long to serialize
+        fmt!("%?", m.pats.map(|p| pat_to_str(*p, bcx.sess().intr())))
+    } else {
+        fmt!("%u pats", m.pats.len())
+    }
+}
+
+fn matches_to_str(bcx: block, m: &[@Match]) -> ~str {
+    fmt!("%?", m.map(|n| match_to_str(bcx, *n)))
+}
+
+fn has_nested_bindings(m: &[@Match], col: uint) -> bool {
+    for vec::each(m) |br| {
+        match br.pats[col].node {
+          ast::pat_ident(_, _, Some(_)) => return true,
+          _ => ()
+        }
+    }
+    return false;
+}
+
+fn expand_nested_bindings(bcx: block, m: &[@Match/&r],
+                          col: uint, val: ValueRef)
+    -> ~[@Match/&r]
+{
+    debug!("expand_nested_bindings(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    do m.map |br| {
+        match br.pats[col].node {
+            ast::pat_ident(_, path, Some(inner)) => {
+                let pats = vec::append(
+                    vec::slice(br.pats, 0u, col),
+                    vec::append(~[inner],
+                                vec::view(br.pats, col + 1u, br.pats.len())));
+
+                let binding_info =
+                    br.data.bindings_map.get(path_to_ident(path));
+
+                Store(bcx, val, binding_info.llmatch);
+                @Match {pats: pats, data: br.data}
+            }
+            _ => {
+                *br
+            }
+        }
+    }
+}
+
+type enter_pat = fn(@ast::pat) -> Option<~[@ast::pat]>;
+
+fn assert_is_binding_or_wild(bcx: block, p: @ast::pat) {
+    if !pat_is_binding_or_wild(bcx.tcx().def_map, p) {
+        bcx.sess().span_bug(
+            p.span,
+            fmt!("Expected an identifier pattern but found p: %s",
+                 pat_to_str(p, bcx.sess().intr())));
+    }
+}
+
+fn enter_match(bcx: block, dm: DefMap, m: &[@Match/&r],
+               col: uint, val: ValueRef, e: enter_pat)
+    -> ~[@Match/&r]
+{
+    debug!("enter_match(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    let mut result = ~[];
+    for vec::each(m) |br| {
+        match e(br.pats[col]) {
+            Some(sub) => {
+                let pats =
+                    vec::append(
+                        vec::append(sub, vec::view(br.pats, 0u, col)),
+                        vec::view(br.pats, col + 1u, br.pats.len()));
+
+                let self = br.pats[col];
+                match self.node {
+                    ast::pat_ident(_, path, None) => {
+                        if pat_is_binding(dm, self) {
+                            let binding_info =
+                                br.data.bindings_map.get(path_to_ident(path));
+                            Store(bcx, val, binding_info.llmatch);
+                        }
+                    }
+                    _ => {}
+                }
+
+                result.push(@Match {pats: pats, data: br.data});
+            }
+            None => ()
+        }
+    }
+
+    debug!("result=%s", matches_to_str(bcx, result));
+
+    return result;
+}
+
+fn enter_default(bcx: block, dm: DefMap, m: &[@Match/&r],
+                 col: uint, val: ValueRef)
+    -> ~[@Match/&r]
+{
+    debug!("enter_default(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    do enter_match(bcx, dm, m, col, val) |p| {
+        match p.node {
+          ast::pat_wild | ast::pat_rec(_, _) | ast::pat_tup(_) |
+          ast::pat_struct(*) => Some(~[]),
+          ast::pat_ident(_, _, None) if pat_is_binding(dm, p) => Some(~[]),
+          _ => None
+        }
+    }
+}
+
+// <pcwalton> nmatsakis: what does enter_opt do?
+// <pcwalton> in trans/match
+// <pcwalton> trans/match.rs is like stumbling around in a dark cave
+// <nmatsakis> pcwalton: the enter family of functions adjust the set of
+//             patterns as needed
+// <nmatsakis> yeah, at some point I kind of achieved some level of
+//             understanding
+// <nmatsakis> anyhow, they adjust the patterns given that something of that
+//             kind has been found
+// <nmatsakis> pcwalton: ok, right, so enter_XXX() adjusts the patterns, as I
+//             said
+// <nmatsakis> enter_match() kind of embodies the generic code
+// <nmatsakis> it is provided with a function that tests each pattern to see
+//             if it might possibly apply and so forth
+// <nmatsakis> so, if you have a pattern like {a: _, b: _, _} and one like _
+// <nmatsakis> then _ would be expanded to (_, _)
+// <nmatsakis> one spot for each of the sub-patterns
+// <nmatsakis> enter_opt() is one of the more complex; it covers the fallible
+//             cases
+// <nmatsakis> enter_rec_or_struct() or enter_tuple() are simpler, since they
+//             are infallible patterns
+// <nmatsakis> so all patterns must either be records (resp. tuples) or
+//             wildcards
+
+fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
+             variant_size: uint, val: ValueRef)
+    -> ~[@Match/&r]
+{
+    debug!("enter_opt(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    let tcx = bcx.tcx();
+    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
+    do enter_match(bcx, tcx.def_map, m, col, val) |p| {
+        match /*bad*/copy p.node {
+            ast::pat_enum(_, subpats) => {
+                if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
+                    Some(option::get_or_default(subpats,
+                                             vec::from_elem(variant_size,
+                                                            dummy)))
+                } else {
+                    None
+                }
+            }
+            ast::pat_ident(_, _, None)
+                    if pat_is_variant_or_struct(tcx.def_map, p) => {
+                if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
+                    Some(~[])
+                } else {
+                    None
+                }
+            }
+            ast::pat_ident(_, _, None) if pat_is_const(tcx.def_map, p) => {
+                let const_def = tcx.def_map.get(p.id);
+                let const_def_id = ast_util::def_id_of_def(const_def);
+                if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) {
+                    Some(~[])
+                } else {
+                    None
+                }
+            }
+            ast::pat_lit(l) => {
+                if opt_eq(tcx, &lit(ExprLit(l)), opt) {Some(~[])} else {None}
+            }
+            ast::pat_range(l1, l2) => {
+                if opt_eq(tcx, &range(l1, l2), opt) {Some(~[])} else {None}
+            }
+            ast::pat_struct(_, field_pats, _) => {
+                if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
+                    // Look up the struct variant ID.
+                    let struct_id;
+                    match tcx.def_map.get(p.id) {
+                        ast::def_variant(_, found_struct_id) => {
+                            struct_id = found_struct_id;
+                        }
+                        _ => {
+                            tcx.sess.span_bug(p.span, ~"expected enum \
+                                                        variant def");
+                        }
+                    }
+
+                    // Reorder the patterns into the same order they were
+                    // specified in the struct definition. Also fill in
+                    // unspecified fields with dummy.
+                    let reordered_patterns = dvec::DVec();
+                    for ty::lookup_struct_fields(tcx, struct_id).each
+                        |field| {
+                            match field_pats.find(|p|
+                                                  p.ident == field.ident) {
+                                None => reordered_patterns.push(dummy),
+                                Some(fp) => reordered_patterns.push(fp.pat)
+                            }
+                    }
+                    Some(dvec::unwrap(move reordered_patterns))
+                } else {
+                    None
+                }
+            }
+            ast::pat_vec(elems, tail) => {
+                match tail {
+                    Some(_) => {
+                        if opt_eq(tcx, &vec_len_ge(elems.len()), opt) {
+                            Some(vec::append_one(elems, tail.get()))
+                        } else {
+                            None
+                        }
+                    }
+                    None => {
+                        if opt_eq(tcx, &vec_len_eq(elems.len()), opt) {
+                            Some(copy elems)
+                        } else {
+                            None
+                        }
+                    }
+                }
+            }
+            _ => {
+                assert_is_binding_or_wild(bcx, p);
+                Some(vec::from_elem(variant_size, dummy))
+            }
+        }
+    }
+}
+
+fn enter_rec_or_struct(bcx: block, dm: DefMap, m: &[@Match/&r], col: uint,
+                       fields: ~[ast::ident], val: ValueRef) -> ~[@Match/&r] {
+    debug!("enter_rec_or_struct(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
+    do enter_match(bcx, dm, m, col, val) |p| {
+        match /*bad*/copy p.node {
+            ast::pat_rec(fpats, _) | ast::pat_struct(_, fpats, _) => {
+                let mut pats = ~[];
+                for vec::each(fields) |fname| {
+                    match fpats.find(|p| p.ident == *fname) {
+                        None => pats.push(dummy),
+                        Some(pat) => pats.push(pat.pat)
+                    }
+                }
+                Some(pats)
+            }
+            _ => {
+                assert_is_binding_or_wild(bcx, p);
+                Some(vec::from_elem(fields.len(), dummy))
+            }
+        }
+    }
+}
+
+fn enter_tup(bcx: block, dm: DefMap, m: &[@Match/&r],
+             col: uint, val: ValueRef, n_elts: uint)
+    -> ~[@Match/&r]
+{
+    debug!("enter_tup(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
+    do enter_match(bcx, dm, m, col, val) |p| {
+        match /*bad*/copy p.node {
+            ast::pat_tup(elts) => {
+                Some(elts)
+            }
+            _ => {
+                assert_is_binding_or_wild(bcx, p);
+                Some(vec::from_elem(n_elts, dummy))
+            }
+        }
+    }
+}
+
+fn enter_tuple_struct(bcx: block, dm: DefMap, m: &[@Match/&r], col: uint,
+                      val: ValueRef, n_elts: uint)
+    -> ~[@Match/&r]
+{
+    debug!("enter_tuple_struct(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
+    do enter_match(bcx, dm, m, col, val) |p| {
+        match /*bad*/copy p.node {
+            ast::pat_enum(_, Some(elts)) => Some(elts),
+            _ => {
+                assert_is_binding_or_wild(bcx, p);
+                Some(vec::from_elem(n_elts, dummy))
+            }
+        }
+    }
+}
+
+fn enter_box(bcx: block, dm: DefMap, m: &[@Match/&r],
+             col: uint, val: ValueRef)
+    -> ~[@Match/&r]
+{
+    debug!("enter_box(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
+    do enter_match(bcx, dm, m, col, val) |p| {
+        match p.node {
+            ast::pat_box(sub) => {
+                Some(~[sub])
+            }
+            _ => {
+                assert_is_binding_or_wild(bcx, p);
+                Some(~[dummy])
+            }
+        }
+    }
+}
+
+fn enter_uniq(bcx: block, dm: DefMap, m: &[@Match/&r],
+              col: uint, val: ValueRef)
+    -> ~[@Match/&r]
+{
+    debug!("enter_uniq(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
+    do enter_match(bcx, dm, m, col, val) |p| {
+        match p.node {
+            ast::pat_uniq(sub) => {
+                Some(~[sub])
+            }
+            _ => {
+                assert_is_binding_or_wild(bcx, p);
+                Some(~[dummy])
+            }
+        }
+    }
+}
+
+fn enter_region(bcx: block, dm: DefMap, m: &[@Match/&r],
+                col: uint, val: ValueRef)
+    -> ~[@Match/&r]
+{
+    debug!("enter_region(bcx=%s, m=%s, col=%u, val=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           col,
+           bcx.val_str(val));
+    let _indenter = indenter();
+
+    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
+    do enter_match(bcx, dm, m, col, val) |p| {
+        match p.node {
+            ast::pat_region(sub) => {
+                Some(~[sub])
+            }
+            _ => {
+                assert_is_binding_or_wild(bcx, p);
+                Some(~[dummy])
+            }
+        }
+    }
+}
+
+// Returns the options in one column of matches. An option is something that
+// needs to be conditionally matched at runtime; for example, the discriminant
+// on a set of enum variants or a literal.
+fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] {
+    fn add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, val: Opt) {
+        if set.any(|l| opt_eq(tcx, l, &val)) {return;}
+        set.push(val);
+    }
+
+    let found = DVec();
+    for vec::each(m) |br| {
+        let cur = br.pats[col];
+        match /*bad*/copy cur.node {
+            ast::pat_lit(l) => {
+                add_to_set(ccx.tcx, &found, lit(ExprLit(l)));
+            }
+            ast::pat_ident(*) => {
+                // This is one of: an enum variant, a unit-like struct, or a
+                // variable binding.
+                match ccx.tcx.def_map.find(cur.id) {
+                    Some(ast::def_variant(*)) => {
+                        add_to_set(ccx.tcx, &found,
+                                   variant_opt(ccx.tcx, cur.id));
+                    }
+                    Some(ast::def_struct(*)) => {
+                        add_to_set(ccx.tcx, &found,
+                                   lit(UnitLikeStructLit(cur.id)));
+                    }
+                    Some(ast::def_const(const_did)) => {
+                        add_to_set(ccx.tcx, &found,
+                                   lit(ConstLit(const_did)));
+                    }
+                    _ => {}
+                }
+            }
+            ast::pat_enum(*) | ast::pat_struct(*) => {
+                // This could be one of: a tuple-like enum variant, a
+                // struct-like enum variant, or a struct.
+                match ccx.tcx.def_map.find(cur.id) {
+                    Some(ast::def_variant(*)) => {
+                        add_to_set(ccx.tcx, &found,
+                                   variant_opt(ccx.tcx, cur.id));
+                    }
+                    _ => {}
+                }
+            }
+            ast::pat_range(l1, l2) => {
+                add_to_set(ccx.tcx, &found, range(l1, l2));
+            }
+            ast::pat_vec(elems, tail) => {
+                let opt = match tail {
+                    None => vec_len_eq(elems.len()),
+                    Some(_) => vec_len_ge(elems.len())
+                };
+                add_to_set(ccx.tcx, &found, opt);
+            }
+            _ => {}
+        }
+    }
+    return dvec::unwrap(move found);
+}
+
+fn extract_variant_args(bcx: block, pat_id: ast::node_id,
+                        vdefs: {enm: def_id, var: def_id},
+                        val: ValueRef)
+    -> {vals: ~[ValueRef], bcx: block}
+{
+    let _icx = bcx.insn_ctxt("match::extract_variant_args");
+    let ccx = bcx.fcx.ccx;
+    let enum_ty_substs = match ty::get(node_id_type(bcx, pat_id)).sty {
+      ty::ty_enum(id, ref substs) => {
+        assert id == vdefs.enm;
+        /*bad*/copy (*substs).tps
+      }
+      _ => bcx.sess().bug(~"extract_variant_args: pattern has non-enum type")
+    };
+    let mut blobptr = val;
+    let variants = ty::enum_variants(ccx.tcx, vdefs.enm);
+    let size = ty::enum_variant_with_id(ccx.tcx, vdefs.enm,
+                                        vdefs.var).args.len();
+    if size > 0u && (*variants).len() != 1u {
+        let enumptr =
+            PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
+        blobptr = GEPi(bcx, enumptr, [0u, 1u]);
+    }
+    let vdefs_tg = vdefs.enm;
+    let vdefs_var = vdefs.var;
+    let args = do vec::from_fn(size) |i| {
+        GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var,
+                 /*bad*/copy enum_ty_substs, i)
+    };
+    return {vals: args, bcx: bcx};
+}
+
+fn extract_vec_elems(bcx: block, pat_id: ast::node_id,
+                     elem_count: uint, tail: bool, val: ValueRef)
+    -> {vals: ~[ValueRef], bcx: block}
+{
+    let _icx = bcx.insn_ctxt("match::extract_vec_elems");
+    let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
+    let unboxed = load_if_immediate(bcx, val, vt.vec_ty);
+    let (base, len) = tvec::get_base_and_len(bcx, unboxed, vt.vec_ty);
+
+    let mut elems = do vec::from_fn(elem_count) |i| {
+        GEPi(bcx, base, ~[i])
+    };
+    if tail {
+        let tail_offset = Mul(bcx, vt.llunit_size,
+            C_int(bcx.ccx(), elem_count as int)
+        );
+        let tail_begin = tvec::pointer_add(bcx, base, tail_offset);
+        let tail_len = Sub(bcx, len, tail_offset);
+        let tail_ty = ty::mk_evec(bcx.tcx(),
+            {ty: vt.unit_ty, mutbl: ast::m_imm},
+            ty::vstore_slice(ty::re_static)
+        );
+        let scratch = scratch_datum(bcx, tail_ty, false);
+        Store(bcx, tail_begin,
+            GEPi(bcx, scratch.val, [0u, abi::slice_elt_base])
+        );
+        Store(bcx, tail_len,
+            GEPi(bcx, scratch.val, [0u, abi::slice_elt_len])
+        );
+        elems.push(scratch.val);
+        scratch.add_clean(bcx);
+    }
+    return {vals: elems, bcx: bcx};
+}
+
+// NB: This function does not collect fields from struct-like enum variants.
+fn collect_record_or_struct_fields(bcx: block, m: &[@Match], col: uint) ->
+                                   ~[ast::ident] {
+    let mut fields: ~[ast::ident] = ~[];
+    for vec::each(m) |br| {
+        match /*bad*/copy br.pats[col].node {
+          ast::pat_rec(fs, _) => extend(&mut fields, fs),
+          ast::pat_struct(_, fs, _) => {
+            match ty::get(node_id_type(bcx, br.pats[col].id)).sty {
+              ty::ty_struct(*) => extend(&mut fields, fs),
+              _ => ()
+            }
+          }
+          _ => ()
+        }
+    }
+    return fields;
+
+    fn extend(idents: &mut ~[ast::ident], field_pats: &[ast::field_pat]) {
+        for field_pats.each |field_pat| {
+            let field_ident = field_pat.ident;
+            if !vec::any(*idents, |x| *x == field_ident) {
+                idents.push(field_ident);
+            }
+        }
+    }
+}
+
+fn root_pats_as_necessary(bcx: block, m: &[@Match],
+                          col: uint, val: ValueRef)
+{
+    for vec::each(m) |br| {
+        let pat_id = br.pats[col].id;
+
+        match bcx.ccx().maps.root_map.find({id:pat_id, derefs:0u}) {
+            None => (),
+            Some(scope_id) => {
+                // Note: the scope_id will always be the id of the match.  See
+                // the extended comment in rustc::middle::borrowck::preserve()
+                // for details (look for the case covering cat_discr).
+
+                let datum = Datum {val: val, ty: node_id_type(bcx, pat_id),
+                                   mode: ByRef, source: FromLvalue};
+                datum.root(bcx, scope_id);
+                return; // if we kept going, we'd only re-root the same value
+            }
+        }
+    }
+}
+
+// Macro for deciding whether any of the remaining matches fit a given kind of
+// pattern.  Note that, because the macro is well-typed, either ALL of the
+// 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) => (
+        vec::any($m, |br| {
+            match br.pats[col].node {
+                $pattern => true,
+                _ => false
+            }
+        })
+    )
+)
+
+fn any_box_pat(m: &[@Match], col: uint) -> bool {
+    any_pat!(m, ast::pat_box(_))
+}
+
+fn any_uniq_pat(m: &[@Match], col: uint) -> bool {
+    any_pat!(m, ast::pat_uniq(_))
+}
+
+fn any_region_pat(m: &[@Match], col: uint) -> bool {
+    any_pat!(m, ast::pat_region(_))
+}
+
+fn any_tup_pat(m: &[@Match], col: uint) -> bool {
+    any_pat!(m, ast::pat_tup(_))
+}
+
+fn any_tuple_struct_pat(bcx: block, m: &[@Match], col: uint) -> bool {
+    vec::any(m, |br| {
+        let pat = br.pats[col];
+        match pat.node {
+            ast::pat_enum(_, Some(_)) => {
+                match bcx.tcx().def_map.find(pat.id) {
+                    Some(ast::def_struct(*)) => true,
+                    _ => false
+                }
+            }
+            _ => false
+        }
+    })
+}
+
+type mk_fail = fn@() -> BasicBlockRef;
+
+fn pick_col(m: &[@Match]) -> uint {
+    fn score(p: @ast::pat) -> uint {
+        match p.node {
+          ast::pat_lit(_) | ast::pat_enum(_, _) | ast::pat_range(_, _) => 1u,
+          ast::pat_ident(_, _, Some(p)) => score(p),
+          _ => 0u
+        }
+    }
+    let scores = vec::to_mut(vec::from_elem(m[0].pats.len(), 0u));
+    for vec::each(m) |br| {
+        let mut i = 0u;
+        for vec::each(br.pats) |p| { scores[i] += score(*p); i += 1u; }
+    }
+    let mut max_score = 0u;
+    let mut best_col = 0u;
+    let mut i = 0u;
+    for vec::each(scores) |score| {
+        let score = *score;
+
+        // Irrefutable columns always go first, they'd only be duplicated in
+        // the branches.
+        if score == 0u { return i; }
+        // If no irrefutable ones are found, we pick the one with the biggest
+        // branching factor.
+        if score > max_score { max_score = score; best_col = i; }
+        i += 1u;
+    }
+    return best_col;
+}
+
+enum branch_kind { no_branch, single, switch, compare, compare_vec_len, }
+
+impl branch_kind : cmp::Eq {
+    pure fn eq(&self, other: &branch_kind) -> bool {
+        ((*self) as uint) == ((*other) as uint)
+    }
+    pure fn ne(&self, other: &branch_kind) -> bool { !(*self).eq(other) }
+}
+
+// Compiles a comparison between two things.
+fn compare_values(cx: block, lhs: ValueRef, rhs: ValueRef, rhs_t: ty::t) ->
+                  Result {
+    let _icx = cx.insn_ctxt("compare_values");
+    if ty::type_is_scalar(rhs_t) {
+      let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::eq);
+      return rslt(rs.bcx, rs.val);
+    }
+
+    match ty::get(rhs_t).sty {
+        ty::ty_estr(ty::vstore_uniq) => {
+            let scratch_result = scratch_datum(cx, ty::mk_bool(cx.tcx()),
+                                               false);
+            let scratch_lhs = alloca(cx, val_ty(lhs));
+            Store(cx, lhs, scratch_lhs);
+            let scratch_rhs = alloca(cx, val_ty(rhs));
+            Store(cx, rhs, scratch_rhs);
+            let did = cx.tcx().lang_items.uniq_str_eq_fn();
+            let bcx = callee::trans_rtcall_or_lang_call(cx, did,
+                                                        ~[scratch_lhs,
+                                                          scratch_rhs],
+                                                        expr::SaveIn(
+                                                         scratch_result.val));
+            return scratch_result.to_result(bcx);
+        }
+        ty::ty_estr(_) => {
+            let scratch_result = scratch_datum(cx, ty::mk_bool(cx.tcx()),
+                                               false);
+            let did = cx.tcx().lang_items.str_eq_fn();
+            let bcx = callee::trans_rtcall_or_lang_call(cx, did,
+                                                        ~[lhs, rhs],
+                                                        expr::SaveIn(
+                                                         scratch_result.val));
+            return scratch_result.to_result(bcx);
+        }
+        _ => {
+            cx.tcx().sess.bug(~"only scalars and strings supported in \
+                                compare_values");
+        }
+    }
+}
+
+fn store_non_ref_bindings(bcx: block,
+                          data: &ArmData,
+                          opt_temp_cleanups: Option<&DVec<ValueRef>>)
+    -> block
+{
+    /*!
+     *
+     * For each copy/move binding, copy the value from the value
+     * being matched into its final home.  This code executes once
+     * one of the patterns for a given arm has completely matched.
+     * It adds temporary cleanups to the `temp_cleanups` array,
+     * if one is provided.
+     */
+
+    let mut bcx = bcx;
+    for data.bindings_map.each_value |binding_info| {
+        match binding_info.trmode {
+            TrByValue(is_move, lldest) => {
+                let llval = Load(bcx, binding_info.llmatch); // get a T*
+                let datum = Datum {val: llval, ty: binding_info.ty,
+                                   mode: ByRef, source: FromLvalue};
+                bcx = {
+                    if is_move {
+                        datum.move_to(bcx, INIT, lldest)
+                    } else {
+                        datum.copy_to(bcx, INIT, lldest)
+                    }
+                };
+
+                for opt_temp_cleanups.each |temp_cleanups| {
+                    add_clean_temp_mem(bcx, lldest, binding_info.ty);
+                    temp_cleanups.push(lldest);
+                }
+            }
+            TrByRef | TrByImplicitRef => {}
+        }
+    }
+    return bcx;
+}
+
+fn insert_lllocals(bcx: block,
+                   data: &ArmData,
+                   add_cleans: bool) -> block {
+    /*!
+     *
+     * For each binding in `data.bindings_map`, adds an appropriate entry into
+     * the `fcx.lllocals` map.  If add_cleans is true, then adds cleanups for
+     * the bindings. */
+
+    for data.bindings_map.each_value |binding_info| {
+        let llval = match binding_info.trmode {
+            // By value bindings: use the stack slot that we
+            // copied/moved the value into
+            TrByValue(_, lldest) => {
+                if add_cleans {
+                    add_clean(bcx, lldest, binding_info.ty);
+                }
+
+                lldest
+            }
+
+            // By ref binding: use the ptr into the matched value
+            TrByRef => {
+                binding_info.llmatch
+            }
+
+            // Ugly: for implicit ref, we actually want a T*, but
+            // we have a T**, so we had to load.  This will go away
+            // once implicit refs go away.
+            TrByImplicitRef => {
+                Load(bcx, binding_info.llmatch)
+            }
+        };
+
+        bcx.fcx.lllocals.insert(binding_info.id,
+                                local_mem(llval));
+    }
+    return bcx;
+}
+
+fn compile_guard(bcx: block,
+                 guard_expr: @ast::expr,
+                 data: &ArmData,
+                 m: &[@Match],
+                 vals: &[ValueRef],
+                 chk: Option<mk_fail>)
+    -> block
+{
+    debug!("compile_guard(bcx=%s, guard_expr=%s, m=%s, vals=%?)",
+           bcx.to_str(),
+           bcx.expr_to_str(guard_expr),
+           matches_to_str(bcx, m),
+           vals.map(|v| bcx.val_str(*v)));
+    let _indenter = indenter();
+
+    let mut bcx = bcx;
+    let temp_cleanups = DVec();
+    bcx = store_non_ref_bindings(bcx, data, Some(&temp_cleanups));
+    bcx = insert_lllocals(bcx, data, false);
+
+    let val = unpack_result!(bcx, {
+        do with_scope_result(bcx, guard_expr.info(),
+                             ~"guard") |bcx| {
+            expr::trans_to_datum(bcx, guard_expr).to_result()
+        }
+    });
+
+    // Revoke the temp cleanups now that the guard successfully executed.
+    for temp_cleanups.each |llval| {
+        revoke_clean(bcx, *llval);
+    }
+
+    return do with_cond(bcx, Not(bcx, val)) |bcx| {
+        // Guard does not match: free the values we copied,
+        // and remove all bindings from the lllocals table
+        let bcx = drop_bindings(bcx, data);
+        compile_submatch(bcx, m, vals, chk);
+        bcx
+    };
+
+    fn drop_bindings(bcx: block, data: &ArmData) -> block {
+        let mut bcx = bcx;
+        for data.bindings_map.each_value |binding_info| {
+            match binding_info.trmode {
+                TrByValue(_, llval) => {
+                    bcx = glue::drop_ty(bcx, llval, binding_info.ty);
+                }
+                TrByRef | TrByImplicitRef => {}
+            }
+            bcx.fcx.lllocals.remove(binding_info.id);
+        }
+        return bcx;
+    }
+}
+
+fn compile_submatch(bcx: block,
+                    m: &[@Match],
+                    vals: &[ValueRef],
+                    chk: Option<mk_fail>)
+{
+    debug!("compile_submatch(bcx=%s, m=%s, vals=%?)",
+           bcx.to_str(),
+           matches_to_str(bcx, m),
+           vals.map(|v| bcx.val_str(*v)));
+    let _indenter = indenter();
+
+    /*
+      For an empty match, a fall-through case must exist
+     */
+    assert(m.len() > 0u || chk.is_some());
+    let _icx = bcx.insn_ctxt("match::compile_submatch");
+    let mut bcx = bcx;
+    let tcx = bcx.tcx(), dm = tcx.def_map;
+    if m.len() == 0u {
+        Br(bcx, chk.get()());
+        return;
+    }
+    if m[0].pats.len() == 0u {
+        let data = m[0].data;
+        match data.arm.guard {
+            Some(guard_expr) => {
+                bcx = compile_guard(bcx, guard_expr, m[0].data,
+                                    vec::view(m, 1, m.len()),
+                                    vals, chk);
+            }
+            _ => ()
+        }
+        Br(bcx, data.bodycx.llbb);
+        return;
+    }
+
+    let col = pick_col(m);
+    let val = vals[col];
+    let m = {
+        if has_nested_bindings(m, col) {
+            expand_nested_bindings(bcx, m, col, val)
+        } else {
+            m.to_vec()
+        }
+    };
+
+    let vals_left = vec::append(vec::slice(vals, 0u, col),
+                                vec::view(vals, col + 1u, vals.len()));
+    let ccx = bcx.fcx.ccx;
+    let mut pat_id = 0;
+    for vec::each(m) |br| {
+        // Find a real id (we're adding placeholder wildcard patterns, but
+        // each column is guaranteed to have at least one real pattern)
+        if pat_id == 0 { pat_id = br.pats[col].id; }
+    }
+
+    root_pats_as_necessary(bcx, m, col, val);
+
+    let rec_fields = collect_record_or_struct_fields(bcx, m, col);
+    if rec_fields.len() > 0 {
+        let pat_ty = node_id_type(bcx, pat_id);
+        do expr::with_field_tys(tcx, pat_ty, None) |_has_dtor, field_tys| {
+            let rec_vals = rec_fields.map(|field_name| {
+                let ix = ty::field_idx_strict(tcx, *field_name, field_tys);
+                GEPi(bcx, val, struct_field(ix))
+            });
+            compile_submatch(
+                bcx,
+                enter_rec_or_struct(bcx, dm, m, col, rec_fields, val),
+                vec::append(rec_vals, vals_left),
+                chk);
+        }
+        return;
+    }
+
+    if any_tup_pat(m, col) {
+        let tup_ty = node_id_type(bcx, pat_id);
+        let n_tup_elts = match /*bad*/copy ty::get(tup_ty).sty {
+          ty::ty_tup(elts) => elts.len(),
+          _ => ccx.sess.bug(~"non-tuple type in tuple pattern")
+        };
+        let tup_vals = vec::from_fn(n_tup_elts, |i| GEPi(bcx, val, [0u, i]));
+        compile_submatch(bcx, enter_tup(bcx, dm, m, col, val, n_tup_elts),
+                         vec::append(tup_vals, vals_left), chk);
+        return;
+    }
+
+    if any_tuple_struct_pat(bcx, m, col) {
+        let struct_ty = node_id_type(bcx, pat_id);
+        let struct_element_count;
+        match ty::get(struct_ty).sty {
+            ty::ty_struct(struct_id, _) => {
+                struct_element_count =
+                    ty::lookup_struct_fields(tcx, struct_id).len();
+            }
+            _ => {
+                ccx.sess.bug(~"non-struct type in tuple struct pattern");
+            }
+        }
+
+        let llstructvals = vec::from_fn(
+            struct_element_count, |i| GEPi(bcx, val, struct_field(i)));
+        compile_submatch(bcx,
+                         enter_tuple_struct(bcx, dm, m, col, val,
+                                            struct_element_count),
+                         vec::append(llstructvals, vals_left),
+                         chk);
+        return;
+    }
+
+    // Unbox in case of a box field
+    if any_box_pat(m, col) {
+        let llbox = Load(bcx, val);
+        let box_no_addrspace = non_gc_box_cast(bcx, llbox);
+        let unboxed =
+            GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]);
+        compile_submatch(bcx, enter_box(bcx, dm, m, col, val),
+                         vec::append(~[unboxed], vals_left), chk);
+        return;
+    }
+
+    if any_uniq_pat(m, col) {
+        let llbox = Load(bcx, val);
+        let box_no_addrspace = non_gc_box_cast(bcx, llbox);
+        let unboxed =
+            GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]);
+        compile_submatch(bcx, enter_uniq(bcx, dm, m, col, val),
+                         vec::append(~[unboxed], vals_left), chk);
+        return;
+    }
+
+    if any_region_pat(m, col) {
+        let loaded_val = Load(bcx, val);
+        compile_submatch(bcx, enter_region(bcx, dm, m, col, val),
+                         vec::append(~[loaded_val], vals_left), chk);
+        return;
+    }
+
+    // Decide what kind of branch we need
+    let opts = get_options(ccx, m, col);
+    let mut kind = no_branch;
+    let mut test_val = val;
+    if opts.len() > 0u {
+        match opts[0] {
+            var(_, vdef) => {
+                if (*ty::enum_variants(tcx, vdef.enm)).len() == 1u {
+                    kind = single;
+                } else {
+                    let enumptr =
+                        PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
+                    let discrimptr = GEPi(bcx, enumptr, [0u, 0u]);
+                    test_val = Load(bcx, discrimptr);
+                    kind = switch;
+                }
+            }
+            lit(_) => {
+                let pty = node_id_type(bcx, pat_id);
+                test_val = load_if_immediate(bcx, val, pty);
+                kind = if ty::type_is_integral(pty) { switch }
+                else { compare };
+            }
+            range(_, _) => {
+                test_val = Load(bcx, val);
+                kind = compare;
+            },
+            vec_len_eq(_) | vec_len_ge(_) => {
+                let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
+                let unboxed = load_if_immediate(bcx, val, vt.vec_ty);
+                let (_, len) = tvec::get_base_and_len(
+                    bcx, unboxed, vt.vec_ty
+                );
+                test_val = SDiv(bcx, len, vt.llunit_size);
+                kind = compare_vec_len;
+            }
+        }
+    }
+    for vec::each(opts) |o| {
+        match *o {
+            range(_, _) => { kind = compare; break }
+            _ => ()
+        }
+    }
+    let else_cx = match kind {
+        no_branch | single => bcx,
+        _ => sub_block(bcx, ~"match_else")
+    };
+    let sw = if kind == switch {
+        Switch(bcx, test_val, else_cx.llbb, opts.len())
+    } else {
+        C_int(ccx, 0) // Placeholder for when not using a switch
+    };
+
+    let defaults = enter_default(else_cx, dm, m, col, val);
+    let exhaustive = chk.is_none() && defaults.len() == 0u;
+    let len = opts.len();
+    let mut i = 0u;
+
+    // Compile subtrees for each option
+    for vec::each(opts) |opt| {
+        i += 1u;
+        let mut opt_cx = else_cx;
+        if !exhaustive || i < len {
+            opt_cx = sub_block(bcx, ~"match_case");
+            match kind {
+              single => Br(bcx, opt_cx.llbb),
+              switch => {
+                  match trans_opt(bcx, opt) {
+                      single_result(r) => {
+                        unsafe {
+                          llvm::LLVMAddCase(sw, r.val, opt_cx.llbb);
+                          bcx = r.bcx;
+                        }
+                      }
+                      _ => {
+                          bcx.sess().bug(
+                              ~"in compile_submatch, expected \
+                                trans_opt to return a single_result")
+                      }
+                  }
+              }
+              compare => {
+                  let t = node_id_type(bcx, pat_id);
+                  let Result {bcx: after_cx, val: matches} = {
+                      do with_scope_result(bcx, None,
+                                           ~"compare_scope") |bcx| {
+                          match trans_opt(bcx, opt) {
+                              single_result(
+                                  Result {bcx, val}) => {
+                                  compare_values(bcx, test_val, val, t)
+                              }
+                              lower_bound(
+                                  Result {bcx, val}) => {
+                                  compare_scalar_types(
+                                          bcx, test_val, val,
+                                          t, ast::ge)
+                              }
+                              range_result(
+                                  Result {val: vbegin, _},
+                                  Result {bcx, val: vend}) => {
+                                  let Result {bcx, val: llge} =
+                                      compare_scalar_types(
+                                          bcx, test_val,
+                                          vbegin, t, ast::ge);
+                                  let Result {bcx, val: llle} =
+                                      compare_scalar_types(
+                                          bcx, test_val, vend,
+                                          t, ast::le);
+                                  rslt(bcx, And(bcx, llge, llle))
+                              }
+                          }
+                      }
+                  };
+                  bcx = sub_block(after_cx, ~"compare_next");
+                  CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb);
+              }
+              compare_vec_len => {
+                  let Result {bcx: after_cx, val: matches} = {
+                      do with_scope_result(bcx, None,
+                                           ~"compare_vec_len_scope") |bcx| {
+                          match trans_opt(bcx, opt) {
+                              single_result(
+                                  Result {bcx, val}) => {
+                                  let value = compare_scalar_values(
+                                      bcx, test_val, val,
+                                      signed_int, ast::eq);
+                                  rslt(bcx, value)
+                              }
+                              lower_bound(
+                                  Result {bcx, val: val}) => {
+                                  let value = compare_scalar_values(
+                                      bcx, test_val, val,
+                                      signed_int, ast::ge);
+                                  rslt(bcx, value)
+                              }
+                              range_result(
+                                  Result {val: vbegin, _},
+                                  Result {bcx, val: vend}) => {
+                                  let llge =
+                                      compare_scalar_values(
+                                          bcx, test_val,
+                                          vbegin, signed_int, ast::ge);
+                                  let llle =
+                                      compare_scalar_values(
+                                          bcx, test_val, vend,
+                                          signed_int, ast::le);
+                                  rslt(bcx, And(bcx, llge, llle))
+                              }
+                          }
+                      }
+                  };
+                  bcx = sub_block(after_cx, ~"compare_vec_len_next");
+                  CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb);
+              }
+              _ => ()
+            }
+        } else if kind == compare || kind == compare_vec_len {
+            Br(bcx, else_cx.llbb);
+        }
+
+        let mut size = 0u;
+        let mut unpacked = ~[];
+        match *opt {
+            var(_, vdef) => {
+                let args = extract_variant_args(opt_cx, pat_id, vdef, val);
+                size = args.vals.len();
+                unpacked = /*bad*/copy args.vals;
+                opt_cx = args.bcx;
+            }
+            vec_len_eq(n) | vec_len_ge(n) => {
+                let tail = match *opt {
+                    vec_len_ge(_) => true,
+                    _ => false
+                };
+                let args = extract_vec_elems(opt_cx, pat_id, n, tail, val);
+                size = args.vals.len();
+                unpacked = /*bad*/copy args.vals;
+                opt_cx = args.bcx;
+            }
+            lit(_) | range(_, _) => ()
+        }
+        let opt_ms = enter_opt(opt_cx, m, opt, col, size, val);
+        let opt_vals = vec::append(unpacked, vals_left);
+        compile_submatch(opt_cx, opt_ms, opt_vals, chk);
+    }
+
+    // Compile the fall-through case, if any
+    if !exhaustive {
+        if kind == compare || kind == compare_vec_len {
+            Br(bcx, else_cx.llbb);
+        }
+        if kind != single {
+            compile_submatch(else_cx, defaults, vals_left, chk);
+        }
+    }
+}
+
+fn trans_match(bcx: block,
+             match_expr: @ast::expr,
+             discr_expr: @ast::expr,
+             arms: ~[ast::arm],
+             dest: Dest) -> block {
+    let _icx = bcx.insn_ctxt("match::trans_match");
+    do with_scope(bcx, match_expr.info(), ~"match") |bcx| {
+        trans_match_inner(bcx, discr_expr, arms, dest)
+    }
+}
+
+fn trans_match_inner(scope_cx: block,
+                   discr_expr: @ast::expr,
+                   arms: &[ast::arm],
+                   dest: Dest) -> block {
+    let _icx = scope_cx.insn_ctxt("match::trans_match_inner");
+    let mut bcx = scope_cx;
+    let tcx = bcx.tcx();
+
+    let discr_datum = unpack_datum!(bcx, {
+        expr::trans_to_datum(bcx, discr_expr)
+    });
+    if bcx.unreachable {
+        return bcx;
+    }
+
+    let mut arm_datas = ~[], matches = ~[];
+    for vec::each(arms) |arm| {
+        let body = scope_block(bcx, arm.body.info(), ~"case_body");
+
+        // Create the bindings map, which is a mapping from each binding name
+        // to an alloca() that will be the value for that local variable.
+        // Note that we use the names because each binding will have many ids
+        // from the various alternatives.
+        let bindings_map = HashMap();
+        do pat_bindings(tcx.def_map, arm.pats[0]) |bm, p_id, s, path| {
+            let ident = path_to_ident(path);
+            let variable_ty = node_id_type(bcx, p_id);
+            let llvariable_ty = type_of::type_of(bcx.ccx(), variable_ty);
+
+            let llmatch, trmode;
+            match bm {
+                ast::bind_by_value | ast::bind_by_move => {
+                    // in this case, the type of the variable will be T,
+                    // but we need to store a *T
+                    let is_move = (bm == ast::bind_by_move);
+                    llmatch = alloca(bcx, T_ptr(llvariable_ty));
+                    trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
+                }
+                ast::bind_infer => {
+                    // in this case also, the type of the variable will be T,
+                    // but we need to store a *T
+                    let is_move = match tcx.value_modes.find(p_id) {
+                        None => {
+                            tcx.sess.span_bug(s, ~"no value mode");
+                        }
+                        Some(MoveValue) => true,
+                        Some(CopyValue) | Some(ReadValue) => false
+                    };
+                    llmatch = alloca(bcx, T_ptr(llvariable_ty));
+                    trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
+                }
+                ast::bind_by_ref(_) => {
+                    llmatch = alloca(bcx, llvariable_ty);
+                    trmode = TrByRef;
+                }
+            };
+            bindings_map.insert(ident, BindingInfo {
+                llmatch: llmatch, trmode: trmode,
+                id: p_id, ty: variable_ty
+            });
+        }
+
+        let arm_data = @ArmData {bodycx: body,
+                                 arm: arm,
+                                 bindings_map: bindings_map};
+        arm_datas.push(arm_data);
+        for vec::each(arm.pats) |p| {
+            matches.push(@Match {pats: ~[*p], data: arm_data});
+        }
+    }
+
+    let t = node_id_type(bcx, discr_expr.id);
+    let chk = {
+        if ty::type_is_empty(tcx, t) {
+            // Special case for empty types
+            let fail_cx = @mut None;
+            Some(|| mk_fail(scope_cx, discr_expr.span,
+                            ~"scrutinizing value that can't exist", fail_cx))
+        } else {
+            None
+        }
+    };
+    let lldiscr = discr_datum.to_ref_llval(bcx);
+    compile_submatch(bcx, matches, ~[lldiscr], chk);
+
+    let arm_cxs = DVec();
+    for arm_datas.each |arm_data| {
+        let mut bcx = arm_data.bodycx;
+
+        // If this arm has a guard, then the various by-value bindings have
+        // already been copied into their homes.  If not, we do it here.  This
+        // is just to reduce code space.  See extensive comment at the start
+        // of the file for more details.
+        if arm_data.arm.guard.is_none() {
+            bcx = store_non_ref_bindings(bcx, *arm_data, None);
+        }
+
+        // insert bindings into the lllocals map and add cleanups
+        bcx = insert_lllocals(bcx, *arm_data, true);
+
+        bcx = controlflow::trans_block(bcx, arm_data.arm.body, dest);
+        bcx = trans_block_cleanups(bcx, block_cleanups(arm_data.bodycx));
+        arm_cxs.push(bcx);
+    }
+
+    return controlflow::join_blocks(scope_cx, dvec::unwrap(move arm_cxs));
+
+    fn mk_fail(bcx: block, sp: span, +msg: ~str,
+               finished: @mut Option<BasicBlockRef>) -> BasicBlockRef {
+        match *finished { Some(bb) => return bb, _ => () }
+        let fail_cx = sub_block(bcx, ~"case_fallthrough");
+        controlflow::trans_fail(fail_cx, Some(sp), msg);
+        *finished = Some(fail_cx.llbb);
+        return fail_cx.llbb;
+    }
+}
+
+enum IrrefutablePatternBindingMode {
+    // Stores the association between node ID and LLVM value in `lllocals`.
+    BindLocal,
+    // Stores the association between node ID and LLVM value in `llargs`.
+    BindArgument
+}
+
+// Not match-related, but similar to the pattern-munging code above
+fn bind_irrefutable_pat(bcx: block,
+                        pat: @ast::pat,
+                        val: ValueRef,
+                        make_copy: bool,
+                        binding_mode: IrrefutablePatternBindingMode)
+                     -> block {
+    let _icx = bcx.insn_ctxt("match::bind_irrefutable_pat");
+    let ccx = bcx.fcx.ccx;
+    let mut bcx = bcx;
+
+    // Necessary since bind_irrefutable_pat is called outside trans_match
+    match /*bad*/copy pat.node {
+        ast::pat_ident(_, _,inner) => {
+            if pat_is_variant_or_struct(bcx.tcx().def_map, pat) {
+                return bcx;
+            }
+
+            if make_copy {
+                let binding_ty = node_id_type(bcx, pat.id);
+                let datum = Datum {val: val, ty: binding_ty,
+                                   mode: ByRef, source: FromRvalue};
+                let scratch = scratch_datum(bcx, binding_ty, false);
+                datum.copy_to_datum(bcx, INIT, scratch);
+                match binding_mode {
+                    BindLocal => {
+                        bcx.fcx.lllocals.insert(pat.id,
+                                                local_mem(scratch.val));
+                    }
+                    BindArgument => {
+                        bcx.fcx.llargs.insert(pat.id,
+                                              local_mem(scratch.val));
+                    }
+                }
+                add_clean(bcx, scratch.val, binding_ty);
+            } else {
+                match binding_mode {
+                    BindLocal => {
+                        bcx.fcx.lllocals.insert(pat.id, local_mem(val));
+                    }
+                    BindArgument => {
+                        bcx.fcx.llargs.insert(pat.id, local_mem(val));
+                    }
+                }
+            }
+
+            for inner.each |inner_pat| {
+                bcx = bind_irrefutable_pat(
+                    bcx, *inner_pat, val, true, binding_mode);
+            }
+        }
+        ast::pat_enum(_, sub_pats) => {
+            match bcx.tcx().def_map.find(pat.id) {
+                Some(ast::def_variant(*)) => {
+                    let pat_def = ccx.tcx.def_map.get(pat.id);
+                    let vdefs = ast_util::variant_def_ids(pat_def);
+                    let args = extract_variant_args(bcx, pat.id, vdefs, val);
+                    for sub_pats.each |sub_pat| {
+                        for vec::eachi(args.vals) |i, argval| {
+                            bcx = bind_irrefutable_pat(bcx,
+                                                       sub_pat[i],
+                                                       *argval,
+                                                       make_copy,
+                                                       binding_mode);
+                        }
+                    }
+                }
+                Some(ast::def_struct(*)) => {
+                    match sub_pats {
+                        None => {
+                            // This is a unit-like struct. Nothing to do here.
+                        }
+                        Some(elems) => {
+                            // This is the tuple variant case.
+                            for vec::eachi(elems) |i, elem| {
+                                let fldptr = GEPi(bcx, val, struct_field(i));
+                                bcx = bind_irrefutable_pat(bcx,
+                                                           *elem,
+                                                           fldptr,
+                                                           make_copy,
+                                                           binding_mode);
+                            }
+                        }
+                    }
+                }
+                _ => {
+                    // Nothing to do here.
+                }
+            }
+        }
+        ast::pat_rec(fields, _) | ast::pat_struct(_, fields, _) => {
+            let tcx = bcx.tcx();
+            let pat_ty = node_id_type(bcx, pat.id);
+            do expr::with_field_tys(tcx, pat_ty, None) |_hd, field_tys| {
+                for vec::each(fields) |f| {
+                    let ix = ty::field_idx_strict(tcx, f.ident, field_tys);
+                    let fldptr = GEPi(bcx, val, struct_field(ix));
+                    bcx = bind_irrefutable_pat(bcx,
+                                               f.pat,
+                                               fldptr,
+                                               make_copy,
+                                               binding_mode);
+                }
+            }
+        }
+        ast::pat_tup(elems) => {
+            for vec::eachi(elems) |i, elem| {
+                let fldptr = GEPi(bcx, val, [0u, i]);
+                bcx = bind_irrefutable_pat(bcx,
+                                           *elem,
+                                           fldptr,
+                                           make_copy,
+                                           binding_mode);
+            }
+        }
+        ast::pat_box(inner) | ast::pat_uniq(inner) => {
+            let llbox = Load(bcx, val);
+            let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
+            bcx = bind_irrefutable_pat(bcx,
+                                       inner,
+                                       unboxed,
+                                       true,
+                                       binding_mode);
+        }
+        ast::pat_region(inner) => {
+            let loaded_val = Load(bcx, val);
+            bcx = bind_irrefutable_pat(bcx,
+                                       inner,
+                                       loaded_val,
+                                       true,
+                                       binding_mode);
+        }
+        ast::pat_wild | ast::pat_lit(_) | ast::pat_range(_, _) |
+        ast::pat_vec(*) => ()
+    }
+    return bcx;
+}
+
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
diff --git a/src/librustc/middle/trans/alt.rs b/src/librustc/middle/trans/alt.rs
deleted file mode 100644 (file)
index 922dc23..0000000
+++ /dev/null
@@ -1,1791 +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.
-
-/*!
- *
- * # Compilation of match statements
- *
- * I will endeavor to explain the code as best I can.  I have only a loose
- * understanding of some parts of it.
- *
- * ## Matching
- *
- * The basic state of the code is maintained in an array `m` of `@Match`
- * objects.  Each `@Match` describes some list of patterns, all of which must
- * match against the current list of values.  If those patterns match, then
- * the arm listed in the match is the correct arm.  A given arm may have
- * multiple corresponding match entries, one for each alternative that
- * remains.  As we proceed these sets of matches are adjusted by the various
- * `enter_XXX()` functions, each of which adjusts the set of options given
- * some information about the value which has been matched.
- *
- * So, initially, there is one value and N matches, each of which have one
- * constituent pattern.  N here is usually the number of arms but may be
- * greater, if some arms have multiple alternatives.  For example, here:
- *
- *     enum Foo { A, B(int), C(uint, uint) }
- *     match foo {
- *         A => ...,
- *         B(x) => ...,
- *         C(1u, 2) => ...,
- *         C(_) => ...
- *     }
- *
- * The value would be `foo`.  There would be four matches, each of which
- * contains one pattern (and, in one case, a guard).  We could collect the
- * various options and then compile the code for the case where `foo` is an
- * `A`, a `B`, and a `C`.  When we generate the code for `C`, we would (1)
- * drop the two matches that do not match a `C` and (2) expand the other two
- * into two patterns each.  In the first case, the two patterns would be `1u`
- * and `2`, and the in the second case the _ pattern would be expanded into
- * `_` and `_`.  The two values are of course the arguments to `C`.
- *
- * Here is a quick guide to the various functions:
- *
- * - `compile_submatch()`: The main workhouse.  It takes a list of values and
- *   a list of matches and finds the various possibilities that could occur.
- *
- * - `enter_XXX()`: modifies the list of matches based on some information
- *   about the value that has been matched.  For example,
- *   `enter_rec_or_struct()` adjusts the values given that a record or struct
- *   has been matched.  This is an infallible pattern, so *all* of the matches
- *   must be either wildcards or record/struct patterns.  `enter_opt()`
- *   handles the fallible cases, and it is correspondingly more complex.
- *
- * ## Bindings
- *
- * We store information about the bound variables for each arm as part of the
- * per-arm `ArmData` struct.  There is a mapping from identifiers to
- * `BindingInfo` structs.  These structs contain the mode/id/type of the
- * binding, but they also contain up to two LLVM values, called `llmatch` and
- * `llbinding` respectively (the `llbinding`, as will be described shortly, is
- * optional and only present for by-value bindings---therefore it is bundled
- * up as part of the `TransBindingMode` type).  Both point at allocas.
- *
- * The `llmatch` binding always stores a pointer into the value being matched
- * which points at the data for the binding.  If the value being matched has
- * type `T`, then, `llmatch` will point at an alloca of type `T*` (and hence
- * `llmatch` has type `T**`).  So, if you have a pattern like:
- *
- *    let a: A = ...;
- *    let b: B = ...;
- *    match (a, b) { (ref c, copy d) => { ... } }
- *
- * For `c` and `d`, we would generate allocas of type `C*` and `D*`
- * respectively.  These are called the `llmatch`.  As we match, when we come
- * up against an identifier, we store the current pointer into the
- * corresponding alloca.
- *
- * In addition, for each by-value binding (copy or move), we will create a
- * second alloca (`llbinding`) that will hold the final value.  In this
- * example, that means that `d` would have this second alloca of type `D` (and
- * hence `llbinding` has type `D*`).
- *
- * Once a pattern is completely matched, and assuming that there is no guard
- * pattern, we will branch to a block that leads to the body itself.  For any
- * by-value bindings, this block will first load the ptr from `llmatch` (the
- * one of type `D*`) and copy/move the value into `llbinding` (the one of type
- * `D`).  The second alloca then becomes the value of the local variable.  For
- * by ref bindings, the value of the local variable is simply the first
- * alloca.
- *
- * So, for the example above, we would generate a setup kind of like this:
- *
- *        +-------+
- *        | Entry |
- *        +-------+
- *            |
- *        +-------------------------------------------+
- *        | llmatch_c = (addr of first half of tuple) |
- *        | llmatch_d = (addr of first half of tuple) |
- *        +-------------------------------------------+
- *            |
- *        +--------------------------------------+
- *        | *llbinding_d = **llmatch_dlbinding_d |
- *        +--------------------------------------+
- *
- * If there is a guard, the situation is slightly different, because we must
- * execute the guard code.  Moreover, we need to do so once for each of the
- * alternatives that lead to the arm, because if the guard fails, they may
- * have different points from which to continue the search. Therefore, in that
- * case, we generate code that looks more like:
- *
- *        +-------+
- *        | Entry |
- *        +-------+
- *            |
- *        +-------------------------------------------+
- *        | llmatch_c = (addr of first half of tuple) |
- *        | llmatch_d = (addr of first half of tuple) |
- *        +-------------------------------------------+
- *            |
- *        +-------------------------------------------------+
- *        | *llbinding_d = **llmatch_dlbinding_d            |
- *        | check condition                                 |
- *        | if false { free *llbinding_d, goto next case }  |
- *        | if true { goto body }                           |
- *        +-------------------------------------------------+
- *
- * The handling for the cleanups is a bit... sensitive.  Basically, the body
- * is the one that invokes `add_clean()` for each binding.  During the guard
- * evaluation, we add temporary cleanups and revoke them after the guard is
- * evaluated (it could fail, after all).  Presuming the guard fails, we drop
- * the various values we copied explicitly.  Note that guards and moves are
- * just plain incompatible.
- *
- */
-
-use back::abi;
-use lib::llvm::llvm;
-use lib::llvm::{ValueRef, BasicBlockRef};
-use middle::pat_util::*;
-use middle::resolve::DefMap;
-use middle::trans::base::*;
-use middle::trans::build::*;
-use middle::trans::common::*;
-use middle::trans::datum::*;
-use middle::trans::expr::Dest;
-use middle::ty::{CopyValue, MoveValue, ReadValue};
-use util::common::indenter;
-
-use core::dvec::DVec;
-use std::map::HashMap;
-use syntax::ast::def_id;
-use syntax::ast;
-use syntax::ast_util::{dummy_sp, path_to_ident};
-use syntax::ast_util;
-use syntax::codemap::span;
-use syntax::print::pprust::pat_to_str;
-
-fn macros() { include!("macros.rs"); } // FIXME(#3114): Macro import/export.
-
-// An option identifying a literal: either a unit-like struct or an
-// expression.
-enum Lit {
-    UnitLikeStructLit(ast::node_id),    // the node ID of the pattern
-    ExprLit(@ast::expr),
-    ConstLit(ast::def_id),              // the def ID of the constant
-}
-
-// An option identifying a branch (either a literal, a enum variant or a
-// range)
-enum Opt {
-    lit(Lit),
-    var(/* disr val */int, /* variant dids */{enm: def_id, var: def_id}),
-    range(@ast::expr, @ast::expr),
-    vec_len_eq(uint),
-    vec_len_ge(uint)
-}
-
-fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool {
-    match (*a, *b) {
-      (lit(a), lit(b)) => {
-        match (a, b) {
-            (UnitLikeStructLit(a), UnitLikeStructLit(b)) => a == b,
-            _ => {
-                let a_expr;
-                match a {
-                    ExprLit(existing_a_expr) => a_expr = existing_a_expr,
-                    ConstLit(a_const) => {
-                        let e = const_eval::lookup_const_by_id(tcx, a_const);
-                        a_expr = e.get();
-                    }
-                    UnitLikeStructLit(_) => {
-                        fail ~"UnitLikeStructLit should have been handled \
-                               above"
-                    }
-                }
-
-                let b_expr;
-                match b {
-                    ExprLit(existing_b_expr) => b_expr = existing_b_expr,
-                    ConstLit(b_const) => {
-                        let e = const_eval::lookup_const_by_id(tcx, b_const);
-                        b_expr = e.get();
-                    }
-                    UnitLikeStructLit(_) => {
-                        fail ~"UnitLikeStructLit should have been handled \
-                               above"
-                    }
-                }
-
-                const_eval::compare_lit_exprs(tcx, a_expr, b_expr) == 0
-            }
-        }
-      }
-      (range(a1, a2), range(b1, b2)) => {
-        const_eval::compare_lit_exprs(tcx, a1, b1) == 0 &&
-        const_eval::compare_lit_exprs(tcx, a2, b2) == 0
-      }
-      (var(a, _), var(b, _)) => a == b,
-      (vec_len_eq(a), vec_len_eq(b)) => a == b,
-      (vec_len_ge(a), vec_len_ge(b)) => a == b,
-      _ => false
-    }
-}
-
-enum opt_result {
-    single_result(Result),
-    lower_bound(Result),
-    range_result(Result, Result),
-}
-fn trans_opt(bcx: block, o: &Opt) -> opt_result {
-    let _icx = bcx.insn_ctxt("alt::trans_opt");
-    let ccx = bcx.ccx();
-    let mut bcx = bcx;
-    match *o {
-        lit(ExprLit(lit_expr)) => {
-            let datumblock = expr::trans_to_datum(bcx, lit_expr);
-            return single_result(datumblock.to_result());
-        }
-        lit(UnitLikeStructLit(pat_id)) => {
-            let struct_ty = ty::node_id_to_type(bcx.tcx(), pat_id);
-            let datumblock = datum::scratch_datum(bcx, struct_ty, true);
-            return single_result(datumblock.to_result(bcx));
-        }
-        lit(ConstLit(lit_id)) => {
-            let llval = consts::get_const_val(bcx.ccx(), lit_id);
-            return single_result(rslt(bcx, llval));
-        }
-        var(disr_val, _) => {
-            return single_result(rslt(bcx, C_int(ccx, disr_val)));
-        }
-        range(l1, l2) => {
-            return range_result(rslt(bcx, consts::const_expr(ccx, l1)),
-                                rslt(bcx, consts::const_expr(ccx, l2)));
-        }
-        vec_len_eq(n) => {
-            return single_result(rslt(bcx, C_int(ccx, n as int)));
-        }
-        vec_len_ge(n) => {
-            return lower_bound(rslt(bcx, C_int(ccx, n as int)));
-        }
-    }
-}
-
-fn variant_opt(tcx: ty::ctxt, pat_id: ast::node_id) -> Opt {
-    match tcx.def_map.get(pat_id) {
-        ast::def_variant(enum_id, var_id) => {
-            let variants = ty::enum_variants(tcx, enum_id);
-            for vec::each(*variants) |v| {
-                if var_id == v.id {
-                    return var(v.disr_val, {enm: enum_id, var: var_id});
-                }
-            }
-            core::util::unreachable();
-        }
-        ast::def_struct(_) => {
-            return lit(UnitLikeStructLit(pat_id));
-        }
-        _ => {
-            tcx.sess.bug(~"non-variant or struct in variant_opt()");
-        }
-    }
-}
-
-enum TransBindingMode {
-    TrByValue(/*ismove:*/ bool, /*llbinding:*/ ValueRef),
-    TrByRef,
-    TrByImplicitRef
-}
-
-/**
- * Information about a pattern binding:
- * - `llmatch` is a pointer to a stack slot.  The stack slot contains a
- *   pointer into the value being matched.  Hence, llmatch has type `T**`
- *   where `T` is the value being matched.
- * - `trmode` is the trans binding mode
- * - `id` is the node id of the binding
- * - `ty` is the Rust type of the binding */
-struct BindingInfo {
-    llmatch: ValueRef,
-    trmode: TransBindingMode,
-    id: ast::node_id,
-    ty: ty::t,
-}
-
-type BindingsMap = HashMap<ident, BindingInfo>;
-
-struct ArmData {
-    bodycx: block,
-    arm: &ast::arm,
-    bindings_map: BindingsMap
-}
-
-struct Match {
-    pats: ~[@ast::pat],
-    data: @ArmData
-}
-
-fn match_to_str(bcx: block, m: &Match) -> ~str {
-    if bcx.sess().verbose() {
-        // for many programs, this just take too long to serialize
-        fmt!("%?", m.pats.map(|p| pat_to_str(*p, bcx.sess().intr())))
-    } else {
-        fmt!("%u pats", m.pats.len())
-    }
-}
-
-fn matches_to_str(bcx: block, m: &[@Match]) -> ~str {
-    fmt!("%?", m.map(|n| match_to_str(bcx, *n)))
-}
-
-fn has_nested_bindings(m: &[@Match], col: uint) -> bool {
-    for vec::each(m) |br| {
-        match br.pats[col].node {
-          ast::pat_ident(_, _, Some(_)) => return true,
-          _ => ()
-        }
-    }
-    return false;
-}
-
-fn expand_nested_bindings(bcx: block, m: &[@Match/&r],
-                          col: uint, val: ValueRef)
-    -> ~[@Match/&r]
-{
-    debug!("expand_nested_bindings(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    do m.map |br| {
-        match br.pats[col].node {
-            ast::pat_ident(_, path, Some(inner)) => {
-                let pats = vec::append(
-                    vec::slice(br.pats, 0u, col),
-                    vec::append(~[inner],
-                                vec::view(br.pats, col + 1u, br.pats.len())));
-
-                let binding_info =
-                    br.data.bindings_map.get(path_to_ident(path));
-
-                Store(bcx, val, binding_info.llmatch);
-                @Match {pats: pats, data: br.data}
-            }
-            _ => {
-                *br
-            }
-        }
-    }
-}
-
-type enter_pat = fn(@ast::pat) -> Option<~[@ast::pat]>;
-
-fn assert_is_binding_or_wild(bcx: block, p: @ast::pat) {
-    if !pat_is_binding_or_wild(bcx.tcx().def_map, p) {
-        bcx.sess().span_bug(
-            p.span,
-            fmt!("Expected an identifier pattern but found p: %s",
-                 pat_to_str(p, bcx.sess().intr())));
-    }
-}
-
-fn enter_match(bcx: block, dm: DefMap, m: &[@Match/&r],
-               col: uint, val: ValueRef, e: enter_pat)
-    -> ~[@Match/&r]
-{
-    debug!("enter_match(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    let mut result = ~[];
-    for vec::each(m) |br| {
-        match e(br.pats[col]) {
-            Some(sub) => {
-                let pats =
-                    vec::append(
-                        vec::append(sub, vec::view(br.pats, 0u, col)),
-                        vec::view(br.pats, col + 1u, br.pats.len()));
-
-                let self = br.pats[col];
-                match self.node {
-                    ast::pat_ident(_, path, None) => {
-                        if pat_is_binding(dm, self) {
-                            let binding_info =
-                                br.data.bindings_map.get(path_to_ident(path));
-                            Store(bcx, val, binding_info.llmatch);
-                        }
-                    }
-                    _ => {}
-                }
-
-                result.push(@Match {pats: pats, data: br.data});
-            }
-            None => ()
-        }
-    }
-
-    debug!("result=%s", matches_to_str(bcx, result));
-
-    return result;
-}
-
-fn enter_default(bcx: block, dm: DefMap, m: &[@Match/&r],
-                 col: uint, val: ValueRef)
-    -> ~[@Match/&r]
-{
-    debug!("enter_default(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    do enter_match(bcx, dm, m, col, val) |p| {
-        match p.node {
-          ast::pat_wild | ast::pat_rec(_, _) | ast::pat_tup(_) |
-          ast::pat_struct(*) => Some(~[]),
-          ast::pat_ident(_, _, None) if pat_is_binding(dm, p) => Some(~[]),
-          _ => None
-        }
-    }
-}
-
-// <pcwalton> nmatsakis: what does enter_opt do?
-// <pcwalton> in trans/alt
-// <pcwalton> trans/alt.rs is like stumbling around in a dark cave
-// <nmatsakis> pcwalton: the enter family of functions adjust the set of
-//             patterns as needed
-// <nmatsakis> yeah, at some point I kind of achieved some level of
-//             understanding
-// <nmatsakis> anyhow, they adjust the patterns given that something of that
-//             kind has been found
-// <nmatsakis> pcwalton: ok, right, so enter_XXX() adjusts the patterns, as I
-//             said
-// <nmatsakis> enter_match() kind of embodies the generic code
-// <nmatsakis> it is provided with a function that tests each pattern to see
-//             if it might possibly apply and so forth
-// <nmatsakis> so, if you have a pattern like {a: _, b: _, _} and one like _
-// <nmatsakis> then _ would be expanded to (_, _)
-// <nmatsakis> one spot for each of the sub-patterns
-// <nmatsakis> enter_opt() is one of the more complex; it covers the fallible
-//             cases
-// <nmatsakis> enter_rec_or_struct() or enter_tuple() are simpler, since they
-//             are infallible patterns
-// <nmatsakis> so all patterns must either be records (resp. tuples) or
-//             wildcards
-
-fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
-             variant_size: uint, val: ValueRef)
-    -> ~[@Match/&r]
-{
-    debug!("enter_opt(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    let tcx = bcx.tcx();
-    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
-    do enter_match(bcx, tcx.def_map, m, col, val) |p| {
-        match p.node {
-            ast::pat_enum(_, subpats) => {
-                if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
-                    Some(option::get_default(subpats,
-                                             vec::from_elem(variant_size,
-                                                            dummy)))
-                } else {
-                    None
-                }
-            }
-            ast::pat_ident(_, _, None)
-                    if pat_is_variant_or_struct(tcx.def_map, p) => {
-                if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
-                    Some(~[])
-                } else {
-                    None
-                }
-            }
-            ast::pat_ident(_, _, None) if pat_is_const(tcx.def_map, p) => {
-                let const_def = tcx.def_map.get(p.id);
-                let const_def_id = ast_util::def_id_of_def(const_def);
-                if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) {
-                    Some(~[])
-                } else {
-                    None
-                }
-            }
-            ast::pat_lit(l) => {
-                if opt_eq(tcx, &lit(ExprLit(l)), opt) {Some(~[])} else {None}
-            }
-            ast::pat_range(l1, l2) => {
-                if opt_eq(tcx, &range(l1, l2), opt) {Some(~[])} else {None}
-            }
-            ast::pat_struct(_, field_pats, _) => {
-                if opt_eq(tcx, &variant_opt(tcx, p.id), opt) {
-                    // Look up the struct variant ID.
-                    let struct_id;
-                    match tcx.def_map.get(p.id) {
-                        ast::def_variant(_, found_struct_id) => {
-                            struct_id = found_struct_id;
-                        }
-                        _ => {
-                            tcx.sess.span_bug(p.span, ~"expected enum \
-                                                        variant def");
-                        }
-                    }
-
-                    // Reorder the patterns into the same order they were
-                    // specified in the struct definition. Also fill in
-                    // unspecified fields with dummy.
-                    let reordered_patterns = dvec::DVec();
-                    for ty::lookup_struct_fields(tcx, struct_id).each
-                        |field| {
-                            match field_pats.find(|p|
-                                                  p.ident == field.ident) {
-                                None => reordered_patterns.push(dummy),
-                                Some(fp) => reordered_patterns.push(fp.pat)
-                            }
-                    }
-                    Some(dvec::unwrap(move reordered_patterns))
-                } else {
-                    None
-                }
-            }
-            ast::pat_vec(elems, tail) => {
-                match tail {
-                    Some(_) => {
-                        if opt_eq(tcx, &vec_len_ge(elems.len()), opt) {
-                            Some(vec::append_one(elems, tail.get()))
-                        } else {
-                            None
-                        }
-                    }
-                    None => {
-                        if opt_eq(tcx, &vec_len_eq(elems.len()), opt) {
-                            Some(copy elems)
-                        } else {
-                            None
-                        }
-                    }
-                }
-            }
-            _ => {
-                assert_is_binding_or_wild(bcx, p);
-                Some(vec::from_elem(variant_size, dummy))
-            }
-        }
-    }
-}
-
-fn enter_rec_or_struct(bcx: block, dm: DefMap, m: &[@Match/&r], col: uint,
-                       fields: ~[ast::ident], val: ValueRef) -> ~[@Match/&r] {
-    debug!("enter_rec_or_struct(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
-    do enter_match(bcx, dm, m, col, val) |p| {
-        match p.node {
-            ast::pat_rec(fpats, _) | ast::pat_struct(_, fpats, _) => {
-                let mut pats = ~[];
-                for vec::each(fields) |fname| {
-                    match fpats.find(|p| p.ident == *fname) {
-                        None => pats.push(dummy),
-                        Some(pat) => pats.push(pat.pat)
-                    }
-                }
-                Some(pats)
-            }
-            _ => {
-                assert_is_binding_or_wild(bcx, p);
-                Some(vec::from_elem(fields.len(), dummy))
-            }
-        }
-    }
-}
-
-fn enter_tup(bcx: block, dm: DefMap, m: &[@Match/&r],
-             col: uint, val: ValueRef, n_elts: uint)
-    -> ~[@Match/&r]
-{
-    debug!("enter_tup(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
-    do enter_match(bcx, dm, m, col, val) |p| {
-        match p.node {
-            ast::pat_tup(elts) => {
-                Some(elts)
-            }
-            _ => {
-                assert_is_binding_or_wild(bcx, p);
-                Some(vec::from_elem(n_elts, dummy))
-            }
-        }
-    }
-}
-
-fn enter_tuple_struct(bcx: block, dm: DefMap, m: &[@Match/&r], col: uint,
-                      val: ValueRef, n_elts: uint)
-    -> ~[@Match/&r]
-{
-    debug!("enter_tuple_struct(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
-    do enter_match(bcx, dm, m, col, val) |p| {
-        match p.node {
-            ast::pat_enum(_, Some(elts)) => Some(elts),
-            _ => {
-                assert_is_binding_or_wild(bcx, p);
-                Some(vec::from_elem(n_elts, dummy))
-            }
-        }
-    }
-}
-
-fn enter_box(bcx: block, dm: DefMap, m: &[@Match/&r],
-             col: uint, val: ValueRef)
-    -> ~[@Match/&r]
-{
-    debug!("enter_box(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
-    do enter_match(bcx, dm, m, col, val) |p| {
-        match p.node {
-            ast::pat_box(sub) => {
-                Some(~[sub])
-            }
-            _ => {
-                assert_is_binding_or_wild(bcx, p);
-                Some(~[dummy])
-            }
-        }
-    }
-}
-
-fn enter_uniq(bcx: block, dm: DefMap, m: &[@Match/&r],
-              col: uint, val: ValueRef)
-    -> ~[@Match/&r]
-{
-    debug!("enter_uniq(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
-    do enter_match(bcx, dm, m, col, val) |p| {
-        match p.node {
-            ast::pat_uniq(sub) => {
-                Some(~[sub])
-            }
-            _ => {
-                assert_is_binding_or_wild(bcx, p);
-                Some(~[dummy])
-            }
-        }
-    }
-}
-
-fn enter_region(bcx: block, dm: DefMap, m: &[@Match/&r],
-                col: uint, val: ValueRef)
-    -> ~[@Match/&r]
-{
-    debug!("enter_region(bcx=%s, m=%s, col=%u, val=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           col,
-           bcx.val_str(val));
-    let _indenter = indenter();
-
-    let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
-    do enter_match(bcx, dm, m, col, val) |p| {
-        match p.node {
-            ast::pat_region(sub) => {
-                Some(~[sub])
-            }
-            _ => {
-                assert_is_binding_or_wild(bcx, p);
-                Some(~[dummy])
-            }
-        }
-    }
-}
-
-// Returns the options in one column of matches. An option is something that
-// needs to be conditionally matched at runtime; for example, the discriminant
-// on a set of enum variants or a literal.
-fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] {
-    fn add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, val: Opt) {
-        if set.any(|l| opt_eq(tcx, l, &val)) {return;}
-        set.push(val);
-    }
-
-    let found = DVec();
-    for vec::each(m) |br| {
-        let cur = br.pats[col];
-        match cur.node {
-            ast::pat_lit(l) => {
-                add_to_set(ccx.tcx, &found, lit(ExprLit(l)));
-            }
-            ast::pat_ident(*) => {
-                // This is one of: an enum variant, a unit-like struct, or a
-                // variable binding.
-                match ccx.tcx.def_map.find(cur.id) {
-                    Some(ast::def_variant(*)) => {
-                        add_to_set(ccx.tcx, &found,
-                                   variant_opt(ccx.tcx, cur.id));
-                    }
-                    Some(ast::def_struct(*)) => {
-                        add_to_set(ccx.tcx, &found,
-                                   lit(UnitLikeStructLit(cur.id)));
-                    }
-                    Some(ast::def_const(const_did)) => {
-                        add_to_set(ccx.tcx, &found,
-                                   lit(ConstLit(const_did)));
-                    }
-                    _ => {}
-                }
-            }
-            ast::pat_enum(*) | ast::pat_struct(*) => {
-                // This could be one of: a tuple-like enum variant, a
-                // struct-like enum variant, or a struct.
-                match ccx.tcx.def_map.find(cur.id) {
-                    Some(ast::def_variant(*)) => {
-                        add_to_set(ccx.tcx, &found,
-                                   variant_opt(ccx.tcx, cur.id));
-                    }
-                    _ => {}
-                }
-            }
-            ast::pat_range(l1, l2) => {
-                add_to_set(ccx.tcx, &found, range(l1, l2));
-            }
-            ast::pat_vec(elems, tail) => {
-                let opt = match tail {
-                    None => vec_len_eq(elems.len()),
-                    Some(_) => vec_len_ge(elems.len())
-                };
-                add_to_set(ccx.tcx, &found, opt);
-            }
-            _ => {}
-        }
-    }
-    return dvec::unwrap(move found);
-}
-
-fn extract_variant_args(bcx: block, pat_id: ast::node_id,
-                        vdefs: {enm: def_id, var: def_id},
-                        val: ValueRef)
-    -> {vals: ~[ValueRef], bcx: block}
-{
-    let _icx = bcx.insn_ctxt("alt::extract_variant_args");
-    let ccx = bcx.fcx.ccx;
-    let enum_ty_substs = match ty::get(node_id_type(bcx, pat_id)).sty {
-      ty::ty_enum(id, ref substs) => { assert id == vdefs.enm; (*substs).tps }
-      _ => bcx.sess().bug(~"extract_variant_args: pattern has non-enum type")
-    };
-    let mut blobptr = val;
-    let variants = ty::enum_variants(ccx.tcx, vdefs.enm);
-    let size = ty::enum_variant_with_id(ccx.tcx, vdefs.enm,
-                                        vdefs.var).args.len();
-    if size > 0u && (*variants).len() != 1u {
-        let enumptr =
-            PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
-        blobptr = GEPi(bcx, enumptr, [0u, 1u]);
-    }
-    let vdefs_tg = vdefs.enm;
-    let vdefs_var = vdefs.var;
-    let args = do vec::from_fn(size) |i| {
-        GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var,
-                 enum_ty_substs, i)
-    };
-    return {vals: args, bcx: bcx};
-}
-
-fn extract_vec_elems(bcx: block, pat_id: ast::node_id,
-                     elem_count: uint, tail: bool, val: ValueRef)
-    -> {vals: ~[ValueRef], bcx: block}
-{
-    let _icx = bcx.insn_ctxt("alt::extract_vec_elems");
-    let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
-    let unboxed = load_if_immediate(bcx, val, vt.vec_ty);
-    let (base, len) = tvec::get_base_and_len(bcx, unboxed, vt.vec_ty);
-
-    let mut elems = do vec::from_fn(elem_count) |i| {
-        GEPi(bcx, base, ~[i])
-    };
-    if tail {
-        let tail_offset = Mul(bcx, vt.llunit_size,
-            C_int(bcx.ccx(), elem_count as int)
-        );
-        let tail_begin = tvec::pointer_add(bcx, base, tail_offset);
-        let tail_len = Sub(bcx, len, tail_offset);
-        let tail_ty = ty::mk_evec(bcx.tcx(),
-            {ty: vt.unit_ty, mutbl: ast::m_imm},
-            ty::vstore_slice(ty::re_static)
-        );
-        let scratch = scratch_datum(bcx, tail_ty, false);
-        Store(bcx, tail_begin,
-            GEPi(bcx, scratch.val, [0u, abi::slice_elt_base])
-        );
-        Store(bcx, tail_len,
-            GEPi(bcx, scratch.val, [0u, abi::slice_elt_len])
-        );
-        elems.push(scratch.val);
-        scratch.add_clean(bcx);
-    }
-    return {vals: elems, bcx: bcx};
-}
-
-// NB: This function does not collect fields from struct-like enum variants.
-fn collect_record_or_struct_fields(bcx: block, m: &[@Match], col: uint) ->
-                                   ~[ast::ident] {
-    let mut fields: ~[ast::ident] = ~[];
-    for vec::each(m) |br| {
-        match br.pats[col].node {
-          ast::pat_rec(fs, _) => extend(&mut fields, fs),
-          ast::pat_struct(_, fs, _) => {
-            match ty::get(node_id_type(bcx, br.pats[col].id)).sty {
-              ty::ty_struct(*) => extend(&mut fields, fs),
-              _ => ()
-            }
-          }
-          _ => ()
-        }
-    }
-    return fields;
-
-    fn extend(idents: &mut ~[ast::ident], field_pats: &[ast::field_pat]) {
-        for field_pats.each |field_pat| {
-            let field_ident = field_pat.ident;
-            if !vec::any(*idents, |x| *x == field_ident) {
-                idents.push(field_ident);
-            }
-        }
-    }
-}
-
-fn root_pats_as_necessary(bcx: block, m: &[@Match],
-                          col: uint, val: ValueRef)
-{
-    for vec::each(m) |br| {
-        let pat_id = br.pats[col].id;
-
-        match bcx.ccx().maps.root_map.find({id:pat_id, derefs:0u}) {
-            None => (),
-            Some(scope_id) => {
-                // Note: the scope_id will always be the id of the alt.  See
-                // the extended comment in rustc::middle::borrowck::preserve()
-                // for details (look for the case covering cat_discr).
-
-                let datum = Datum {val: val, ty: node_id_type(bcx, pat_id),
-                                   mode: ByRef, source: FromLvalue};
-                datum.root(bcx, scope_id);
-                return; // if we kept going, we'd only re-root the same value
-            }
-        }
-    }
-}
-
-// Macro for deciding whether any of the remaining matches fit a given kind of
-// pattern.  Note that, because the macro is well-typed, either ALL of the
-// 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) => (
-        vec::any($m, |br| {
-            match br.pats[col].node {
-                $pattern => true,
-                _ => false
-            }
-        })
-    )
-)
-
-fn any_box_pat(m: &[@Match], col: uint) -> bool {
-    any_pat!(m, ast::pat_box(_))
-}
-
-fn any_uniq_pat(m: &[@Match], col: uint) -> bool {
-    any_pat!(m, ast::pat_uniq(_))
-}
-
-fn any_region_pat(m: &[@Match], col: uint) -> bool {
-    any_pat!(m, ast::pat_region(_))
-}
-
-fn any_tup_pat(m: &[@Match], col: uint) -> bool {
-    any_pat!(m, ast::pat_tup(_))
-}
-
-fn any_tuple_struct_pat(bcx: block, m: &[@Match], col: uint) -> bool {
-    vec::any(m, |br| {
-        let pat = br.pats[col];
-        match pat.node {
-            ast::pat_enum(_, Some(_)) => {
-                match bcx.tcx().def_map.find(pat.id) {
-                    Some(ast::def_struct(*)) => true,
-                    _ => false
-                }
-            }
-            _ => false
-        }
-    })
-}
-
-type mk_fail = fn@() -> BasicBlockRef;
-
-fn pick_col(m: &[@Match]) -> uint {
-    fn score(p: @ast::pat) -> uint {
-        match p.node {
-          ast::pat_lit(_) | ast::pat_enum(_, _) | ast::pat_range(_, _) => 1u,
-          ast::pat_ident(_, _, Some(p)) => score(p),
-          _ => 0u
-        }
-    }
-    let scores = vec::to_mut(vec::from_elem(m[0].pats.len(), 0u));
-    for vec::each(m) |br| {
-        let mut i = 0u;
-        for vec::each(br.pats) |p| { scores[i] += score(*p); i += 1u; }
-    }
-    let mut max_score = 0u;
-    let mut best_col = 0u;
-    let mut i = 0u;
-    for vec::each(scores) |score| {
-        let score = *score;
-
-        // Irrefutable columns always go first, they'd only be duplicated in
-        // the branches.
-        if score == 0u { return i; }
-        // If no irrefutable ones are found, we pick the one with the biggest
-        // branching factor.
-        if score > max_score { max_score = score; best_col = i; }
-        i += 1u;
-    }
-    return best_col;
-}
-
-enum branch_kind { no_branch, single, switch, compare, compare_vec_len, }
-
-impl branch_kind : cmp::Eq {
-    pure fn eq(&self, other: &branch_kind) -> bool {
-        ((*self) as uint) == ((*other) as uint)
-    }
-    pure fn ne(&self, other: &branch_kind) -> bool { !(*self).eq(other) }
-}
-
-// Compiles a comparison between two things.
-fn compare_values(cx: block, lhs: ValueRef, rhs: ValueRef, rhs_t: ty::t) ->
-                  Result {
-    let _icx = cx.insn_ctxt("compare_values");
-    if ty::type_is_scalar(rhs_t) {
-      let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::eq);
-      return rslt(rs.bcx, rs.val);
-    }
-
-    match ty::get(rhs_t).sty {
-        ty::ty_estr(ty::vstore_uniq) => {
-            let scratch_result = scratch_datum(cx, ty::mk_bool(cx.tcx()),
-                                               false);
-            let scratch_lhs = alloca(cx, val_ty(lhs));
-            Store(cx, lhs, scratch_lhs);
-            let scratch_rhs = alloca(cx, val_ty(rhs));
-            Store(cx, rhs, scratch_rhs);
-            let did = cx.tcx().lang_items.uniq_str_eq_fn.get();
-            let bcx = callee::trans_rtcall_or_lang_call(cx, did,
-                                                        ~[scratch_lhs,
-                                                          scratch_rhs],
-                                                        expr::SaveIn(
-                                                         scratch_result.val));
-            return scratch_result.to_result(bcx);
-        }
-        ty::ty_estr(_) => {
-            let scratch_result = scratch_datum(cx, ty::mk_bool(cx.tcx()),
-                                               false);
-            let did = cx.tcx().lang_items.str_eq_fn.get();
-            let bcx = callee::trans_rtcall_or_lang_call(cx, did,
-                                                        ~[lhs, rhs],
-                                                        expr::SaveIn(
-                                                         scratch_result.val));
-            return scratch_result.to_result(bcx);
-        }
-        _ => {
-            cx.tcx().sess.bug(~"only scalars and strings supported in \
-                                compare_values");
-        }
-    }
-}
-
-fn store_non_ref_bindings(bcx: block,
-                          data: &ArmData,
-                          opt_temp_cleanups: Option<&DVec<ValueRef>>)
-    -> block
-{
-    /*!
-     *
-     * For each copy/move binding, copy the value from the value
-     * being matched into its final home.  This code executes once
-     * one of the patterns for a given arm has completely matched.
-     * It adds temporary cleanups to the `temp_cleanups` array,
-     * if one is provided.
-     */
-
-    let mut bcx = bcx;
-    for data.bindings_map.each_value |binding_info| {
-        match binding_info.trmode {
-            TrByValue(is_move, lldest) => {
-                let llval = Load(bcx, binding_info.llmatch); // get a T*
-                let datum = Datum {val: llval, ty: binding_info.ty,
-                                   mode: ByRef, source: FromLvalue};
-                bcx = {
-                    if is_move {
-                        datum.move_to(bcx, INIT, lldest)
-                    } else {
-                        datum.copy_to(bcx, INIT, lldest)
-                    }
-                };
-
-                for opt_temp_cleanups.each |temp_cleanups| {
-                    add_clean_temp_mem(bcx, lldest, binding_info.ty);
-                    temp_cleanups.push(lldest);
-                }
-            }
-            TrByRef | TrByImplicitRef => {}
-        }
-    }
-    return bcx;
-}
-
-fn insert_lllocals(bcx: block,
-                   data: &ArmData,
-                   add_cleans: bool) -> block {
-    /*!
-     *
-     * For each binding in `data.bindings_map`, adds an appropriate entry into
-     * the `fcx.lllocals` map.  If add_cleans is true, then adds cleanups for
-     * the bindings. */
-
-    for data.bindings_map.each_value |binding_info| {
-        let llval = match binding_info.trmode {
-            // By value bindings: use the stack slot that we
-            // copied/moved the value into
-            TrByValue(_, lldest) => {
-                if add_cleans {
-                    add_clean(bcx, lldest, binding_info.ty);
-                }
-
-                lldest
-            }
-
-            // By ref binding: use the ptr into the matched value
-            TrByRef => {
-                binding_info.llmatch
-            }
-
-            // Ugly: for implicit ref, we actually want a T*, but
-            // we have a T**, so we had to load.  This will go away
-            // once implicit refs go away.
-            TrByImplicitRef => {
-                Load(bcx, binding_info.llmatch)
-            }
-        };
-
-        bcx.fcx.lllocals.insert(binding_info.id,
-                                local_mem(llval));
-    }
-    return bcx;
-}
-
-fn compile_guard(bcx: block,
-                 guard_expr: @ast::expr,
-                 data: &ArmData,
-                 m: &[@Match],
-                 vals: &[ValueRef],
-                 chk: Option<mk_fail>)
-    -> block
-{
-    debug!("compile_guard(bcx=%s, guard_expr=%s, m=%s, vals=%?)",
-           bcx.to_str(),
-           bcx.expr_to_str(guard_expr),
-           matches_to_str(bcx, m),
-           vals.map(|v| bcx.val_str(*v)));
-    let _indenter = indenter();
-
-    let mut bcx = bcx;
-    let temp_cleanups = DVec();
-    bcx = store_non_ref_bindings(bcx, data, Some(&temp_cleanups));
-    bcx = insert_lllocals(bcx, data, false);
-
-    let val = unpack_result!(bcx, {
-        do with_scope_result(bcx, guard_expr.info(),
-                             ~"guard") |bcx| {
-            expr::trans_to_datum(bcx, guard_expr).to_result()
-        }
-    });
-
-    // Revoke the temp cleanups now that the guard successfully executed.
-    for temp_cleanups.each |llval| {
-        revoke_clean(bcx, *llval);
-    }
-
-    return do with_cond(bcx, Not(bcx, val)) |bcx| {
-        // Guard does not match: free the values we copied,
-        // and remove all bindings from the lllocals table
-        let bcx = drop_bindings(bcx, data);
-        compile_submatch(bcx, m, vals, chk);
-        bcx
-    };
-
-    fn drop_bindings(bcx: block, data: &ArmData) -> block {
-        let mut bcx = bcx;
-        for data.bindings_map.each_value |binding_info| {
-            match binding_info.trmode {
-                TrByValue(_, llval) => {
-                    bcx = glue::drop_ty(bcx, llval, binding_info.ty);
-                }
-                TrByRef | TrByImplicitRef => {}
-            }
-            bcx.fcx.lllocals.remove(binding_info.id);
-        }
-        return bcx;
-    }
-}
-
-fn compile_submatch(bcx: block,
-                    m: &[@Match],
-                    vals: &[ValueRef],
-                    chk: Option<mk_fail>)
-{
-    debug!("compile_submatch(bcx=%s, m=%s, vals=%?)",
-           bcx.to_str(),
-           matches_to_str(bcx, m),
-           vals.map(|v| bcx.val_str(*v)));
-    let _indenter = indenter();
-
-    /*
-      For an empty match, a fall-through case must exist
-     */
-    assert(m.len() > 0u || chk.is_some());
-    let _icx = bcx.insn_ctxt("alt::compile_submatch");
-    let mut bcx = bcx;
-    let tcx = bcx.tcx(), dm = tcx.def_map;
-    if m.len() == 0u {
-        Br(bcx, chk.get()());
-        return;
-    }
-    if m[0].pats.len() == 0u {
-        let data = m[0].data;
-        match data.arm.guard {
-            Some(guard_expr) => {
-                bcx = compile_guard(bcx, guard_expr, m[0].data,
-                                    vec::view(m, 1, m.len()),
-                                    vals, chk);
-            }
-            _ => ()
-        }
-        Br(bcx, data.bodycx.llbb);
-        return;
-    }
-
-    let col = pick_col(m);
-    let val = vals[col];
-    let m = {
-        if has_nested_bindings(m, col) {
-            expand_nested_bindings(bcx, m, col, val)
-        } else {
-            m.to_vec()
-        }
-    };
-
-    let vals_left = vec::append(vec::slice(vals, 0u, col),
-                                vec::view(vals, col + 1u, vals.len()));
-    let ccx = bcx.fcx.ccx;
-    let mut pat_id = 0;
-    for vec::each(m) |br| {
-        // Find a real id (we're adding placeholder wildcard patterns, but
-        // each column is guaranteed to have at least one real pattern)
-        if pat_id == 0 { pat_id = br.pats[col].id; }
-    }
-
-    root_pats_as_necessary(bcx, m, col, val);
-
-    let rec_fields = collect_record_or_struct_fields(bcx, m, col);
-    if rec_fields.len() > 0 {
-        let pat_ty = node_id_type(bcx, pat_id);
-        do expr::with_field_tys(tcx, pat_ty, None) |_has_dtor, field_tys| {
-            let rec_vals = rec_fields.map(|field_name| {
-                let ix = ty::field_idx_strict(tcx, *field_name, field_tys);
-                GEPi(bcx, val, struct_field(ix))
-            });
-            compile_submatch(
-                bcx,
-                enter_rec_or_struct(bcx, dm, m, col, rec_fields, val),
-                vec::append(rec_vals, vals_left),
-                chk);
-        }
-        return;
-    }
-
-    if any_tup_pat(m, col) {
-        let tup_ty = node_id_type(bcx, pat_id);
-        let n_tup_elts = match ty::get(tup_ty).sty {
-          ty::ty_tup(elts) => elts.len(),
-          _ => ccx.sess.bug(~"non-tuple type in tuple pattern")
-        };
-        let tup_vals = vec::from_fn(n_tup_elts, |i| GEPi(bcx, val, [0u, i]));
-        compile_submatch(bcx, enter_tup(bcx, dm, m, col, val, n_tup_elts),
-                         vec::append(tup_vals, vals_left), chk);
-        return;
-    }
-
-    if any_tuple_struct_pat(bcx, m, col) {
-        let struct_ty = node_id_type(bcx, pat_id);
-        let struct_element_count;
-        match ty::get(struct_ty).sty {
-            ty::ty_struct(struct_id, _) => {
-                struct_element_count =
-                    ty::lookup_struct_fields(tcx, struct_id).len();
-            }
-            _ => {
-                ccx.sess.bug(~"non-struct type in tuple struct pattern");
-            }
-        }
-
-        let llstructvals = vec::from_fn(
-            struct_element_count, |i| GEPi(bcx, val, struct_field(i)));
-        compile_submatch(bcx,
-                         enter_tuple_struct(bcx, dm, m, col, val,
-                                            struct_element_count),
-                         vec::append(llstructvals, vals_left),
-                         chk);
-        return;
-    }
-
-    // Unbox in case of a box field
-    if any_box_pat(m, col) {
-        let llbox = Load(bcx, val);
-        let box_no_addrspace = non_gc_box_cast(bcx, llbox);
-        let unboxed =
-            GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]);
-        compile_submatch(bcx, enter_box(bcx, dm, m, col, val),
-                         vec::append(~[unboxed], vals_left), chk);
-        return;
-    }
-
-    if any_uniq_pat(m, col) {
-        let llbox = Load(bcx, val);
-        let box_no_addrspace = non_gc_box_cast(bcx, llbox);
-        let unboxed =
-            GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]);
-        compile_submatch(bcx, enter_uniq(bcx, dm, m, col, val),
-                         vec::append(~[unboxed], vals_left), chk);
-        return;
-    }
-
-    if any_region_pat(m, col) {
-        let loaded_val = Load(bcx, val);
-        compile_submatch(bcx, enter_region(bcx, dm, m, col, val),
-                         vec::append(~[loaded_val], vals_left), chk);
-        return;
-    }
-
-    // Decide what kind of branch we need
-    let opts = get_options(ccx, m, col);
-    let mut kind = no_branch;
-    let mut test_val = val;
-    if opts.len() > 0u {
-        match opts[0] {
-            var(_, vdef) => {
-                if (*ty::enum_variants(tcx, vdef.enm)).len() == 1u {
-                    kind = single;
-                } else {
-                    let enumptr =
-                        PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
-                    let discrimptr = GEPi(bcx, enumptr, [0u, 0u]);
-                    test_val = Load(bcx, discrimptr);
-                    kind = switch;
-                }
-            }
-            lit(_) => {
-                let pty = node_id_type(bcx, pat_id);
-                test_val = load_if_immediate(bcx, val, pty);
-                kind = if ty::type_is_integral(pty) { switch }
-                else { compare };
-            }
-            range(_, _) => {
-                test_val = Load(bcx, val);
-                kind = compare;
-            },
-            vec_len_eq(_) | vec_len_ge(_) => {
-                let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
-                let unboxed = load_if_immediate(bcx, val, vt.vec_ty);
-                let (_, len) = tvec::get_base_and_len(
-                    bcx, unboxed, vt.vec_ty
-                );
-                test_val = SDiv(bcx, len, vt.llunit_size);
-                kind = compare_vec_len;
-            }
-        }
-    }
-    for vec::each(opts) |o| {
-        match *o {
-            range(_, _) => { kind = compare; break }
-            _ => ()
-        }
-    }
-    let else_cx = match kind {
-        no_branch | single => bcx,
-        _ => sub_block(bcx, ~"match_else")
-    };
-    let sw = if kind == switch {
-        Switch(bcx, test_val, else_cx.llbb, opts.len())
-    } else {
-        C_int(ccx, 0) // Placeholder for when not using a switch
-    };
-
-    let defaults = enter_default(else_cx, dm, m, col, val);
-    let exhaustive = chk.is_none() && defaults.len() == 0u;
-    let len = opts.len();
-    let mut i = 0u;
-
-    // Compile subtrees for each option
-    for vec::each(opts) |opt| {
-        i += 1u;
-        let mut opt_cx = else_cx;
-        if !exhaustive || i < len {
-            opt_cx = sub_block(bcx, ~"match_case");
-            match kind {
-              single => Br(bcx, opt_cx.llbb),
-              switch => {
-                  match trans_opt(bcx, opt) {
-                      single_result(r) => {
-                          llvm::LLVMAddCase(sw, r.val, opt_cx.llbb);
-                          bcx = r.bcx;
-                      }
-                      _ => {
-                          bcx.sess().bug(
-                              ~"in compile_submatch, expected \
-                                trans_opt to return a single_result")
-                      }
-                  }
-              }
-              compare => {
-                  let t = node_id_type(bcx, pat_id);
-                  let Result {bcx: after_cx, val: matches} = {
-                      do with_scope_result(bcx, None,
-                                           ~"compare_scope") |bcx| {
-                          match trans_opt(bcx, opt) {
-                              single_result(
-                                  Result {bcx, val}) => {
-                                  compare_values(bcx, test_val, val, t)
-                              }
-                              lower_bound(
-                                  Result {bcx, val}) => {
-                                  compare_scalar_types(
-                                          bcx, test_val, val,
-                                          t, ast::ge)
-                              }
-                              range_result(
-                                  Result {val: vbegin, _},
-                                  Result {bcx, val: vend}) => {
-                                  let Result {bcx, val: llge} =
-                                      compare_scalar_types(
-                                          bcx, test_val,
-                                          vbegin, t, ast::ge);
-                                  let Result {bcx, val: llle} =
-                                      compare_scalar_types(
-                                          bcx, test_val, vend,
-                                          t, ast::le);
-                                  rslt(bcx, And(bcx, llge, llle))
-                              }
-                          }
-                      }
-                  };
-                  bcx = sub_block(after_cx, ~"compare_next");
-                  CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb);
-              }
-              compare_vec_len => {
-                  let Result {bcx: after_cx, val: matches} = {
-                      do with_scope_result(bcx, None,
-                                           ~"compare_vec_len_scope") |bcx| {
-                          match trans_opt(bcx, opt) {
-                              single_result(
-                                  Result {bcx, val}) => {
-                                  let value = compare_scalar_values(
-                                      bcx, test_val, val,
-                                      signed_int, ast::eq);
-                                  rslt(bcx, value)
-                              }
-                              lower_bound(
-                                  Result {bcx, val: val}) => {
-                                  let value = compare_scalar_values(
-                                      bcx, test_val, val,
-                                      signed_int, ast::ge);
-                                  rslt(bcx, value)
-                              }
-                              range_result(
-                                  Result {val: vbegin, _},
-                                  Result {bcx, val: vend}) => {
-                                  let llge =
-                                      compare_scalar_values(
-                                          bcx, test_val,
-                                          vbegin, signed_int, ast::ge);
-                                  let llle =
-                                      compare_scalar_values(
-                                          bcx, test_val, vend,
-                                          signed_int, ast::le);
-                                  rslt(bcx, And(bcx, llge, llle))
-                              }
-                          }
-                      }
-                  };
-                  bcx = sub_block(after_cx, ~"compare_vec_len_next");
-                  CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb);
-              }
-              _ => ()
-            }
-        } else if kind == compare || kind == compare_vec_len {
-            Br(bcx, else_cx.llbb);
-        }
-
-        let mut size = 0u;
-        let mut unpacked = ~[];
-        match *opt {
-            var(_, vdef) => {
-                let args = extract_variant_args(opt_cx, pat_id, vdef, val);
-                size = args.vals.len();
-                unpacked = args.vals;
-                opt_cx = args.bcx;
-            }
-            vec_len_eq(n) | vec_len_ge(n) => {
-                let tail = match *opt {
-                    vec_len_ge(_) => true,
-                    _ => false
-                };
-                let args = extract_vec_elems(opt_cx, pat_id, n, tail, val);
-                size = args.vals.len();
-                unpacked = args.vals;
-                opt_cx = args.bcx;
-            }
-            lit(_) | range(_, _) => ()
-        }
-        let opt_ms = enter_opt(opt_cx, m, opt, col, size, val);
-        let opt_vals = vec::append(unpacked, vals_left);
-        compile_submatch(opt_cx, opt_ms, opt_vals, chk);
-    }
-
-    // Compile the fall-through case, if any
-    if !exhaustive {
-        if kind == compare || kind == compare_vec_len {
-            Br(bcx, else_cx.llbb);
-        }
-        if kind != single {
-            compile_submatch(else_cx, defaults, vals_left, chk);
-        }
-    }
-}
-
-fn trans_alt(bcx: block,
-             alt_expr: @ast::expr,
-             discr_expr: @ast::expr,
-             arms: ~[ast::arm],
-             dest: Dest) -> block {
-    let _icx = bcx.insn_ctxt("alt::trans_alt");
-    do with_scope(bcx, alt_expr.info(), ~"alt") |bcx| {
-        trans_alt_inner(bcx, discr_expr, arms, dest)
-    }
-}
-
-fn trans_alt_inner(scope_cx: block,
-                   discr_expr: @ast::expr,
-                   arms: &[ast::arm],
-                   dest: Dest) -> block {
-    let _icx = scope_cx.insn_ctxt("alt::trans_alt_inner");
-    let mut bcx = scope_cx;
-    let tcx = bcx.tcx();
-
-    let discr_datum = unpack_datum!(bcx, {
-        expr::trans_to_datum(bcx, discr_expr)
-    });
-    if bcx.unreachable {
-        return bcx;
-    }
-
-    let mut arm_datas = ~[], matches = ~[];
-    for vec::each(arms) |arm| {
-        let body = scope_block(bcx, arm.body.info(), ~"case_body");
-
-        // Create the bindings map, which is a mapping from each binding name
-        // to an alloca() that will be the value for that local variable.
-        // Note that we use the names because each binding will have many ids
-        // from the various alternatives.
-        let bindings_map = std::map::HashMap();
-        do pat_bindings(tcx.def_map, arm.pats[0]) |bm, p_id, s, path| {
-            let ident = path_to_ident(path);
-            let variable_ty = node_id_type(bcx, p_id);
-            let llvariable_ty = type_of::type_of(bcx.ccx(), variable_ty);
-
-            let llmatch, trmode;
-            match bm {
-                ast::bind_by_value | ast::bind_by_move => {
-                    // in this case, the type of the variable will be T,
-                    // but we need to store a *T
-                    let is_move = (bm == ast::bind_by_move);
-                    llmatch = alloca(bcx, T_ptr(llvariable_ty));
-                    trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
-                }
-                ast::bind_infer => {
-                    // in this case also, the type of the variable will be T,
-                    // but we need to store a *T
-                    let is_move = match tcx.value_modes.find(p_id) {
-                        None => {
-                            tcx.sess.span_bug(s, ~"no value mode");
-                        }
-                        Some(MoveValue) => true,
-                        Some(CopyValue) | Some(ReadValue) => false
-                    };
-                    llmatch = alloca(bcx, T_ptr(llvariable_ty));
-                    trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
-                }
-                ast::bind_by_ref(_) => {
-                    llmatch = alloca(bcx, llvariable_ty);
-                    trmode = TrByRef;
-                }
-            };
-            bindings_map.insert(ident, BindingInfo {
-                llmatch: llmatch, trmode: trmode,
-                id: p_id, ty: variable_ty
-            });
-        }
-
-        let arm_data = @ArmData {bodycx: body,
-                                 arm: arm,
-                                 bindings_map: bindings_map};
-        arm_datas.push(arm_data);
-        for vec::each(arm.pats) |p| {
-            matches.push(@Match {pats: ~[*p], data: arm_data});
-        }
-    }
-
-    let t = node_id_type(bcx, discr_expr.id);
-    let chk = {
-        if ty::type_is_empty(tcx, t) {
-            // Special case for empty types
-            let fail_cx = @mut None;
-            Some(|| mk_fail(scope_cx, discr_expr.span,
-                            ~"scrutinizing value that can't exist", fail_cx))
-        } else {
-            None
-        }
-    };
-    let lldiscr = discr_datum.to_ref_llval(bcx);
-    compile_submatch(bcx, matches, ~[lldiscr], chk);
-
-    let arm_cxs = DVec();
-    for arm_datas.each |arm_data| {
-        let mut bcx = arm_data.bodycx;
-
-        // If this arm has a guard, then the various by-value bindings have
-        // already been copied into their homes.  If not, we do it here.  This
-        // is just to reduce code space.  See extensive comment at the start
-        // of the file for more details.
-        if arm_data.arm.guard.is_none() {
-            bcx = store_non_ref_bindings(bcx, *arm_data, None);
-        }
-
-        // insert bindings into the lllocals map and add cleanups
-        bcx = insert_lllocals(bcx, *arm_data, true);
-
-        bcx = controlflow::trans_block(bcx, arm_data.arm.body, dest);
-        bcx = trans_block_cleanups(bcx, block_cleanups(arm_data.bodycx));
-        arm_cxs.push(bcx);
-    }
-
-    return controlflow::join_blocks(scope_cx, dvec::unwrap(move arm_cxs));
-
-    fn mk_fail(bcx: block, sp: span, msg: ~str,
-               finished: @mut Option<BasicBlockRef>) -> BasicBlockRef {
-        match *finished { Some(bb) => return bb, _ => () }
-        let fail_cx = sub_block(bcx, ~"case_fallthrough");
-        controlflow::trans_fail(fail_cx, Some(sp), msg);
-        *finished = Some(fail_cx.llbb);
-        return fail_cx.llbb;
-    }
-}
-
-enum IrrefutablePatternBindingMode {
-    // Stores the association between node ID and LLVM value in `lllocals`.
-    BindLocal,
-    // Stores the association between node ID and LLVM value in `llargs`.
-    BindArgument
-}
-
-// Not alt-related, but similar to the pattern-munging code above
-fn bind_irrefutable_pat(bcx: block,
-                        pat: @ast::pat,
-                        val: ValueRef,
-                        make_copy: bool,
-                        binding_mode: IrrefutablePatternBindingMode)
-                     -> block {
-    let _icx = bcx.insn_ctxt("alt::bind_irrefutable_pat");
-    let ccx = bcx.fcx.ccx;
-    let mut bcx = bcx;
-
-    // Necessary since bind_irrefutable_pat is called outside trans_alt
-    match pat.node {
-        ast::pat_ident(_, _,inner) => {
-            if pat_is_variant_or_struct(bcx.tcx().def_map, pat) {
-                return bcx;
-            }
-
-            if make_copy {
-                let binding_ty = node_id_type(bcx, pat.id);
-                let datum = Datum {val: val, ty: binding_ty,
-                                   mode: ByRef, source: FromRvalue};
-                let scratch = scratch_datum(bcx, binding_ty, false);
-                datum.copy_to_datum(bcx, INIT, scratch);
-                match binding_mode {
-                    BindLocal => {
-                        bcx.fcx.lllocals.insert(pat.id,
-                                                local_mem(scratch.val));
-                    }
-                    BindArgument => {
-                        bcx.fcx.llargs.insert(pat.id,
-                                              local_mem(scratch.val));
-                    }
-                }
-                add_clean(bcx, scratch.val, binding_ty);
-            } else {
-                match binding_mode {
-                    BindLocal => {
-                        bcx.fcx.lllocals.insert(pat.id, local_mem(val));
-                    }
-                    BindArgument => {
-                        bcx.fcx.llargs.insert(pat.id, local_mem(val));
-                    }
-                }
-            }
-
-            for inner.each |inner_pat| {
-                bcx = bind_irrefutable_pat(
-                    bcx, *inner_pat, val, true, binding_mode);
-            }
-        }
-        ast::pat_enum(_, sub_pats) => {
-            match bcx.tcx().def_map.find(pat.id) {
-                Some(ast::def_variant(*)) => {
-                    let pat_def = ccx.tcx.def_map.get(pat.id);
-                    let vdefs = ast_util::variant_def_ids(pat_def);
-                    let args = extract_variant_args(bcx, pat.id, vdefs, val);
-                    for sub_pats.each |sub_pat| {
-                        for vec::eachi(args.vals) |i, argval| {
-                            bcx = bind_irrefutable_pat(bcx,
-                                                       sub_pat[i],
-                                                       *argval,
-                                                       make_copy,
-                                                       binding_mode);
-                        }
-                    }
-                }
-                Some(ast::def_struct(*)) => {
-                    match sub_pats {
-                        None => {
-                            // This is a unit-like struct. Nothing to do here.
-                        }
-                        Some(elems) => {
-                            // This is the tuple variant case.
-                            for vec::eachi(elems) |i, elem| {
-                                let fldptr = GEPi(bcx, val, struct_field(i));
-                                bcx = bind_irrefutable_pat(bcx,
-                                                           *elem,
-                                                           fldptr,
-                                                           make_copy,
-                                                           binding_mode);
-                            }
-                        }
-                    }
-                }
-                _ => {
-                    // Nothing to do here.
-                }
-            }
-        }
-        ast::pat_rec(fields, _) | ast::pat_struct(_, fields, _) => {
-            let tcx = bcx.tcx();
-            let pat_ty = node_id_type(bcx, pat.id);
-            do expr::with_field_tys(tcx, pat_ty, None) |_hd, field_tys| {
-                for vec::each(fields) |f| {
-                    let ix = ty::field_idx_strict(tcx, f.ident, field_tys);
-                    let fldptr = GEPi(bcx, val, struct_field(ix));
-                    bcx = bind_irrefutable_pat(bcx,
-                                               f.pat,
-                                               fldptr,
-                                               make_copy,
-                                               binding_mode);
-                }
-            }
-        }
-        ast::pat_tup(elems) => {
-            for vec::eachi(elems) |i, elem| {
-                let fldptr = GEPi(bcx, val, [0u, i]);
-                bcx = bind_irrefutable_pat(bcx,
-                                           *elem,
-                                           fldptr,
-                                           make_copy,
-                                           binding_mode);
-            }
-        }
-        ast::pat_box(inner) | ast::pat_uniq(inner) => {
-            let llbox = Load(bcx, val);
-            let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
-            bcx = bind_irrefutable_pat(bcx,
-                                       inner,
-                                       unboxed,
-                                       true,
-                                       binding_mode);
-        }
-        ast::pat_region(inner) => {
-            let loaded_val = Load(bcx, val);
-            bcx = bind_irrefutable_pat(bcx,
-                                       inner,
-                                       loaded_val,
-                                       true,
-                                       binding_mode);
-        }
-        ast::pat_wild | ast::pat_lit(_) | ast::pat_range(_, _) |
-        ast::pat_vec(*) => ()
-    }
-    return bcx;
-}
-
-// Local Variables:
-// mode: rust
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
index d0ce66da43f52708ca4c541060be68272a38fcc7..40740be54cf5bb581448e252d4cef229bfa0bd28 100644 (file)
@@ -23,6 +23,8 @@
 //     but many TypeRefs correspond to one ty::t; for instance, tup(int, int,
 //     int) and rec(x=int, y=int, z=int) will have the same TypeRef.
 
+use core::prelude::*;
+
 use back::link::{mangle_exported_name};
 use back::link::{mangle_internal_name_by_path_and_seq};
 use back::link::{mangle_internal_name_by_path};
 use lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef};
 use lib::llvm::{True, False};
 use lib::llvm::{llvm, mk_target_data, mk_type_names};
+use lib;
 use metadata::common::link_meta;
 use metadata::{csearch, cstore, decoder, encoder};
+use middle::astencode;
 use middle::pat_util::*;
+use middle::resolve;
+use middle::trans::_match;
 use middle::trans::build::*;
+use middle::trans::callee;
 use middle::trans::common::*;
+use middle::trans::consts;
+use middle::trans::controlflow;
+use middle::trans::datum;
+use middle::trans::debuginfo;
+use middle::trans::expr;
+use middle::trans::foreign;
+use middle::trans::glue;
+use middle::trans::inline;
+use middle::trans::meth;
+use middle::trans::monomorphize;
+use middle::trans::reachable;
 use middle::trans::shape::*;
+use middle::trans::tvec;
 use middle::trans::type_of::*;
 use util::common::indenter;
 use util::common::is_main_name;
 use util::ppaux::{ty_to_str, ty_to_short_str};
 use util::ppaux;
 
+use core::either;
+use core::hash;
+use core::int;
+use core::io;
 use core::libc::{c_uint, c_ulonglong};
 use core::option::{is_none, is_some};
+use core::option;
+use core::uint;
 use std::map::HashMap;
 use std::smallintmap;
 use std::{map, time, list};
-use syntax::ast_map::{path, path_mod, path_name};
+use syntax::ast_map::{path, path_elt_to_str, path_mod, path_name};
 use syntax::ast_util::{def_id_of_def, local_def, path_to_ident};
 use syntax::attr;
 use syntax::codemap::span;
@@ -103,7 +128,7 @@ fn insn_ctxt(s: &str) -> icx_popper {
     }
 }
 
-fn log_fn_time(ccx: @crate_ctxt, name: ~str, start: time::Timespec,
+fn log_fn_time(ccx: @crate_ctxt, +name: ~str, start: time::Timespec,
                end: time::Timespec) {
     let elapsed = 1000 * ((end.sec - start.sec) as int) +
         ((end.nsec as int) - (start.nsec as int)) / 1000000;
@@ -113,19 +138,23 @@ fn log_fn_time(ccx: @crate_ctxt, name: ~str, start: time::Timespec,
 fn decl_fn(llmod: ModuleRef, name: ~str, cc: lib::llvm::CallConv,
            llty: TypeRef) -> ValueRef {
     let llfn: ValueRef = str::as_c_str(name, |buf| {
-        llvm::LLVMGetOrInsertFunction(llmod, buf, llty)
+        unsafe {
+            llvm::LLVMGetOrInsertFunction(llmod, buf, llty)
+        }
     });
-    lib::llvm::SetFunctionCallConv(llfn, cc);
+    unsafe {
+        lib::llvm::SetFunctionCallConv(llfn, cc);
+    }
     return llfn;
 }
 
-fn decl_cdecl_fn(llmod: ModuleRef, name: ~str, llty: TypeRef) -> ValueRef {
+fn decl_cdecl_fn(llmod: ModuleRef, +name: ~str, llty: TypeRef) -> ValueRef {
     return decl_fn(llmod, name, lib::llvm::CCallConv, llty);
 }
 
 // Only use this if you are going to actually define the function. It's
 // not valid to simply declare a function as internal.
-fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, llty: TypeRef) ->
+fn decl_internal_cdecl_fn(llmod: ModuleRef, +name: ~str, llty: TypeRef) ->
    ValueRef {
     let llfn = decl_cdecl_fn(llmod, name, llty);
     lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
@@ -133,26 +162,36 @@ fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, llty: TypeRef) ->
 }
 
 fn get_extern_fn(externs: HashMap<~str, ValueRef>,
-                 llmod: ModuleRef, name: ~str,
-                 cc: lib::llvm::CallConv, ty: TypeRef) -> ValueRef {
-    if externs.contains_key(name) { return externs.get(name); }
-    let f = decl_fn(llmod, name, cc, ty);
+                 llmod: ModuleRef,
+                 +name: ~str,
+                 cc: lib::llvm::CallConv,
+                 ty: TypeRef) -> ValueRef {
+    // XXX: Bad copy.
+    if externs.contains_key(copy name) { return externs.get(name); }
+    // XXX: Bad copy.
+    let f = decl_fn(llmod, copy name, cc, ty);
     externs.insert(name, f);
     return f;
 }
 
 fn get_extern_const(externs: HashMap<~str, ValueRef>, llmod: ModuleRef,
-                    name: ~str, ty: TypeRef) -> ValueRef {
-    if externs.contains_key(name) { return externs.get(name); }
-    let c = str::as_c_str(name, |buf| llvm::LLVMAddGlobal(llmod, ty, buf));
-    externs.insert(name, c);
-    return c;
+                    +name: ~str, ty: TypeRef) -> ValueRef {
+    unsafe {
+        // XXX: Bad copy.
+        if externs.contains_key(copy name) { return externs.get(name); }
+        let c = str::as_c_str(name, |buf| {
+            llvm::LLVMAddGlobal(llmod, ty, buf)
+        });
+        externs.insert(name, c);
+        return c;
+    }
 }
 
 fn get_simple_extern_fn(cx: block,
                         externs: HashMap<~str, ValueRef>,
                         llmod: ModuleRef,
-                        name: ~str, n_args: int) -> ValueRef {
+                        +name: ~str,
+                        n_args: int) -> ValueRef {
     let _icx = cx.insn_ctxt("get_simple_extern_fn");
     let ccx = cx.fcx.ccx;
     let inputs = vec::from_elem(n_args as uint, ccx.int_type);
@@ -162,7 +201,7 @@ fn get_simple_extern_fn(cx: block,
 }
 
 fn trans_foreign_call(cx: block, externs: HashMap<~str, ValueRef>,
-                      llmod: ModuleRef, name: ~str, args: ~[ValueRef]) ->
+                      llmod: ModuleRef, +name: ~str, args: ~[ValueRef]) ->
    ValueRef {
     let _icx = cx.insn_ctxt("trans_foreign_call");
     let n = args.len() as int;
@@ -239,14 +278,20 @@ fn opaque_box_body(bcx: block,
 
 // malloc_raw_dyn: allocates a box to contain a given type, but with a
 // potentially dynamic size.
-fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap,
+fn malloc_raw_dyn(bcx: block,
+                  t: ty::t,
+                  heap: heap,
                   size: ValueRef) -> Result {
     let _icx = bcx.insn_ctxt("malloc_raw");
     let ccx = bcx.ccx();
 
-    let (mk_fn, rtcall) = match heap {
-      heap_shared => (ty::mk_imm_box, ~"malloc"),
-      heap_exchange => (ty::mk_imm_uniq, ~"exchange_malloc")
+    let (mk_fn, langcall) = match heap {
+        heap_shared => {
+            (ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn())
+        }
+        heap_exchange => {
+            (ty::mk_imm_uniq, bcx.tcx().lang_items.exchange_malloc_fn())
+        }
     };
 
     // Grab the TypeRef type of box_ptr_ty.
@@ -260,8 +305,11 @@ fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap,
     // Allocate space:
     let tydesc = PointerCast(bcx, static_ti.tydesc, T_ptr(T_i8()));
     let rval = alloca_zeroed(bcx, T_ptr(T_i8()));
-    let bcx = callee::trans_rtcall(bcx, rtcall, ~[tydesc, size],
-                                   expr::SaveIn(rval));
+    let bcx = callee::trans_rtcall_or_lang_call(
+        bcx,
+        langcall,
+        ~[tydesc, size],
+        expr::SaveIn(rval));
     return rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty));
 }
 
@@ -274,12 +322,14 @@ fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap,
 * wrong address space and thus be the wrong type.
 */
 fn non_gc_box_cast(bcx: block, val: ValueRef) -> ValueRef {
-    debug!("non_gc_box_cast");
-    add_comment(bcx, ~"non_gc_box_cast");
-    assert(llvm::LLVMGetPointerAddressSpace(val_ty(val)) == gc_box_addrspace
-           || bcx.unreachable);
-    let non_gc_t = T_ptr(llvm::LLVMGetElementType(val_ty(val)));
-    PointerCast(bcx, val, non_gc_t)
+    unsafe {
+        debug!("non_gc_box_cast");
+        add_comment(bcx, ~"non_gc_box_cast");
+        assert(llvm::LLVMGetPointerAddressSpace(val_ty(val)) ==
+                gc_box_addrspace || bcx.unreachable);
+        let non_gc_t = T_ptr(llvm::LLVMGetElementType(val_ty(val)));
+        PointerCast(bcx, val, non_gc_t)
+    }
 }
 
 // malloc_raw: expects an unboxed type and returns a pointer to
@@ -333,25 +383,36 @@ fn get_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
 }
 
 fn set_no_inline(f: ValueRef) {
-    llvm::LLVMAddFunctionAttr(f, lib::llvm::NoInlineAttribute as c_ulonglong,
-                              0u as c_ulonglong);
+    unsafe {
+        llvm::LLVMAddFunctionAttr(f,
+                                  lib::llvm::NoInlineAttribute as c_ulonglong,
+                                  0u as c_ulonglong);
+    }
 }
 
 fn set_no_unwind(f: ValueRef) {
-    llvm::LLVMAddFunctionAttr(f, lib::llvm::NoUnwindAttribute as c_ulonglong,
-                              0u as c_ulonglong);
+    unsafe {
+        llvm::LLVMAddFunctionAttr(f,
+                                  lib::llvm::NoUnwindAttribute as c_ulonglong,
+                                  0u as c_ulonglong);
+    }
 }
 
 // Tell LLVM to emit the information necessary to unwind the stack for the
 // function f.
 fn set_uwtable(f: ValueRef) {
-    llvm::LLVMAddFunctionAttr(f, lib::llvm::UWTableAttribute as c_ulonglong,
-                              0u as c_ulonglong);
+    unsafe {
+        llvm::LLVMAddFunctionAttr(f,
+                                  lib::llvm::UWTableAttribute as c_ulonglong,
+                                  0u as c_ulonglong);
+    }
 }
 
 fn set_inline_hint(f: ValueRef) {
-    llvm::LLVMAddFunctionAttr(f, lib::llvm::InlineHintAttribute
-                              as c_ulonglong, 0u as c_ulonglong);
+    unsafe {
+        llvm::LLVMAddFunctionAttr(f, lib::llvm::InlineHintAttribute
+                                  as c_ulonglong, 0u as c_ulonglong);
+    }
 }
 
 fn set_inline_hint_if_appr(attrs: ~[ast::attribute],
@@ -365,12 +426,16 @@ fn set_inline_hint_if_appr(attrs: ~[ast::attribute],
 }
 
 fn set_always_inline(f: ValueRef) {
-    llvm::LLVMAddFunctionAttr(f, lib::llvm::AlwaysInlineAttribute
-                              as c_ulonglong, 0u as c_ulonglong);
+    unsafe {
+        llvm::LLVMAddFunctionAttr(f, lib::llvm::AlwaysInlineAttribute
+                                  as c_ulonglong, 0u as c_ulonglong);
+    }
 }
 
 fn set_custom_stack_growth_fn(f: ValueRef) {
-    llvm::LLVMAddFunctionAttr(f, 0u as c_ulonglong, 1u as c_ulonglong);
+    unsafe {
+        llvm::LLVMAddFunctionAttr(f, 0u as c_ulonglong, 1u as c_ulonglong);
+    }
 }
 
 fn set_glue_inlining(f: ValueRef, t: ty::t) {
@@ -381,8 +446,9 @@ fn set_glue_inlining(f: ValueRef, t: ty::t) {
 
 // Double-check that we never ask LLVM to declare the same symbol twice. It
 // silently mangles such symbols, breaking our linkage model.
-fn note_unique_llvm_symbol(ccx: @crate_ctxt, sym: ~str) {
-    if ccx.all_llvm_symbols.contains_key(sym) {
+fn note_unique_llvm_symbol(ccx: @crate_ctxt, +sym: ~str) {
+    // XXX: Bad copy.
+    if ccx.all_llvm_symbols.contains_key(copy sym) {
         ccx.sess.bug(~"duplicate LLVM symbol: " + sym);
     }
     ccx.all_llvm_symbols.insert(sym, ());
@@ -415,7 +481,11 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id,
 // Structural comparison: a rather involved form of glue.
 fn maybe_name_value(cx: @crate_ctxt, v: ValueRef, s: ~str) {
     if cx.sess.opts.save_temps {
-        let _: () = str::as_c_str(s, |buf| llvm::LLVMSetValueName(v, buf));
+        let _: () = str::as_c_str(s, |buf| {
+            unsafe {
+                llvm::LLVMSetValueName(v, buf)
+            }
+        });
     }
 }
 
@@ -453,11 +523,10 @@ fn compare_scalar_types(cx: block, lhs: ValueRef, rhs: ValueRef,
 fn compare_scalar_values(cx: block, lhs: ValueRef, rhs: ValueRef,
                          nt: scalar_type, op: ast::binop) -> ValueRef {
     let _icx = cx.insn_ctxt("compare_scalar_values");
-    fn die_(cx: block) -> ! {
+    fn die(cx: block) -> ! {
         cx.tcx().sess.bug(~"compare_scalar_values: must be a\
           comparison operator");
     }
-    let die = fn@() -> ! { die_(cx) };
     match nt {
       nil_type => {
         // We don't need to do actual comparisons for nil.
@@ -466,7 +535,7 @@ fn die_(cx: block) -> ! {
           ast::eq | ast::le | ast::ge => return C_bool(true),
           ast::ne | ast::lt | ast::gt => return C_bool(false),
           // refinements would be nice
-          _ => die()
+          _ => die(cx)
         }
       }
       floating_point => {
@@ -477,7 +546,7 @@ fn die_(cx: block) -> ! {
           ast::le => lib::llvm::RealOLE,
           ast::gt => lib::llvm::RealOGT,
           ast::ge => lib::llvm::RealOGE,
-          _ => die()
+          _ => die(cx)
         };
         return FCmp(cx, cmp, lhs, rhs);
       }
@@ -489,7 +558,7 @@ fn die_(cx: block) -> ! {
           ast::le => lib::llvm::IntSLE,
           ast::gt => lib::llvm::IntSGT,
           ast::ge => lib::llvm::IntSGE,
-          _ => die()
+          _ => die(cx)
         };
         return ICmp(cx, cmp, lhs, rhs);
       }
@@ -501,7 +570,7 @@ fn die_(cx: block) -> ! {
           ast::le => lib::llvm::IntULE,
           ast::gt => lib::llvm::IntUGT,
           ast::ge => lib::llvm::IntUGE,
-          _ => die()
+          _ => die(cx)
         };
         return ICmp(cx, cmp, lhs, rhs);
       }
@@ -538,23 +607,24 @@ fn iter_variant(cx: block, a_tup: ValueRef,
             let mut j = 0u;
             let v_id = variant.id;
             for vec::each(fn_ty.sig.inputs) |a| {
-                let llfldp_a = GEP_enum(cx, a_tup, tid, v_id, tps, j);
+                let llfldp_a = GEP_enum(cx, a_tup, tid, v_id,
+                                        /*bad*/copy tps, j);
                 // XXX: Is "None" right here?
                 let ty_subst = ty::subst_tps(ccx.tcx, tps, None, a.ty);
                 cx = f(cx, llfldp_a, ty_subst);
                 j += 1u;
             }
           }
-          _ => cx.tcx().sess.bug(~"iter_variant: not a function type")
+          _ => cx.tcx().sess.bug(fmt!("iter_variant: not a function type: \
+                                       %s (variant name = %s)",
+                                      cx.ty_to_str(fn_ty),
+                                      cx.sess().str_of(variant.name)))
         }
         return cx;
     }
 
-    /*
-    Typestate constraint that shows the unimpl case doesn't happen?
-    */
     let mut cx = cx;
-    match ty::get(t).sty {
+    match /*bad*/copy ty::get(t).sty {
       ty::ty_rec(*) | ty::ty_struct(*) => {
           do expr::with_field_tys(cx.tcx(), t, None) |_has_dtor, field_tys| {
               for vec::eachi(field_tys) |i, field_ty| {
@@ -580,8 +650,12 @@ fn iter_variant(cx: block, a_tup: ValueRef,
 
         // Cast the enums to types we can GEP into.
         if n_variants == 1u {
-            return iter_variant(cx, av, variants[0],
-                             (*substs).tps, tid, f);
+            return iter_variant(cx,
+                                av,
+                                variants[0],
+                                /*bad*/copy substs.tps,
+                                tid,
+                                f);
         }
 
         let ccx = cx.ccx();
@@ -606,7 +680,7 @@ fn iter_variant(cx: block, a_tup: ValueRef,
             AddCase(llswitch, C_int(ccx, variant.disr_val), variant_cx.llbb);
             let variant_cx =
                 iter_variant(variant_cx, llunion_a_ptr, *variant,
-                             (*substs).tps, tid, f);
+                             /*bad*/copy (*substs).tps, tid, f);
             Br(variant_cx, next_cx.llbb);
         }
         return next_cx;
@@ -625,8 +699,11 @@ fn cast_shift_expr_rhs(cx: block, op: ast::binop,
 
 fn cast_shift_const_rhs(op: ast::binop,
                         lhs: ValueRef, rhs: ValueRef) -> ValueRef {
-    cast_shift_rhs(op, lhs, rhs,
-                   llvm::LLVMConstTrunc, llvm::LLVMConstZExt)
+    unsafe {
+        cast_shift_rhs(op, lhs, rhs,
+                       |a, b| unsafe { llvm::LLVMConstTrunc(a, b) },
+                       |a, b| unsafe { llvm::LLVMConstZExt(a, b) })
+    }
 }
 
 fn cast_shift_rhs(op: ast::binop,
@@ -635,22 +712,24 @@ fn cast_shift_rhs(op: ast::binop,
                   zext: fn(ValueRef, TypeRef) -> ValueRef
                  ) -> ValueRef {
     // Shifts may have any size int on the rhs
-    if ast_util::is_shift_binop(op) {
-        let rhs_llty = val_ty(rhs);
-        let lhs_llty = val_ty(lhs);
-        let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty);
-        let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty);
-        if lhs_sz < rhs_sz {
-            trunc(rhs, lhs_llty)
-        } else if lhs_sz > rhs_sz {
-            // FIXME (#1877: If shifting by negative
-            // values becomes not undefined then this is wrong.
-            zext(rhs, lhs_llty)
+    unsafe {
+        if ast_util::is_shift_binop(op) {
+            let rhs_llty = val_ty(rhs);
+            let lhs_llty = val_ty(lhs);
+            let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty);
+            let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty);
+            if lhs_sz < rhs_sz {
+                trunc(rhs, lhs_llty)
+            } else if lhs_sz > rhs_sz {
+                // FIXME (#1877: If shifting by negative
+                // values becomes not undefined then this is wrong.
+                zext(rhs, lhs_llty)
+            } else {
+                rhs
+            }
         } else {
             rhs
         }
-    } else {
-        rhs
     }
 }
 
@@ -676,7 +755,7 @@ fn fail_if_zero(cx: block, span: span, divmod: ast::binop,
       }
     };
     do with_cond(cx, is_zero) |bcx| {
-        controlflow::trans_fail(bcx, Some(span), text)
+        controlflow::trans_fail(bcx, Some(span), /*bad*/copy text)
     }
 }
 
@@ -700,26 +779,52 @@ fn trans_external_path(ccx: @crate_ctxt, did: ast::def_id, t: ty::t)
     };
 }
 
+fn get_discrim_val(cx: @crate_ctxt, span: span, enum_did: ast::def_id,
+                   variant_did: ast::def_id) -> ValueRef {
+    // Can't use `discrims` from the crate context here because
+    // those discriminants have an extra level of indirection,
+    // and there's no LLVM constant load instruction.
+    let mut lldiscrim_opt = None;
+    for ty::enum_variants(cx.tcx, enum_did).each |variant_info| {
+        if variant_info.id == variant_did {
+            lldiscrim_opt = Some(C_int(cx,
+                                       variant_info.disr_val));
+            break;
+        }
+    }
+
+    match lldiscrim_opt {
+        None => {
+            cx.tcx.sess.span_bug(span, ~"didn't find discriminant?!");
+        }
+        Some(found_lldiscrim) => {
+            found_lldiscrim
+        }
+    }
+}
+
 fn lookup_discriminant(ccx: @crate_ctxt, vid: ast::def_id) -> ValueRef {
-    let _icx = ccx.insn_ctxt("lookup_discriminant");
-    match ccx.discrims.find(vid) {
-      None => {
-        // It's an external discriminant that we haven't seen yet.
-        assert (vid.crate != ast::local_crate);
-        let sym = csearch::get_symbol(ccx.sess.cstore, vid);
-        let gvar = str::as_c_str(sym, |buf| {
-            llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
-        });
-        lib::llvm::SetLinkage(gvar, lib::llvm::ExternalLinkage);
-        llvm::LLVMSetGlobalConstant(gvar, True);
-        ccx.discrims.insert(vid, gvar);
-        return gvar;
-      }
-      Some(llval) => return llval,
+    unsafe {
+        let _icx = ccx.insn_ctxt("lookup_discriminant");
+        match ccx.discrims.find(vid) {
+            None => {
+                // It's an external discriminant that we haven't seen yet.
+                assert (vid.crate != ast::local_crate);
+                let sym = csearch::get_symbol(ccx.sess.cstore, vid);
+                let gvar = str::as_c_str(sym, |buf| {
+                    llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
+                });
+                lib::llvm::SetLinkage(gvar, lib::llvm::ExternalLinkage);
+                llvm::LLVMSetGlobalConstant(gvar, True);
+                ccx.discrims.insert(vid, gvar);
+                return gvar;
+            }
+            Some(llval) => return llval,
+        }
     }
 }
 
-fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) -> block {
+fn invoke(bcx: block, llfn: ValueRef, +llargs: ~[ValueRef]) -> block {
     let _icx = bcx.insn_ctxt("invoke_");
     if bcx.unreachable { return bcx; }
     if need_invoke(bcx) {
@@ -919,16 +1024,17 @@ fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef {
     return v;
 }
 
-fn trans_trace(bcx: block, sp_opt: Option<span>, trace_str: ~str) {
+fn trans_trace(bcx: block, sp_opt: Option<span>, +trace_str: ~str) {
     if !bcx.sess().trace() { return; }
     let _icx = bcx.insn_ctxt("trans_trace");
-    add_comment(bcx, trace_str);
+    // XXX: Bad copy.
+    add_comment(bcx, copy trace_str);
     let V_trace_str = C_cstr(bcx.ccx(), trace_str);
     let {V_filename, V_line} = match sp_opt {
       Some(sp) => {
         let sess = bcx.sess();
         let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo);
-        {V_filename: C_cstr(bcx.ccx(), loc.file.name),
+        {V_filename: C_cstr(bcx.ccx(), /*bad*/copy loc.file.name),
          V_line: loc.line as int}
       }
       None => {
@@ -999,11 +1105,11 @@ fn init_local(bcx: block, local: @ast::local) -> block {
            bcx.to_str());
     add_clean(bcx, llptr, ty);
 
-    return alt::bind_irrefutable_pat(bcx,
-                                     local.node.pat,
-                                     llptr,
-                                     false,
-                                     alt::BindLocal);
+    return _match::bind_irrefutable_pat(bcx,
+                                       local.node.pat,
+                                       llptr,
+                                       false,
+                                       _match::BindLocal);
 }
 
 fn trans_stmt(cx: block, s: ast::stmt) -> block {
@@ -1022,7 +1128,7 @@ fn trans_stmt(cx: block, s: ast::stmt) -> block {
             bcx = expr::trans_into(cx, e, expr::Ignore);
         }
         ast::stmt_decl(d, _) => {
-            match d.node {
+            match /*bad*/copy d.node {
                 ast::decl_local(locals) => {
                     for vec::each(locals) |local| {
                         bcx = init_local(bcx, *local);
@@ -1043,25 +1149,39 @@ fn trans_stmt(cx: block, s: ast::stmt) -> block {
 // You probably don't want to use this one. See the
 // next three functions instead.
 fn new_block(cx: fn_ctxt, parent: Option<block>, +kind: block_kind,
-             is_lpad: bool, name: ~str, opt_node_info: Option<node_info>)
+             is_lpad: bool, +name: ~str, opt_node_info: Option<node_info>)
     -> block {
 
     let s = if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo {
         (cx.ccx.names)(name)
-    } else { special_idents::invalid };
-    let llbb: BasicBlockRef = str::as_c_str(cx.ccx.sess.str_of(s), |buf| {
-        llvm::LLVMAppendBasicBlock(cx.llfn, buf)
-    });
-    let bcx = mk_block(llbb, parent, move kind, is_lpad, opt_node_info, cx);
-    do option::iter(&parent) |cx| {
-        if cx.unreachable { Unreachable(bcx); }
+    } else {
+        special_idents::invalid
     };
-    return bcx;
+    unsafe {
+        let llbb: BasicBlockRef = str::as_c_str(cx.ccx.sess.str_of(s), |buf| {
+            llvm::LLVMAppendBasicBlock(cx.llfn, buf)
+        });
+        let bcx = mk_block(llbb,
+                           parent,
+                           move kind,
+                           is_lpad,
+                           opt_node_info,
+                           cx);
+        do option::iter(&parent) |cx| {
+            if cx.unreachable { Unreachable(bcx); }
+        };
+        return bcx;
+    }
 }
 
 fn simple_block_scope() -> block_kind {
-    block_scope({loop_break: None, loop_label: None, mut cleanups: ~[],
-                 mut cleanup_paths: ~[], mut landing_pad: None})
+    block_scope(scope_info {
+        loop_break: None,
+        loop_label: None,
+        mut cleanups: ~[],
+        mut cleanup_paths: ~[],
+        mut landing_pad: None
+    })
 }
 
 // Use this when you're at the top block of a function or the like.
@@ -1072,14 +1192,14 @@ fn top_scope_block(fcx: fn_ctxt, opt_node_info: Option<node_info>) -> block {
 
 fn scope_block(bcx: block,
                opt_node_info: Option<node_info>,
-               n: ~str) -> block {
+               +n: ~str) -> block {
     return new_block(bcx.fcx, Some(bcx), simple_block_scope(), bcx.is_lpad,
                   n, opt_node_info);
 }
 
 fn loop_scope_block(bcx: block, loop_break: block, loop_label: Option<ident>,
-                    n: ~str, opt_node_info: Option<node_info>) -> block {
-    return new_block(bcx.fcx, Some(bcx), block_scope({
+                    +n: ~str, opt_node_info: Option<node_info>) -> block {
+    return new_block(bcx.fcx, Some(bcx), block_scope(scope_info {
         loop_break: Some(loop_break),
         loop_label: loop_label,
         mut cleanups: ~[],
@@ -1089,12 +1209,12 @@ fn loop_scope_block(bcx: block, loop_break: block, loop_label: Option<ident>,
 }
 
 // Use this when creating a block for the inside of a landing pad.
-fn lpad_block(bcx: block, n: ~str) -> block {
+fn lpad_block(bcx: block, +n: ~str) -> block {
     new_block(bcx.fcx, Some(bcx), block_non_scope, true, n, None)
 }
 
 // Use this when you're making a general CFG BB within a scope.
-fn sub_block(bcx: block, n: ~str) -> block {
+fn sub_block(bcx: block, +n: ~str) -> block {
     new_block(bcx.fcx, Some(bcx), block_non_scope, bcx.is_lpad, n, None)
 }
 
@@ -1200,7 +1320,7 @@ fn leave_block(bcx: block, out_of: block) -> block {
 }
 
 fn with_scope(bcx: block, opt_node_info: Option<node_info>,
-              name: ~str, f: fn(block) -> block) -> block {
+              +name: ~str, f: fn(block) -> block) -> block {
     let _icx = bcx.insn_ctxt("with_scope");
 
     debug!("with_scope(bcx=%s, opt_node_info=%?, name=%s)",
@@ -1212,10 +1332,11 @@ fn with_scope(bcx: block, opt_node_info: Option<node_info>,
     leave_block(f(scope_cx), scope_cx)
 }
 
-fn with_scope_result(bcx: block, opt_node_info: Option<node_info>,
-                     name: ~str, f: fn(block) -> Result)
-    -> Result
-{
+fn with_scope_result(bcx: block,
+                     opt_node_info: Option<node_info>,
+                     +name: ~str,
+                     f: fn(block) -> Result)
+                  -> Result {
     let _icx = bcx.insn_ctxt("with_scope_result");
     let scope_cx = scope_block(bcx, opt_node_info, name);
     Br(bcx, scope_cx.llbb);
@@ -1224,7 +1345,7 @@ fn with_scope_result(bcx: block, opt_node_info: Option<node_info>,
 }
 
 fn with_scope_datumblock(bcx: block, opt_node_info: Option<node_info>,
-                         name: ~str, f: fn(block) -> datum::DatumBlock)
+                         +name: ~str, f: fn(block) -> datum::DatumBlock)
     -> datum::DatumBlock
 {
     use middle::trans::datum::DatumBlock;
@@ -1240,7 +1361,7 @@ fn block_locals(b: ast::blk, it: fn(@ast::local)) {
     for vec::each(b.node.stmts) |s| {
         match s.node {
           ast::stmt_decl(d, _) => {
-            match d.node {
+            match /*bad*/copy d.node {
               ast::decl_local(locals) => {
                 for vec::each(locals) |local| {
                     it(*local);
@@ -1265,7 +1386,9 @@ fn alloc_local(cx: block, local: @ast::local) -> block {
     if cx.sess().opts.debuginfo {
         do option::iter(&simple_name) |name| {
             str::as_c_str(cx.ccx().sess.str_of(*name), |buf| {
-                llvm::LLVMSetValueName(val, buf)
+                unsafe {
+                    llvm::LLVMSetValueName(val, buf)
+                }
             });
         }
     }
@@ -1372,7 +1495,11 @@ fn alloca_zeroed(cx: block, t: TypeRef) -> ValueRef {
 
 fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef {
     let _icx = cx.insn_ctxt("alloca");
-    if cx.unreachable { return llvm::LLVMGetUndef(t); }
+    if cx.unreachable {
+        unsafe {
+            return llvm::LLVMGetUndef(t);
+        }
+    }
     let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas);
     let p = Alloca(initcx, t);
     if zero { memzero(initcx, p, t); }
@@ -1381,7 +1508,11 @@ fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef {
 
 fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef {
     let _icx = cx.insn_ctxt("arrayalloca");
-    if cx.unreachable { return llvm::LLVMGetUndef(t); }
+    if cx.unreachable {
+        unsafe {
+            return llvm::LLVMGetUndef(t);
+        }
+    }
     return ArrayAlloca(
         base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), t, v);
 }
@@ -1389,10 +1520,12 @@ fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef {
 // Creates the standard set of basic blocks for a function
 fn mk_standard_basic_blocks(llfn: ValueRef) ->
    {sa: BasicBlockRef, rt: BasicBlockRef} {
-    {sa: str::as_c_str(~"static_allocas",
-                       |buf| llvm::LLVMAppendBasicBlock(llfn, buf)),
-     rt: str::as_c_str(~"return",
-                       |buf| llvm::LLVMAppendBasicBlock(llfn, buf))}
+    unsafe {
+        {sa: str::as_c_str(~"static_allocas",
+                           |buf| llvm::LLVMAppendBasicBlock(llfn, buf)),
+         rt: str::as_c_str(~"return",
+                           |buf| llvm::LLVMAppendBasicBlock(llfn, buf))}
+    }
 }
 
 
@@ -1403,16 +1536,17 @@ fn mk_standard_basic_blocks(llfn: ValueRef) ->
 //  - new_fn_ctxt
 //  - trans_args
 fn new_fn_ctxt_w_id(ccx: @crate_ctxt,
-                    path: path,
+                    +path: path,
                     llfndecl: ValueRef,
                     id: ast::node_id,
                     impl_id: Option<ast::def_id>,
-                    param_substs: Option<param_substs>,
+                    +param_substs: Option<param_substs>,
                     sp: Option<span>) -> fn_ctxt {
     let llbbs = mk_standard_basic_blocks(llfndecl);
-    return @{llfn: llfndecl,
-          llenv: llvm::LLVMGetParam(llfndecl, 1u as c_uint),
-          llretptr: llvm::LLVMGetParam(llfndecl, 0u as c_uint),
+    return @fn_ctxt_ {
+          llfn: llfndecl,
+          llenv: unsafe { llvm::LLVMGetParam(llfndecl, 1u as c_uint) },
+          llretptr: unsafe { llvm::LLVMGetParam(llfndecl, 0u as c_uint) },
           mut llstaticallocas: llbbs.sa,
           mut llloadenv: None,
           mut llreturn: llbbs.rt,
@@ -1427,11 +1561,15 @@ fn new_fn_ctxt_w_id(ccx: @crate_ctxt,
           param_substs: param_substs,
           span: sp,
           path: path,
-          ccx: ccx};
+          ccx: ccx
+    };
 }
 
-fn new_fn_ctxt(ccx: @crate_ctxt, path: path, llfndecl: ValueRef,
-               sp: Option<span>) -> fn_ctxt {
+fn new_fn_ctxt(ccx: @crate_ctxt,
+               +path: path,
+               llfndecl: ValueRef,
+               sp: Option<span>)
+            -> fn_ctxt {
     return new_fn_ctxt_w_id(ccx, path, llfndecl, -1, None, None, sp);
 }
 
@@ -1475,8 +1613,10 @@ fn create_llargs_for_fn_args(cx: fn_ctxt,
     // Return an array containing the ValueRefs that we get from
     // llvm::LLVMGetParam for each argument.
     vec::from_fn(args.len(), |i| {
-        let arg_n = first_real_arg + i;
-        llvm::LLVMGetParam(cx.llfn, arg_n as c_uint)
+        unsafe {
+            let arg_n = first_real_arg + i;
+            llvm::LLVMGetParam(cx.llfn, arg_n as c_uint)
+        }
     })
 }
 
@@ -1540,11 +1680,11 @@ fn copy_args_to_allocas(fcx: fn_ctxt,
             }
         }
 
-        bcx = alt::bind_irrefutable_pat(bcx,
-                                        args[arg_n].pat,
-                                        llarg,
-                                        false,
-                                        alt::BindArgument);
+        bcx = _match::bind_irrefutable_pat(bcx,
+                                          args[arg_n].pat,
+                                          llarg,
+                                          false,
+                                          _match::BindArgument);
 
         fcx.llargs.insert(arg_id, local_mem(llarg));
 
@@ -1583,10 +1723,13 @@ enum self_arg { impl_self(ty::t), impl_owned_self(ty::t), no_self, }
 // trans_closure: Builds an LLVM function out of a source function.
 // If the function closes over its environment a closure will be
 // returned.
-fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
-                 body: ast::blk, llfndecl: ValueRef,
+fn trans_closure(ccx: @crate_ctxt,
+                 +path: path,
+                 decl: ast::fn_decl,
+                 body: ast::blk,
+                 llfndecl: ValueRef,
                  ty_self: self_arg,
-                 param_substs: Option<param_substs>,
+                 +param_substs: Option<param_substs>,
                  id: ast::node_id,
                  impl_id: Option<ast::def_id>,
                  maybe_load_env: fn(fn_ctxt),
@@ -1598,12 +1741,15 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
     // Set up arguments to the function.
     let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, id, impl_id, param_substs,
                                   Some(body.span));
-    let raw_llargs = create_llargs_for_fn_args(fcx, ty_self, decl.inputs);
+    let raw_llargs = create_llargs_for_fn_args(fcx, ty_self,
+                                               /*bad*/copy decl.inputs);
 
     // Set GC for function.
     if ccx.sess.opts.gc {
         do str::as_c_str("generic") |strategy| {
-            llvm::LLVMSetGC(fcx.llfn, strategy);
+            unsafe {
+                llvm::LLVMSetGC(fcx.llfn, strategy);
+            }
         }
         ccx.uses_gc = true;
     }
@@ -1642,12 +1788,12 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
 // trans_fn: creates an LLVM function corresponding to a source language
 // function.
 fn trans_fn(ccx: @crate_ctxt,
-            path: path,
+            +path: path,
             decl: ast::fn_decl,
             body: ast::blk,
             llfndecl: ValueRef,
             ty_self: self_arg,
-            param_substs: Option<param_substs>,
+            +param_substs: Option<param_substs>,
             id: ast::node_id,
             impl_id: Option<ast::def_id>) {
     let do_time = ccx.sess.trans_stats();
@@ -1656,7 +1802,8 @@ fn trans_fn(ccx: @crate_ctxt,
     debug!("trans_fn(ty_self=%?)", ty_self);
     let _icx = ccx.insn_ctxt("trans_fn");
     ccx.stats.n_fns += 1;
-    trans_closure(ccx, path, decl, body, llfndecl, ty_self,
+    // XXX: Bad copy of `path`.
+    trans_closure(ccx, copy path, decl, body, llfndecl, ty_self,
                   param_substs, id, impl_id,
                   |fcx| {
                       if ccx.sess.opts.extra_debuginfo {
@@ -1676,7 +1823,7 @@ fn trans_enum_variant(ccx: @crate_ctxt,
                       args: ~[ast::variant_arg],
                       disr: int,
                       is_degen: bool,
-                      param_substs: Option<param_substs>,
+                      +param_substs: Option<param_substs>,
                       llfndecl: ValueRef) {
     let _icx = ccx.insn_ctxt("trans_enum_variant");
     // Translate variant arguments to function arguments.
@@ -1687,11 +1834,13 @@ fn trans_enum_variant(ccx: @crate_ctxt,
                                      ast_util::dummy_sp(),
                                      special_idents::arg),
          id: varg.id});
+    // XXX: Bad copy of `param_substs`.
     let fcx = new_fn_ctxt_w_id(ccx, ~[], llfndecl, variant.node.id, None,
-                               param_substs, None);
-    let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
+                               copy param_substs, None);
+    // XXX: Bad copy.
+    let raw_llargs = create_llargs_for_fn_args(fcx, no_self, copy fn_args);
     let ty_param_substs = match param_substs {
-      Some(substs) => substs.tys,
+      Some(ref substs) => /*bad*/copy substs.tys,
       None => ~[]
     };
     let bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
@@ -1712,7 +1861,7 @@ fn trans_enum_variant(ccx: @crate_ctxt,
     let v_id = local_def(variant.node.id);
     for vec::eachi(args) |i, va| {
         let lldestptr = GEP_enum(bcx, llblobptr, t_id, v_id,
-                                 ty_param_substs, i);
+                                 /*bad*/copy ty_param_substs, i);
         // If this argument to this function is a enum, it'll have come in to
         // this function as an opaque blob due to the way that type_of()
         // works. So we have to cast to the destination's view of the type.
@@ -1732,7 +1881,7 @@ fn trans_enum_variant(ccx: @crate_ctxt,
 fn trans_tuple_struct(ccx: @crate_ctxt,
                       fields: ~[@ast::struct_field],
                       ctor_id: ast::node_id,
-                      param_substs: Option<param_substs>,
+                      +param_substs: Option<param_substs>,
                       llfndecl: ValueRef) {
     let _icx = ccx.insn_ctxt("trans_tuple_struct");
 
@@ -1750,7 +1899,9 @@ fn trans_tuple_struct(ccx: @crate_ctxt,
 
     let fcx = new_fn_ctxt_w_id(ccx, ~[], llfndecl, ctor_id, None,
                                param_substs, None);
-    let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
+
+    // XXX: Bad copy.
+    let raw_llargs = create_llargs_for_fn_args(fcx, no_self, copy fn_args);
 
     let bcx = top_scope_block(fcx, None);
     let lltop = bcx.llbb;
@@ -1774,11 +1925,14 @@ fn trans_tuple_struct(ccx: @crate_ctxt,
     finish_fn(fcx, lltop);
 }
 
-fn trans_struct_dtor(ccx: @crate_ctxt, path: path,
-    body: ast::blk, dtor_id: ast::node_id,
-    psubsts: Option<param_substs>,
-    hash_id: Option<mono_id>, parent_id: ast::def_id)
-    -> ValueRef {
+fn trans_struct_dtor(ccx: @crate_ctxt,
+                     +path: path,
+                     body: ast::blk,
+                     dtor_id: ast::node_id,
+                     +psubsts: Option<param_substs>,
+                     hash_id: Option<mono_id>,
+                     parent_id: ast::def_id)
+                  -> ValueRef {
   let tcx = ccx.tcx;
   /* Look up the parent class's def_id */
   let mut class_ty = ty::lookup_item_type(tcx, parent_id).ty;
@@ -1791,7 +1945,8 @@ fn trans_struct_dtor(ccx: @crate_ctxt, path: path,
      and returns () */
   let lldty = type_of_dtor(ccx, class_ty);
 
-  let s = get_dtor_symbol(ccx, path, dtor_id, psubsts);
+  // XXX: Bad copies.
+  let s = get_dtor_symbol(ccx, copy path, dtor_id, copy psubsts);
 
   /* Register the dtor as a function. It has external linkage */
   let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, lldty);
@@ -1817,23 +1972,23 @@ fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def,
         *i += 1;
 
         match variant.node.kind {
-            ast::tuple_variant_kind(args) if args.len() > 0 => {
+            ast::tuple_variant_kind(ref args) if args.len() > 0 => {
                 let llfn = get_item_val(ccx, variant.node.id);
-                trans_enum_variant(ccx, id, *variant, args, disr_val,
-                                   degen, None, llfn);
+                trans_enum_variant(ccx, id, *variant, /*bad*/copy *args,
+                                   disr_val, degen, None, llfn);
             }
             ast::tuple_variant_kind(_) => {
                 // Nothing to do.
             }
             ast::struct_variant_kind(struct_def) => {
-                trans_struct_def(ccx, struct_def, tps, path,
+                trans_struct_def(ccx, struct_def, /*bad*/copy tps, path,
                                  variant.node.id);
             }
             ast::enum_variant_kind(ref enum_definition) => {
                 trans_enum_def(ccx,
                                *enum_definition,
                                id,
-                               tps,
+                               /*bad*/copy tps,
                                degen,
                                path,
                                vi,
@@ -1850,24 +2005,26 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
         // tjc: ?
         _ => fail ~"trans_item",
     };
-    match item.node {
-      ast::item_fn(decl, purity, tps, ref body) => {
+    match /*bad*/copy item.node {
+      // XXX: Bad copies.
+      ast::item_fn(copy decl, purity, copy tps, ref body) => {
         if purity == ast::extern_fn  {
             let llfndecl = get_item_val(ccx, item.id);
             foreign::trans_foreign_fn(ccx,
                                      vec::append(
-                                         *path,
+                                         /*bad*/copy *path,
                                          ~[path_name(item.ident)]),
                                      decl, (*body), llfndecl, item.id);
         } else if tps.is_empty() {
             let llfndecl = get_item_val(ccx, item.id);
             trans_fn(ccx,
-                     vec::append(*path, ~[path_name(item.ident)]),
+                     vec::append(/*bad*/copy *path, ~[path_name(item.ident)]),
                      decl, (*body), llfndecl, no_self, None, item.id, None);
         } else {
             for vec::each((*body).node.stmts) |stmt| {
                 match stmt.node {
-                  ast::stmt_decl(@{node: ast::decl_item(i), _}, _) => {
+                  ast::stmt_decl(@ast::spanned { node: ast::decl_item(i),
+                                                 _ }, _) => {
                     trans_item(ccx, *i);
                   }
                   _ => ()
@@ -1876,26 +2033,27 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
         }
       }
       ast::item_impl(tps, _, _, ms) => {
-        meth::trans_impl(ccx, *path, item.ident, ms, tps, None,
+        meth::trans_impl(ccx, /*bad*/copy *path, item.ident, ms, tps, None,
                          item.id);
       }
       ast::item_mod(m) => {
         trans_mod(ccx, m);
       }
-      ast::item_enum(ref enum_definition, tps) => {
+      ast::item_enum(ref enum_definition, ref tps) => {
         if tps.len() == 0u {
             let degen = (*enum_definition).variants.len() == 1u;
             let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
             let mut i = 0;
-            trans_enum_def(ccx, (*enum_definition), item.id, tps, degen, path,
-                           vi, &mut i);
+            trans_enum_def(ccx, (*enum_definition), item.id, /*bad*/copy *tps,
+                           degen, path, vi, &mut i);
         }
       }
       ast::item_const(_, expr) => consts::trans_const(ccx, expr, item.id),
       ast::item_foreign_mod(foreign_mod) => {
         let abi = match attr::foreign_abi(item.attrs) {
           either::Right(abi_) => abi_,
-          either::Left(ref msg) => ccx.sess.span_fatal(item.span, (*msg))
+          either::Left(ref msg) => ccx.sess.span_fatal(item.span,
+                                                       /*bad*/copy *msg)
         };
         foreign::trans_foreign_mod(ccx, foreign_mod, abi);
       }
@@ -1914,7 +2072,7 @@ fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
     if tps.len() == 0u {
         // Translate the destructor.
         do option::iter(&struct_def.dtor) |dtor| {
-            trans_struct_dtor(ccx, *path, dtor.node.body,
+            trans_struct_dtor(ccx, /*bad*/copy *path, dtor.node.body,
                              dtor.node.id, None, None, local_def(id));
         };
 
@@ -1924,8 +2082,8 @@ fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
             // otherwise this is a unit-like struct.
             Some(ctor_id) if struct_def.fields.len() > 0 => {
                 let llfndecl = get_item_val(ccx, ctor_id);
-                trans_tuple_struct(ccx, struct_def.fields, ctor_id, None,
-                                   llfndecl);
+                trans_tuple_struct(ccx, /*bad*/copy struct_def.fields,
+                                   ctor_id, None, llfndecl);
             }
             Some(_) | None => {}
         }
@@ -1949,31 +2107,55 @@ fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef {
     return struct_elt(llpairty, 0u);
 }
 
-fn register_fn(ccx: @crate_ctxt, sp: span, path: path,
-               node_id: ast::node_id) -> ValueRef {
+fn register_fn(ccx: @crate_ctxt,
+               sp: span,
+               +path: path,
+               node_id: ast::node_id,
+               attrs: &[ast::attribute])
+            -> ValueRef {
     let t = ty::node_id_to_type(ccx.tcx, node_id);
-    register_fn_full(ccx, sp, path, node_id, t)
+    register_fn_full(ccx, sp, path, node_id, attrs, t)
 }
 
-fn register_fn_full(ccx: @crate_ctxt, sp: span, path: path,
-                    node_id: ast::node_id, node_type: ty::t) -> ValueRef {
+fn register_fn_full(ccx: @crate_ctxt,
+                    sp: span,
+                    +path: path,
+                    node_id: ast::node_id,
+                    attrs: &[ast::attribute],
+                    node_type: ty::t)
+                 -> ValueRef {
     let llfty = type_of_fn_from_ty(ccx, node_type);
-    register_fn_fuller(ccx, sp, path, node_id, node_type,
+    register_fn_fuller(ccx, sp, path, node_id, attrs, node_type,
                        lib::llvm::CCallConv, llfty)
 }
 
-fn register_fn_fuller(ccx: @crate_ctxt, sp: span, path: path,
-                      node_id: ast::node_id, node_type: ty::t,
-                      cc: lib::llvm::CallConv, llfty: TypeRef) -> ValueRef {
-    let ps: ~str = mangle_exported_name(ccx, path, node_type);
-    let llfn: ValueRef = decl_fn(ccx.llmod, ps, cc, llfty);
-    ccx.item_symbols.insert(node_id, ps);
-
-    debug!("register_fn_fuller created fn %s for item %d with path %s",
-           val_str(ccx.tn, llfn), node_id,
+fn register_fn_fuller(ccx: @crate_ctxt,
+                      sp: span,
+                      +path: path,
+                      node_id: ast::node_id,
+                      attrs: &[ast::attribute],
+                      node_type: ty::t,
+                      cc: lib::llvm::CallConv,
+                      llfty: TypeRef)
+                   -> ValueRef {
+    debug!("register_fn_fuller creating fn for item %d with path %s",
+           node_id,
            ast_map::path_to_str(path, ccx.sess.parse_sess.interner));
 
-    let is_main = is_main_name(path) && !ccx.sess.building_library;
+    let ps = if attr::attrs_contains_name(attrs, "no_mangle") {
+        path_elt_to_str(path.last(), ccx.sess.parse_sess.interner)
+    } else {
+        mangle_exported_name(ccx, /*bad*/copy path, node_type)
+    };
+
+    // XXX: Bad copy.
+    let llfn: ValueRef = decl_fn(ccx.llmod, copy ps, cc, llfty);
+    ccx.item_symbols.insert(node_id, ps);
+
+    // FIXME #4404 android JNI hacks
+    let is_main = is_main_name(path) && (!ccx.sess.building_library ||
+                      (ccx.sess.building_library &&
+                       ccx.sess.targ_cfg.os == session::os_android));
     if is_main { create_main_wrapper(ccx, sp, llfn); }
     llfn
 }
@@ -2007,8 +2189,8 @@ fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef) -> ValueRef {
         let lltop = bcx.llbb;
 
         // Call main.
-        let lloutputarg = llvm::LLVMGetParam(llfdecl, 0 as c_uint);
-        let llenvarg = llvm::LLVMGetParam(llfdecl, 1 as c_uint);
+        let lloutputarg = unsafe { llvm::LLVMGetParam(llfdecl, 0 as c_uint) };
+        let llenvarg = unsafe { llvm::LLVMGetParam(llfdecl, 1 as c_uint) };
         let mut args = ~[lloutputarg, llenvarg];
         Call(bcx, main_llfn, args);
 
@@ -2023,24 +2205,44 @@ fn create_entry_fn(ccx: @crate_ctxt, rust_main: ValueRef) {
         #[cfg(unix)]
         fn main_name() -> ~str { return ~"main"; }
         let llfty = T_fn(~[ccx.int_type, ccx.int_type], ccx.int_type);
-        let llfn = decl_cdecl_fn(ccx.llmod, main_name(), llfty);
+
+        // FIXME #4404 android JNI hacks
+        let llfn = if ccx.sess.building_library {
+            decl_cdecl_fn(ccx.llmod, ~"amain", llfty)
+        } else {
+            decl_cdecl_fn(ccx.llmod, main_name(), llfty)
+        };
         let llbb = str::as_c_str(~"top", |buf| {
-            llvm::LLVMAppendBasicBlock(llfn, buf)
+            unsafe {
+                llvm::LLVMAppendBasicBlock(llfn, buf)
+            }
         });
         let bld = ccx.builder.B;
-        llvm::LLVMPositionBuilderAtEnd(bld, llbb);
+        unsafe {
+            llvm::LLVMPositionBuilderAtEnd(bld, llbb);
+        }
         let crate_map = ccx.crate_map;
         let start_ty = T_fn(~[val_ty(rust_main), ccx.int_type, ccx.int_type,
                              val_ty(crate_map)], ccx.int_type);
         let start = decl_cdecl_fn(ccx.llmod, ~"rust_start", start_ty);
 
-        let args = ~[rust_main, llvm::LLVMGetParam(llfn, 0 as c_uint),
-                    llvm::LLVMGetParam(llfn, 1 as c_uint), crate_map];
+        let args = if ccx.sess.building_library unsafe {
+            ~[rust_main,
+              llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
+              llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
+              crate_map]
+        } else unsafe {
+            ~[rust_main, llvm::LLVMGetParam(llfn, 0 as c_uint),
+              llvm::LLVMGetParam(llfn, 1 as c_uint), crate_map]
+        };
+
         let result = unsafe {
             llvm::LLVMBuildCall(bld, start, vec::raw::to_ptr(args),
                                 args.len() as c_uint, noname())
         };
-        llvm::LLVMBuildRet(bld, result);
+        unsafe {
+            llvm::LLVMBuildRet(bld, result);
+        }
     }
 }
 
@@ -2056,7 +2258,7 @@ fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef,
 
 fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path {
     vec::append(
-        *match ccx.tcx.items.get(i.id) {
+        /*bad*/copy *match ccx.tcx.items.get(i.id) {
             ast_map::node_item(_, p) => p,
                 // separate map for paths?
             _ => fail ~"item_path"
@@ -2066,17 +2268,21 @@ fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path {
 
 /* If there's already a symbol for the dtor with <id> and substs <substs>,
    return it; otherwise, create one and register it, returning it as well */
-fn get_dtor_symbol(ccx: @crate_ctxt, path: path, id: ast::node_id,
-                   substs: Option<param_substs>) -> ~str {
+fn get_dtor_symbol(ccx: @crate_ctxt,
+                   +path: path,
+                   id: ast::node_id,
+                   +substs: Option<param_substs>)
+                -> ~str {
   let t = ty::node_id_to_type(ccx.tcx, id);
   match ccx.item_symbols.find(id) {
-     Some(ref s) => (*s),
+     Some(ref s) => (/*bad*/copy *s),
      None if substs.is_none() => {
        let s = mangle_exported_name(
            ccx,
            vec::append(path, ~[path_name((ccx.names)(~"dtor"))]),
            t);
-       ccx.item_symbols.insert(id, s);
+       // XXX: Bad copy, use `@str`?
+       ccx.item_symbols.insert(id, copy s);
        s
      }
      None   => {
@@ -2110,24 +2316,36 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
         let mut exprt = false;
         let val = match ccx.tcx.items.get(id) {
           ast_map::node_item(i, pth) => {
-            let my_path = vec::append(*pth, ~[path_name(i.ident)]);
+            let my_path = vec::append(/*bad*/copy *pth,
+                                      ~[path_name(i.ident)]);
             match i.node {
-              ast::item_const(_, _) => {
+              ast::item_const(_, expr) => {
                 let typ = ty::node_id_to_type(ccx.tcx, i.id);
                 let s = mangle_exported_name(ccx, my_path, typ);
-                let g = str::as_c_str(s, |buf| {
-                    llvm::LLVMAddGlobal(ccx.llmod, type_of(ccx, typ), buf)
-                });
-                ccx.item_symbols.insert(i.id, s);
-                g
+                // We need the translated value here, because for enums the
+                // LLVM type is not fully determined by the Rust type.
+                let v = consts::const_expr(ccx, expr);
+                ccx.const_values.insert(id, v);
+                unsafe {
+                    let llty = llvm::LLVMTypeOf(v);
+                    let g = str::as_c_str(s, |buf| {
+                        llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
+                    });
+                    ccx.item_symbols.insert(i.id, s);
+                    g
+                }
               }
               ast::item_fn(_, purity, _, _) => {
                 let llfn = if purity != ast::extern_fn {
-                    register_fn(ccx, i.span, my_path, i.id)
+                    register_fn(ccx, i.span, my_path, i.id, i.attrs)
                 } else {
-                    foreign::register_foreign_fn(ccx, i.span, my_path, i.id)
+                    foreign::register_foreign_fn(ccx,
+                                                 i.span,
+                                                 my_path,
+                                                 i.id,
+                                                 i.attrs)
                 };
-                set_inline_hint_if_appr(i.attrs, llfn);
+                set_inline_hint_if_appr(/*bad*/copy i.attrs, llfn);
                 llfn
               }
               _ => fail ~"get_item_val: weird result in table"
@@ -2155,14 +2373,20 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
             match ni.node {
                 ast::foreign_item_fn(*) => {
                     register_fn(ccx, ni.span,
-                                vec::append(*pth, ~[path_name(ni.ident)]),
-                                ni.id)
+                                vec::append(/*bad*/copy *pth,
+                                            ~[path_name(ni.ident)]),
+                                ni.id,
+                                ni.attrs)
                 }
                 ast::foreign_item_const(*) => {
                     let typ = ty::node_id_to_type(ccx.tcx, ni.id);
                     let ident = ccx.sess.parse_sess.interner.get(ni.ident);
                     let g = do str::as_c_str(*ident) |buf| {
-                        llvm::LLVMAddGlobal(ccx.llmod, type_of(ccx, typ), buf)
+                        unsafe {
+                            llvm::LLVMAddGlobal(ccx.llmod,
+                                                type_of(ccx, typ),
+                                                buf)
+                        }
                     };
                     g
                 }
@@ -2178,10 +2402,14 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
             let class_ty = ty::lookup_item_type(tcx, parent_id).ty;
             // This code shouldn't be reached if the class is generic
             assert !ty::type_has_params(class_ty);
-            let lldty = T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(tcx))),
-                    T_ptr(type_of(ccx, class_ty))],
-                                   llvm::LLVMVoidType());
-            let s = get_dtor_symbol(ccx, *pt, dt.node.id, None);
+            let lldty = unsafe {
+                T_fn(~[
+                    T_ptr(type_of(ccx, ty::mk_nil(tcx))),
+                    T_ptr(type_of(ccx, class_ty))
+                ],
+                llvm::LLVMVoidType())
+            };
+            let s = get_dtor_symbol(ccx, /*bad*/copy *pt, dt.node.id, None);
 
             /* Make the declaration for the dtor */
             let llfn = decl_internal_cdecl_fn(ccx.llmod, s, lldty);
@@ -2191,15 +2419,15 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
 
           ast_map::node_variant(ref v, enm, pth) => {
             let llfn;
-            match (*v).node.kind {
+            match /*bad*/copy (*v).node.kind {
                 ast::tuple_variant_kind(args) => {
                     assert args.len() != 0u;
-                    let pth = vec::append(*pth,
+                    let pth = vec::append(/*bad*/copy *pth,
                                           ~[path_name(enm.ident),
                                             path_name((*v).node.name)]);
                     llfn = match enm.node {
                       ast::item_enum(_, _) => {
-                        register_fn(ccx, (*v).span, pth, id)
+                        register_fn(ccx, (*v).span, pth, id, enm.attrs)
                       }
                       _ => fail ~"node_variant, shouldn't happen"
                     };
@@ -2223,8 +2451,11 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
                                        a non-tuple-like struct")
                 }
                 Some(ctor_id) => {
-                    let llfn = register_fn(ccx, struct_item.span,
-                                           *struct_path, ctor_id);
+                    let llfn = register_fn(ccx,
+                                           struct_item.span,
+                                           /*bad*/copy *struct_path,
+                                           ctor_id,
+                                           struct_item.attrs);
                     set_inline_hint(llfn);
                     llfn
                 }
@@ -2247,10 +2478,10 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
 fn register_method(ccx: @crate_ctxt, id: ast::node_id, pth: @ast_map::path,
                 m: @ast::method) -> ValueRef {
     let mty = ty::node_id_to_type(ccx.tcx, id);
-    let pth = vec::append(*pth, ~[path_name((ccx.names)(~"meth")),
+    let pth = vec::append(/*bad*/copy *pth, ~[path_name((ccx.names)(~"meth")),
                                   path_name(m.ident)]);
-    let llfn = register_fn_full(ccx, m.span, pth, id, mty);
-    set_inline_hint_if_appr(m.attrs, llfn);
+    let llfn = register_fn_full(ccx, m.span, pth, id, m.attrs, mty);
+    set_inline_hint_if_appr(/*bad*/copy m.attrs, llfn);
     llfn
 }
 
@@ -2264,16 +2495,23 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
         let mut i = 0;
         let path = item_path(ccx, it);
         for vec::each((*enum_definition).variants) |variant| {
-            let p = vec::append(path, ~[path_name(variant.node.name),
-                                        path_name(special_idents::descrim)]);
+            let p = vec::append(/*bad*/copy path, ~[
+                path_name(variant.node.name),
+                path_name(special_idents::descrim)
+            ]);
             let s = mangle_exported_name(ccx, p, ty::mk_int(ccx.tcx));
             let disr_val = vi[i].disr_val;
-            note_unique_llvm_symbol(ccx, s);
+            // XXX: Bad copy.
+            note_unique_llvm_symbol(ccx, copy s);
             let discrim_gvar = str::as_c_str(s, |buf| {
-                llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
+                unsafe {
+                    llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
+                }
             });
-            llvm::LLVMSetInitializer(discrim_gvar, C_int(ccx, disr_val));
-            llvm::LLVMSetGlobalConstant(discrim_gvar, True);
+            unsafe {
+                llvm::LLVMSetInitializer(discrim_gvar, C_int(ccx, disr_val));
+                llvm::LLVMSetGlobalConstant(discrim_gvar, True);
+            }
             ccx.discrims.insert(
                 local_def(variant.node.id), discrim_gvar);
             ccx.discrim_symbols.insert(variant.node.id, s);
@@ -2285,10 +2523,12 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
 }
 
 fn trans_constants(ccx: @crate_ctxt, crate: @ast::crate) {
-    visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
-        visit_item: |a| trans_constant(ccx, a),
-        ..*visit::default_simple_visitor()
-    }));
+    visit::visit_crate(
+        *crate, (),
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_item: |a| trans_constant(ccx, a),
+            ..*visit::default_simple_visitor()
+        }));
 }
 
 fn vp2i(cx: block, v: ValueRef) -> ValueRef {
@@ -2297,7 +2537,9 @@ fn vp2i(cx: block, v: ValueRef) -> ValueRef {
 }
 
 fn p2i(ccx: @crate_ctxt, v: ValueRef) -> ValueRef {
-    return llvm::LLVMConstPtrToInt(v, ccx.int_type);
+    unsafe {
+        return llvm::LLVMConstPtrToInt(v, ccx.int_type);
+    }
 }
 
 fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
@@ -2420,6 +2662,12 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
                                 T_fn(~[T_i32(), T_i1()], T_i32()));
     let cttz64 = decl_cdecl_fn(llmod, ~"llvm.cttz.i64",
                                 T_fn(~[T_i64(), T_i1()], T_i64()));
+    let bswap16 = decl_cdecl_fn(llmod, ~"llvm.bswap.i16",
+                                T_fn(~[T_i16()], T_i16()));
+    let bswap32 = decl_cdecl_fn(llmod, ~"llvm.bswap.i32",
+                                T_fn(~[T_i32()], T_i32()));
+    let bswap64 = decl_cdecl_fn(llmod, ~"llvm.bswap.i64",
+                                T_fn(~[T_i64()], T_i64()));
 
     let intrinsics = HashMap();
     intrinsics.insert(~"llvm.gcroot", gcroot);
@@ -2472,6 +2720,9 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
     intrinsics.insert(~"llvm.cttz.i16", cttz16);
     intrinsics.insert(~"llvm.cttz.i32", cttz32);
     intrinsics.insert(~"llvm.cttz.i64", cttz64);
+    intrinsics.insert(~"llvm.bswap.i16", bswap16);
+    intrinsics.insert(~"llvm.bswap.i32", bswap32);
+    intrinsics.insert(~"llvm.bswap.i64", bswap64);
 
     return intrinsics;
 }
@@ -2497,92 +2748,6 @@ fn trap(bcx: block) {
     }
 }
 
-fn push_rtcall(ccx: @crate_ctxt, name: ~str, did: ast::def_id) {
-    match ccx.rtcalls.find(name) {
-        Some(existing_did) if did != existing_did => {
-            ccx.sess.fatal(fmt!("multiple definitions for runtime call %s",
-                                name));
-        }
-        Some(_) | None => {
-            ccx.rtcalls.insert(name, did);
-        }
-    }
-}
-
-fn gather_local_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) {
-    visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
-        visit_item: |item| match item.node {
-            ast::item_fn(*) => {
-                let attr_metas = attr::attr_metas(
-                    attr::find_attrs_by_name(item.attrs, ~"rt"));
-                for vec::each(attr_metas) |attr_meta| {
-                    match attr::get_meta_item_list(*attr_meta) {
-                        Some(list) => {
-                            let head = vec::head(list);
-                            let name = attr::get_meta_item_name(head);
-                            push_rtcall(ccx, name, {crate: ast::local_crate,
-                                                    node: item.id});
-                        }
-                        None => ()
-                    }
-                }
-            }
-            _ => ()
-        },
-        ..*visit::default_simple_visitor()
-    }));
-}
-
-fn gather_external_rtcalls(ccx: @crate_ctxt) {
-    do cstore::iter_crate_data(ccx.sess.cstore) |_cnum, cmeta| {
-        let get_crate_data: decoder::GetCrateDataCb = |cnum| {
-            cstore::get_crate_data(ccx.sess.cstore, cnum)
-        };
-        do decoder::each_path(ccx.sess.intr(), cmeta, get_crate_data) |path| {
-            let pathname = path.path_string;
-            match path.def_like {
-              decoder::dl_def(d) => {
-                match d {
-                  ast::def_fn(did, _) => {
-                    // FIXME (#2861): This should really iterate attributes
-                    // like gather_local_rtcalls, but we'll need to
-                    // export attributes in metadata/encoder before we can do
-                    // that.
-                    let sentinel = ~"rt::rt_";
-                    let slen = str::len(sentinel);
-                    if str::starts_with(pathname, sentinel) {
-                        let name = str::substr(pathname,
-                                               slen, str::len(pathname)-slen);
-                        push_rtcall(ccx, name, did);
-                    }
-                  }
-                  _ => ()
-                }
-              }
-              _ => ()
-            }
-            true
-        }
-    }
-}
-
-fn gather_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) {
-    gather_local_rtcalls(ccx, crate);
-    gather_external_rtcalls(ccx);
-
-    // FIXME (#2861): Check for other rtcalls too, once they are
-    // supported. Also probably want to check type signature so we don't crash
-    // in some obscure place in LLVM if the user provides the wrong signature
-    // for an rtcall.
-    let expected_rtcalls =
-        ~[~"exchange_free", ~"exchange_malloc", ~"fail_", ~"free", ~"malloc"];
-    for vec::each(expected_rtcalls) |name| {
-        if !ccx.rtcalls.contains_key(*name) {
-            fail fmt!("no definition for runtime call %s", *name);
-        }
-    }
-}
-
 fn decl_gc_metadata(ccx: @crate_ctxt, llmod_id: ~str) {
     if !ccx.sess.opts.gc || !ccx.uses_gc {
         return;
@@ -2590,20 +2755,28 @@ fn decl_gc_metadata(ccx: @crate_ctxt, llmod_id: ~str) {
 
     let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id;
     let gc_metadata = do str::as_c_str(gc_metadata_name) |buf| {
-        llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
+        unsafe {
+            llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
+        }
     };
-    llvm::LLVMSetGlobalConstant(gc_metadata, True);
-    lib::llvm::SetLinkage(gc_metadata, lib::llvm::ExternalLinkage);
-    ccx.module_data.insert(~"_gc_module_metadata", gc_metadata);
+    unsafe {
+        llvm::LLVMSetGlobalConstant(gc_metadata, True);
+        lib::llvm::SetLinkage(gc_metadata, lib::llvm::ExternalLinkage);
+        ccx.module_data.insert(~"_gc_module_metadata", gc_metadata);
+    }
 }
 
 fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
     let elttype = T_struct(~[ccx.int_type, ccx.int_type]);
     let maptype = T_array(elttype, ccx.module_data.size() + 1u);
     let map = str::as_c_str(~"_rust_mod_map", |buf| {
-        llvm::LLVMAddGlobal(ccx.llmod, maptype, buf)
+        unsafe {
+            llvm::LLVMAddGlobal(ccx.llmod, maptype, buf)
+        }
     });
-    lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage);
+    unsafe {
+        lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage);
+    }
     let mut elts: ~[ValueRef] = ~[];
     for ccx.module_data.each |key, val| {
         let elt = C_struct(~[p2i(ccx, C_cstr(ccx, key)),
@@ -2612,7 +2785,9 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
     }
     let term = C_struct(~[C_int(ccx, 0), C_int(ccx, 0)]);
     elts.push(term);
-    llvm::LLVMSetInitializer(map, C_array(elttype, elts));
+    unsafe {
+        llvm::LLVMSetInitializer(map, C_array(elttype, elts));
+    }
     return map;
 }
 
@@ -2631,7 +2806,9 @@ fn decl_crate_map(sess: session::Session, mapmeta: link_meta,
     let arrtype = T_array(int_type, n_subcrates as uint);
     let maptype = T_struct(~[T_i32(), T_ptr(T_i8()), int_type, arrtype]);
     let map = str::as_c_str(sym_name, |buf| {
-        llvm::LLVMAddGlobal(llmod, maptype, buf)
+        unsafe {
+            llvm::LLVMAddGlobal(llmod, maptype, buf)
+        }
     });
     lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
     return map;
@@ -2647,7 +2824,9 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
             ~"_" + cstore::get_crate_vers(cstore, i) +
             ~"_" + cstore::get_crate_hash(cstore, i);
         let cr = str::as_c_str(nm, |buf| {
-            llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
+            unsafe {
+                llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
+            }
         });
         subcrates.push(p2i(ccx, cr));
         i += 1;
@@ -2655,7 +2834,7 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
     subcrates.push(C_int(ccx, 0));
 
     let llannihilatefn;
-    let annihilate_def_id = ccx.tcx.lang_items.annihilate_fn.get();
+    let annihilate_def_id = ccx.tcx.lang_items.annihilate_fn();
     if annihilate_def_id.crate == ast::local_crate {
         llannihilatefn = get_item_val(ccx, annihilate_def_id.node);
     } else {
@@ -2666,19 +2845,20 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
                                              annihilate_fn_type);
     }
 
-    llvm::LLVMSetInitializer(map, C_struct(
-        ~[C_i32(1),
-          lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn,
-                                                T_ptr(T_i8())),
-          p2i(ccx, create_module_map(ccx)),
-          C_array(ccx.int_type, subcrates)]));
+    unsafe {
+        llvm::LLVMSetInitializer(map, C_struct(
+            ~[C_i32(1),
+              lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn,
+                                                    T_ptr(T_i8())),
+              p2i(ccx, create_module_map(ccx)),
+              C_array(ccx.int_type, subcrates)]));
+    }
 }
 
-fn crate_ctxt_to_encode_parms(cx: @crate_ctxt)
-    -> encoder::encode_parms {
-
+fn crate_ctxt_to_encode_parms(cx: @crate_ctxt) -> encoder::encode_parms {
+    // XXX: Bad copy of `c`, whatever it is.
     let encode_inlined_item =
-        |a,b,c,d| astencode::encode_inlined_item(a, b, c, d, cx.maps);
+        |a,b,c,d| astencode::encode_inlined_item(a, b, copy c, d, cx.maps);
 
     return {
         diag: cx.sess.diagnostic(),
@@ -2687,7 +2867,7 @@ fn crate_ctxt_to_encode_parms(cx: @crate_ctxt)
         reexports2: cx.exp_map2,
         item_symbols: cx.item_symbols,
         discrim_symbols: cx.discrim_symbols,
-        link_meta: cx.link_meta,
+        link_meta: /*bad*/copy cx.link_meta,
         cstore: cx.sess.cstore,
         encode_inlined_item: encode_inlined_item
     };
@@ -2699,21 +2879,25 @@ fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) {
     let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate));
     let llconst = C_struct(~[llmeta]);
     let mut llglobal = str::as_c_str(~"rust_metadata", |buf| {
-        llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf)
-    });
-    llvm::LLVMSetInitializer(llglobal, llconst);
-    str::as_c_str(cx.sess.targ_cfg.target_strs.meta_sect_name, |buf| {
-        llvm::LLVMSetSection(llglobal, buf)
+        unsafe {
+            llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf)
+        }
     });
-    lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
+    unsafe {
+        llvm::LLVMSetInitializer(llglobal, llconst);
+        str::as_c_str(cx.sess.targ_cfg.target_strs.meta_sect_name, |buf| {
+            llvm::LLVMSetSection(llglobal, buf)
+        });
+        lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
 
-    let t_ptr_i8 = T_ptr(T_i8());
-    llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8);
-    let llvm_used = str::as_c_str(~"llvm.used", |buf| {
-        llvm::LLVMAddGlobal(cx.llmod, T_array(t_ptr_i8, 1u), buf)
-    });
-    lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
-    llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, ~[llglobal]));
+        let t_ptr_i8 = T_ptr(T_i8());
+        llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8);
+        let llvm_used = str::as_c_str(~"llvm.used", |buf| {
+            llvm::LLVMAddGlobal(cx.llmod, T_array(t_ptr_i8, 1u), buf)
+        });
+        lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
+        llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, ~[llglobal]));
+    }
 }
 
 // Writes the current ABI version into the crate.
@@ -2746,143 +2930,142 @@ fn trans_crate(sess: session::Session,
     // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
     let llmod_id = link_meta.name + ~".rc";
 
-    let llmod = str::as_c_str(llmod_id, |buf| {
-        llvm::LLVMModuleCreateWithNameInContext
-            (buf, llvm::LLVMGetGlobalContext())
-    });
-    let data_layout = sess.targ_cfg.target_strs.data_layout;
-    let targ_triple = sess.targ_cfg.target_strs.target_triple;
-    let _: () =
-        str::as_c_str(data_layout,
-                    |buf| llvm::LLVMSetDataLayout(llmod, buf));
-    let _: () =
-        str::as_c_str(targ_triple,
-                    |buf| llvm::LLVMSetTarget(llmod, buf));
-    let targ_cfg = sess.targ_cfg;
-    let td = mk_target_data(sess.targ_cfg.target_strs.data_layout);
-    let tn = mk_type_names();
-    let intrinsics = declare_intrinsics(llmod);
-    if sess.opts.extra_debuginfo {
-        declare_dbg_intrinsics(llmod, intrinsics);
-    }
-    let int_type = T_int(targ_cfg);
-    let float_type = T_float(targ_cfg);
-    let task_type = T_task(targ_cfg);
-    let taskptr_type = T_ptr(task_type);
-    lib::llvm::associate_type(tn, ~"taskptr", taskptr_type);
-    let tydesc_type = T_tydesc(targ_cfg);
-    lib::llvm::associate_type(tn, ~"tydesc", tydesc_type);
-    let crate_map = decl_crate_map(sess, link_meta, llmod);
-    let dbg_cx = if sess.opts.debuginfo {
-        option::Some(debuginfo::mk_ctxt(llmod_id, sess.parse_sess.interner))
-    } else {
-        option::None
-    };
+    unsafe {
+        let llmod = str::as_c_str(llmod_id, |buf| {
+            llvm::LLVMModuleCreateWithNameInContext
+                (buf, llvm::LLVMGetGlobalContext())
+        });
+        let data_layout = /*bad*/copy sess.targ_cfg.target_strs.data_layout;
+        let targ_triple = /*bad*/copy sess.targ_cfg.target_strs.target_triple;
+        let _: () =
+            str::as_c_str(data_layout,
+                        |buf| llvm::LLVMSetDataLayout(llmod, buf));
+        let _: () =
+            str::as_c_str(targ_triple,
+                        |buf| llvm::LLVMSetTarget(llmod, buf));
+        let targ_cfg = sess.targ_cfg;
+        let td = mk_target_data(
+            /*bad*/copy sess.targ_cfg.target_strs.data_layout);
+        let tn = mk_type_names();
+        let intrinsics = declare_intrinsics(llmod);
+        if sess.opts.extra_debuginfo {
+            declare_dbg_intrinsics(llmod, intrinsics);
+        }
+        let int_type = T_int(targ_cfg);
+        let float_type = T_float(targ_cfg);
+        let task_type = T_task(targ_cfg);
+        let taskptr_type = T_ptr(task_type);
+        lib::llvm::associate_type(tn, ~"taskptr", taskptr_type);
+        let tydesc_type = T_tydesc(targ_cfg);
+        lib::llvm::associate_type(tn, ~"tydesc", tydesc_type);
+        let crate_map = decl_crate_map(sess, link_meta, llmod);
+        let dbg_cx = if sess.opts.debuginfo {
+            Some(debuginfo::mk_ctxt(copy llmod_id, sess.parse_sess.interner))
+        } else {
+            None
+        };
 
-    let ccx =
-        @{sess: sess,
-          llmod: llmod,
-          td: td,
-          tn: tn,
-          externs: HashMap(),
-          intrinsics: intrinsics,
-          item_vals: HashMap(),
-          exp_map2: emap2,
-          reachable: reachable,
-          item_symbols: HashMap(),
-          mut main_fn: None::<ValueRef>,
-          link_meta: link_meta,
-          enum_sizes: ty::new_ty_hash(),
-          discrims: HashMap(),
-          discrim_symbols: HashMap(),
-          tydescs: ty::new_ty_hash(),
-          mut finished_tydescs: false,
-          external: HashMap(),
-          monomorphized: HashMap(),
-          monomorphizing: HashMap(),
-          type_use_cache: HashMap(),
-          vtables: map::HashMap(),
-          const_cstr_cache: HashMap(),
-          const_globals: HashMap(),
-          const_values: HashMap(),
-          module_data: HashMap(),
-          lltypes: ty::new_ty_hash(),
-          names: new_namegen(sess.parse_sess.interner),
-          next_addrspace: new_addrspace_gen(),
-          symbol_hasher: symbol_hasher,
-          type_hashcodes: ty::new_ty_hash(),
-          type_short_names: ty::new_ty_hash(),
-          all_llvm_symbols: HashMap(),
-          tcx: tcx,
-          maps: maps,
-          stats:
-              {mut n_static_tydescs: 0u,
-               mut n_glues_created: 0u,
-               mut n_null_glues: 0u,
-               mut n_real_glues: 0u,
-               mut n_fns: 0u,
-               mut n_monos: 0u,
-               mut n_inlines: 0u,
-               mut n_closures: 0u,
-               llvm_insn_ctxt: @mut ~[],
-               llvm_insns: HashMap(),
-               fn_times: @mut ~[]},
-          upcalls:
-              upcall::declare_upcalls(targ_cfg, llmod),
-          rtcalls: HashMap(),
-          tydesc_type: tydesc_type,
-          int_type: int_type,
-          float_type: float_type,
-          task_type: task_type,
-          opaque_vec_type: T_opaque_vec(targ_cfg),
-          builder: BuilderRef_res(llvm::LLVMCreateBuilder()),
-          shape_cx: mk_ctxt(llmod),
-          crate_map: crate_map,
-          mut uses_gc: false,
-          dbg_cx: dbg_cx,
-          mut do_not_commit_warning_issued: false};
-
-
-    gather_rtcalls(ccx, crate);
+        let ccx = @crate_ctxt {
+              sess: sess,
+              llmod: llmod,
+              td: td,
+              tn: tn,
+              externs: HashMap(),
+              intrinsics: intrinsics,
+              item_vals: HashMap(),
+              exp_map2: emap2,
+              reachable: reachable,
+              item_symbols: HashMap(),
+              mut main_fn: None::<ValueRef>,
+              link_meta: copy link_meta,    // XXX: Bad copy.
+              enum_sizes: ty::new_ty_hash(),
+              discrims: HashMap(),
+              discrim_symbols: HashMap(),
+              tydescs: ty::new_ty_hash(),
+              mut finished_tydescs: false,
+              external: HashMap(),
+              monomorphized: HashMap(),
+              monomorphizing: HashMap(),
+              type_use_cache: HashMap(),
+              vtables: map::HashMap(),
+              const_cstr_cache: HashMap(),
+              const_globals: HashMap(),
+              const_values: HashMap(),
+              module_data: HashMap(),
+              lltypes: ty::new_ty_hash(),
+              names: new_namegen(sess.parse_sess.interner),
+              next_addrspace: new_addrspace_gen(),
+              symbol_hasher: symbol_hasher,
+              type_hashcodes: ty::new_ty_hash(),
+              type_short_names: ty::new_ty_hash(),
+              all_llvm_symbols: HashMap(),
+              tcx: tcx,
+              maps: maps,
+              stats:
+                  {mut n_static_tydescs: 0u,
+                   mut n_glues_created: 0u,
+                   mut n_null_glues: 0u,
+                   mut n_real_glues: 0u,
+                   mut n_fns: 0u,
+                   mut n_monos: 0u,
+                   mut n_inlines: 0u,
+                   mut n_closures: 0u,
+                   llvm_insn_ctxt: @mut ~[],
+                   llvm_insns: HashMap(),
+                   fn_times: @mut ~[]},
+              upcalls: upcall::declare_upcalls(targ_cfg, llmod),
+              tydesc_type: tydesc_type,
+              int_type: int_type,
+              float_type: float_type,
+              task_type: task_type,
+              opaque_vec_type: T_opaque_vec(targ_cfg),
+              builder: BuilderRef_res(unsafe { llvm::LLVMCreateBuilder() }),
+              shape_cx: mk_ctxt(llmod),
+              crate_map: crate_map,
+              mut uses_gc: false,
+              dbg_cx: dbg_cx,
+              mut do_not_commit_warning_issued: false
+        };
 
-    {
-        let _icx = ccx.insn_ctxt("data");
-        trans_constants(ccx, crate);
-    }
+        {
+            let _icx = ccx.insn_ctxt("data");
+            trans_constants(ccx, crate);
+        }
 
-    {
-        let _icx = ccx.insn_ctxt("text");
-        trans_mod(ccx, crate.node.module);
-    }
-
-    decl_gc_metadata(ccx, llmod_id);
-    fill_crate_map(ccx, crate_map);
-    glue::emit_tydescs(ccx);
-    write_abi_version(ccx);
-
-    // Translate the metadata.
-    write_metadata(ccx, crate);
-    if ccx.sess.trans_stats() {
-        io::println(~"--- trans stats ---");
-        io::println(fmt!("n_static_tydescs: %u",
-                         ccx.stats.n_static_tydescs));
-        io::println(fmt!("n_glues_created: %u",
-                         ccx.stats.n_glues_created));
-        io::println(fmt!("n_null_glues: %u", ccx.stats.n_null_glues));
-        io::println(fmt!("n_real_glues: %u", ccx.stats.n_real_glues));
-
-        io::println(fmt!("n_fns: %u", ccx.stats.n_fns));
-        io::println(fmt!("n_monos: %u", ccx.stats.n_monos));
-        io::println(fmt!("n_inlines: %u", ccx.stats.n_inlines));
-        io::println(fmt!("n_closures: %u", ccx.stats.n_closures));
-    }
-
-    if ccx.sess.count_llvm_insns() {
-        for ccx.stats.llvm_insns.each |k, v| {
-            io::println(fmt!("%-7u %s", v, k));
+        {
+            let _icx = ccx.insn_ctxt("text");
+            trans_mod(ccx, crate.node.module);
+        }
+
+        decl_gc_metadata(ccx, llmod_id);
+        fill_crate_map(ccx, crate_map);
+        glue::emit_tydescs(ccx);
+        write_abi_version(ccx);
+
+        // Translate the metadata.
+        write_metadata(ccx, crate);
+        if ccx.sess.trans_stats() {
+            io::println(~"--- trans stats ---");
+            io::println(fmt!("n_static_tydescs: %u",
+                             ccx.stats.n_static_tydescs));
+            io::println(fmt!("n_glues_created: %u",
+                             ccx.stats.n_glues_created));
+            io::println(fmt!("n_null_glues: %u", ccx.stats.n_null_glues));
+            io::println(fmt!("n_real_glues: %u", ccx.stats.n_real_glues));
+
+            io::println(fmt!("n_fns: %u", ccx.stats.n_fns));
+            io::println(fmt!("n_monos: %u", ccx.stats.n_monos));
+            io::println(fmt!("n_inlines: %u", ccx.stats.n_inlines));
+            io::println(fmt!("n_closures: %u", ccx.stats.n_closures));
+        }
+
+        if ccx.sess.count_llvm_insns() {
+            for ccx.stats.llvm_insns.each |k, v| {
+                io::println(fmt!("%-7u %s", v, k));
+            }
         }
+        return (llmod, link_meta);
     }
-    return (llmod, link_meta);
 }
 //
 // Local Variables:
index 614a02a9700529906fa535f61fe63598b881a271..dcf1b488d6fa7e28f0243c397054a8fd2b555aa4 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 use codemap::span;
 use lib::llvm::llvm;
 use lib::llvm::{CallConv, TypeKind, AtomicBinOp, AtomicOrdering};
 use libc::{c_uint, c_int};
 use middle::trans::common::*;
 
+use core::cast;
+use core::libc;
+use core::str;
+use core::vec;
 use std::map::HashMap;
 use syntax::codemap;
 
 fn B(cx: block) -> BuilderRef {
-    let b = cx.fcx.ccx.builder.B;
-    llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
-    return b;
+    unsafe {
+        let b = cx.fcx.ccx.builder.B;
+        llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
+        return b;
+    }
 }
 
 fn count_insn(cx: block, category: &str) {
@@ -49,8 +56,8 @@ fn count_insn(cx: block, category: &str) {
         let mut s = ~".";
         i = 0u;
         while i < len {
-            let e = v[i];
-            i = mm.get(e);
+            let e = /*bad*/copy v[i];
+            i = mm.get(/*bad*/ copy e);
             s += ~"/";
             s += e;
             i += 1u;
@@ -77,19 +84,23 @@ fn count_insn(cx: block, category: &str) {
 // further instructions to the block should simply be ignored.
 
 fn RetVoid(cx: block) {
-    if cx.unreachable { return; }
-    assert (!cx.terminated);
-    cx.terminated = true;
-    count_insn(cx, "retvoid");
-    llvm::LLVMBuildRetVoid(B(cx));
+    unsafe {
+        if cx.unreachable { return; }
+        assert (!cx.terminated);
+        cx.terminated = true;
+        count_insn(cx, "retvoid");
+        llvm::LLVMBuildRetVoid(B(cx));
+    }
 }
 
 fn Ret(cx: block, V: ValueRef) {
-    if cx.unreachable { return; }
-    assert (!cx.terminated);
-    cx.terminated = true;
-    count_insn(cx, "ret");
-    llvm::LLVMBuildRet(B(cx), V);
+    unsafe {
+        if cx.unreachable { return; }
+        assert (!cx.terminated);
+        cx.terminated = true;
+        count_insn(cx, "ret");
+        llvm::LLVMBuildRet(B(cx), V);
+    }
 }
 
 fn AggregateRet(cx: block, RetVals: ~[ValueRef]) {
@@ -103,41 +114,51 @@ fn AggregateRet(cx: block, RetVals: ~[ValueRef]) {
 }
 
 fn Br(cx: block, Dest: BasicBlockRef) {
-    if cx.unreachable { return; }
-    assert (!cx.terminated);
-    cx.terminated = true;
-    count_insn(cx, "br");
-    llvm::LLVMBuildBr(B(cx), Dest);
+    unsafe {
+        if cx.unreachable { return; }
+        assert (!cx.terminated);
+        cx.terminated = true;
+        count_insn(cx, "br");
+        llvm::LLVMBuildBr(B(cx), Dest);
+    }
 }
 
 fn CondBr(cx: block, If: ValueRef, Then: BasicBlockRef,
           Else: BasicBlockRef) {
-    if cx.unreachable { return; }
-    assert (!cx.terminated);
-    cx.terminated = true;
-    count_insn(cx, "condbr");
-    llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
+    unsafe {
+        if cx.unreachable { return; }
+        assert (!cx.terminated);
+        cx.terminated = true;
+        count_insn(cx, "condbr");
+        llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
+    }
 }
 
 fn Switch(cx: block, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
     -> ValueRef {
-    if cx.unreachable { return _Undef(V); }
-    assert !cx.terminated;
-    cx.terminated = true;
-    return llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases as c_uint);
+    unsafe {
+        if cx.unreachable { return _Undef(V); }
+        assert !cx.terminated;
+        cx.terminated = true;
+        return llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases as c_uint);
+    }
 }
 
 fn AddCase(S: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef) {
-    if llvm::LLVMIsUndef(S) == lib::llvm::True { return; }
-    llvm::LLVMAddCase(S, OnVal, Dest);
+    unsafe {
+        if llvm::LLVMIsUndef(S) == lib::llvm::True { return; }
+        llvm::LLVMAddCase(S, OnVal, Dest);
+    }
 }
 
 fn IndirectBr(cx: block, Addr: ValueRef, NumDests: uint) {
-    if cx.unreachable { return; }
-    assert (!cx.terminated);
-    cx.terminated = true;
-    count_insn(cx, "indirectbr");
-    llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests as c_uint);
+    unsafe {
+        if cx.unreachable { return; }
+        assert (!cx.terminated);
+        cx.terminated = true;
+        count_insn(cx, "indirectbr");
+        llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests as c_uint);
+    }
 }
 
 // This is a really awful way to get a zero-length c-string, but better (and a
@@ -179,263 +200,342 @@ fn FastInvoke(cx: block, Fn: ValueRef, Args: ~[ValueRef],
 }
 
 fn Unreachable(cx: block) {
-    if cx.unreachable { return; }
-    cx.unreachable = true;
-    if !cx.terminated {
-        count_insn(cx, "unreachable");
-        llvm::LLVMBuildUnreachable(B(cx));
+    unsafe {
+        if cx.unreachable { return; }
+        cx.unreachable = true;
+        if !cx.terminated {
+            count_insn(cx, "unreachable");
+            llvm::LLVMBuildUnreachable(B(cx));
+        }
     }
 }
 
 fn _Undef(val: ValueRef) -> ValueRef {
-    return llvm::LLVMGetUndef(val_ty(val));
+    unsafe {
+        return llvm::LLVMGetUndef(val_ty(val));
+    }
 }
 
 /* Arithmetic */
 fn Add(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "add");
-    return llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "add");
+        return llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn NSWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "nswadd");
-    return llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "nswadd");
+        return llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn NUWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "nuwadd");
-    return llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "nuwadd");
+        return llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn FAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "fadd");
-    return llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "fadd");
+        return llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn Sub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "sub");
-    return llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "sub");
+        return llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn NSWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "nwsub");
-    return llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "nwsub");
+        return llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn NUWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "nuwsub");
-    return llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "nuwsub");
+        return llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn FSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "sub");
-    return llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "sub");
+        return llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn Mul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "mul");
-    return llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "mul");
+        return llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn NSWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "nswmul");
-    return llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "nswmul");
+        return llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn NUWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "nuwmul");
-    return llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "nuwmul");
+        return llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn FMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "fmul");
-    return llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "fmul");
+        return llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn UDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "udiv");
-    return llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "udiv");
+        return llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn SDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "sdiv");
-    return llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "sdiv");
+        return llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn ExactSDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "extractsdiv");
-    return llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "extractsdiv");
+        return llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn FDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "fdiv");
-    return llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "fdiv");
+        return llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn URem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "urem");
-    return llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "urem");
+        return llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn SRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "srem");
-    return llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "srem");
+        return llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn FRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "frem");
-    return llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "frem");
+        return llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn Shl(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "shl");
-    return llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "shl");
+        return llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn LShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "lshr");
-    return llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "lshr");
+        return llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn AShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "ashr");
-    return llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "ashr");
+        return llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn And(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "and");
-    return llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "and");
+        return llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn Or(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "or");
-    return llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "or");
+        return llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn Xor(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "xor");
-    return llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "xor");
+        return llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
+    }
 }
 
-fn BinOp(cx: block, Op: Opcode, LHS: ValueRef, RHS: ValueRef) ->
-   ValueRef {
-    if cx.unreachable { return _Undef(LHS); }
-    count_insn(cx, "binop");
-    return llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
+fn BinOp(cx: block, Op: Opcode, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
+    unsafe {
+        if cx.unreachable { return _Undef(LHS); }
+        count_insn(cx, "binop");
+        return llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
+    }
 }
 
 fn Neg(cx: block, V: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(V); }
-    count_insn(cx, "neg");
-    return llvm::LLVMBuildNeg(B(cx), V, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(V); }
+        count_insn(cx, "neg");
+        return llvm::LLVMBuildNeg(B(cx), V, noname());
+    }
 }
 
 fn NSWNeg(cx: block, V: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(V); }
-    count_insn(cx, "nswneg");
-    return llvm::LLVMBuildNSWNeg(B(cx), V, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(V); }
+        count_insn(cx, "nswneg");
+        return llvm::LLVMBuildNSWNeg(B(cx), V, noname());
+    }
 }
 
 fn NUWNeg(cx: block, V: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(V); }
-    count_insn(cx, "nuwneg");
-    return llvm::LLVMBuildNUWNeg(B(cx), V, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(V); }
+        count_insn(cx, "nuwneg");
+        return llvm::LLVMBuildNUWNeg(B(cx), V, noname());
+    }
 }
 fn FNeg(cx: block, V: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(V); }
-    count_insn(cx, "fneg");
-    return llvm::LLVMBuildFNeg(B(cx), V, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(V); }
+        count_insn(cx, "fneg");
+        return llvm::LLVMBuildFNeg(B(cx), V, noname());
+    }
 }
 
 fn Not(cx: block, V: ValueRef) -> ValueRef {
-    if cx.unreachable { return _Undef(V); }
-    count_insn(cx, "not");
-    return llvm::LLVMBuildNot(B(cx), V, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(V); }
+        count_insn(cx, "not");
+        return llvm::LLVMBuildNot(B(cx), V, noname());
+    }
 }
 
 /* Memory */
 fn Malloc(cx: block, Ty: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
-    count_insn(cx, "malloc");
-    return llvm::LLVMBuildMalloc(B(cx), Ty, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
+        count_insn(cx, "malloc");
+        return llvm::LLVMBuildMalloc(B(cx), Ty, noname());
+    }
 }
 
 fn ArrayMalloc(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
-    count_insn(cx, "arraymalloc");
-    return llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
+        count_insn(cx, "arraymalloc");
+        return llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname());
+    }
 }
 
 fn Alloca(cx: block, Ty: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
-    count_insn(cx, "alloca");
-    return llvm::LLVMBuildAlloca(B(cx), Ty, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
+        count_insn(cx, "alloca");
+        return llvm::LLVMBuildAlloca(B(cx), Ty, noname());
+    }
 }
 
 fn ArrayAlloca(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
-    count_insn(cx, "arrayalloca");
-    return llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
+        count_insn(cx, "arrayalloca");
+        return llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname());
+    }
 }
 
 fn Free(cx: block, PointerVal: ValueRef) {
-    if cx.unreachable { return; }
-    count_insn(cx, "free");
-    llvm::LLVMBuildFree(B(cx), PointerVal);
+    unsafe {
+        if cx.unreachable { return; }
+        count_insn(cx, "free");
+        llvm::LLVMBuildFree(B(cx), PointerVal);
+    }
 }
 
 fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
-    let ccx = cx.fcx.ccx;
-    if cx.unreachable {
-        let ty = val_ty(PointerVal);
-        let eltty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Array {
-            llvm::LLVMGetElementType(ty) } else { ccx.int_type };
-        return llvm::LLVMGetUndef(eltty);
+    unsafe {
+        let ccx = cx.fcx.ccx;
+        if cx.unreachable {
+            let ty = val_ty(PointerVal);
+            let eltty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Array {
+                llvm::LLVMGetElementType(ty) } else { ccx.int_type };
+            return llvm::LLVMGetUndef(eltty);
+        }
+        count_insn(cx, "load");
+        return llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
     }
-    count_insn(cx, "load");
-    return llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
 }
 
 fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
-    if cx.unreachable { return; }
-    debug!("Store %s -> %s",
-           val_str(cx.ccx().tn, Val),
-           val_str(cx.ccx().tn, Ptr));
-    count_insn(cx, "store");
-    llvm::LLVMBuildStore(B(cx), Val, Ptr);
+    unsafe {
+        if cx.unreachable { return; }
+        debug!("Store %s -> %s",
+               val_str(cx.ccx().tn, Val),
+               val_str(cx.ccx().tn, Ptr));
+        count_insn(cx, "store");
+        llvm::LLVMBuildStore(B(cx), Val, Ptr);
+    }
 }
 
 fn GEP(cx: block, Pointer: ValueRef, Indices: ~[ValueRef]) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
     unsafe {
-    count_insn(cx, "gep");
-    return llvm::LLVMBuildGEP(B(cx), Pointer, vec::raw::to_ptr(Indices),
-                               Indices.len() as c_uint, noname());
+        if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
+        count_insn(cx, "gep");
+        return llvm::LLVMBuildGEP(B(cx), Pointer, vec::raw::to_ptr(Indices),
+                                   Indices.len() as c_uint, noname());
     }
 }
 
@@ -451,182 +551,234 @@ fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef {
 
 fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) ->
    ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
     unsafe {
-        count_insn(cx, "inboundsgep");
-    return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer,
-                                       vec::raw::to_ptr(Indices),
-                                       Indices.len() as c_uint,
-                                       noname());
+        if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
+        unsafe {
+            count_insn(cx, "inboundsgep");
+        return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer,
+                                           vec::raw::to_ptr(Indices),
+                                           Indices.len() as c_uint,
+                                           noname());
+        }
     }
 }
 
 fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
-    count_insn(cx, "structgep");
-    return llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx as c_uint, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
+        count_insn(cx, "structgep");
+        return llvm::LLVMBuildStructGEP(B(cx),
+                                        Pointer,
+                                        Idx as c_uint,
+                                        noname());
+    }
 }
 
 fn GlobalString(cx: block, _Str: *libc::c_char) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
-    count_insn(cx, "globalstring");
-    return llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
+        count_insn(cx, "globalstring");
+        return llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
+    }
 }
 
 fn GlobalStringPtr(cx: block, _Str: *libc::c_char) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
-    count_insn(cx, "globalstringptr");
-    return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
+        count_insn(cx, "globalstringptr");
+        return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
+    }
 }
 
 /* Casts */
 fn Trunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "trunc");
-    return llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "trunc");
+        return llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn ZExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "zext");
-    return llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "zext");
+        return llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn SExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "sext");
-    return llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "sext");
+        return llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn FPToUI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "fptoui");
-    return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "fptoui");
+        return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn FPToSI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "fptosi");
-    return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "fptosi");
+        return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn UIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "uitofp");
-    return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "uitofp");
+        return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn SIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "sitofp");
-    return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "sitofp");
+        return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn FPTrunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "fptrunc");
-    return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "fptrunc");
+        return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn FPExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "fpext");
-    return llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "fpext");
+        return llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn PtrToInt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "ptrtoint");
-    return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "ptrtoint");
+        return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn IntToPtr(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "inttoptr");
-    return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "inttoptr");
+        return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn BitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "bitcast");
-    return llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "bitcast");
+        return llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname());
+    }
 }
 
-fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
-   ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "zextorbitcast");
-    return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname());
+fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "zextorbitcast");
+        return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname());
+    }
 }
 
-fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
-   ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "sextorbitcast");
-    return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname());
+fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "sextorbitcast");
+        return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname());
+    }
 }
 
-fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
-   ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "truncorbitcast");
-    return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname());
+fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "truncorbitcast");
+        return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname());
+    }
 }
 
-fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: TypeRef,
-        _Name: *u8) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "cast");
-    return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname());
+fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: TypeRef, _: *u8)
+     -> ValueRef {
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "cast");
+        return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname());
+    }
 }
 
 fn PointerCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "pointercast");
-    return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "pointercast");
+        return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn IntCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "intcast");
-    return llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "intcast");
+        return llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname());
+    }
 }
 
 fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
-    count_insn(cx, "fpcast");
-    return llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
+        count_insn(cx, "fpcast");
+        return llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname());
+    }
 }
 
 
 /* Comparisons */
 fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef)
-    -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
-    count_insn(cx, "icmp");
-    return llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname());
+     -> ValueRef {
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
+        count_insn(cx, "icmp");
+        return llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname());
+    }
 }
 
 fn FCmp(cx: block, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef)
-    -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
-    count_insn(cx, "fcmp");
-    return llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname());
+     -> ValueRef {
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
+        count_insn(cx, "fcmp");
+        return llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname());
+    }
 }
 
 /* Miscellaneous instructions */
 fn EmptyPhi(cx: block, Ty: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
-    count_insn(cx, "emptyphi");
-    return llvm::LLVMBuildPhi(B(cx), Ty, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
+        count_insn(cx, "emptyphi");
+        return llvm::LLVMBuildPhi(B(cx), Ty, noname());
+    }
 }
 
 fn Phi(cx: block, Ty: TypeRef, vals: ~[ValueRef], bbs: ~[BasicBlockRef])
-   -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
-    assert vals.len() == bbs.len();
-    let phi = EmptyPhi(cx, Ty);
+    -> ValueRef {
     unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
+        assert vals.len() == bbs.len();
+        let phi = EmptyPhi(cx, Ty);
         count_insn(cx, "addincoming");
         llvm::LLVMAddIncoming(phi, vec::raw::to_ptr(vals),
                               vec::raw::to_ptr(bbs),
@@ -636,8 +788,8 @@ fn Phi(cx: block, Ty: TypeRef, vals: ~[ValueRef], bbs: ~[BasicBlockRef])
 }
 
 fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
-    if llvm::LLVMIsUndef(phi) == lib::llvm::True { return; }
     unsafe {
+        if llvm::LLVMIsUndef(phi) == lib::llvm::True { return; }
         let valptr = cast::reinterpret_cast(&ptr::addr_of(&val));
         let bbptr = cast::reinterpret_cast(&ptr::addr_of(&bb));
         llvm::LLVMAddIncoming(phi, valptr, bbptr, 1 as c_uint);
@@ -645,12 +797,14 @@ fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
 }
 
 fn _UndefReturn(cx: block, Fn: ValueRef) -> ValueRef {
-    let ccx = cx.fcx.ccx;
-    let ty = val_ty(Fn);
-    let retty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Integer {
-        llvm::LLVMGetReturnType(ty) } else { ccx.int_type };
-        count_insn(cx, ~"");
-    return llvm::LLVMGetUndef(retty);
+    unsafe {
+        let ccx = cx.fcx.ccx;
+        let ty = val_ty(Fn);
+        let retty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Integer {
+            llvm::LLVMGetReturnType(ty) } else { ccx.int_type };
+            count_insn(cx, ~"");
+        return llvm::LLVMGetUndef(retty);
+    }
 }
 
 fn add_span_comment(bcx: block, sp: span, text: ~str) {
@@ -658,24 +812,27 @@ fn add_span_comment(bcx: block, sp: span, text: ~str) {
     if !ccx.sess.no_asm_comments() {
         let s = text + ~" (" + ccx.sess.codemap.span_to_str(sp)
             + ~")";
-        log(debug, s);
+        log(debug, copy s);
         add_comment(bcx, s);
     }
 }
 
 fn add_comment(bcx: block, text: ~str) {
-    let ccx = bcx.ccx();
-    if !ccx.sess.no_asm_comments() {
-        let sanitized = str::replace(text, ~"$", ~"");
-        let comment_text = ~"# " + str::replace(sanitized, ~"\n", ~"\n\t# ");
-        let asm = str::as_c_str(comment_text, |c| {
-            str::as_c_str(~"", |e| {
-                count_insn(bcx, ~"inlineasm");
-                llvm::LLVMConstInlineAsm(T_fn(~[], T_void()), c, e,
-                                         False, False)
-            })
-        });
-        Call(bcx, asm, ~[]);
+    unsafe {
+        let ccx = bcx.ccx();
+        if !ccx.sess.no_asm_comments() {
+            let sanitized = str::replace(text, ~"$", ~"");
+            let comment_text = ~"# " +
+                str::replace(sanitized, ~"\n", ~"\n\t# ");
+            let asm = str::as_c_str(comment_text, |c| {
+                str::as_c_str(~"", |e| {
+                    count_insn(bcx, ~"inlineasm");
+                    llvm::LLVMConstInlineAsm(T_fn(~[], T_void()), c, e,
+                                             False, False)
+                })
+            });
+            Call(bcx, asm, ~[]);
+        }
     }
 }
 
@@ -719,120 +876,152 @@ fn CallWithConv(cx: block, Fn: ValueRef, Args: ~[ValueRef],
 
 fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) ->
    ValueRef {
-    if cx.unreachable { return _Undef(Then); }
-    count_insn(cx, "select");
-    return llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
+    unsafe {
+        if cx.unreachable { return _Undef(Then); }
+        count_insn(cx, "select");
+        return llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
+    }
 }
 
 fn VAArg(cx: block, list: ValueRef, Ty: TypeRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
-    count_insn(cx, "vaarg");
-    return llvm::LLVMBuildVAArg(B(cx), list, Ty, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
+        count_insn(cx, "vaarg");
+        return llvm::LLVMBuildVAArg(B(cx), list, Ty, noname());
+    }
 }
 
 fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) ->
    ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
-    count_insn(cx, "extractelement");
-    return llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
+        count_insn(cx, "extractelement");
+        return llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
+    }
 }
 
 fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef,
                  Index: ValueRef) {
-    if cx.unreachable { return; }
-    count_insn(cx, "insertelement");
-    llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
+    unsafe {
+        if cx.unreachable { return; }
+        count_insn(cx, "insertelement");
+        llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
+    }
 }
 
 fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
                  Mask: ValueRef) {
-    if cx.unreachable { return; }
-    count_insn(cx, "shufflevector");
-    llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
+    unsafe {
+        if cx.unreachable { return; }
+        count_insn(cx, "shufflevector");
+        llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
+    }
 }
 
 fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
-    count_insn(cx, "extractvalue");
-    return llvm::LLVMBuildExtractValue(
-        B(cx), AggVal, Index as c_uint, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
+        count_insn(cx, "extractvalue");
+        return llvm::LLVMBuildExtractValue(
+            B(cx), AggVal, Index as c_uint, noname());
+    }
 }
 
 fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef,
                Index: uint) {
-    if cx.unreachable { return; }
-    count_insn(cx, "insertvalue");
-    llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index as c_uint,
-                               noname());
+    unsafe {
+        if cx.unreachable { return; }
+        count_insn(cx, "insertvalue");
+        llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index as c_uint,
+                                   noname());
+    }
 }
 
 fn IsNull(cx: block, Val: ValueRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
-    count_insn(cx, "isnull");
-    return llvm::LLVMBuildIsNull(B(cx), Val, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
+        count_insn(cx, "isnull");
+        return llvm::LLVMBuildIsNull(B(cx), Val, noname());
+    }
 }
 
 fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef {
-    if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
-    count_insn(cx, "isnotnull");
-    return llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
+    unsafe {
+        if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
+        count_insn(cx, "isnotnull");
+        return llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
+    }
 }
 
 fn PtrDiff(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
-    let ccx = cx.fcx.ccx;
-    if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type); }
-    count_insn(cx, "ptrdiff");
-    return llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
+    unsafe {
+        let ccx = cx.fcx.ccx;
+        if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type); }
+        count_insn(cx, "ptrdiff");
+        return llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
+    }
 }
 
 fn Trap(cx: block) {
-    if cx.unreachable { return; }
-    let b = B(cx);
-    let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(b);
-    let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
-    let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
-    let T: ValueRef = str::as_c_str(~"llvm.trap", |buf| {
-        llvm::LLVMGetNamedFunction(M, buf)
-    });
-    assert (T as int != 0);
-    let Args: ~[ValueRef] = ~[];
     unsafe {
-        count_insn(cx, "trap");
-        llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args),
-                            Args.len() as c_uint, noname());
+        if cx.unreachable { return; }
+        let b = B(cx);
+        let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(b);
+        let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
+        let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
+        let T: ValueRef = str::as_c_str(~"llvm.trap", |buf| {
+            llvm::LLVMGetNamedFunction(M, buf)
+        });
+        assert (T as int != 0);
+        let Args: ~[ValueRef] = ~[];
+        unsafe {
+            count_insn(cx, "trap");
+            llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args),
+                                Args.len() as c_uint, noname());
+        }
     }
 }
 
 fn LandingPad(cx: block, Ty: TypeRef, PersFn: ValueRef,
               NumClauses: uint) -> ValueRef {
-    assert !cx.terminated && !cx.unreachable;
-    count_insn(cx, "landingpad");
-    return llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn,
-                                  NumClauses as c_uint, noname());
+    unsafe {
+        assert !cx.terminated && !cx.unreachable;
+        count_insn(cx, "landingpad");
+        return llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn,
+                                      NumClauses as c_uint, noname());
+    }
 }
 
 fn SetCleanup(cx: block, LandingPad: ValueRef) {
-    count_insn(cx, "setcleanup");
-    llvm::LLVMSetCleanup(LandingPad, lib::llvm::True);
+    unsafe {
+        count_insn(cx, "setcleanup");
+        llvm::LLVMSetCleanup(LandingPad, lib::llvm::True);
+    }
 }
 
 fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
-    assert (!cx.terminated);
-    cx.terminated = true;
-    count_insn(cx, "resume");
-    return llvm::LLVMBuildResume(B(cx), Exn);
+    unsafe {
+        assert (!cx.terminated);
+        cx.terminated = true;
+        count_insn(cx, "resume");
+        return llvm::LLVMBuildResume(B(cx), Exn);
+    }
 }
 
 // Atomic Operations
 fn AtomicCmpXchg(cx: block, dst: ValueRef,
                  cmp: ValueRef, src: ValueRef,
                  order: AtomicOrdering) -> ValueRef {
-    llvm::LLVMBuildAtomicCmpXchg(B(cx), dst, cmp, src, order)
+    unsafe {
+        llvm::LLVMBuildAtomicCmpXchg(B(cx), dst, cmp, src, order)
+    }
 }
 fn AtomicRMW(cx: block, op: AtomicBinOp,
              dst: ValueRef, src: ValueRef,
              order: AtomicOrdering) -> ValueRef {
-    llvm::LLVMBuildAtomicRMW(B(cx), op, dst, src, order)
+    unsafe {
+        llvm::LLVMBuildAtomicRMW(B(cx), op, dst, src, order)
+    }
 }
 
 //
index eb0d86b6d045ba7bbc1984db58fb6002c5a582f1..f676bcea5d51b2d1e54cc18f8e51c9b2c968895d 100644 (file)
 // and methods are represented as just a fn ptr and not a full
 // closure.
 
+use core::prelude::*;
+
 use lib::llvm::ValueRef;
 use middle::trans::base::{get_item_val, trans_external_path};
 use middle::trans::build::*;
+use middle::trans::callee;
+use middle::trans::closure;
 use middle::trans::common::{block, node_id_type_params};
 use middle::trans::datum::*;
 use middle::trans::datum::Datum;
+use middle::trans::inline;
+use middle::trans::meth;
+use middle::trans::monomorphize;
+use middle::typeck;
 use util::common::indenter;
 
 use syntax::ast;
@@ -153,7 +161,7 @@ fn trans_fn_ref(bcx: block,
 fn trans_fn_ref_with_vtables_to_callee(bcx: block,
                                        def_id: ast::def_id,
                                        ref_id: ast::node_id,
-                                       type_params: ~[ty::t],
+                                       +type_params: ~[ty::t],
                                        vtables: Option<typeck::vtable_res>)
     -> Callee
 {
@@ -166,7 +174,7 @@ fn trans_fn_ref_with_vtables(
     bcx: block,            //
     def_id: ast::def_id,   // def id of fn
     ref_id: ast::node_id,  // node id of use of fn; may be zero if N/A
-    type_params: ~[ty::t], // values for fn's ty params
+    +type_params: ~[ty::t], // values for fn's ty params
     vtables: Option<typeck::vtable_res>)
     -> FnData
 {
@@ -327,13 +335,6 @@ fn trans_method_call(in_cx: block,
         DontAutorefArg)
 }
 
-fn trans_rtcall(bcx: block, name: ~str, args: ~[ValueRef], dest: expr::Dest)
-    -> block
-{
-    let did = bcx.ccx().rtcalls[name];
-    return trans_rtcall_or_lang_call(bcx, did, args, dest);
-}
-
 fn trans_rtcall_or_lang_call(bcx: block, did: ast::def_id, args: ~[ValueRef],
                              dest: expr::Dest) -> block {
     let fty = if did.crate == ast::local_crate {
@@ -365,7 +366,8 @@ fn trans_rtcall_or_lang_call_with_type_params(bcx: block,
         bcx, None, fty, rty,
         |bcx| {
             let callee =
-                trans_fn_ref_with_vtables_to_callee(bcx, did, 0, type_params,
+                trans_fn_ref_with_vtables_to_callee(bcx, did, 0,
+                                                    copy type_params,
                                                     None);
 
             let new_llval;
@@ -389,7 +391,7 @@ fn trans_rtcall_or_lang_call_with_type_params(bcx: block,
 
 fn body_contains_ret(body: ast::blk) -> bool {
     let cx = {mut found: false};
-    visit::visit_block(body, cx, visit::mk_vt(@{
+    visit::visit_block(body, cx, visit::mk_vt(@visit::Visitor {
         visit_item: |_i, _cx, _v| { },
         visit_expr: |e: @ast::expr, cx: {mut found: bool}, v| {
             if !cx.found {
@@ -416,7 +418,7 @@ fn trans_call_inner(
     autoref_arg: AutorefArg) -> block
 {
     do base::with_scope(in_cx, call_info, ~"call") |cx| {
-        let ret_in_loop = match args {
+        let ret_in_loop = match /*bad*/copy args {
           ArgExprs(args) => {
             args.len() > 0u && match vec::last(args).node {
               ast::expr_loop_body(@{
@@ -438,32 +440,34 @@ fn trans_call_inner(
             Some(flag)
         } else { None };
 
-        let (llfn, llenv) = match callee.data {
-            Fn(d) => {
-                (d.llfn, llvm::LLVMGetUndef(T_opaque_box_ptr(ccx)))
-            }
-            Method(d) => {
-                // Weird but true: we pass self in the *environment* slot!
-                let llself = PointerCast(bcx, d.llself,
-                                         T_opaque_box_ptr(ccx));
-                (d.llfn, llself)
-            }
-            Closure(d) => {
-                // Closures are represented as (llfn, llclosure) pair:
-                // load the requisite values out.
-                let pair = d.to_ref_llval(bcx);
-                let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
-                let llfn = Load(bcx, llfn);
-                let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
-                let llenv = Load(bcx, llenv);
-                (llfn, llenv)
+        let (llfn, llenv) = unsafe {
+            match callee.data {
+                Fn(d) => {
+                    (d.llfn, llvm::LLVMGetUndef(T_opaque_box_ptr(ccx)))
+                }
+                Method(d) => {
+                    // Weird but true: we pass self in the *environment* slot!
+                    let llself = PointerCast(bcx, d.llself,
+                                             T_opaque_box_ptr(ccx));
+                    (d.llfn, llself)
+                }
+                Closure(d) => {
+                    // Closures are represented as (llfn, llclosure) pair:
+                    // load the requisite values out.
+                    let pair = d.to_ref_llval(bcx);
+                    let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
+                    let llfn = Load(bcx, llfn);
+                    let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
+                    let llenv = Load(bcx, llenv);
+                    (llfn, llenv)
+                }
             }
         };
 
-        let args_res = trans_args(bcx, llenv, args, fn_expr_ty,
+        let args_res = trans_args(bcx, llenv, /*bad*/copy args, fn_expr_ty,
                                   dest, ret_flag, autoref_arg);
         bcx = args_res.bcx;
-        let mut llargs = args_res.args;
+        let mut llargs = /*bad*/copy args_res.args;
 
         let llretslot = args_res.retslot;
 
@@ -491,8 +495,10 @@ fn trans_call_inner(
         bcx = base::invoke(bcx, llfn, llargs);
         match dest { // drop the value if it is not being saved.
             expr::Ignore => {
-                if llvm::LLVMIsUndef(llretslot) != lib::llvm::True {
-                    bcx = glue::drop_ty(bcx, llretslot, ret_ty);
+                unsafe {
+                    if llvm::LLVMIsUndef(llretslot) != lib::llvm::True {
+                        bcx = glue::drop_ty(bcx, llretslot, ret_ty);
+                    }
                 }
             }
             expr::SaveIn(_) => { }
@@ -520,8 +526,12 @@ enum CallArgs {
     ArgVals(~[ValueRef])
 }
 
-fn trans_args(cx: block, llenv: ValueRef, args: CallArgs, fn_ty: ty::t,
-              dest: expr::Dest, ret_flag: Option<ValueRef>,
+fn trans_args(cx: block,
+              llenv: ValueRef,
+              +args: CallArgs,
+              fn_ty: ty::t,
+              dest: expr::Dest,
+              ret_flag: Option<ValueRef>,
               +autoref_arg: AutorefArg)
     -> {bcx: block, args: ~[ValueRef], retslot: ValueRef}
 {
@@ -539,7 +549,9 @@ fn trans_args(cx: block, llenv: ValueRef, args: CallArgs, fn_ty: ty::t,
         expr::SaveIn(dst) => dst,
         expr::Ignore => {
             if ty::type_is_nil(retty) {
-                llvm::LLVMGetUndef(T_ptr(T_nil()))
+                unsafe {
+                    llvm::LLVMGetUndef(T_ptr(T_nil()))
+                }
             } else {
                 alloc_ty(bcx, retty)
             }
@@ -615,15 +627,19 @@ fn trans_arg_expr(bcx: block,
         Some(_) => {
             match arg_expr.node {
                 ast::expr_loop_body(
-                    blk@@{node:ast::expr_fn_block(decl, ref body, cap), _}) =>
+                    // XXX: Bad copy.
+                    blk@@{
+                        node: ast::expr_fn_block(copy decl, ref body, cap),
+                        _
+                    }) =>
                 {
-                    let scratch_ty = expr_ty(bcx, blk);
+                    let scratch_ty = expr_ty(bcx, arg_expr);
                     let scratch = alloc_ty(bcx, scratch_ty);
                     let arg_ty = expr_ty(bcx, arg_expr);
                     let proto = ty::ty_fn_proto(arg_ty);
                     let bcx = closure::trans_expr_fn(
-                        bcx, proto, decl, (*body), blk.id, cap,
-                        Some(ret_flag), expr::SaveIn(scratch));
+                        bcx, proto, decl, /*bad*/copy *body, arg_expr.id,
+                        blk.id, cap, Some(ret_flag), expr::SaveIn(scratch));
                     DatumBlock {bcx: bcx,
                                 datum: Datum {val: scratch,
                                               ty: scratch_ty,
@@ -652,7 +668,9 @@ fn trans_arg_expr(bcx: block,
         // be inspected. It's important for the value
         // to have type lldestty (the callee's expected type).
         let llformal_ty = type_of::type_of(ccx, formal_ty.ty);
-        val = llvm::LLVMGetUndef(llformal_ty);
+        unsafe {
+            val = llvm::LLVMGetUndef(llformal_ty);
+        }
     } else {
         // FIXME(#3548) use the adjustments table
         match autoref_arg {
index 5110bc261f7a987f1f9b954a6c09b39d529538db..35917e4911cc6cbc819c9a3f48618b2a4c642e82 100644 (file)
@@ -8,15 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use back::abi;
 use back::link::{mangle_internal_name_by_path_and_seq};
 use back::link::{mangle_internal_name_by_path};
 use lib::llvm::llvm;
 use lib::llvm::{ValueRef, TypeRef};
+use middle::capture;
 use middle::trans::base::*;
 use middle::trans::build::*;
+use middle::trans::callee;
 use middle::trans::common::*;
 use middle::trans::datum::{Datum, INIT, ByRef, ByValue, FromLvalue};
+use middle::trans::expr;
+use middle::trans::glue;
 use middle::trans::type_of::*;
 use util::ppaux::ty_to_str;
 
@@ -207,7 +213,8 @@ fn store_environment(bcx: block,
     let ccx = bcx.ccx(), tcx = ccx.tcx;
 
     // compute the shape of the closure
-    let cdata_ty = mk_closure_tys(tcx, bound_values);
+    // XXX: Bad copy.
+    let cdata_ty = mk_closure_tys(tcx, copy bound_values);
 
     // allocate closure in the heap
     let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, proto, cdata_ty);
@@ -332,7 +339,9 @@ fn load_environment(fcx: fn_ctxt,
             let ll =
                 str::as_c_str(~"load_env",
                               |buf|
-                              llvm::LLVMAppendBasicBlock(fcx.llfn, buf));
+                              unsafe {
+                                llvm::LLVMAppendBasicBlock(fcx.llfn, buf)
+                              });
             fcx.llloadenv = Some(ll);
             ll
         }
@@ -370,12 +379,34 @@ fn load_environment(fcx: fn_ctxt,
 
 fn trans_expr_fn(bcx: block,
                  proto: ast::Proto,
-                 decl: ast::fn_decl,
-                 body: ast::blk,
-                 id: ast::node_id,
+                 +decl: ast::fn_decl,
+                 +body: ast::blk,
+                 outer_id: ast::node_id,
+                 user_id: ast::node_id,
                  cap_clause: ast::capture_clause,
                  is_loop_body: Option<Option<ValueRef>>,
-                 dest: expr::Dest) -> block {
+                 dest: expr::Dest) -> block
+{
+    /*!
+     *
+     * Translates the body of a closure expression.
+     *
+     * - `proto`
+     * - `decl`
+     * - `body`
+     * - `outer_id`: The id of the closure expression with the correct
+     *   type.  This is usually the same as as `user_id`, but in the
+     *   case of a `for` loop, the `outer_id` will have the return
+     *   type of boolean, and the `user_id` will have the return type
+     *   of `nil`.
+     * - `user_id`: The id of the closure as the user expressed it.
+         Generally the same as `outer_id`
+     * - `cap_clause`: information about captured variables, if any.
+     * - `is_loop_body`: `Some()` if this is part of a `for` loop.
+     * - `dest`: where to write the closure value, which must be a
+         (fn ptr, env) pair
+     */
+
     let _icx = bcx.insn_ctxt("closure::trans_expr_fn");
 
     let dest_addr = match dest {
@@ -386,22 +417,28 @@ fn trans_expr_fn(bcx: block,
     };
 
     let ccx = bcx.ccx();
-    let fty = node_id_type(bcx, id);
+    let fty = node_id_type(bcx, outer_id);
     let llfnty = type_of_fn_from_ty(ccx, fty);
-    let sub_path = vec::append_one(bcx.fcx.path,
+    let sub_path = vec::append_one(/*bad*/copy bcx.fcx.path,
                                    path_name(special_idents::anon));
-    let s = mangle_internal_name_by_path_and_seq(ccx, sub_path, ~"expr_fn");
+    // XXX: Bad copy.
+    let s = mangle_internal_name_by_path_and_seq(ccx,
+                                                 copy sub_path,
+                                                 ~"expr_fn");
     let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
 
-    let trans_closure_env = fn@(proto: ast::Proto) -> Result {
-        let cap_vars = capture::compute_capture_vars(ccx.tcx, id, proto,
+    // XXX: Bad copies.
+    let trans_closure_env = |proto, copy body, copy sub_path, copy decl| {
+        let cap_vars = capture::compute_capture_vars(ccx.tcx, user_id, proto,
                                                      cap_clause);
         let ret_handle = match is_loop_body { Some(x) => x, None => None };
-        let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, proto,
+        // XXX: Bad copy.
+        let {llbox, cdata_ty, bcx} = build_closure(bcx, copy cap_vars, proto,
                                                    ret_handle);
-        trans_closure(ccx, sub_path, decl, body, llfn, no_self,
-                      bcx.fcx.param_substs, id, None, |fcx| {
-            load_environment(fcx, cdata_ty, cap_vars,
+        trans_closure(ccx, /*bad*/copy sub_path, decl, body, llfn, no_self,
+                      /*bad*/copy bcx.fcx.param_substs, user_id, None,
+                      |fcx| {
+            load_environment(fcx, cdata_ty, copy cap_vars,
                              ret_handle.is_some(), proto);
                       }, |bcx| {
             if is_loop_body.is_some() {
@@ -417,7 +454,7 @@ fn trans_expr_fn(bcx: block,
         }
         ast::ProtoBare => {
             trans_closure(ccx, sub_path, decl, body, llfn, no_self, None,
-                          id, None, |_fcx| { }, |_bcx| { });
+                          user_id, None, |_fcx| { }, |_bcx| { });
             rslt(bcx, C_null(T_opaque_box_ptr(ccx)))
         }
     };
@@ -488,11 +525,13 @@ fn make_opaque_cbox_take_glue(
         let sz = Add(bcx, sz, shape::llsize_of(ccx, T_box_header(ccx)));
 
         // Allocate memory, update original ptr, and copy existing data
-        let malloc = ~"exchange_malloc";
         let opaque_tydesc = PointerCast(bcx, tydesc, T_ptr(T_i8()));
         let rval = alloca_zeroed(bcx, T_ptr(T_i8()));
-        let bcx = callee::trans_rtcall(bcx, malloc, ~[opaque_tydesc, sz],
-                                       expr::SaveIn(rval));
+        let bcx = callee::trans_rtcall_or_lang_call(
+            bcx,
+            bcx.tcx().lang_items.exchange_malloc_fn(),
+            ~[opaque_tydesc, sz],
+            expr::SaveIn(rval));
         let cbox_out = PointerCast(bcx, Load(bcx, rval), llopaquecboxty);
         call_memcpy(bcx, cbox_out, cbox_in, sz);
         Store(bcx, cbox_out, cboxptr);
index 25cd169c403f22837ad9cfc323a039cfa11aadec..5fd36228f7357a4e52e5246f14b46a51bcf0a72f 100644 (file)
@@ -8,36 +8,64 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 /**
    Code that is useful in various trans modules.
 
 */
 
-use libc::c_uint;
-use vec::raw::to_ptr;
-use std::map::{HashMap,Set};
-use syntax::{ast, ast_map};
-use driver::session;
-use session::Session;
-use middle::ty;
+use core::prelude::*;
+
 use back::{link, abi, upcall};
-use syntax::codemap::span;
-use lib::llvm::{llvm, target_data, type_names, associate_type,
-                   name_has_type};
+use driver::session;
+use driver::session::Session;
 use lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef, BuilderRef};
 use lib::llvm::{True, False, Bool};
-use metadata::{csearch};
+use lib::llvm::{llvm, target_data, type_names, associate_type, name_has_type};
+use lib;
 use metadata::common::link_meta;
+use metadata::{csearch};
+use middle::astencode;
+use middle::resolve;
+use middle::trans::base;
+use middle::trans::build;
+use middle::trans::callee;
+use middle::trans::datum;
+use middle::trans::debuginfo;
+use middle::trans::glue;
+use middle::trans::meth;
+use middle::trans::reachable;
+use middle::trans::shape;
+use middle::trans::type_of;
+use middle::trans::type_use;
+use middle::ty;
+use middle::typeck;
+use util::ppaux::{expr_repr, ty_to_str};
+
+use core::cast;
+use core::cmp;
+use core::hash;
+use core::libc::c_uint;
+use core::ptr;
+use core::str;
+use core::to_bytes;
+use core::vec::raw::to_ptr;
+use core::vec;
+use std::map::{HashMap, Set};
+use syntax::ast::ident;
 use syntax::ast_map::path;
-use util::ppaux::ty_to_str;
-use syntax::print::pprust::expr_to_str;
+use syntax::codemap::span;
 use syntax::parse::token::ident_interner;
-use syntax::ast::ident;
+use syntax::print::pprust::expr_to_str;
+use syntax::{ast, ast_map};
 
 type namegen = fn@(~str) -> ident;
 fn new_namegen(intr: @ident_interner) -> namegen {
     return fn@(prefix: ~str) -> ident {
-        return intr.gensym(@fmt!("%s_%u", prefix, intr.gensym(@prefix).repr))
+        // XXX: Bad copies.
+        return intr.gensym(@fmt!("%s_%u",
+                                 prefix,
+                                 intr.gensym(@copy prefix).repr))
     };
 }
 
@@ -109,7 +137,11 @@ fn new_addrspace_gen() -> addrspace_gen {
 
 struct BuilderRef_res {
     B: BuilderRef,
-    drop { llvm::LLVMDisposeBuilder(self.B); }
+    drop {
+        unsafe {
+            llvm::LLVMDisposeBuilder(self.B);
+        }
+    }
 }
 
 fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res {
@@ -119,7 +151,7 @@ fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res {
 }
 
 // Crate context.  Every crate we compile has one of these.
-type crate_ctxt = {
+struct crate_ctxt {
      sess: session::Session,
      llmod: ModuleRef,
      td: target_data,
@@ -175,7 +207,6 @@ fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res {
      maps: astencode::maps,
      stats: stats,
      upcalls: @upcall::upcalls,
-     rtcalls: HashMap<~str, ast::def_id>,
      tydesc_type: TypeRef,
      int_type: TypeRef,
      float_type: TypeRef,
@@ -189,7 +220,8 @@ fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res {
      // is not emitted by LLVM's GC pass when no functions use GC.
      mut uses_gc: bool,
      dbg_cx: Option<debuginfo::debug_ctxt>,
-     mut do_not_commit_warning_issued: bool};
+     mut do_not_commit_warning_issued: bool
+}
 
 // Types used for llself.
 struct ValSelfData {
@@ -202,10 +234,12 @@ enum local_val { local_mem(ValueRef), local_imm(ValueRef), }
 
 // Here `self_ty` is the real type of the self parameter to this method. It
 // will only be set in the case of default methods.
-type param_substs = {tys: ~[ty::t],
-                     vtables: Option<typeck::vtable_res>,
-                     bounds: @~[ty::param_bounds],
-                     self_ty: Option<ty::t>};
+struct param_substs {
+    tys: ~[ty::t],
+    vtables: Option<typeck::vtable_res>,
+    bounds: @~[ty::param_bounds],
+    self_ty: Option<ty::t>
+}
 
 fn param_substs_to_str(tcx: ty::ctxt, substs: &param_substs) -> ~str {
     fmt!("param_substs {tys:%?, vtables:%?, bounds:%?}",
@@ -216,7 +250,7 @@ fn param_substs_to_str(tcx: ty::ctxt, substs: &param_substs) -> ~str {
 
 // Function context.  Every LLVM function we create will have one of
 // these.
-type fn_ctxt = @{
+struct fn_ctxt_ {
     // The ValueRef returned from a call to llvm::LLVMAddFunction; the
     // address of the first instruction in the sequence of
     // instructions for this function that will go in the .text
@@ -280,7 +314,9 @@ fn param_substs_to_str(tcx: ty::ctxt, substs: &param_substs) -> ~str {
 
     // This function's enclosing crate context.
     ccx: @crate_ctxt
-};
+}
+
+pub type fn_ctxt = @fn_ctxt_;
 
 fn warn_not_to_commit(ccx: @crate_ctxt, msg: ~str) {
     if !ccx.do_not_commit_warning_issued {
@@ -444,7 +480,7 @@ fn revoke_clean(cx: block, val: ValueRef) {
 fn block_cleanups(bcx: block) -> ~[cleanup] {
     match bcx.kind {
        block_non_scope  => ~[],
-       block_scope(ref inf) => (*inf).cleanups
+       block_scope(ref inf) => /*bad*/copy inf.cleanups
     }
 }
 
@@ -462,7 +498,7 @@ enum block_kind {
     block_non_scope,
 }
 
-type scope_info = {
+struct scope_info {
     loop_break: Option<block>,
     loop_label: Option<ident>,
     // A list of functions that must be run at when leaving this
@@ -474,7 +510,7 @@ enum block_kind {
     mut cleanup_paths: ~[cleanup_path],
     // Unwinding landing pad. Also cleared when cleanups change.
     mut landing_pad: Option<BasicBlockRef>,
-};
+}
 
 trait get_node_info {
     fn info() -> Option<node_info>;
@@ -581,7 +617,11 @@ fn ty_str(tn: type_names, t: TypeRef) -> ~str {
     return lib::llvm::type_to_str(tn, t);
 }
 
-fn val_ty(v: ValueRef) -> TypeRef { return llvm::LLVMTypeOf(v); }
+fn val_ty(v: ValueRef) -> TypeRef {
+    unsafe {
+        return llvm::LLVMTypeOf(v);
+    }
+}
 
 fn val_str(tn: type_names, v: ValueRef) -> ~str {
     return ty_str(tn, val_ty(v));
@@ -589,12 +629,15 @@ fn val_str(tn: type_names, v: ValueRef) -> ~str {
 
 // Returns the nth element of the given LLVM structure type.
 fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef unsafe {
-    let elt_count = llvm::LLVMCountStructElementTypes(llstructty) as uint;
-    assert (n < elt_count);
-    let mut elt_tys = vec::from_elem(elt_count, T_nil());
-    llvm::LLVMGetStructElementTypes(llstructty,
-                                    ptr::to_mut_unsafe_ptr(&mut elt_tys[0]));
-    return llvm::LLVMGetElementType(elt_tys[n]);
+    unsafe {
+        let elt_count = llvm::LLVMCountStructElementTypes(llstructty) as uint;
+        assert (n < elt_count);
+        let mut elt_tys = vec::from_elem(elt_count, T_nil());
+        llvm::LLVMGetStructElementTypes(
+            llstructty,
+            ptr::to_mut_unsafe_ptr(&mut elt_tys[0]));
+        return llvm::LLVMGetElementType(elt_tys[n]);
+    }
 }
 
 fn in_scope_cx(cx: block, f: fn(scope_info)) {
@@ -633,7 +676,7 @@ fn node_id_to_str(id: ast::node_id) -> ~str {
     }
 
     fn expr_to_str(e: @ast::expr) -> ~str {
-        util::ppaux::expr_repr(self.tcx(), e)
+        expr_repr(self.tcx(), e)
     }
 
     fn expr_is_lval(e: @ast::expr) -> bool {
@@ -679,41 +722,30 @@ fn to_str() -> ~str {
 
 // LLVM type constructors.
 fn T_void() -> TypeRef {
-    // Note: For the time being llvm is kinda busted here, it has the notion
-    // of a 'void' type that can only occur as part of the signature of a
-    // function, but no general unit type of 0-sized value. This is, afaict,
-    // vestigial from its C heritage, and we'll be attempting to submit a
-    // patch upstream to fix it. In the mean time we only model function
-    // outputs (Rust functions and C functions) using T_void, and model the
-    // Rust general purpose nil type you can construct as 1-bit (always
-    // zero). This makes the result incorrect for now -- things like a tuple
-    // of 10 nil values will have 10-bit size -- but it doesn't seem like we
-    // have any other options until it's fixed upstream.
-
-    return llvm::LLVMVoidType();
+    unsafe {
+        return llvm::LLVMVoidType();
+    }
 }
 
 fn T_nil() -> TypeRef {
-    // NB: See above in T_void().
-
-    return llvm::LLVMInt1Type();
+    return T_struct(~[])
 }
 
-fn T_metadata() -> TypeRef { return llvm::LLVMMetadataType(); }
+fn T_metadata() -> TypeRef { unsafe { return llvm::LLVMMetadataType(); } }
 
-fn T_i1() -> TypeRef { return llvm::LLVMInt1Type(); }
+fn T_i1() -> TypeRef { unsafe { return llvm::LLVMInt1Type(); } }
 
-fn T_i8() -> TypeRef { return llvm::LLVMInt8Type(); }
+fn T_i8() -> TypeRef { unsafe { return llvm::LLVMInt8Type(); } }
 
-fn T_i16() -> TypeRef { return llvm::LLVMInt16Type(); }
+fn T_i16() -> TypeRef { unsafe { return llvm::LLVMInt16Type(); } }
 
-fn T_i32() -> TypeRef { return llvm::LLVMInt32Type(); }
+fn T_i32() -> TypeRef { unsafe { return llvm::LLVMInt32Type(); } }
 
-fn T_i64() -> TypeRef { return llvm::LLVMInt64Type(); }
+fn T_i64() -> TypeRef { unsafe { return llvm::LLVMInt64Type(); } }
 
-fn T_f32() -> TypeRef { return llvm::LLVMFloatType(); }
+fn T_f32() -> TypeRef { unsafe { return llvm::LLVMFloatType(); } }
 
-fn T_f64() -> TypeRef { return llvm::LLVMDoubleType(); }
+fn T_f64() -> TypeRef { unsafe { return llvm::LLVMDoubleType(); } }
 
 fn T_bool() -> TypeRef { return T_i1(); }
 
@@ -779,25 +811,39 @@ fn T_fn_pair(cx: @crate_ctxt, tfn: TypeRef) -> TypeRef {
 }
 
 fn T_ptr(t: TypeRef) -> TypeRef {
-    return llvm::LLVMPointerType(t, default_addrspace);
+    unsafe {
+        return llvm::LLVMPointerType(t, default_addrspace);
+    }
 }
 
 fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef {
-    return llvm::LLVMPointerType(t, addrspace);
+    unsafe {
+        return llvm::LLVMPointerType(t, addrspace);
+    }
 }
 
 fn T_struct(elts: ~[TypeRef]) -> TypeRef unsafe {
-    return llvm::LLVMStructType(to_ptr(elts), elts.len() as c_uint, False);
+    unsafe {
+        return llvm::LLVMStructType(to_ptr(elts),
+                                    elts.len() as c_uint,
+                                    False);
+    }
 }
 
 fn T_named_struct(name: ~str) -> TypeRef {
-    let c = llvm::LLVMGetGlobalContext();
-    return str::as_c_str(name, |buf| llvm::LLVMStructCreateNamed(c, buf));
+    unsafe {
+        let c = llvm::LLVMGetGlobalContext();
+        return str::as_c_str(name, |buf| llvm::LLVMStructCreateNamed(c, buf));
+    }
 }
 
 fn set_struct_body(t: TypeRef, elts: ~[TypeRef]) unsafe {
-    llvm::LLVMStructSetBody(t, to_ptr(elts),
-                            elts.len() as c_uint, False);
+    unsafe {
+        llvm::LLVMStructSetBody(t,
+                                to_ptr(elts),
+                                elts.len() as c_uint,
+                                False);
+    }
 }
 
 fn T_empty_struct() -> TypeRef { return T_struct(~[]); }
@@ -833,14 +879,16 @@ fn T_task(targ_cfg: @session::config) -> TypeRef {
 fn T_tydesc_field(cx: @crate_ctxt, field: uint) -> TypeRef unsafe {
     // Bit of a kludge: pick the fn typeref out of the tydesc..
 
-    let mut tydesc_elts: ~[TypeRef] =
-        vec::from_elem::<TypeRef>(abi::n_tydesc_fields,
-                                 T_nil());
-    llvm::LLVMGetStructElementTypes(
-        cx.tydesc_type,
-        ptr::to_mut_unsafe_ptr(&mut tydesc_elts[0]));
-    let t = llvm::LLVMGetElementType(tydesc_elts[field]);
-    return t;
+    unsafe {
+        let mut tydesc_elts: ~[TypeRef] =
+            vec::from_elem::<TypeRef>(abi::n_tydesc_fields,
+                                     T_nil());
+        llvm::LLVMGetStructElementTypes(
+            cx.tydesc_type,
+            ptr::to_mut_unsafe_ptr(&mut tydesc_elts[0]));
+        let t = llvm::LLVMGetElementType(tydesc_elts[field]);
+        return t;
+    }
 }
 
 fn T_generic_glue_fn(cx: @crate_ctxt) -> TypeRef {
@@ -872,7 +920,9 @@ fn T_tydesc(targ_cfg: @session::config) -> TypeRef {
 }
 
 fn T_array(t: TypeRef, n: uint) -> TypeRef {
-    return llvm::LLVMArrayType(t, n as c_uint);
+    unsafe {
+        return llvm::LLVMArrayType(t, n as c_uint);
+    }
 }
 
 // Interior vector.
@@ -915,7 +965,9 @@ fn T_box(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
 }
 
 fn T_box_ptr(t: TypeRef) -> TypeRef {
-    return llvm::LLVMPointerType(t, gc_box_addrspace);
+    unsafe {
+        return llvm::LLVMPointerType(t, gc_box_addrspace);
+    }
 }
 
 fn T_opaque_box(cx: @crate_ctxt) -> TypeRef {
@@ -931,7 +983,9 @@ fn T_unique(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
 }
 
 fn T_unique_ptr(t: TypeRef) -> TypeRef {
-    return llvm::LLVMPointerType(t, gc_box_addrspace);
+    unsafe {
+        return llvm::LLVMPointerType(t, gc_box_addrspace);
+    }
 }
 
 fn T_port(cx: @crate_ctxt, _t: TypeRef) -> TypeRef {
@@ -1010,20 +1064,26 @@ fn T_opaque_trait(cx: @crate_ctxt, vstore: ty::vstore) -> TypeRef {
 
 
 // LLVM constant constructors.
-fn C_null(t: TypeRef) -> ValueRef { return llvm::LLVMConstNull(t); }
+fn C_null(t: TypeRef) -> ValueRef {
+    unsafe {
+        return llvm::LLVMConstNull(t);
+    }
+}
 
 fn C_integral(t: TypeRef, u: u64, sign_extend: Bool) -> ValueRef {
-    return llvm::LLVMConstInt(t, u, sign_extend);
+    unsafe {
+        return llvm::LLVMConstInt(t, u, sign_extend);
+    }
 }
 
 fn C_floating(s: ~str, t: TypeRef) -> ValueRef {
-    return str::as_c_str(s, |buf| llvm::LLVMConstRealOfString(t, buf));
+    unsafe {
+        return str::as_c_str(s, |buf| llvm::LLVMConstRealOfString(t, buf));
+    }
 }
 
 fn C_nil() -> ValueRef {
-    // NB: See comment above in T_void().
-
-    return C_integral(T_i1(), 0u64, False);
+    return C_struct(~[]);
 }
 
 fn C_bool(b: bool) -> ValueRef {
@@ -1051,90 +1111,116 @@ fn C_uint(cx: @crate_ctxt, i: uint) -> ValueRef {
 
 // This is a 'c-like' raw string, which differs from
 // our boxed-and-length-annotated strings.
-fn C_cstr(cx: @crate_ctxt, s: ~str) -> ValueRef {
-    match cx.const_cstr_cache.find(s) {
-      Some(llval) => return llval,
-      None => ()
-    }
+fn C_cstr(cx: @crate_ctxt, +s: ~str) -> ValueRef {
+    unsafe {
+        match cx.const_cstr_cache.find(s) {
+          Some(llval) => return llval,
+          None => ()
+        }
 
-    let sc = do str::as_c_str(s) |buf| {
-        llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
-    };
-    let g =
-        str::as_c_str(fmt!("str%u", (cx.names)(~"str").repr),
-                    |buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf));
-    llvm::LLVMSetInitializer(g, sc);
-    llvm::LLVMSetGlobalConstant(g, True);
-    lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
+        let sc = do str::as_c_str(s) |buf| {
+            llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
+        };
+        let g =
+            str::as_c_str(fmt!("str%u", (cx.names)(~"str").repr),
+                        |buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf));
+        llvm::LLVMSetInitializer(g, sc);
+        llvm::LLVMSetGlobalConstant(g, True);
+        lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
 
-    cx.const_cstr_cache.insert(s, g);
+        cx.const_cstr_cache.insert(s, g);
 
-    return g;
+        return g;
+    }
 }
 
-fn C_estr_slice(cx: @crate_ctxt, s: ~str) -> ValueRef {
-    let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), T_ptr(T_i8()));
-    C_struct(~[cs, C_uint(cx, str::len(s) + 1u /* +1 for null */)])
+// NB: Do not use `do_spill_noroot` to make this into a constant string, or
+// you will be kicked off fast isel. See issue #4352 for an example of this.
+fn C_estr_slice(cx: @crate_ctxt, +s: ~str) -> ValueRef {
+    unsafe {
+        let len = str::len(s);
+        let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), T_ptr(T_i8()));
+        C_struct(~[cs, C_uint(cx, len + 1u /* +1 for null */)])
+    }
 }
 
 // Returns a Plain Old LLVM String:
 fn C_postr(s: ~str) -> ValueRef {
-    return do str::as_c_str(s) |buf| {
-        llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
-    };
+    unsafe {
+        return do str::as_c_str(s) |buf| {
+            llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
+        };
+    }
 }
 
 fn C_zero_byte_arr(size: uint) -> ValueRef unsafe {
-    let mut i = 0u;
-    let mut elts: ~[ValueRef] = ~[];
-    while i < size { elts.push(C_u8(0u)); i += 1u; }
-    return llvm::LLVMConstArray(T_i8(), vec::raw::to_ptr(elts),
-                             elts.len() as c_uint);
+    unsafe {
+        let mut i = 0u;
+        let mut elts: ~[ValueRef] = ~[];
+        while i < size { elts.push(C_u8(0u)); i += 1u; }
+        return llvm::LLVMConstArray(T_i8(),
+                                    vec::raw::to_ptr(elts),
+                                    elts.len() as c_uint);
+    }
 }
 
 fn C_struct(elts: &[ValueRef]) -> ValueRef {
-    do vec::as_imm_buf(elts) |ptr, len| {
-        llvm::LLVMConstStruct(ptr, len as c_uint, False)
+    unsafe {
+        do vec::as_imm_buf(elts) |ptr, len| {
+            llvm::LLVMConstStruct(ptr, len as c_uint, False)
+        }
     }
 }
 
 fn C_named_struct(T: TypeRef, elts: &[ValueRef]) -> ValueRef {
-    do vec::as_imm_buf(elts) |ptr, len| {
-        llvm::LLVMConstNamedStruct(T, ptr, len as c_uint)
+    unsafe {
+        do vec::as_imm_buf(elts) |ptr, len| {
+            llvm::LLVMConstNamedStruct(T, ptr, len as c_uint)
+        }
     }
 }
 
 fn C_array(ty: TypeRef, elts: ~[ValueRef]) -> ValueRef unsafe {
-    return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts),
-                             elts.len() as c_uint);
+    unsafe {
+        return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts),
+                                 elts.len() as c_uint);
+    }
 }
 
 fn C_bytes(bytes: ~[u8]) -> ValueRef unsafe {
-    return llvm::LLVMConstString(
-        cast::reinterpret_cast(&vec::raw::to_ptr(bytes)),
-        bytes.len() as c_uint, True);
+    unsafe {
+        return llvm::LLVMConstString(
+            cast::reinterpret_cast(&vec::raw::to_ptr(bytes)),
+            bytes.len() as c_uint, True);
+    }
 }
 
 fn C_bytes_plus_null(bytes: ~[u8]) -> ValueRef unsafe {
-    return llvm::LLVMConstString(
-        cast::reinterpret_cast(&vec::raw::to_ptr(bytes)),
-        bytes.len() as c_uint, False);
+    unsafe {
+        return llvm::LLVMConstString(
+            cast::reinterpret_cast(&vec::raw::to_ptr(bytes)),
+            bytes.len() as c_uint, False);
+    }
 }
 
-fn C_shape(ccx: @crate_ctxt, bytes: ~[u8]) -> ValueRef {
-    let llshape = C_bytes_plus_null(bytes);
-    let name = fmt!("shape%u", (ccx.names)(~"shape").repr);
-    let llglobal = str::as_c_str(name, |buf| {
-        llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf)
-    });
-    llvm::LLVMSetInitializer(llglobal, llshape);
-    llvm::LLVMSetGlobalConstant(llglobal, True);
-    lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
-    return llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8()));
+fn C_shape(ccx: @crate_ctxt, +bytes: ~[u8]) -> ValueRef {
+    unsafe {
+        let llshape = C_bytes_plus_null(bytes);
+        let name = fmt!("shape%u", (ccx.names)(~"shape").repr);
+        let llglobal = str::as_c_str(name, |buf| {
+            llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf)
+        });
+        llvm::LLVMSetInitializer(llglobal, llshape);
+        llvm::LLVMSetGlobalConstant(llglobal, True);
+        lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
+        return llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8()));
+    }
 }
 
 fn get_param(fndecl: ValueRef, param: uint) -> ValueRef {
-    llvm::LLVMGetParam(fndecl, param as c_uint)
+    unsafe {
+        llvm::LLVMGetParam(fndecl, param as c_uint)
+    }
 }
 
 // Used to identify cached monomorphized functions and vtables
@@ -1147,29 +1233,30 @@ enum mono_param_id {
               datum::DatumMode),
 }
 
-type mono_id_ = {
+struct mono_id_ {
     def: ast::def_id,
     params: ~[mono_param_id],
     impl_did_opt: Option<ast::def_id>
-};
+}
 
 type mono_id = @mono_id_;
 
 impl mono_param_id : cmp::Eq {
     pure fn eq(&self, other: &mono_param_id) -> bool {
-        match ((*self), (*other)) {
-            (mono_precise(ty_a, ids_a), mono_precise(ty_b, ids_b)) => {
+        match (self, other) {
+            (&mono_precise(ty_a, ref ids_a),
+             &mono_precise(ty_b, ref ids_b)) => {
                 ty_a == ty_b && ids_a == ids_b
             }
-            (mono_any, mono_any) => true,
-            (mono_repr(size_a, align_a, is_float_a, mode_a),
-             mono_repr(size_b, align_b, is_float_b, mode_b)) => {
+            (&mono_any, &mono_any) => true,
+            (&mono_repr(size_a, align_a, is_float_a, mode_a),
+             &mono_repr(size_b, align_b, is_float_b, mode_b)) => {
                 size_a == size_b && align_a == align_b &&
                     is_float_a == is_float_b && mode_a == mode_b
             }
-            (mono_precise(*), _) => false,
-            (mono_any, _) => false,
-            (mono_repr(*), _) => false
+            (&mono_precise(*), _) => false,
+            (&mono_any, _) => false,
+            (&mono_repr(*), _) => false
         }
     }
     pure fn ne(&self, other: &mono_param_id) -> bool { !(*self).eq(other) }
@@ -1184,7 +1271,7 @@ impl mono_id_ : cmp::Eq {
 
 impl mono_param_id : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
-        match *self {
+        match /*bad*/copy *self {
           mono_precise(t, mids) =>
           to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), &mids, lsb0, f),
 
@@ -1196,7 +1283,7 @@ impl mono_param_id : to_bytes::IterBytes {
     }
 }
 
-impl mono_id_ : core::to_bytes::IterBytes {
+impl mono_id_ : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f);
     }
@@ -1233,7 +1320,7 @@ fn path_str(sess: session::Session, p: path) -> ~str {
 }
 
 fn monomorphize_type(bcx: block, t: ty::t) -> ty::t {
-    match bcx.fcx.param_substs {
+    match /*bad*/copy bcx.fcx.param_substs {
         Some(substs) => {
             ty::subst_tps(bcx.tcx(), substs.tys, substs.self_ty, t)
         }
@@ -1254,7 +1341,7 @@ fn expr_ty(bcx: block, ex: @ast::expr) -> ty::t {
 fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] {
     let tcx = bcx.tcx();
     let params = ty::node_id_to_type_params(tcx, id);
-    match bcx.fcx.param_substs {
+    match /*bad*/copy bcx.fcx.param_substs {
       Some(substs) => {
         do vec::map(params) |t| {
             ty::subst_tps(tcx, substs.tys, substs.self_ty, *t)
@@ -1273,18 +1360,18 @@ fn node_vtables(bcx: block, id: ast::node_id) -> Option<typeck::vtable_res> {
 fn resolve_vtables_in_fn_ctxt(fcx: fn_ctxt, vts: typeck::vtable_res)
     -> typeck::vtable_res
 {
-    @vec::map(*vts, |d| resolve_vtable_in_fn_ctxt(fcx, *d))
+    @vec::map(*vts, |d| resolve_vtable_in_fn_ctxt(fcx, copy *d))
 }
 
 // Apply the typaram substitutions in the fn_ctxt to a vtable. This should
 // eliminate any vtable_params.
-fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin)
+fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, +vt: typeck::vtable_origin)
     -> typeck::vtable_origin
 {
     let tcx = fcx.ccx.tcx;
     match vt {
         typeck::vtable_static(trait_id, tys, sub) => {
-            let tys = match fcx.param_substs {
+            let tys = match /*bad*/copy fcx.param_substs {
                 Some(substs) => {
                     do vec::map(tys) |t| {
                         ty::subst_tps(tcx, substs.tys, substs.self_ty, *t)
@@ -1302,12 +1389,12 @@ fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin)
                 }
                 _ => {
                     tcx.sess.bug(fmt!(
-                        "resolve_vtable_in_fn_ctxt: asked to lookup %? but \
-                         no vtables in the fn_ctxt!", vt))
+                        "resolve_vtable_in_fn_ctxt: asked to lookup but \
+                         no vtables in the fn_ctxt!"))
                 }
             }
         }
-        _ => vt
+        vt => vt
     }
 }
 
@@ -1324,10 +1411,10 @@ fn find_vtable(tcx: ty::ctxt, ps: &param_substs,
     let vtables_to_skip =
         ty::count_traits_and_supertraits(tcx, first_n_bounds);
     let vtable_off = vtables_to_skip + n_bound;
-    ps.vtables.get()[vtable_off]
+    /*bad*/ copy ps.vtables.get()[vtable_off]
 }
 
-fn dummy_substs(tps: ~[ty::t]) -> ty::substs {
+fn dummy_substs(+tps: ~[ty::t]) -> ty::substs {
     {self_r: Some(ty::re_bound(ty::br_self)),
      self_ty: None,
      tps: tps}
index 355e78014805dc9343d0540353adbdf5fb037989..74aaec0d7e73f89d8c49717efae3be787990322c 100644 (file)
@@ -8,8 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use middle::const_eval;
 use middle::trans::base::get_insn_ctxt;
 use middle::trans::common::*;
+use middle::trans::consts;
+use middle::trans::expr;
+use middle::ty;
 
 use syntax::{ast, ast_util, codemap, ast_map};
 
@@ -32,12 +38,12 @@ fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
                                 ~"integer literal doesn't have a type")
         }
       }
-      ast::lit_float(fs, t) => C_floating(*fs, T_float_ty(cx, t)),
+      ast::lit_float(fs, t) => C_floating(/*bad*/copy *fs, T_float_ty(cx, t)),
       ast::lit_float_unsuffixed(fs) => {
         let lit_float_ty = ty::node_id_to_type(cx.tcx, e.id);
         match ty::get(lit_float_ty).sty {
           ty::ty_float(t) => {
-            C_floating(*fs, T_float_ty(cx, t))
+            C_floating(/*bad*/copy *fs, T_float_ty(cx, t))
           }
           _ => {
             cx.sess.span_bug(lit.span,
@@ -48,46 +54,54 @@ fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
       }
       ast::lit_bool(b) => C_bool(b),
       ast::lit_nil => C_nil(),
-      ast::lit_str(s) => C_estr_slice(cx, *s)
+      ast::lit_str(s) => C_estr_slice(cx, /*bad*/copy *s)
     }
 }
 
 fn const_ptrcast(cx: @crate_ctxt, a: ValueRef, t: TypeRef) -> ValueRef {
-    let b = llvm::LLVMConstPointerCast(a, T_ptr(t));
-    assert cx.const_globals.insert(b as int, a);
-    b
+    unsafe {
+        let b = llvm::LLVMConstPointerCast(a, T_ptr(t));
+        assert cx.const_globals.insert(b as int, a);
+        b
+    }
 }
 
 fn const_vec(cx: @crate_ctxt, e: @ast::expr, es: &[@ast::expr])
     -> (ValueRef, ValueRef, TypeRef) {
-    let vec_ty = ty::expr_ty(cx.tcx, e);
-    let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
-    let llunitty = type_of::type_of(cx, unit_ty);
-    let v = C_array(llunitty, es.map(|e| const_expr(cx, *e)));
-    let unit_sz = shape::llsize_of(cx, llunitty);
-    let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz);
-    return (v, sz, llunitty);
+    unsafe {
+        let vec_ty = ty::expr_ty(cx.tcx, e);
+        let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
+        let llunitty = type_of::type_of(cx, unit_ty);
+        let v = C_array(llunitty, es.map(|e| const_expr(cx, *e)));
+        let unit_sz = shape::llsize_of(cx, llunitty);
+        let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz);
+        return (v, sz, llunitty);
+    }
 }
 
 fn const_deref(cx: @crate_ctxt, v: ValueRef) -> ValueRef {
-    let v = match cx.const_globals.find(v as int) {
-        Some(v) => v,
-        None => v
-    };
-    assert llvm::LLVMIsGlobalConstant(v) == True;
-    let v = llvm::LLVMGetInitializer(v);
-    v
+    unsafe {
+        let v = match cx.const_globals.find(v as int) {
+            Some(v) => v,
+            None => v
+        };
+        assert llvm::LLVMIsGlobalConstant(v) == True;
+        let v = llvm::LLVMGetInitializer(v);
+        v
+    }
 }
 
 fn const_get_elt(cx: @crate_ctxt, v: ValueRef, us: &[c_uint]) -> ValueRef {
-    let r = do vec::as_imm_buf(us) |p, len| {
-        llvm::LLVMConstExtractValue(v, p, len as c_uint)
-    };
+    unsafe {
+        let r = do vec::as_imm_buf(us) |p, len| {
+            llvm::LLVMConstExtractValue(v, p, len as c_uint)
+        };
 
-    debug!("const_get_elt(v=%s, us=%?, r=%s)",
-           val_str(cx.tn, v), us, val_str(cx.tn, r));
+        debug!("const_get_elt(v=%s, us=%?, r=%s)",
+               val_str(cx.tn, v), us, val_str(cx.tn, r));
 
-    return r;
+        return r;
+    }
 }
 
 fn const_autoderef(cx: @crate_ctxt, ty: ty::t, v: ValueRef)
@@ -124,340 +138,347 @@ fn get_const_val(cx: @crate_ctxt, def_id: ast::def_id) -> ValueRef {
 }
 
 fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
-    let _icx = cx.insn_ctxt("const_expr");
-    return match e.node {
-      ast::expr_lit(lit) => consts::const_lit(cx, e, *lit),
-      ast::expr_binary(b, e1, e2) => {
-        let te1 = const_expr(cx, e1);
-        let te2 = const_expr(cx, e2);
+    unsafe {
+        let _icx = cx.insn_ctxt("const_expr");
+        return match /*bad*/copy e.node {
+          ast::expr_lit(lit) => consts::const_lit(cx, e, *lit),
+          ast::expr_binary(b, e1, e2) => {
+            let te1 = const_expr(cx, e1);
+            let te2 = const_expr(cx, e2);
 
-        let te2 = base::cast_shift_const_rhs(b, te1, te2);
+            let te2 = base::cast_shift_const_rhs(b, te1, te2);
 
-        /* Neither type is bottom, and we expect them to be unified already,
-         * so the following is safe. */
-        let ty = ty::expr_ty(cx.tcx, e1);
-        let is_float = ty::type_is_fp(ty);
-        let signed = ty::type_is_signed(ty);
-        return match b {
-          ast::add   => {
-            if is_float { llvm::LLVMConstFAdd(te1, te2) }
-            else        { llvm::LLVMConstAdd(te1, te2) }
-          }
-          ast::subtract => {
-            if is_float { llvm::LLVMConstFSub(te1, te2) }
-            else        { llvm::LLVMConstSub(te1, te2) }
-          }
-          ast::mul    => {
-            if is_float { llvm::LLVMConstFMul(te1, te2) }
-            else        { llvm::LLVMConstMul(te1, te2) }
-          }
-          ast::div    => {
-            if is_float    { llvm::LLVMConstFDiv(te1, te2) }
-            else if signed { llvm::LLVMConstSDiv(te1, te2) }
-            else           { llvm::LLVMConstUDiv(te1, te2) }
-          }
-          ast::rem    => {
-            if is_float    { llvm::LLVMConstFRem(te1, te2) }
-            else if signed { llvm::LLVMConstSRem(te1, te2) }
-            else           { llvm::LLVMConstURem(te1, te2) }
-          }
-          ast::and    |
-          ast::or     => cx.sess.span_unimpl(e.span, ~"binop logic"),
-          ast::bitxor => llvm::LLVMConstXor(te1, te2),
-          ast::bitand => llvm::LLVMConstAnd(te1, te2),
-          ast::bitor  => llvm::LLVMConstOr(te1, te2),
-          ast::shl    => llvm::LLVMConstShl(te1, te2),
-          ast::shr    => {
-            if signed { llvm::LLVMConstAShr(te1, te2) }
-            else      { llvm::LLVMConstLShr(te1, te2) }
+            /* Neither type is bottom, and we expect them to be unified
+             * already, so the following is safe. */
+            let ty = ty::expr_ty(cx.tcx, e1);
+            let is_float = ty::type_is_fp(ty);
+            let signed = ty::type_is_signed(ty);
+            return match b {
+              ast::add   => {
+                if is_float { llvm::LLVMConstFAdd(te1, te2) }
+                else        { llvm::LLVMConstAdd(te1, te2) }
+              }
+              ast::subtract => {
+                if is_float { llvm::LLVMConstFSub(te1, te2) }
+                else        { llvm::LLVMConstSub(te1, te2) }
+              }
+              ast::mul    => {
+                if is_float { llvm::LLVMConstFMul(te1, te2) }
+                else        { llvm::LLVMConstMul(te1, te2) }
+              }
+              ast::div    => {
+                if is_float    { llvm::LLVMConstFDiv(te1, te2) }
+                else if signed { llvm::LLVMConstSDiv(te1, te2) }
+                else           { llvm::LLVMConstUDiv(te1, te2) }
+              }
+              ast::rem    => {
+                if is_float    { llvm::LLVMConstFRem(te1, te2) }
+                else if signed { llvm::LLVMConstSRem(te1, te2) }
+                else           { llvm::LLVMConstURem(te1, te2) }
+              }
+              ast::and    |
+              ast::or     => cx.sess.span_unimpl(e.span, ~"binop logic"),
+              ast::bitxor => llvm::LLVMConstXor(te1, te2),
+              ast::bitand => llvm::LLVMConstAnd(te1, te2),
+              ast::bitor  => llvm::LLVMConstOr(te1, te2),
+              ast::shl    => llvm::LLVMConstShl(te1, te2),
+              ast::shr    => {
+                if signed { llvm::LLVMConstAShr(te1, te2) }
+                else      { llvm::LLVMConstLShr(te1, te2) }
+              }
+              ast::eq     |
+              ast::lt     |
+              ast::le     |
+              ast::ne     |
+              ast::ge     |
+              ast::gt     => cx.sess.span_unimpl(e.span, ~"binop comparator")
+            }
           }
-          ast::eq     |
-          ast::lt     |
-          ast::le     |
-          ast::ne     |
-          ast::ge     |
-          ast::gt     => cx.sess.span_unimpl(e.span, ~"binop comparator")
-        }
-      }
-      ast::expr_unary(u, e) => {
-        let te = const_expr(cx, e);
-        let ty = ty::expr_ty(cx.tcx, e);
-        let is_float = ty::type_is_fp(ty);
-        return match u {
-          ast::box(_)  |
-          ast::uniq(_) |
-          ast::deref  => const_deref(cx, te),
-          ast::not    => llvm::LLVMConstNot(te),
-          ast::neg    => {
-            if is_float { llvm::LLVMConstFNeg(te) }
-            else        { llvm::LLVMConstNeg(te) }
+          ast::expr_unary(u, e) => {
+            let te = const_expr(cx, e);
+            let ty = ty::expr_ty(cx.tcx, e);
+            let is_float = ty::type_is_fp(ty);
+            return match u {
+              ast::box(_)  |
+              ast::uniq(_) |
+              ast::deref  => const_deref(cx, te),
+              ast::not    => llvm::LLVMConstNot(te),
+              ast::neg    => {
+                if is_float { llvm::LLVMConstFNeg(te) }
+                else        { llvm::LLVMConstNeg(te) }
+              }
+            }
           }
-        }
-      }
-      ast::expr_field(base, field, _) => {
-          let bt = ty::expr_ty(cx.tcx, base);
-          let bv = const_expr(cx, base);
-          let (bt, bv) = const_autoderef(cx, bt, bv);
-          do expr::with_field_tys(cx.tcx, bt, None) |_has_dtor, field_tys| {
-              let ix = ty::field_idx_strict(cx.tcx, field, field_tys);
+          ast::expr_field(base, field, _) => {
+              let bt = ty::expr_ty(cx.tcx, base);
+              let bv = const_expr(cx, base);
+              let (bt, bv) = const_autoderef(cx, bt, bv);
+              do expr::with_field_tys(cx.tcx, bt, None) |_, field_tys| {
+                  let ix = ty::field_idx_strict(cx.tcx, field, field_tys);
 
-              // Note: ideally, we'd use `struct_field()` here instead
-              // of hardcoding [0, ix], but we can't because it yields
-              // the wrong type and also inserts an extra 0 that is
-              // not needed in the constant variety:
-              const_get_elt(cx, bv, [0, ix as c_uint])
+                  // Note: ideally, we'd use `struct_field()` here instead
+                  // of hardcoding [0, ix], but we can't because it yields
+                  // the wrong type and also inserts an extra 0 that is
+                  // not needed in the constant variety:
+                  const_get_elt(cx, bv, [0, ix as c_uint])
+              }
           }
-      }
 
-      ast::expr_index(base, index) => {
-          let bt = ty::expr_ty(cx.tcx, base);
-          let bv = const_expr(cx, base);
-          let (bt, bv) = const_autoderef(cx, bt, bv);
-          let iv = match const_eval::eval_const_expr(cx.tcx, index) {
-              const_eval::const_int(i) => i as u64,
-              const_eval::const_uint(u) => u,
-              _ => cx.sess.span_bug(index.span,
-                                    ~"index is not an integer-constant \
-                                      expression")
-          };
-          let (arr, _len) = match ty::get(bt).sty {
-              ty::ty_evec(_, vstore) | ty::ty_estr(vstore) =>
-                  match vstore {
-                  ty::vstore_fixed(u) =>
-                      (bv, C_uint(cx, u)),
+          ast::expr_index(base, index) => {
+              let bt = ty::expr_ty(cx.tcx, base);
+              let bv = const_expr(cx, base);
+              let (bt, bv) = const_autoderef(cx, bt, bv);
+              let iv = match const_eval::eval_const_expr(cx.tcx, index) {
+                  const_eval::const_int(i) => i as u64,
+                  const_eval::const_uint(u) => u,
+                  _ => cx.sess.span_bug(index.span,
+                                        ~"index is not an integer-constant \
+                                          expression")
+              };
+              let (arr, _len) = match ty::get(bt).sty {
+                  ty::ty_evec(_, vstore) | ty::ty_estr(vstore) =>
+                      match vstore {
+                      ty::vstore_fixed(u) =>
+                          (bv, C_uint(cx, u)),
 
-                  ty::vstore_slice(_) => {
-                      let unit_ty = ty::sequence_element_type(cx.tcx, bt);
-                      let llunitty = type_of::type_of(cx, unit_ty);
-                      let unit_sz = shape::llsize_of(cx, llunitty);
+                      ty::vstore_slice(_) => {
+                          let unit_ty = ty::sequence_element_type(cx.tcx, bt);
+                          let llunitty = type_of::type_of(cx, unit_ty);
+                          let unit_sz = shape::llsize_of(cx, llunitty);
 
-                      (const_deref(cx, const_get_elt(cx, bv, [0])),
-                       llvm::LLVMConstUDiv(const_get_elt(cx, bv, [1]),
-                                           unit_sz))
+                          (const_deref(cx, const_get_elt(cx, bv, [0])),
+                           llvm::LLVMConstUDiv(const_get_elt(cx, bv, [1]),
+                                               unit_sz))
+                      },
+                      _ => cx.sess.span_bug(base.span,
+                                            ~"index-expr base must be \
+                                              fixed-size or slice")
                   },
-                  _ => cx.sess.span_bug(base.span,
-                                        ~"index-expr base must be \
-                                          fixed-size or slice")
-              },
-              _ =>  cx.sess.span_bug(base.span,
-                                     ~"index-expr base must be \
-                                       a vector or string type")
-          };
+                  _ =>  cx.sess.span_bug(base.span,
+                                         ~"index-expr base must be \
+                                           a vector or string type")
+              };
 
-          // FIXME #3169: This is a little odd but it arises due to a weird
-          // wrinkle in LLVM: it doesn't appear willing to let us call
-          // LLVMConstIntGetZExtValue on the size element of the slice, or
-          // seemingly any integer-const involving a sizeof() call. Despite
-          // that being "a const", it's not the kind of const you can ask
-          // for the integer-value of, evidently. This might be an LLVM
-          // bug, not sure. In any case, to work around this we drop down
-          // to the array-type level here and just ask how long the
-          // array-type itself is, ignoring the length we pulled out of the
-          // slice. This in turn only works because we picked out the
-          // original globalvar via const_deref and so can recover the
-          // array-size of the underlying array, and all this will hold
-          // together exactly as long as we _don't_ support const
-          // sub-slices (that is, slices that represent something other
-          // than a whole array).  At that point we'll have more and uglier
-          // work to do here, but for now this should work.
-          //
-          // In the future, what we should be doing here is the
-          // moral equivalent of:
-          //
-          // let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
-          //
-          // but we might have to do substantially more magic to
-          // make it work. Or figure out what is causing LLVM to
-          // not want to consider sizeof() a constant expression
-          // we can get the value (as a number) out of.
+              // FIXME #3169: This is a little odd but it arises due to a
+              // weird wrinkle in LLVM: it doesn't appear willing to let us
+              // call LLVMConstIntGetZExtValue on the size element of the
+              // slice, or seemingly any integer-const involving a sizeof()
+              // call. Despite that being "a const", it's not the kind of
+              // const you can ask for the integer-value of, evidently. This
+              // might be an LLVM bug, not sure. In any case, to work around
+              // this we drop down to the array-type level here and just ask
+              // how long the array-type itself is, ignoring the length we
+              // pulled out of the slice. This in turn only works because we
+              // picked out the original globalvar via const_deref and so can
+              // recover the array-size of the underlying array, and all this
+              // will hold together exactly as long as we _don't_ support
+              // const sub-slices (that is, slices that represent something
+              // other than a whole array).  At that point we'll have more and
+              // uglier work to do here, but for now this should work.
+              //
+              // In the future, what we should be doing here is the
+              // moral equivalent of:
+              //
+              // let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
+              //
+              // but we might have to do substantially more magic to
+              // make it work. Or figure out what is causing LLVM to
+              // not want to consider sizeof() a constant expression
+              // we can get the value (as a number) out of.
 
-          let len = llvm::LLVMGetArrayLength(val_ty(arr)) as u64;
-          let len = match ty::get(bt).sty {
-              ty::ty_estr(*) => {assert len > 0; len - 1},
-              _ => len
-          };
-          if iv >= len {
-              // FIXME #3170: report this earlier on in the const-eval
-              // pass. Reporting here is a bit late.
-              cx.sess.span_err(e.span,
-                               ~"const index-expr is out of bounds");
+              let len = llvm::LLVMGetArrayLength(val_ty(arr)) as u64;
+              let len = match ty::get(bt).sty {
+                  ty::ty_estr(*) => {assert len > 0; len - 1},
+                  _ => len
+              };
+              if iv >= len {
+                  // FIXME #3170: report this earlier on in the const-eval
+                  // pass. Reporting here is a bit late.
+                  cx.sess.span_err(e.span,
+                                   ~"const index-expr is out of bounds");
+              }
+              const_get_elt(cx, arr, [iv as c_uint])
           }
-          const_get_elt(cx, arr, [iv as c_uint])
-      }
-      ast::expr_cast(base, _) => {
-        let ety = ty::expr_ty(cx.tcx, e), llty = type_of::type_of(cx, ety);
-        let basety = ty::expr_ty(cx.tcx, base);
-        let v = const_expr(cx, base);
-        match (expr::cast_type_kind(basety),
-               expr::cast_type_kind(ety)) {
+          ast::expr_cast(base, _) => {
+            let ety = ty::expr_ty(cx.tcx, e);
+            let llty = type_of::type_of(cx, ety);
+            let basety = ty::expr_ty(cx.tcx, base);
+            let v = const_expr(cx, base);
+            match (expr::cast_type_kind(basety),
+                   expr::cast_type_kind(ety)) {
 
-          (expr::cast_integral, expr::cast_integral) => {
-            let s = if ty::type_is_signed(basety) { True } else { False };
-            llvm::LLVMConstIntCast(v, llty, s)
-          }
-          (expr::cast_integral, expr::cast_float) => {
-            if ty::type_is_signed(basety) { llvm::LLVMConstSIToFP(v, llty) }
-            else { llvm::LLVMConstUIToFP(v, llty) }
-          }
-          (expr::cast_float, expr::cast_float) => {
-            llvm::LLVMConstFPCast(v, llty)
-          }
-          (expr::cast_float, expr::cast_integral) => {
-            if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) }
-            else { llvm::LLVMConstFPToUI(v, llty) }
-          }
-          _ => cx.sess.impossible_case(e.span,
-                                       ~"bad combination of types for cast")
-        }
-      }
-      ast::expr_addr_of(ast::m_imm, sub) => {
-        let cv = const_expr(cx, sub);
-        let subty = ty::expr_ty(cx.tcx, sub),
-        llty = type_of::type_of(cx, subty);
-        let gv = do str::as_c_str("const") |name| {
-            llvm::LLVMAddGlobal(cx.llmod, llty, name)
-        };
-        llvm::LLVMSetInitializer(gv, cv);
-        llvm::LLVMSetGlobalConstant(gv, True);
-        gv
-      }
-      ast::expr_tup(es) => {
-        C_struct(es.map(|e| const_expr(cx, *e)))
-      }
-      ast::expr_rec(ref fs, None) => {
-          C_struct([C_struct(
-              (*fs).map(|f| const_expr(cx, f.node.expr)))])
-      }
-      ast::expr_struct(_, ref fs, _) => {
-          let ety = ty::expr_ty(cx.tcx, e);
-          let cs = do expr::with_field_tys(cx.tcx,
-                                           ety,
-                                           None) |_hd, field_tys| {
-              field_tys.map(|field_ty| {
-                  match fs.find(|f| field_ty.ident == f.node.ident) {
-                      Some(ref f) => const_expr(cx, (*f).node.expr),
-                      None => {
-                          cx.tcx.sess.span_bug(
-                              e.span, ~"missing struct field");
-                      }
-                  }
-              })
-          };
-          let llty = type_of::type_of(cx, ety);
-          C_named_struct(llty, [C_struct(cs)])
-      }
-      ast::expr_vec(es, ast::m_imm) => {
-        let (v, _, _) = const_vec(cx, e, es);
-        v
-      }
-      ast::expr_vstore(e, ast::expr_vstore_fixed(_)) => {
-        const_expr(cx, e)
-      }
-      ast::expr_vstore(sub, ast::expr_vstore_slice) => {
-        match sub.node {
-          ast::expr_lit(lit) => {
-            match lit.node {
-              ast::lit_str(*) => { const_expr(cx, sub) }
-              _ => { cx.sess.span_bug(e.span,
-                                      ~"bad const-slice lit") }
+              (expr::cast_integral, expr::cast_integral) => {
+                let s = if ty::type_is_signed(basety) { True } else { False };
+                llvm::LLVMConstIntCast(v, llty, s)
+              }
+              (expr::cast_integral, expr::cast_float) => {
+                if ty::type_is_signed(basety) {
+                    llvm::LLVMConstSIToFP(v, llty)
+                } else {
+                    llvm::LLVMConstUIToFP(v, llty)
+                }
+              }
+              (expr::cast_float, expr::cast_float) => {
+                llvm::LLVMConstFPCast(v, llty)
+              }
+              (expr::cast_float, expr::cast_integral) => {
+                if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) }
+                else { llvm::LLVMConstFPToUI(v, llty) }
+              }
+              _ => {
+                cx.sess.impossible_case(e.span,
+                                        ~"bad combination of types for cast")
+              }
             }
           }
-          ast::expr_vec(es, ast::m_imm) => {
-            let (cv, sz, llunitty) = const_vec(cx, e, es);
-            let llty = val_ty(cv);
+          ast::expr_addr_of(ast::m_imm, sub) => {
+            let cv = const_expr(cx, sub);
+            let subty = ty::expr_ty(cx.tcx, sub),
+            llty = type_of::type_of(cx, subty);
             let gv = do str::as_c_str("const") |name| {
                 llvm::LLVMAddGlobal(cx.llmod, llty, name)
             };
             llvm::LLVMSetInitializer(gv, cv);
             llvm::LLVMSetGlobalConstant(gv, True);
-            let p = const_ptrcast(cx, gv, llunitty);
-            C_struct(~[p, sz])
+            gv
           }
-          _ => cx.sess.span_bug(e.span,
-                                ~"bad const-slice expr")
-        }
-      }
-      ast::expr_path(pth) => {
-        assert pth.types.len() == 0;
-        match cx.tcx.def_map.find(e.id) {
-            Some(ast::def_fn(def_id, _)) => {
-                assert ast_util::is_local(def_id);
-                let f = base::get_item_val(cx, def_id.node);
-                C_struct(~[f, C_null(T_opaque_box_ptr(cx))])
+          ast::expr_tup(es) => {
+            C_struct(es.map(|e| const_expr(cx, *e)))
+          }
+          ast::expr_rec(ref fs, None) => {
+              C_struct([C_struct(
+                  (*fs).map(|f| const_expr(cx, f.node.expr)))])
+          }
+          ast::expr_struct(_, ref fs, _) => {
+              let ety = ty::expr_ty(cx.tcx, e);
+              let cs = do expr::with_field_tys(cx.tcx,
+                                               ety,
+                                               None) |_hd, field_tys| {
+                  field_tys.map(|field_ty| {
+                      match fs.find(|f| field_ty.ident == f.node.ident) {
+                          Some(ref f) => const_expr(cx, (*f).node.expr),
+                          None => {
+                              cx.tcx.sess.span_bug(
+                                  e.span, ~"missing struct field");
+                          }
+                      }
+                  })
+              };
+              let llty = type_of::type_of(cx, ety);
+              C_named_struct(llty, [C_struct(cs)])
+          }
+          ast::expr_vec(es, ast::m_imm) => {
+            let (v, _, _) = const_vec(cx, e, es);
+            v
+          }
+          ast::expr_vstore(e, ast::expr_vstore_fixed(_)) => {
+            const_expr(cx, e)
+          }
+          ast::expr_vstore(sub, ast::expr_vstore_slice) => {
+            match /*bad*/copy sub.node {
+              ast::expr_lit(lit) => {
+                match lit.node {
+                  ast::lit_str(*) => { const_expr(cx, sub) }
+                  _ => { cx.sess.span_bug(e.span,
+                                          ~"bad const-slice lit") }
+                }
+              }
+              ast::expr_vec(es, ast::m_imm) => {
+                let (cv, sz, llunitty) = const_vec(cx, e, es);
+                let llty = val_ty(cv);
+                let gv = do str::as_c_str("const") |name| {
+                    llvm::LLVMAddGlobal(cx.llmod, llty, name)
+                };
+                llvm::LLVMSetInitializer(gv, cv);
+                llvm::LLVMSetGlobalConstant(gv, True);
+                let p = const_ptrcast(cx, gv, llunitty);
+                C_struct(~[p, sz])
+              }
+              _ => cx.sess.span_bug(e.span,
+                                    ~"bad const-slice expr")
             }
-            Some(ast::def_const(def_id)) => {
-                get_const_val(cx, def_id)
+          }
+          ast::expr_path(pth) => {
+            assert pth.types.len() == 0;
+            match cx.tcx.def_map.find(e.id) {
+                Some(ast::def_fn(def_id, _)) => {
+                    assert ast_util::is_local(def_id);
+                    let f = base::get_item_val(cx, def_id.node);
+                    C_struct(~[f, C_null(T_opaque_box_ptr(cx))])
+                }
+                Some(ast::def_const(def_id)) => {
+                    get_const_val(cx, def_id)
+                }
+                Some(ast::def_variant(enum_did, variant_did)) => {
+                    // Note that we know this is a C-like (nullary) enum
+                    // variant or we wouldn't have gotten here -- the constant
+                    // checker forbids paths that don't map to C-like enum
+                    // variants.
+                    let lldiscrim = base::get_discrim_val(cx, e.span,
+                                                          enum_did,
+                                                          variant_did);
+                    C_struct(~[lldiscrim])
+                }
+                Some(ast::def_struct(_)) => {
+                    let ety = ty::expr_ty(cx.tcx, e);
+                    let llty = type_of::type_of(cx, ety);
+                    C_null(llty)
+                }
+                _ => {
+                    cx.sess.span_bug(e.span,
+                                     ~"expected a const, fn, or variant def")
+                }
             }
-            Some(ast::def_variant(enum_did, variant_did)) => {
-                // Note that we know this is a C-like (nullary) enum variant,
-                // or we wouldn't have gotten here -- the constant checker
-                // forbids paths that don't map to C-like enum variants.
-                let ety = ty::expr_ty(cx.tcx, e);
-                let llty = type_of::type_of(cx, ety);
-                let llstructtys = lib::llvm::struct_element_types(llty);
-
-                // Can't use `discrims` from the crate context here because
-                // those discriminants have an extra level of indirection,
-                // and there's no LLVM constant load instruction.
-                let mut lldiscrim_opt = None;
-                for ty::enum_variants(cx.tcx, enum_did).each |variant_info| {
-                    if variant_info.id == variant_did {
-                        lldiscrim_opt = Some(C_int(cx,
-                                                   variant_info.disr_val));
-                        break;
+          }
+          ast::expr_call(callee, args, _) => {
+            match cx.tcx.def_map.find(callee.id) {
+                Some(ast::def_struct(def_id)) => {
+                    let ety = ty::expr_ty(cx.tcx, e);
+                    let llty = type_of::type_of(cx, ety);
+                    let llstructbody =
+                        C_struct(args.map(|a| const_expr(cx, *a)));
+                    if ty::ty_dtor(cx.tcx, def_id).is_present() {
+                        C_named_struct(llty, ~[ llstructbody, C_u8(0) ])
+                    } else {
+                        C_named_struct(llty, ~[ llstructbody ])
                     }
                 }
+            Some(ast::def_variant(tid, vid)) => {
+                let ety = ty::expr_ty(cx.tcx, e);
+                let degen = ty::enum_is_univariant(cx.tcx, tid);
+                let size = shape::static_size_of_enum(cx, ety);
 
-                let lldiscrim;
-                match lldiscrim_opt {
-                    None => {
-                        cx.tcx.sess.span_bug(e.span,
-                                             ~"didn't find discriminant?!");
-                    }
-                    Some(found_lldiscrim) => {
-                        lldiscrim = found_lldiscrim;
-                    }
-                }
+                let discrim = base::get_discrim_val(cx, e.span, tid, vid);
+                let c_args = C_struct(args.map(|a| const_expr(cx, *a)));
 
-                C_named_struct(llty, ~[ lldiscrim, C_null(llstructtys[1]) ])
-            }
-            Some(ast::def_struct(_)) => {
-                let ety = ty::expr_ty(cx.tcx, e);
-                let llty = type_of::type_of(cx, ety);
-                C_null(llty)
-            }
-            _ => {
-                cx.sess.span_bug(e.span,
-                                 ~"expected a const, fn, or variant def")
-            }
-        }
-      }
-      ast::expr_call(callee, args, _) => {
-        match cx.tcx.def_map.find(callee.id) {
-            Some(ast::def_struct(def_id)) => {
-                let ety = ty::expr_ty(cx.tcx, e);
-                let llty = type_of::type_of(cx, ety);
-                let llstructbody = C_struct(args.map(|a| const_expr(cx, *a)));
-                if ty::ty_dtor(cx.tcx, def_id).is_present() {
-                    C_named_struct(llty, ~[ llstructbody, C_u8(0) ])
+                let fields = if !degen {
+                    ~[discrim, c_args]
+                } else if size == 0 {
+                    ~[discrim]
                 } else {
-                    C_named_struct(llty, ~[ llstructbody ])
-                }
+                    ~[c_args]
+                };
+
+                C_struct(fields)
             }
-            _ => cx.sess.span_bug(e.span, ~"expected a struct def")
-        }
-      }
-      ast::expr_paren(e) => { return const_expr(cx, e); }
-      _ => cx.sess.span_bug(e.span,
-            ~"bad constant expression type in consts::const_expr")
-    };
+                _ => cx.sess.span_bug(e.span, ~"expected a struct def")
+            }
+          }
+          ast::expr_paren(e) => { return const_expr(cx, e); }
+          _ => cx.sess.span_bug(e.span,
+                ~"bad constant expression type in consts::const_expr")
+        };
+    }
 }
 
-fn trans_const(ccx: @crate_ctxt, e: @ast::expr, id: ast::node_id) {
-    let _icx = ccx.insn_ctxt("trans_const");
-    let g = base::get_item_val(ccx, id);
-    let v = const_expr(ccx, e);
-    ccx.const_values.insert(id, v);
-    llvm::LLVMSetInitializer(g, v);
-    llvm::LLVMSetGlobalConstant(g, True);
+fn trans_const(ccx: @crate_ctxt, _e: @ast::expr, id: ast::node_id) {
+    unsafe {
+        let _icx = ccx.insn_ctxt("trans_const");
+        let g = base::get_item_val(ccx, id);
+        // At this point, get_item_val has already translated the
+        // constant's initializer to determine its LLVM type.
+        let v = ccx.const_values.get(id);
+        llvm::LLVMSetInitializer(g, v);
+        llvm::LLVMSetGlobalConstant(g, True);
+    }
 }
index 2a9cece231b7359b377148a15ebfe5e179b5dd18..b325e33f03a1897ac640be4b19e6dcafc5769af2 100644 (file)
@@ -8,11 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use lib::llvm::ValueRef;
 use middle::trans::base::*;
+use middle::trans::callee;
 use middle::trans::common::*;
 use middle::trans::datum::*;
 
+use core::str;
+
 fn macros() { include!("macros.rs"); } // FIXME(#3114): Macro import/export.
 
 fn trans_block(bcx: block, b: ast::blk, dest: expr::Dest) -> block {
@@ -168,23 +173,28 @@ fn trans_log(log_ex: @ast::expr,
     }
 
     let modpath = vec::append(
-        ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))],
-        vec::filter(bcx.fcx.path, |e|
+        ~[path_mod(ccx.sess.ident_of(/*bad*/copy ccx.link_meta.name))],
+        bcx.fcx.path.filtered(|e|
             match *e { path_mod(_) => true, _ => false }
         ));
-    let modname = path_str(ccx.sess, modpath);
+    // XXX: Bad copy.
+    let modname = path_str(ccx.sess, copy modpath);
 
-    let global = if ccx.module_data.contains_key(modname) {
+    // XXX: Bad copy.
+    let global = if ccx.module_data.contains_key(copy modname) {
         ccx.module_data.get(modname)
     } else {
         let s = link::mangle_internal_name_by_path_and_seq(
             ccx, modpath, ~"loglevel");
-        let global = str::as_c_str(s, |buf| {
-            llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
-        });
-        llvm::LLVMSetGlobalConstant(global, False);
-        llvm::LLVMSetInitializer(global, C_null(T_i32()));
-        lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage);
+        let global;
+        unsafe {
+            global = str::as_c_str(s, |buf| {
+                llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
+            });
+            llvm::LLVMSetGlobalConstant(global, False);
+            llvm::LLVMSetInitializer(global, C_null(T_i32()));
+            lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage);
+        }
         ccx.module_data.insert(modname, global);
         global
     };
@@ -205,7 +215,7 @@ fn trans_log(log_ex: @ast::expr,
 
             // Call the polymorphic log function
             let val = val_datum.to_ref_llval(bcx);
-            let did = bcx.tcx().lang_items.log_type_fn.get();
+            let did = bcx.tcx().lang_items.log_type_fn();
             let bcx = callee::trans_rtcall_or_lang_call_with_type_params(
                 bcx, did, ~[level, val], ~[val_datum.ty], expr::Ignore);
             bcx
@@ -221,7 +231,11 @@ fn trans_break_cont(bcx: block, opt_label: Option<ident>, to_end: bool)
     let mut target;
     loop {
         match unwind.kind {
-          block_scope({loop_break: Some(brk), loop_label: l, _}) => {
+          block_scope(scope_info {
+            loop_break: Some(brk),
+            loop_label: l,
+            _
+          }) => {
               // If we're looking for a labeled loop, check the label...
               target = if to_end {
                   brk
@@ -303,7 +317,7 @@ fn trans_check_expr(bcx: block, chk_expr: @ast::expr,
         }
     };
     do with_cond(bcx, Not(bcx, val)) |bcx| {
-        trans_fail(bcx, Some(pred_expr.span), expr_str)
+        trans_fail(bcx, Some(pred_expr.span), /*bad*/copy expr_str)
     }
 }
 
@@ -333,7 +347,7 @@ fn trans_fail_expr(bcx: block,
     }
 }
 
-fn trans_fail(bcx: block, sp_opt: Option<span>, fail_str: ~str)
+fn trans_fail(bcx: block, sp_opt: Option<span>, +fail_str: ~str)
     -> block
 {
     let _icx = bcx.insn_ctxt("trans_fail");
@@ -350,7 +364,7 @@ fn trans_fail_value(bcx: block, sp_opt: Option<span>, V_fail_str: ValueRef)
       Some(sp) => {
         let sess = bcx.sess();
         let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo);
-        {V_filename: C_cstr(bcx.ccx(), loc.file.name),
+        {V_filename: C_cstr(bcx.ccx(), /*bad*/copy loc.file.name),
          V_line: loc.line as int}
       }
       None => {
@@ -361,7 +375,8 @@ fn trans_fail_value(bcx: block, sp_opt: Option<span>, V_fail_str: ValueRef)
     let V_str = PointerCast(bcx, V_fail_str, T_ptr(T_i8()));
     let V_filename = PointerCast(bcx, V_filename, T_ptr(T_i8()));
     let args = ~[V_str, V_filename, C_int(ccx, V_line)];
-    let bcx = callee::trans_rtcall(bcx, ~"fail_", args, expr::Ignore);
+    let bcx = callee::trans_rtcall_or_lang_call(
+        bcx, bcx.tcx().lang_items.fail_fn(), args, expr::Ignore);
     Unreachable(bcx);
     return bcx;
 }
@@ -373,12 +388,12 @@ fn trans_fail_bounds_check(bcx: block, sp: span,
 
     let loc = bcx.sess().parse_sess.cm.lookup_char_pos(sp.lo);
     let line = C_int(ccx, loc.line as int);
-    let filename_cstr = C_cstr(bcx.ccx(), loc.file.name);
+    let filename_cstr = C_cstr(bcx.ccx(), /*bad*/copy loc.file.name);
     let filename = PointerCast(bcx, filename_cstr, T_ptr(T_i8()));
 
     let args = ~[filename, line, index, len];
-    let bcx = callee::trans_rtcall(bcx, ~"fail_bounds_check", args,
-                                   expr::Ignore);
+    let bcx = callee::trans_rtcall_or_lang_call(
+        bcx, bcx.tcx().lang_items.fail_bounds_check_fn(), args, expr::Ignore);
     Unreachable(bcx);
     return bcx;
 }
index e303b3611c577dc4d206d222a54eb1d826ca2e71..b94d06585977661e06745abff34c7b7c49b54456 100644 (file)
  * methods themselves.  Most are only suitable for some types of
  * values. */
 
+use core::prelude::*;
+
 use lib::llvm::ValueRef;
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::common::*;
+use middle::trans::common;
+use middle::trans::tvec;
+use middle::typeck;
 use util::common::indenter;
 use util::ppaux::ty_to_str;
 
+use core::cmp;
+use core::option;
+use core::uint;
+use core::vec;
+use syntax::parse::token::special_idents;
+
 enum CopyAction {
     INIT,
     DROP_EXISTING
@@ -669,7 +680,7 @@ fn try_deref(
                 // Check whether this struct is a newtype struct.
                 let fields = ty::struct_fields(ccx.tcx, did, substs);
                 if fields.len() != 1 || fields[0].ident !=
-                    syntax::parse::token::special_idents::unnamed_field {
+                    special_idents::unnamed_field {
                     return None;
                 }
 
index b255b47bab30bac3297a746fd920456b6e664ce4..95ff77c16b95f802d70b0bb9fab6268470f1fea0 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use driver::session;
 use lib::llvm::ValueRef;
 use lib::llvm::llvm;
 use middle::trans::base;
 use middle::trans::build::B;
 use middle::trans::common::*;
+use middle::trans::shape;
+use middle::trans::type_of;
+use middle::trans;
 use middle::ty;
 use util::ppaux::ty_to_str;
 
+use core::libc;
+use core::option;
+use core::sys;
 use std::map::HashMap;
 use std::map;
 use syntax::ast::Ty;
@@ -61,7 +69,9 @@
 
 fn llstr(s: ~str) -> ValueRef {
     str::as_c_str(s, |sbuf| {
-        llvm::LLVMMDString(sbuf, str::len(s) as libc::c_uint)
+        unsafe {
+            llvm::LLVMMDString(sbuf, str::len(s) as libc::c_uint)
+        }
     })
 }
 fn lltag(lltag: int) -> ValueRef {
@@ -77,8 +87,10 @@ fn lli1(bval: bool) -> ValueRef {
     C_bool(bval)
 }
 fn llmdnode(elems: ~[ValueRef]) -> ValueRef unsafe {
-    llvm::LLVMMDNode(vec::raw::to_ptr(elems),
-                     vec::len(elems) as libc::c_uint)
+    unsafe {
+        llvm::LLVMMDNode(vec::raw::to_ptr(elems),
+                         vec::len(elems) as libc::c_uint)
+    }
 }
 fn llunused() -> ValueRef {
     lli32(0x0)
@@ -89,7 +101,9 @@ fn llnull() -> ValueRef unsafe {
 
 fn add_named_metadata(cx: @crate_ctxt, name: ~str, val: ValueRef) {
     str::as_c_str(name, |sbuf| {
-        llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val)
+        unsafe {
+            llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val)
+        }
     })
 }
 
@@ -101,7 +115,7 @@ fn add_named_metadata(cx: @crate_ctxt, name: ~str, val: ValueRef) {
     crate_file: ~str
 };
 
-fn mk_ctxt(crate: ~str, intr: @ident_interner) -> debug_ctxt {
+fn mk_ctxt(+crate: ~str, intr: @ident_interner) -> debug_ctxt {
     {llmetadata: map::HashMap(),
      names: new_namegen(intr),
      crate_file: crate}
@@ -175,7 +189,7 @@ fn cached_metadata<T: Copy>(cache: metadata_cache, mdtag: int,
 fn create_compile_unit(cx: @crate_ctxt)
     -> @metadata<compile_unit_md> unsafe {
     let cache = get_cache(cx);
-    let crate_name = cx.dbg_cx.get().crate_file;
+    let crate_name = /*bad*/copy (/*bad*/copy cx.dbg_cx).get().crate_file;
     let tg = CompileUnitTag;
     match cached_metadata::<@metadata<compile_unit_md>>(cache, tg,
                         |md| md.data.name == crate_name) {
@@ -188,7 +202,7 @@ fn create_compile_unit(cx: @crate_ctxt)
     let unit_metadata = ~[lltag(tg),
                          llunused(),
                          lli32(DW_LANG_RUST),
-                         llstr(crate_name),
+                         llstr(copy crate_name),
                          llstr(work_dir),
                          llstr(env!("CFG_VERSION")),
                          lli1(true), // deprecated: main compile unit
@@ -205,7 +219,7 @@ fn create_compile_unit(cx: @crate_ctxt)
 }
 
 fn get_cache(cx: @crate_ctxt) -> metadata_cache {
-    cx.dbg_cx.get().llmetadata
+    (/*bad*/copy cx.dbg_cx).get().llmetadata
 }
 
 fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) {
@@ -217,7 +231,7 @@ fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) {
     }, str::from_slice(work_dir))
 }
 
-fn create_file(cx: @crate_ctxt, full_path: ~str) -> @metadata<file_md> {
+fn create_file(cx: @crate_ctxt, +full_path: ~str) -> @metadata<file_md> {
     let cache = get_cache(cx);;
     let tg = FileDescriptorTag;
     match cached_metadata::<@metadata<file_md>>(
@@ -256,10 +270,10 @@ fn create_block(cx: block) -> @metadata<block_md> {
     let sp = cx.node_info.get().span;
 
     let start = cx.sess().codemap.lookup_char_pos(sp.lo);
-    let fname = start.file.name;
+    let fname = /*bad*/copy start.file.name;
     let end = cx.sess().codemap.lookup_char_pos(sp.hi);
     let tg = LexicalBlockTag;
-    /*alt cached_metadata::<@metadata<block_md>>(
+    /*match cached_metadata::<@metadata<block_md>>(
         cache, tg,
         {|md| start == md.data.start && end == md.data.end}) {
       option::Some(md) { return md; }
@@ -359,12 +373,18 @@ fn create_pointer_type(cx: @crate_ctxt, t: ty::t, span: span,
 };
 
 fn finish_structure(cx: @struct_ctxt) -> ValueRef {
-    return create_composite_type(StructureTypeTag, cx.name, cx.file, cx.line,
-                              cx.total_size, cx.align, 0, option::None,
-                              option::Some(cx.members));
-}
-
-fn create_structure(file: @metadata<file_md>, name: ~str, line: int)
+    return create_composite_type(StructureTypeTag,
+                                 /*bad*/copy cx.name,
+                                 cx.file,
+                                 cx.line,
+                                 cx.total_size,
+                                 cx.align,
+                                 0,
+                                 option::None,
+                                 option::Some(/*bad*/copy cx.members));
+}
+
+fn create_structure(file: @metadata<file_md>, +name: ~str, line: int)
     -> @struct_ctxt {
     let cx = @{file: file.node,
                name: name,
@@ -376,7 +396,7 @@ fn create_structure(file: @metadata<file_md>, name: ~str, line: int)
     return cx;
 }
 
-fn create_derived_type(type_tag: int, file: ValueRef, name: ~str, line: int,
+fn create_derived_type(type_tag: int, file: ValueRef, +name: ~str, line: int,
                        size: int, align: int, offset: int, ty: ValueRef)
     -> ValueRef {
     let lldata = ~[lltag(type_tag),
@@ -392,7 +412,7 @@ fn create_derived_type(type_tag: int, file: ValueRef, name: ~str, line: int,
     return llmdnode(lldata);
 }
 
-fn add_member(cx: @struct_ctxt, name: ~str, line: int, size: int, align: int,
+fn add_member(cx: @struct_ctxt, +name: ~str, line: int, size: int, align: int,
               ty: ValueRef) {
     cx.members.push(create_derived_type(MemberTag, cx.file, name, line,
                                        size * 8, align * 8, cx.total_size,
@@ -406,7 +426,8 @@ fn create_record(cx: @crate_ctxt, t: ty::t, fields: ~[ast::ty_field],
     let file_node = create_file(cx, fname);
     let scx = create_structure(file_node,
                                cx.sess.str_of(
-                                   (cx.dbg_cx.get().names)(~"rec")),
+                                   ((/*bad*/copy cx.dbg_cx).get().names)
+                                   (~"rec")),
                                line_from_span(cx.sess.codemap,
                                               span) as int);
     for fields.each |field| {
@@ -449,10 +470,10 @@ fn create_boxed_type(cx: @crate_ctxt, outer: ty::t, _inner: ty::t,
     return mdval;
 }
 
-fn create_composite_type(type_tag: int, name: ~str, file: ValueRef, line: int,
-                         size: int, align: int, offset: int,
+fn create_composite_type(type_tag: int, +name: ~str, file: ValueRef,
+                         line: int, size: int, align: int, offset: int,
                          derived: Option<ValueRef>,
-                         members: Option<~[ValueRef]>)
+                         +members: Option<~[ValueRef]>)
     -> ValueRef {
     let lldata = ~[lltag(type_tag),
                   file,
@@ -608,10 +629,10 @@ fn t_to_ty(cx: crate_ctxt, t: ty::t, span: span) -> @ast::ty {
 }
 
 fn filename_from_span(cx: @crate_ctxt, sp: codemap::span) -> ~str {
-    cx.sess.codemap.lookup_char_pos(sp.lo).file.name
+    /*bad*/copy cx.sess.codemap.lookup_char_pos(sp.lo).file.name
 }
 
-fn create_var(type_tag: int, context: ValueRef, name: ~str, file: ValueRef,
+fn create_var(type_tag: int, context: ValueRef, +name: ~str, file: ValueRef,
               line: int, ret_ty: ValueRef) -> ValueRef {
     let lldata = ~[lltag(type_tag),
                   context,
@@ -643,7 +664,7 @@ fn create_local_var(bcx: block, local: @ast::local)
     let loc = cx.sess.codemap.lookup_char_pos(local.span.lo);
     let ty = node_id_type(bcx, local.node.id);
     let tymd = create_ty(cx, ty, local.node.ty);
-    let filemd = create_file(cx, loc.file.name);
+    let filemd = create_file(cx, /*bad*/copy loc.file.name);
     let context = match bcx.parent {
         None => create_function(bcx.fcx).node,
         Some(_) => create_block(bcx).node
@@ -687,7 +708,7 @@ fn create_arg(bcx: block, arg: ast::arg, sp: span)
     let loc = cx.sess.codemap.lookup_char_pos(sp.lo);
     let ty = node_id_type(bcx, arg.id);
     let tymd = create_ty(cx, ty, arg.ty);
-    let filemd = create_file(cx, loc.file.name);
+    let filemd = create_file(cx, /*bad*/copy loc.file.name);
     let context = create_function(bcx.fcx);
 
     match arg.pat.node {
@@ -729,12 +750,14 @@ fn update_source_pos(cx: block, s: span) {
                      blockmd.node,
                      llnull()];
     let dbgscope = llmdnode(scopedata);
-    llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope);
+    unsafe {
+        llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope);
+    }
 }
 
 fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
     let cx = fcx.ccx;
-    let dbg_cx = cx.dbg_cx.get();
+    let dbg_cx = (/*bad*/copy cx.dbg_cx).get();
 
     debug!("~~");
     log(debug, fcx.id);
@@ -744,7 +767,7 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
 
     let (ident, ret_ty, id) = match cx.tcx.items.get(fcx.id) {
       ast_map::node_item(item, _) => {
-        match item.node {
+        match /*bad*/copy item.node {
           ast::item_fn(decl, _, _, _) => {
             (item.ident, decl.output, item.id)
           }
@@ -756,7 +779,7 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
           (method.ident, method.decl.output, method.id)
       }
       ast_map::node_expr(expr) => {
-        match expr.node {
+        match /*bad*/copy expr.node {
           ast::expr_fn(_, decl, _, _) => {
             ((dbg_cx.names)(~"fn"), decl.output, expr.id)
           }
index 662469655332c66d6ec42e998467e959412954fe..c26328d7d9c3fb3a02f8c937fb01a782cf194632 100644 (file)
 
 */
 
+use core::prelude::*;
+
 use lib::llvm::ValueRef;
+use middle::resolve;
 use middle::trans::base::*;
 use middle::trans::callee::{AutorefArg, DoAutorefArg, DontAutorefArg};
+use middle::trans::callee;
+use middle::trans::closure;
 use middle::trans::common::*;
+use middle::trans::consts;
+use middle::trans::controlflow;
 use middle::trans::datum::*;
+use middle::trans::machine;
+use middle::trans::meth;
+use middle::trans::tvec;
 use middle::ty::MoveValue;
 use middle::ty::struct_mutable_fields;
 use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn};
 use util::ppaux::ty_to_str;
 
 use syntax::print::pprust::{expr_to_str};
+use syntax::ast;
+use syntax::ast::spanned;
 
 // The primary two functions for translating expressions:
 export trans_to_datum, trans_into;
@@ -506,7 +518,8 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
 
     trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
 
-    match expr.node {
+    // XXX: This copy is really bad.
+    match /*bad*/copy expr.node {
         ast::expr_paren(e) => {
             return trans_rvalue_dps_unadjusted(bcx, e, dest);
         }
@@ -518,7 +531,8 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
             return controlflow::trans_if(bcx, cond, (*thn), els, dest);
         }
         ast::expr_match(discr, ref arms) => {
-            return alt::trans_alt(bcx, expr, discr, (*arms), dest);
+            return _match::trans_match(bcx, expr, discr, /*bad*/copy *arms,
+                                       dest);
         }
         ast::expr_block(ref blk) => {
             return do base::with_scope(bcx, (*blk).info(),
@@ -533,7 +547,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
         ast::expr_tup(args) => {
             return trans_tup(bcx, args, dest);
         }
-        ast::expr_lit(@{node: ast::lit_str(s), _}) => {
+        ast::expr_lit(@ast::spanned {node: ast::lit_str(s), _}) => {
             return tvec::trans_lit_str(bcx, expr, s, dest);
         }
         ast::expr_vstore(contents, ast::expr_vstore_slice) |
@@ -546,13 +560,16 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
         ast::expr_vec(*) | ast::expr_repeat(*) => {
             return tvec::trans_fixed_vstore(bcx, expr, expr, dest);
         }
-        ast::expr_fn(proto, decl, ref body, cap_clause) => {
+        // XXX: Bad copy.
+        ast::expr_fn(proto, copy decl, ref body, cap_clause) => {
             // Don't use this function for anything real. Use the one in
             // astconv instead.
-            return closure::trans_expr_fn(bcx, proto, decl, *body, expr.id,
+            return closure::trans_expr_fn(bcx, proto, decl,
+                                          /*bad*/copy *body,
+                                          expr.id, expr.id,
                                           cap_clause, None, dest);
         }
-        ast::expr_fn_block(decl, ref body, cap_clause) => {
+        ast::expr_fn_block(ref decl, ref body, cap_clause) => {
             let expr_ty = expr_ty(bcx, expr);
             match ty::get(expr_ty).sty {
                 ty::ty_fn(ref fn_ty) => {
@@ -560,7 +577,8 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
                            expr_to_str(expr, tcx.sess.intr()),
                            ty_to_str(tcx, expr_ty));
                     return closure::trans_expr_fn(
-                        bcx, fn_ty.meta.proto, decl, *body, expr.id,
+                        bcx, fn_ty.meta.proto, /*bad*/copy *decl,
+                        /*bad*/copy *body, expr.id, expr.id,
                         cap_clause, None, dest);
                 }
                 _ => {
@@ -573,10 +591,17 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
             match ty::get(expr_ty(bcx, expr)).sty {
                 ty::ty_fn(ref fn_ty) => {
                     match blk.node {
-                        ast::expr_fn_block(decl, ref body, cap) => {
+                        ast::expr_fn_block(copy decl, ref body, cap) => {
                             return closure::trans_expr_fn(
-                                bcx, fn_ty.meta.proto, decl, *body, blk.id,
-                                cap, Some(None), dest);
+                                bcx,
+                                fn_ty.meta.proto,
+                                decl,
+                                /*bad*/copy *body,
+                                expr.id,
+                                blk.id,
+                                cap,
+                                Some(None),
+                                dest);
                         }
                         _ => {
                             bcx.sess().impossible_case(
@@ -776,7 +801,11 @@ fn trans_def_lvalue(bcx: block,
         ast::def_const(did) => {
             let const_ty = expr_ty(bcx, ref_expr);
             let val = if did.crate == ast::local_crate {
-                base::get_item_val(ccx, did.node)
+                // The LLVM global has the type of its initializer,
+                // which may not be equal to the enum's type for
+                // non-C-like enums.
+                PointerCast(bcx, base::get_item_val(ccx, did.node),
+                            T_ptr(type_of(bcx.ccx(), const_ty)))
             } else {
                 base::trans_external_path(ccx, did, const_ty)
             };
@@ -1461,15 +1490,19 @@ fn trans_overloaded_op(bcx: block,
 fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef,
             llsrc: ValueRef, signed: bool) -> ValueRef {
     let _icx = bcx.insn_ctxt("int_cast");
-    let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype);
-    let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype);
-    return if dstsz == srcsz {
-        BitCast(bcx, llsrc, lldsttype)
-    } else if srcsz > dstsz {
-        TruncOrBitCast(bcx, llsrc, lldsttype)
-    } else if signed {
-        SExtOrBitCast(bcx, llsrc, lldsttype)
-    } else { ZExtOrBitCast(bcx, llsrc, lldsttype) };
+    unsafe {
+        let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype);
+        let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype);
+        return if dstsz == srcsz {
+            BitCast(bcx, llsrc, lldsttype)
+        } else if srcsz > dstsz {
+            TruncOrBitCast(bcx, llsrc, lldsttype)
+        } else if signed {
+            SExtOrBitCast(bcx, llsrc, lldsttype)
+        } else {
+            ZExtOrBitCast(bcx, llsrc, lldsttype)
+        };
+    }
 }
 
 fn float_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef,
index e7cdf82fd151664b72f3a9867d676dee1015824b..4c373e0d2170a808c7800d0e80978b4e1e9c470d 100644 (file)
 // The classification code for the x86_64 ABI is taken from the clay language
 // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
 
+use core::prelude::*;
+
 use back::{link, abi};
 use driver::session::arch_x86_64;
+use driver::session::arch_arm;
 use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
 use lib::llvm::{Struct, Array, ModuleRef, CallConv, Attribute};
 use lib::llvm::{StructRetAttribute, ByValAttribute};
 use lib::llvm::{llvm, TypeRef, ValueRef, Integer, Pointer, Float, Double};
+use lib;
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::callee::*;
 use middle::trans::common::*;
 use middle::trans::datum::*;
 use middle::trans::expr::{Dest, Ignore};
+use middle::trans::glue;
+use middle::trans::machine;
+use middle::trans::shape;
 use middle::trans::type_of::*;
+use middle::trans::type_of;
 use middle::ty::{FnTyBase, FnMeta, FnSig};
 use util::ppaux::ty_to_str;
 
 use core::libc::c_uint;
-use std::map::HashMap;
 use syntax::codemap::span;
 use syntax::{ast, ast_util};
 use syntax::{attr, ast_map};
+use syntax::parse::token::special_idents;
 
 export link_name, trans_foreign_mod, register_foreign_fn, trans_foreign_fn,
        trans_intrinsic;
@@ -85,56 +93,65 @@ fn align(off: uint, ty: TypeRef) -> uint {
     }
 
     fn struct_tys(ty: TypeRef) -> ~[TypeRef] {
-        let n = llvm::LLVMCountStructElementTypes(ty);
-        let mut elts = vec::from_elem(n as uint, ptr::null());
-        llvm::LLVMGetStructElementTypes(ty,
-                                        ptr::to_mut_unsafe_ptr(&mut elts[0]));
-        return elts;
+        unsafe {
+            let n = llvm::LLVMCountStructElementTypes(ty);
+        if (n == 0) {
+            return ~[];
+        }
+            let mut elts = vec::from_elem(n as uint, ptr::null());
+            llvm::LLVMGetStructElementTypes(ty,
+                ptr::to_mut_unsafe_ptr(&mut elts[0]));
+            return elts;
+        }
     }
 
     fn ty_align(ty: TypeRef) -> uint {
-        return match llvm::LLVMGetTypeKind(ty) {
-            Integer => {
-                ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
-            }
-            Pointer => 8,
-            Float => 4,
-            Double => 8,
-            Struct => {
-              do vec::foldl(0, struct_tys(ty)) |a, t| {
-                  uint::max(a, ty_align(*t))
-              }
-            }
-            Array => {
-                let elt = llvm::LLVMGetElementType(ty);
-                ty_align(elt)
-            }
-            _ => fail ~"ty_size: unhandled type"
-        };
+        unsafe {
+            return match llvm::LLVMGetTypeKind(ty) {
+                Integer => {
+                    ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
+                }
+                Pointer => 8,
+                Float => 4,
+                Double => 8,
+                Struct => {
+                  do vec::foldl(1, struct_tys(ty)) |a, t| {
+                      uint::max(a, ty_align(*t))
+                  }
+                }
+                Array => {
+                    let elt = llvm::LLVMGetElementType(ty);
+                    ty_align(elt)
+                }
+                _ => fail ~"ty_size: unhandled type"
+            };
+        }
     }
 
     fn ty_size(ty: TypeRef) -> uint {
-        return match llvm::LLVMGetTypeKind(ty) {
-            Integer => {
-                ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
-            }
-            Pointer => 8,
-            Float => 4,
-            Double => 8,
-            Struct => {
-              let size = do vec::foldl(0, struct_tys(ty)) |s, t| {
-                  align(s, *t) + ty_size(*t)
-              };
-              align(size, ty)
-            }
-            Array => {
-              let len = llvm::LLVMGetArrayLength(ty) as uint;
-              let elt = llvm::LLVMGetElementType(ty);
-              let eltsz = ty_size(elt);
-              len * eltsz
-            }
-            _ => fail ~"ty_size: unhandled type"
-        };
+        unsafe {
+            return match llvm::LLVMGetTypeKind(ty) {
+                Integer => {
+                    ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
+                }
+                Pointer => 8,
+                Float => 4,
+                Double => 8,
+                Struct => {
+                  let size = do vec::foldl(0, struct_tys(ty)) |s, t| {
+                      align(s, *t) + ty_size(*t)
+                  };
+                  align(size, ty)
+                }
+                Array => {
+                  let len = llvm::LLVMGetArrayLength(ty) as uint;
+                  let elt = llvm::LLVMGetElementType(ty);
+                  let eltsz = ty_size(elt);
+                  len * eltsz
+                }
+                _ => fail ~"ty_size: unhandled type"
+            };
+        }
     }
 
     fn all_mem(cls: &[mut x86_64_reg_class]) {
@@ -171,109 +188,109 @@ fn unify(cls: &[mut x86_64_reg_class],
     fn classify_struct(tys: &[TypeRef],
                        cls: &[mut x86_64_reg_class], i: uint,
                        off: uint) {
-        if vec::is_empty(tys) {
-            classify(T_i64(), cls, i, off);
-        } else {
-            let mut field_off = off;
-            for vec::each(tys) |ty| {
-                field_off = align(field_off, *ty);
-                classify(*ty, cls, i, field_off);
-                field_off += ty_size(*ty);
-            }
+        let mut field_off = off;
+        for vec::each(tys) |ty| {
+            field_off = align(field_off, *ty);
+            classify(*ty, cls, i, field_off);
+            field_off += ty_size(*ty);
         }
     }
 
     fn classify(ty: TypeRef,
                 cls: &[mut x86_64_reg_class], ix: uint,
                 off: uint) {
-        let t_align = ty_align(ty);
-        let t_size = ty_size(ty);
-
-        let misalign = off % t_align;
-        if misalign != 0u {
-            let mut i = off / 8u;
-            let e = (off + t_size + 7u) / 8u;
-            while i < e {
-                unify(cls, ix + i, memory_class);
-                i += 1u;
+        unsafe {
+            let t_align = ty_align(ty);
+            let t_size = ty_size(ty);
+
+            let misalign = off % t_align;
+            if misalign != 0u {
+                let mut i = off / 8u;
+                let e = (off + t_size + 7u) / 8u;
+                while i < e {
+                    unify(cls, ix + i, memory_class);
+                    i += 1u;
+                }
+                return;
             }
-            return;
-        }
 
-        match llvm::LLVMGetTypeKind(ty) as int {
-            8 /* integer */ |
-            12 /* pointer */ => {
-                unify(cls, ix + off / 8u, integer_class);
-            }
-            2 /* float */ => {
-                if off % 8u == 4u {
-                    unify(cls, ix + off / 8u, sse_fv_class);
-                } else {
-                    unify(cls, ix + off / 8u, sse_fs_class);
+            match llvm::LLVMGetTypeKind(ty) as int {
+                8 /* integer */ |
+                12 /* pointer */ => {
+                    unify(cls, ix + off / 8u, integer_class);
                 }
-            }
-            3 /* double */ => {
-                unify(cls, ix + off / 8u, sse_ds_class);
-            }
-            10 /* struct */ => {
-                classify_struct(struct_tys(ty), cls, ix, off);
-            }
-            11 /* array */ => {
-                let elt = llvm::LLVMGetElementType(ty);
-                let eltsz = ty_size(elt);
-                let len = llvm::LLVMGetArrayLength(ty) as uint;
-                let mut i = 0u;
-                while i < len {
-                    classify(elt, cls, ix, off + i * eltsz);
-                    i += 1u;
+                2 /* float */ => {
+                    if off % 8u == 4u {
+                        unify(cls, ix + off / 8u, sse_fv_class);
+                    } else {
+                        unify(cls, ix + off / 8u, sse_fs_class);
+                    }
+                }
+                3 /* double */ => {
+                    unify(cls, ix + off / 8u, sse_ds_class);
                 }
+                10 /* struct */ => {
+                    classify_struct(struct_tys(ty), cls, ix, off);
+                }
+                11 /* array */ => {
+                    let elt = llvm::LLVMGetElementType(ty);
+                    let eltsz = ty_size(elt);
+                    let len = llvm::LLVMGetArrayLength(ty) as uint;
+                    let mut i = 0u;
+                    while i < len {
+                        classify(elt, cls, ix, off + i * eltsz);
+                        i += 1u;
+                    }
+                }
+                _ => fail ~"classify: unhandled type"
             }
-            _ => fail ~"classify: unhandled type"
         }
     }
 
     fn fixup(ty: TypeRef, cls: &[mut x86_64_reg_class]) {
-        let mut i = 0u;
-        let llty = llvm::LLVMGetTypeKind(ty) as int;
-        let e = vec::len(cls);
-        if vec::len(cls) > 2u &&
-           (llty == 10 /* struct */ ||
-            llty == 11 /* array */) {
-            if is_sse(cls[i]) {
-                i += 1u;
+        unsafe {
+            let mut i = 0u;
+            let llty = llvm::LLVMGetTypeKind(ty) as int;
+            let e = vec::len(cls);
+            if vec::len(cls) > 2u &&
+               (llty == 10 /* struct */ ||
+                llty == 11 /* array */) {
+                if is_sse(cls[i]) {
+                    i += 1u;
+                    while i < e {
+                        if cls[i] != sseup_class {
+                            all_mem(cls);
+                            return;
+                        }
+                        i += 1u;
+                    }
+                } else {
+                    all_mem(cls);
+                    return
+                }
+            } else {
                 while i < e {
-                    if cls[i] != sseup_class {
+                    if cls[i] == memory_class {
                         all_mem(cls);
                         return;
                     }
-                    i += 1u;
-                }
-            } else {
-                all_mem(cls);
-                return
-            }
-        } else {
-            while i < e {
-                if cls[i] == memory_class {
-                    all_mem(cls);
-                    return;
-                }
-                if cls[i] == x87up_class {
-                    // for darwin
-                    // cls[i] = sse_ds_class;
-                    all_mem(cls);
-                    return;
-                }
-                if cls[i] == sseup_class {
-                    cls[i] = sse_int_class;
-                } else if is_sse(cls[i]) {
-                    i += 1;
-                    while cls[i] == sseup_class { i += 1u; }
-                } else if cls[i] == x87_class {
-                    i += 1;
-                    while cls[i] == x87up_class { i += 1u; }
-                } else {
-                    i += 1;
+                    if cls[i] == x87up_class {
+                        // for darwin
+                        // cls[i] = sse_ds_class;
+                        all_mem(cls);
+                        return;
+                    }
+                    if cls[i] == sseup_class {
+                        cls[i] = sse_int_class;
+                    } else if is_sse(cls[i]) {
+                        i += 1;
+                        while cls[i] == sseup_class { i += 1u; }
+                    } else if cls[i] == x87_class {
+                        i += 1;
+                        while cls[i] == x87up_class { i += 1u; }
+                    } else {
+                        i += 1;
+                    }
                 }
             }
         }
@@ -302,33 +319,35 @@ fn llvec_len(cls: &[x86_64_reg_class]) -> uint {
         return len;
     }
 
-    let mut tys = ~[];
-    let mut i = 0u;
-    let e = vec::len(cls);
-    while i < e {
-        match cls[i] {
-            integer_class => {
-                tys.push(T_i64());
-            }
-            sse_fv_class => {
-                let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u;
-                let vec_ty = llvm::LLVMVectorType(T_f32(),
-                                                  vec_len as c_uint);
-                tys.push(vec_ty);
-                i += vec_len;
-                loop;
-            }
-            sse_fs_class => {
-                tys.push(T_f32());
-            }
-            sse_ds_class => {
-                tys.push(T_f64());
+    unsafe {
+        let mut tys = ~[];
+        let mut i = 0u;
+        let e = vec::len(cls);
+        while i < e {
+            match cls[i] {
+                integer_class => {
+                    tys.push(T_i64());
+                }
+                sse_fv_class => {
+                    let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u;
+                    let vec_ty = llvm::LLVMVectorType(T_f32(),
+                                                      vec_len as c_uint);
+                    tys.push(vec_ty);
+                    i += vec_len;
+                    loop;
+                }
+                sse_fs_class => {
+                    tys.push(T_f32());
+                }
+                sse_ds_class => {
+                    tys.push(T_f64());
+                }
+                _ => fail ~"llregtype: unhandled class"
             }
-            _ => fail ~"llregtype: unhandled class"
+            i += 1u;
         }
-        i += 1u;
+        return T_struct(tys);
     }
-    return T_struct(tys);
 }
 
 type x86_64_llty = {
@@ -347,23 +366,26 @@ fn x86_64_tys(atys: &[TypeRef],
               rty: TypeRef,
               ret_def: bool) -> x86_64_tys {
     fn is_reg_ty(ty: TypeRef) -> bool {
-        return match llvm::LLVMGetTypeKind(ty) as int {
-            8 /* integer */ |
-            12 /* pointer */ |
-            2 /* float */ |
-            3 /* double */ => true,
-            _ => false
-        };
+        unsafe {
+            return match llvm::LLVMGetTypeKind(ty) as int {
+                8 /* integer */ |
+                12 /* pointer */ |
+                2 /* float */ |
+                3 /* double */ => true,
+                _ => false
+            };
+        }
     }
 
     fn is_pass_byval(cls: &[x86_64_reg_class]) -> bool {
-        return cls[0] == memory_class ||
-            cls[0] == x87_class ||
-            cls[0] == complex_x87_class;
+        return cls.len() > 0 &&
+            (cls[0] == memory_class ||
+             cls[0] == x87_class ||
+             cls[0] == complex_x87_class);
     }
 
     fn is_ret_bysret(cls: &[x86_64_reg_class]) -> bool {
-        return cls[0] == memory_class;
+        return cls.len() > 0 && cls[0] == memory_class;
     }
 
     fn x86_64_ty(ty: TypeRef,
@@ -424,8 +446,10 @@ fn decl_x86_64_fn(tys: x86_64_tys,
     for vec::eachi(tys.attrs) |i, a| {
         match *a {
             option::Some(attr) => {
-                let llarg = get_param(llfn, i);
-                llvm::LLVMAddAttribute(llarg, attr as c_uint);
+                unsafe {
+                    let llarg = get_param(llfn, i);
+                    llvm::LLVMAddAttribute(llarg, attr as c_uint);
+                }
             }
             _ => ()
         }
@@ -436,7 +460,7 @@ fn decl_x86_64_fn(tys: x86_64_tys,
 fn link_name(ccx: @crate_ctxt, i: @ast::foreign_item) -> ~str {
     match attr::first_attr_value_str_by_name(i.attrs, ~"link_name") {
         None => ccx.sess.str_of(i.ident),
-        option::Some(ref ln) => (*ln)
+        option::Some(ref ln) => (/*bad*/copy *ln)
     }
 }
 
@@ -453,7 +477,9 @@ fn c_arg_and_ret_lltys(ccx: @crate_ctxt,
                        id: ast::node_id) -> (~[TypeRef], TypeRef, ty::t) {
     match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty {
         ty::ty_fn(ref fn_ty) => {
-            let llargtys = type_of_explicit_args(ccx, fn_ty.sig.inputs);
+            let llargtys = type_of_explicit_args(
+                ccx,
+                /*bad*/copy fn_ty.sig.inputs);
             let llretty = type_of::type_of(ccx, fn_ty.sig.output);
             (llargtys, llretty, fn_ty.sig.output)
         }
@@ -464,10 +490,13 @@ fn c_arg_and_ret_lltys(ccx: @crate_ctxt,
 fn c_stack_tys(ccx: @crate_ctxt,
                id: ast::node_id) -> @c_stack_tys {
     let (llargtys, llretty, ret_ty) = c_arg_and_ret_lltys(ccx, id);
-    let bundle_ty = T_struct(vec::append_one(llargtys, T_ptr(llretty)));
+    // XXX: Bad copy.
+    let bundle_ty = T_struct(vec::append_one(copy llargtys, T_ptr(llretty)));
     let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
     let x86_64 = if ccx.sess.targ_cfg.arch == arch_x86_64 {
         option::Some(x86_64_tys(llargtys, llretty, ret_def))
+    } else if ccx.sess.targ_cfg.arch == arch_arm {
+        option::Some(x86_64_tys(llargtys, llretty, ret_def))
     } else {
         option::None
     };
@@ -488,7 +517,7 @@ fn c_stack_tys(ccx: @crate_ctxt,
                            llargbundle: ValueRef, llretval: ValueRef);
 
 fn build_shim_fn_(ccx: @crate_ctxt,
-                  shim_name: ~str,
+                  +shim_name: ~str,
                   llbasefn: ValueRef,
                   tys: @c_stack_tys,
                   cc: lib::llvm::CallConv,
@@ -610,8 +639,8 @@ fn build_args(bcx: block, tys: @c_stack_tys,
 
             match tys.x86_64_tys {
                 Some(ref x86_64) => {
-                    let mut atys = (*x86_64).arg_tys;
-                    let mut attrs = (*x86_64).attrs;
+                    let mut atys = /*bad*/copy (*x86_64).arg_tys;
+                    let mut attrs = /*bad*/copy (*x86_64).attrs;
                     if (*x86_64).sret {
                         let llretptr = GEPi(bcx, llargbundle, [0u, n]);
                         let llretloc = Load(bcx, llretptr);
@@ -654,9 +683,11 @@ fn build_ret(bcx: block, tys: @c_stack_tys,
                   for vec::eachi((*x86_64).attrs) |i, a| {
                         match *a {
                             Some(attr) => {
-                                llvm::LLVMAddInstrAttribute(
-                                    llretval, (i + 1u) as c_uint,
-                                              attr as c_uint);
+                                unsafe {
+                                    llvm::LLVMAddInstrAttribute(
+                                        llretval, (i + 1u) as c_uint,
+                                                  attr as c_uint);
+                                }
                             }
                             _ => ()
                         }
@@ -691,24 +722,24 @@ fn build_ret(bcx: block, tys: @c_stack_tys,
         }
 
         let lname = link_name(ccx, foreign_item);
-        let llbasefn = base_fn(ccx, lname, tys, cc);
+        let llbasefn = base_fn(ccx, copy lname, tys, cc);
         // Name the shim function
         let shim_name = lname + ~"__c_stack_shim";
         return build_shim_fn_(ccx, shim_name, llbasefn, tys, cc,
                            build_args, build_ret);
     }
 
-    fn base_fn(ccx: @crate_ctxt, lname: ~str, tys: @c_stack_tys,
+    fn base_fn(ccx: @crate_ctxt, +lname: ~str, tys: @c_stack_tys,
                cc: lib::llvm::CallConv) -> ValueRef {
         // Declare the "prototype" for the base function F:
         match tys.x86_64_tys {
           Some(ref x86_64) => {
             do decl_x86_64_fn((*x86_64)) |fnty| {
-                decl_fn(ccx.llmod, lname, cc, fnty)
+                decl_fn(ccx.llmod, /*bad*/copy lname, cc, fnty)
             }
           }
           _ => {
-            let llbasefnty = T_fn(tys.arg_tys, tys.ret_ty);
+            let llbasefnty = T_fn(/*bad*/copy tys.arg_tys, tys.ret_ty);
             decl_fn(ccx.llmod, lname, cc, llbasefnty)
           }
         }
@@ -781,8 +812,7 @@ fn build_ret(bcx: block, _tys: @c_stack_tys,
           if abi != ast::foreign_abi_rust_intrinsic {
               let llwrapfn = get_item_val(ccx, id);
               let tys = c_stack_tys(ccx, id);
-              if attr::attrs_contains_name(foreign_item.attrs,
-                                           ~"rust_stack") {
+              if attr::attrs_contains_name(foreign_item.attrs, "rust_stack") {
                   build_direct_fn(ccx, llwrapfn, *foreign_item, tys, cc);
               } else {
                   let llshimfn = build_shim_fn(ccx, *foreign_item, tys, cc);
@@ -801,13 +831,14 @@ fn build_ret(bcx: block, _tys: @c_stack_tys,
 }
 
 fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
-                   path: ast_map::path, substs: param_substs,
+                   +path: ast_map::path, +substs: param_substs,
                    ref_id: Option<ast::node_id>)
 {
     debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident));
 
+    // XXX: Bad copy.
     let fcx = new_fn_ctxt_w_id(ccx, path, decl, item.id, None,
-                               Some(substs), Some(item.span));
+                               Some(copy substs), Some(item.span));
     let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
     match ccx.sess.str_of(item.ident) {
         ~"atomic_cxchg" => {
@@ -1012,8 +1043,7 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
                               proto: ast::ProtoBorrowed,
                               onceness: ast::Many,
                               region: ty::re_bound(ty::br_anon(0)),
-                              bounds: @~[],
-                              ret_style: ast::return_val},
+                              bounds: @~[]},
                 sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
                                        ty: star_u8}],
                             output: ty::mk_nil(bcx.tcx())}
@@ -1262,6 +1292,21 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
             let cttz = ccx.intrinsics.get(~"llvm.cttz.i64");
             Store(bcx, Call(bcx, cttz, ~[x, y]), fcx.llretptr)
         }
+        ~"bswap16" => {
+            let x = get_param(decl, first_real_arg);
+            let cttz = ccx.intrinsics.get(~"llvm.bswap.i16");
+            Store(bcx, Call(bcx, cttz, ~[x]), fcx.llretptr)
+        }
+        ~"bswap32" => {
+            let x = get_param(decl, first_real_arg);
+            let cttz = ccx.intrinsics.get(~"llvm.bswap.i32");
+            Store(bcx, Call(bcx, cttz, ~[x]), fcx.llretptr)
+        }
+        ~"bswap64" => {
+            let x = get_param(decl, first_real_arg);
+            let cttz = ccx.intrinsics.get(~"llvm.bswap.i64");
+            Store(bcx, Call(bcx, cttz, ~[x]), fcx.llretptr)
+        }
         _ => {
             // Could we make this an enum rather than a string? does it get
             // checked earlier?
@@ -1272,19 +1317,20 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
     finish_fn(fcx, lltop);
 }
 
-fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
-                  body: ast::blk, llwrapfn: ValueRef, id: ast::node_id) {
-
+fn trans_foreign_fn(ccx: @crate_ctxt, +path: ast_map::path,
+                    decl: ast::fn_decl, body: ast::blk, llwrapfn: ValueRef,
+                    id: ast::node_id) {
     let _icx = ccx.insn_ctxt("foreign::build_foreign_fn");
 
-    fn build_rust_fn(ccx: @crate_ctxt, path: ast_map::path,
+    fn build_rust_fn(ccx: @crate_ctxt, +path: ast_map::path,
                      decl: ast::fn_decl, body: ast::blk,
                      id: ast::node_id) -> ValueRef {
         let _icx = ccx.insn_ctxt("foreign::foreign::build_rust_fn");
         let t = ty::node_id_to_type(ccx.tcx, id);
+        // XXX: Bad copy.
         let ps = link::mangle_internal_name_by_path(
-            ccx, vec::append_one(path, ast_map::path_name(
-                syntax::parse::token::special_idents::clownshoe_abi
+            ccx, vec::append_one(copy path, ast_map::path_name(
+                special_idents::clownshoe_abi
             )));
         let llty = type_of_fn_from_ty(ccx, t);
         let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty);
@@ -1292,9 +1338,8 @@ fn build_rust_fn(ccx: @crate_ctxt, path: ast_map::path,
         return llfndecl;
     }
 
-    fn build_shim_fn(ccx: @crate_ctxt, path: ast_map::path,
+    fn build_shim_fn(ccx: @crate_ctxt, +path: ast_map::path,
                      llrustfn: ValueRef, tys: @c_stack_tys) -> ValueRef {
-
         let _icx = ccx.insn_ctxt("foreign::foreign::build_shim_fn");
 
         fn build_args(bcx: block, tys: @c_stack_tys,
@@ -1323,7 +1368,7 @@ fn build_ret(_bcx: block, _tys: @c_stack_tys,
 
         let shim_name = link::mangle_internal_name_by_path(
             ccx, vec::append_one(path, ast_map::path_name(
-                syntax::parse::token::special_idents::clownshoe_stack_shim
+                special_idents::clownshoe_stack_shim
             )));
         return build_shim_fn_(ccx, shim_name, llrustfn, tys,
                            lib::llvm::CCallConv,
@@ -1340,8 +1385,8 @@ fn build_args(bcx: block, tys: @c_stack_tys,
             let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_args");
             match tys.x86_64_tys {
                 option::Some(ref x86_64) => {
-                    let mut atys = (*x86_64).arg_tys;
-                    let mut attrs = (*x86_64).attrs;
+                    let mut atys = /*bad*/copy (*x86_64).arg_tys;
+                    let mut attrs = /*bad*/copy (*x86_64).attrs;
                     let mut j = 0u;
                     let llretptr = if (*x86_64).sret {
                         atys = vec::tail(atys);
@@ -1425,16 +1470,20 @@ fn build_ret(bcx: block, tys: @c_stack_tys,
 
     let tys = c_stack_tys(ccx, id);
     // The internal Rust ABI function - runs on the Rust stack
-    let llrustfn = build_rust_fn(ccx, path, decl, body, id);
+    // XXX: Bad copy.
+    let llrustfn = build_rust_fn(ccx, copy path, decl, body, id);
     // The internal shim function - runs on the Rust stack
     let llshimfn = build_shim_fn(ccx, path, llrustfn, tys);
     // The foreign C function - runs on the C stack
     build_wrap_fn(ccx, llshimfn, llwrapfn, tys)
 }
 
-fn register_foreign_fn(ccx: @crate_ctxt, sp: span,
-                     path: ast_map::path, node_id: ast::node_id)
-    -> ValueRef {
+fn register_foreign_fn(ccx: @crate_ctxt,
+                       sp: span,
+                       +path: ast_map::path,
+                       node_id: ast::node_id,
+                       attrs: &[ast::attribute])
+                    -> ValueRef {
     let _icx = ccx.insn_ctxt("foreign::register_foreign_fn");
     let t = ty::node_id_to_type(ccx.tcx, node_id);
     let (llargtys, llretty, ret_ty) = c_arg_and_ret_lltys(ccx, node_id);
@@ -1442,12 +1491,20 @@ fn register_foreign_fn(ccx: @crate_ctxt, sp: span,
         let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
         let x86_64 = x86_64_tys(llargtys, llretty, ret_def);
         do decl_x86_64_fn(x86_64) |fnty| {
-            register_fn_fuller(ccx, sp, path, node_id,
+            register_fn_fuller(ccx, sp, /*bad*/copy path, node_id, attrs,
+                               t, lib::llvm::CCallConv, fnty)
+        }
+    } else if ccx.sess.targ_cfg.arch == arch_arm {
+        let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
+        let x86_64 = x86_64_tys(llargtys, llretty, ret_def);
+        do decl_x86_64_fn(x86_64) |fnty| {
+            register_fn_fuller(ccx, sp, /*bad*/copy path, node_id, attrs,
                                t, lib::llvm::CCallConv, fnty)
         }
+
     } else {
         let llfty = T_fn(llargtys, llretty);
-        register_fn_fuller(ccx, sp, path, node_id,
+        register_fn_fuller(ccx, sp, path, node_id, attrs,
                            t, lib::llvm::CCallConv, llfty)
     }
 }
@@ -1462,7 +1519,9 @@ fn abi_of_foreign_fn(ccx: @crate_ctxt, i: @ast::foreign_item)
       },
       Some(_) => match attr::foreign_abi(i.attrs) {
         either::Right(abi) => abi,
-        either::Left(ref msg) => ccx.sess.span_fatal(i.span, (*msg))
+        either::Left(ref msg) => {
+            ccx.sess.span_fatal(i.span, (/*bad*/copy *msg))
+        }
       }
     }
 }
index a42dee615e4b5e3deed3f2dca21457938a666144..3067051e428d9ac1f6cb452aed6b29a4cab68c4a 100644 (file)
 //
 // Code relating to taking, dropping, etc as well as type descriptors.
 
+use core::prelude::*;
+
 use lib::llvm::{ValueRef, TypeRef};
 use middle::trans::base::*;
+use middle::trans::callee;
+use middle::trans::closure;
 use middle::trans::common::*;
 use middle::trans::build::*;
+use middle::trans::reflect;
+use middle::trans::tvec;
 use middle::trans::type_of::type_of;
+use middle::trans::uniq;
+
+use core::io;
+use core::str;
 
 fn trans_free(cx: block, v: ValueRef) -> block {
     let _icx = cx.insn_ctxt("trans_free");
-    callee::trans_rtcall(cx, ~"free", ~[PointerCast(cx, v, T_ptr(T_i8()))],
-                         expr::Ignore)
+    callee::trans_rtcall_or_lang_call(
+        cx,
+        cx.tcx().lang_items.free_fn(),
+        ~[PointerCast(cx, v, T_ptr(T_i8()))],
+        expr::Ignore)
 }
 
 fn trans_unique_free(cx: block, v: ValueRef) -> block {
     let _icx = cx.insn_ctxt("trans_unique_free");
-    callee::trans_rtcall(
-        cx, ~"exchange_free", ~[PointerCast(cx, v, T_ptr(T_i8()))],
+    callee::trans_rtcall_or_lang_call(
+        cx,
+        cx.tcx().lang_items.exchange_free_fn(),
+        ~[PointerCast(cx, v, T_ptr(T_i8()))],
         expr::Ignore)
 }
 
@@ -434,11 +449,13 @@ fn trans_struct_drop(bcx: block,
 
         // Find and call the actual destructor
         let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did,
-                                     class_did, substs.tps);
+                                     class_did, /*bad*/copy substs.tps);
 
         // The second argument is the "self" argument for drop
-        let params = lib::llvm::fn_ty_param_tys(
-            llvm::LLVMGetElementType(llvm::LLVMTypeOf(dtor_addr)));
+        let params = unsafe {
+            lib::llvm::fn_ty_param_tys(
+                llvm::LLVMGetElementType(llvm::LLVMTypeOf(dtor_addr)))
+        };
 
         // Class dtors have no explicit args, so the params should
         // just consist of the output pointer and the environment
@@ -643,10 +660,13 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
     } else {
         mangle_internal_name_by_seq(ccx, ~"tydesc")
     };
-    note_unique_llvm_symbol(ccx, name);
+    // XXX: Bad copy.
+    note_unique_llvm_symbol(ccx, copy name);
     log(debug, fmt!("+++ declare_tydesc %s %s", ty_to_str(ccx.tcx, t), name));
     let gvar = str::as_c_str(name, |buf| {
-        llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
+        unsafe {
+            llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
+        }
     });
     let inf =
         @{ty: t,
@@ -665,7 +685,7 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
 type glue_helper = fn@(block, ValueRef, ty::t);
 
 fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
-                        name: ~str) -> ValueRef {
+                        +name: ~str) -> ValueRef {
     let _icx = ccx.insn_ctxt("declare_generic_glue");
     let name = name;
     let mut fn_nm;
@@ -676,7 +696,8 @@ fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
         fn_nm = mangle_internal_name_by_seq(ccx, (~"glue_" + name));
     }
     debug!("%s is for type %s", fn_nm, ty_to_str(ccx.tcx, t));
-    note_unique_llvm_symbol(ccx, fn_nm);
+    // XXX: Bad copy.
+    note_unique_llvm_symbol(ccx, copy fn_nm);
     let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty);
     set_glue_inlining(llfn, t);
     return llfn;
@@ -698,7 +719,7 @@ fn make_generic_glue_inner(ccx: @crate_ctxt, t: ty::t,
 
     let bcx = top_scope_block(fcx, None);
     let lltop = bcx.llbb;
-    let llrawptr0 = llvm::LLVMGetParam(llfn, 3u as c_uint);
+    let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, 3u as c_uint) };
     helper(bcx, llrawptr0, t);
     finish_fn(fcx, lltop);
     return llfn;
@@ -736,32 +757,40 @@ fn emit_tydescs(ccx: @crate_ctxt) {
             match copy ti.take_glue {
               None => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
               Some(v) => {
-                ccx.stats.n_real_glues += 1u;
-                llvm::LLVMConstPointerCast(v, glue_fn_ty)
+                unsafe {
+                    ccx.stats.n_real_glues += 1u;
+                    llvm::LLVMConstPointerCast(v, glue_fn_ty)
+                }
               }
             };
         let drop_glue =
             match copy ti.drop_glue {
               None => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
               Some(v) => {
-                ccx.stats.n_real_glues += 1u;
-                llvm::LLVMConstPointerCast(v, glue_fn_ty)
+                unsafe {
+                    ccx.stats.n_real_glues += 1u;
+                    llvm::LLVMConstPointerCast(v, glue_fn_ty)
+                }
               }
             };
         let free_glue =
             match copy ti.free_glue {
               None => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
               Some(v) => {
-                ccx.stats.n_real_glues += 1u;
-                llvm::LLVMConstPointerCast(v, glue_fn_ty)
+                unsafe {
+                    ccx.stats.n_real_glues += 1u;
+                    llvm::LLVMConstPointerCast(v, glue_fn_ty)
+                }
               }
             };
         let visit_glue =
             match copy ti.visit_glue {
               None => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
               Some(v) => {
-                ccx.stats.n_real_glues += 1u;
-                llvm::LLVMConstPointerCast(v, glue_fn_ty)
+                unsafe {
+                    ccx.stats.n_real_glues += 1u;
+                    llvm::LLVMConstPointerCast(v, glue_fn_ty)
+                }
               }
             };
 
@@ -779,21 +808,24 @@ fn emit_tydescs(ccx: @crate_ctxt) {
                              shape, // shape
                              shape_tables]); // shape_tables
 
-        let gvar = ti.tydesc;
-        llvm::LLVMSetInitializer(gvar, tydesc);
-        llvm::LLVMSetGlobalConstant(gvar, True);
-        lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage);
-
-        // Index tydesc by addrspace.
-        if ti.addrspace > gc_box_addrspace {
-            let llty = T_ptr(ccx.tydesc_type);
-            let addrspace_name = fmt!("_gc_addrspace_metadata_%u",
-                                      ti.addrspace as uint);
-            let addrspace_gvar = str::as_c_str(addrspace_name, |buf| {
-                llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
-            });
-            lib::llvm::SetLinkage(addrspace_gvar, lib::llvm::InternalLinkage);
-            llvm::LLVMSetInitializer(addrspace_gvar, gvar);
+        unsafe {
+            let gvar = ti.tydesc;
+            llvm::LLVMSetInitializer(gvar, tydesc);
+            llvm::LLVMSetGlobalConstant(gvar, True);
+            lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage);
+
+            // Index tydesc by addrspace.
+            if ti.addrspace > gc_box_addrspace {
+                let llty = T_ptr(ccx.tydesc_type);
+                let addrspace_name = fmt!("_gc_addrspace_metadata_%u",
+                                          ti.addrspace as uint);
+                let addrspace_gvar = str::as_c_str(addrspace_name, |buf| {
+                    llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
+                });
+                lib::llvm::SetLinkage(addrspace_gvar,
+                                      lib::llvm::InternalLinkage);
+                llvm::LLVMSetInitializer(addrspace_gvar, gvar);
+            }
         }
     };
 }
index 6f5aa792c4748546a8b4cde12c916d06153fc8a8..98842f8b073dbef710199e17c023eec76b77537f 100644 (file)
@@ -8,11 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use middle::astencode;
 use middle::trans::base::{get_insn_ctxt};
 use middle::trans::base::{impl_owned_self, impl_self, no_self};
 use middle::trans::base::{trans_item, get_item_val, self_arg, trans_fn};
 use middle::trans::common::*;
+use middle::trans::common;
+use middle::trans::inline;
+use middle::trans::monomorphize;
 
+use core::vec;
 use syntax::ast;
 use syntax::ast_map::{path, path_mod, path_name};
 use syntax::ast_util::local_def;
@@ -36,7 +43,8 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id,
         match csearch::maybe_get_item_ast(
             ccx.tcx, fn_id,
             |a,b,c,d| {
-                astencode::decode_inlined_item(a, b, ccx.maps, c, d)
+                astencode::decode_inlined_item(a, b, ccx.maps,
+                                               /*bad*/ copy c, d)
             }) {
 
           csearch::not_found => {
index 1c6e500d80682e8dbe01955501ac1632ab3c2dd1..bc1cd5ec911205895e84a93476fa383207246a42 100644 (file)
 
 // Information concerning the machine representation of various types.
 
+
 use middle::trans::common::*;
+use middle::trans::type_of;
+use middle::ty;
+
+use syntax::parse::token::special_idents;
 
 // Creates a simpler, size-equivalent type. The resulting type is guaranteed
 // to have (a) the same size as the type that was passed in; (b) to be non-
@@ -39,7 +44,7 @@ fn simplifier(tcx: ty::ctxt, typ: ty::t) -> ty::t {
           ty::ty_struct(did, ref substs) => {
             let simpl_fields = (if ty::ty_dtor(tcx, did).is_present() {
                 // remember the drop flag
-                  ~[{ident: syntax::parse::token::special_idents::dtor,
+                  ~[{ident: special_idents::dtor,
                      mt: {ty: ty::mk_u8(tcx),
                           mutbl: ast::m_mutbl}}] }
                 else { ~[] }) +
@@ -74,13 +79,17 @@ fn simplifier(tcx: ty::ctxt, typ: ty::t) -> ty::t {
 
 // Returns the number of bytes clobbered by a Store to this type.
 pub fn llsize_of_store(cx: @crate_ctxt, t: TypeRef) -> uint {
-    return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint;
+    unsafe {
+        return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint;
+    }
 }
 
 // Returns the number of bytes between successive elements of type T in an
 // array of T. This is the "ABI" size. It includes any ABI-mandated padding.
 pub fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint {
-    return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint;
+    unsafe {
+        return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint;
+    }
 }
 
 // Returns, as near as we can figure, the "real" size of a type. As in, the
@@ -92,18 +101,22 @@ pub fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint {
 // at the codegen level! In general you should prefer `llbitsize_of_real`
 // below.
 pub fn llsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint {
-    let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint;
-    if nbits & 7u != 0u {
-        // Not an even number of bytes, spills into "next" byte.
-        1u + (nbits >> 3)
-    } else {
-        nbits >> 3
+    unsafe {
+        let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint;
+        if nbits & 7u != 0u {
+            // Not an even number of bytes, spills into "next" byte.
+            1u + (nbits >> 3)
+        } else {
+            nbits >> 3
+        }
     }
 }
 
 /// Returns the "real" size of the type in bits.
 pub fn llbitsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint {
-    llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint
+    unsafe {
+        llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint
+    }
 }
 
 // Returns the "default" size of t, which is calculated by casting null to a
@@ -112,8 +125,22 @@ pub fn llbitsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint {
 // (i.e. including alignment-padding), but goodness knows which alignment it
 // winds up using. Probably the ABI one? Not recommended.
 pub fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
-    return llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t), cx.int_type,
-                               False);
+    unsafe {
+        return llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t),
+                                      cx.int_type,
+                                      False);
+    }
+}
+
+// Returns the "default" size of t (see above), or 1 if the size would
+// be zero.  This is important for things like vectors that expect
+// space to be consumed.
+pub fn nonzero_llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
+    if llbitsize_of_real(cx, t) == 0 {
+        unsafe { llvm::LLVMConstInt(cx.int_type, 1, False) }
+    } else {
+        llsize_of(cx, t)
+    }
 }
 
 // Returns the preferred alignment of the given type for the current target.
@@ -121,22 +148,28 @@ pub fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
 // packing the type into structs. This will be used for things like
 // allocations inside a stack frame, which LLVM has a free hand in.
 pub fn llalign_of_pref(cx: @crate_ctxt, t: TypeRef) -> uint {
-    return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint;
+    unsafe {
+        return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint;
+    }
 }
 
 // Returns the minimum alignment of a type required by the plattform.
 // This is the alignment that will be used for struct fields, arrays,
 // and similar ABI-mandated things.
 pub fn llalign_of_min(cx: @crate_ctxt, t: TypeRef) -> uint {
-    return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint;
+    unsafe {
+        return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint;
+    }
 }
 
 // Returns the "default" alignment of t, which is calculated by casting
 // null to a record containing a single-bit followed by a t value, then
 // doing gep(0,1) to get at the trailing (and presumably padded) t cell.
 pub fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
-    return llvm::LLVMConstIntCast(
-        lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False);
+    unsafe {
+        return llvm::LLVMConstIntCast(
+            lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False);
+    }
 }
 
 // Computes the size of the data part of an enum.
@@ -148,8 +181,9 @@ pub fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint {
         let mut max_size = 0u;
         let variants = ty::enum_variants(cx.tcx, tid);
         for vec::each(*variants) |variant| {
-            let tup_ty = simplify_type(cx.tcx,
-                                       ty::mk_tup(cx.tcx, variant.args));
+            let tup_ty = simplify_type(
+                cx.tcx,
+                ty::mk_tup(cx.tcx, /*bad*/copy variant.args));
             // Perform any type parameter substitutions.
             let tup_ty = ty::subst(cx.tcx, substs, tup_ty);
             // Here we possibly do a recursive call.
index 99175e09af59d7e12877f4be2002e717d50fea21..dad4a8bd2bf4bb167817ca132ed52f50738e5155 100644 (file)
@@ -52,4 +52,4 @@ macro_rules! trace(
     )
 );
 
-}
\ No newline at end of file
+}
index 1dd3ae0ef0e1b3185f0537c004af1bc45196b06e..0fbeb2aadc337c1a2a7f48b2515e1c586ec225ba 100644 (file)
@@ -8,17 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use back::{link, abi};
+use driver;
 use lib::llvm::llvm::LLVMGetParam;
 use lib::llvm::llvm;
 use lib::llvm::{ValueRef, TypeRef};
+use lib;
 use metadata::csearch;
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::callee::*;
+use middle::trans::callee;
 use middle::trans::common::*;
 use middle::trans::expr::{SaveIn, Ignore};
+use middle::trans::expr;
+use middle::trans::glue;
+use middle::trans::inline;
+use middle::trans::monomorphize;
 use middle::trans::type_of::*;
+use middle::typeck;
 use util::ppaux::{ty_to_str, tys_to_str};
 
 use core::libc::c_uint;
@@ -36,7 +46,7 @@
 be generated once they are invoked with specific type parameters,
 see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
 */
-fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
+fn trans_impl(ccx: @crate_ctxt, +path: path, name: ast::ident,
               methods: ~[@ast::method], tps: ~[ast::ty_param],
               self_ty: Option<ty::t>, id: ast::node_id) {
     let _icx = ccx.insn_ctxt("impl::trans_impl");
@@ -45,13 +55,14 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
     for vec::each(methods) |method| {
         if method.tps.len() == 0u {
             let llfn = get_item_val(ccx, method.id);
-            let path = vec::append_one(sub_path, path_name(method.ident));
+            let path = vec::append_one(/*bad*/copy sub_path,
+                                       path_name(method.ident));
 
             let param_substs_opt;
             match self_ty {
                 None => param_substs_opt = None,
                 Some(self_ty) => {
-                    param_substs_opt = Some({
+                    param_substs_opt = Some(param_substs {
                         tys: ~[],
                         vtables: None,
                         bounds: @~[],
@@ -82,13 +93,12 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
 - `impl_id`: the node ID of the impl this method is inside
 */
 fn trans_method(ccx: @crate_ctxt,
-                path: path,
+                +path: path,
                 method: &ast::method,
-                param_substs: Option<param_substs>,
+                +param_substs: Option<param_substs>,
                 base_self_ty: Option<ty::t>,
                 llfn: ValueRef,
                 impl_id: ast::def_id) {
-
     // figure out how self is being passed
     let self_arg = match method.self_ty.node {
       ast::sty_static => {
@@ -104,7 +114,7 @@ fn trans_method(ccx: @crate_ctxt,
         }
         let self_ty = match param_substs {
             None => self_ty,
-            Some({tys: ref tys, _}) => {
+            Some(param_substs {tys: ref tys, _}) => {
                 ty::subst_tps(ccx.tcx, *tys, None, self_ty)
             }
         };
@@ -281,7 +291,7 @@ fn trans_static_method_callee(bcx: block,
     let vtbls = resolve_vtables_in_fn_ctxt(
         bcx.fcx, ccx.maps.vtable_map.get(callee_id));
 
-    match vtbls[bound_index] {
+    match /*bad*/copy vtbls[bound_index] {
         typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => {
 
             let mth_id = method_with_name(bcx.ccx(), impl_did, mname);
@@ -317,8 +327,11 @@ fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id,
                     name: ast::ident) -> ast::def_id {
     if impl_id.crate == ast::local_crate {
         match ccx.tcx.items.get(impl_id.node) {
-          ast_map::node_item(@{node: ast::item_impl(_, _, _, ms), _}, _) => {
-            method_from_methods(ms, name).get()
+          ast_map::node_item(@{
+                node: ast::item_impl(_, _, _, ref ms),
+                _
+            }, _) => {
+            method_from_methods(/*bad*/copy *ms, name).get()
           }
           _ => fail ~"method_with_name"
         }
@@ -331,8 +344,10 @@ fn method_with_name_or_default(ccx: @crate_ctxt, impl_id: ast::def_id,
                                name: ast::ident) -> ast::def_id {
     if impl_id.crate == ast::local_crate {
         match ccx.tcx.items.get(impl_id.node) {
-          ast_map::node_item(@{node: ast::item_impl(_, _, _, ms), _}, _) => {
-              let did = method_from_methods(ms, name);
+          ast_map::node_item(@{
+                node: ast::item_impl(_, _, _, ref ms), _
+          }, _) => {
+              let did = method_from_methods(/*bad*/copy *ms, name);
               if did.is_some() {
                   return did.get();
               } else {
@@ -392,7 +407,7 @@ fn trans_monomorphized_callee(bcx: block,
                               mentry: typeck::method_map_entry,
                               trait_id: ast::def_id,
                               n_method: uint,
-                              vtbl: typeck::vtable_origin)
+                              +vtbl: typeck::vtable_origin)
     -> Callee
 {
     let _icx = bcx.insn_ctxt("impl::trans_monomorphized_callee");
@@ -454,7 +469,7 @@ fn combine_impl_and_methods_tps(bcx: block,
                                 mth_did: ast::def_id,
                                 impl_did: ast::def_id,
                                 callee_id: ast::node_id,
-                                rcvr_substs: ~[ty::t])
+                                +rcvr_substs: ~[ty::t])
     -> ~[ty::t]
 {
     /*!
@@ -477,12 +492,12 @@ fn combine_impl_and_methods_tps(bcx: block,
     let ccx = bcx.ccx();
     let n_m_tps = method_ty_param_count(ccx, mth_did, impl_did);
     let node_substs = node_id_type_params(bcx, callee_id);
+    debug!("rcvr_substs=%?", rcvr_substs.map(|t| bcx.ty_to_str(*t)));
     let ty_substs
         = vec::append(rcvr_substs,
                       vec::tailn(node_substs,
                                  node_substs.len() - n_m_tps));
     debug!("n_m_tps=%?", n_m_tps);
-    debug!("rcvr_substs=%?", rcvr_substs.map(|t| bcx.ty_to_str(*t)));
     debug!("node_substs=%?", node_substs.map(|t| bcx.ty_to_str(*t)));
     debug!("ty_substs=%?", ty_substs.map(|t| bcx.ty_to_str(*t)));
 
@@ -527,7 +542,7 @@ fn combine_impl_and_methods_origins(bcx: block,
     let m_origins = vec::tailn(*r_m_origins, r_m_origins.len() - m_vtables);
 
     // Combine rcvr + method to find the final result:
-    @vec::append(*rcvr_origins, m_origins)
+    @vec::append(/*bad*/copy *rcvr_origins, m_origins)
 }
 
 
@@ -698,7 +713,7 @@ fn trans_trait_callee_from_llval(bcx: block,
     };
 }
 
-fn vtable_id(ccx: @crate_ctxt, origin: typeck::vtable_origin) -> mono_id {
+fn vtable_id(ccx: @crate_ctxt, +origin: typeck::vtable_origin) -> mono_id {
     match origin {
         typeck::vtable_static(impl_id, substs, sub_vtables) => {
             monomorphize::make_mono_id(
@@ -714,18 +729,20 @@ fn vtable_id(ccx: @crate_ctxt, origin: typeck::vtable_origin) -> mono_id {
                 None)
         }
         typeck::vtable_trait(trait_id, substs) => {
-            @{def: trait_id,
-              params: vec::map(substs, |t| mono_precise(*t, None)),
-              impl_did_opt: None}
+            @mono_id_ {
+                def: trait_id,
+                params: vec::map(substs, |t| mono_precise(*t, None)),
+                impl_did_opt: None
+            }
         }
         // can't this be checked at the callee?
         _ => fail ~"vtable_id"
     }
 }
 
-fn get_vtable(ccx: @crate_ctxt, origin: typeck::vtable_origin)
-    -> ValueRef {
-    let hash_id = vtable_id(ccx, origin);
+fn get_vtable(ccx: @crate_ctxt, +origin: typeck::vtable_origin) -> ValueRef {
+    // XXX: Bad copy.
+    let hash_id = vtable_id(ccx, copy origin);
     match ccx.vtables.find(hash_id) {
       Some(val) => val,
       None => match origin {
@@ -738,16 +755,18 @@ fn get_vtable(ccx: @crate_ctxt, origin: typeck::vtable_origin)
 }
 
 fn make_vtable(ccx: @crate_ctxt, ptrs: ~[ValueRef]) -> ValueRef {
-    let _icx = ccx.insn_ctxt("impl::make_vtable");
-    let tbl = C_struct(ptrs);
-    let vt_gvar =
-            str::as_c_str(ccx.sess.str_of((ccx.names)(~"vtable")), |buf| {
-        llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf)
-    });
-    llvm::LLVMSetInitializer(vt_gvar, tbl);
-    llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True);
-    lib::llvm::SetLinkage(vt_gvar, lib::llvm::InternalLinkage);
-    vt_gvar
+    unsafe {
+        let _icx = ccx.insn_ctxt("impl::make_vtable");
+        let tbl = C_struct(ptrs);
+        let vt_gvar =
+                str::as_c_str(ccx.sess.str_of((ccx.names)(~"vtable")), |buf| {
+            llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf)
+        });
+        llvm::LLVMSetInitializer(vt_gvar, tbl);
+        llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True);
+        lib::llvm::SetLinkage(vt_gvar, lib::llvm::InternalLinkage);
+        vt_gvar
+    }
 }
 
 fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t],
@@ -763,7 +782,8 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t],
 
     let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u;
     make_vtable(ccx, vec::map(*ty::trait_methods(tcx, trt_id), |im| {
-        let fty = ty::subst_tps(tcx, substs, None, ty::mk_fn(tcx, im.fty));
+        let fty = ty::subst_tps(tcx, substs, None,
+                                ty::mk_fn(tcx, copy im.fty));
         if (*im.tps).len() > 0u || ty::type_has_self(fty) {
             debug!("(making impl vtable) method has self or type params: %s",
                    tcx.sess.str_of(im.ident));
@@ -858,7 +878,7 @@ fn trans_trait_cast(bcx: block,
     }
 
     // Store the vtable into the pair or triple.
-    let orig = ccx.maps.vtable_map.get(id)[0];
+    let orig = /*bad*/copy ccx.maps.vtable_map.get(id)[0];
     let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig);
     let vtable = get_vtable(bcx.ccx(), orig);
     Store(bcx, vtable, PointerCast(bcx,
index 9d662f875510cb2172a5fad160ae3d9cb27d5986..6ead78a28dd1ac9337373d8ca1be10eee0f17800 100644 (file)
@@ -8,16 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use back::link::mangle_exported_name;
 use middle::trans::base::{get_insn_ctxt};
 use middle::trans::base::{set_inline_hint_if_appr, set_inline_hint};
 use middle::trans::base::{trans_enum_variant, trans_struct_dtor};
 use middle::trans::base::{trans_fn, impl_self, decl_internal_cdecl_fn};
 use middle::trans::base::{trans_item, get_item_val, no_self, self_arg};
+use middle::trans::base;
 use middle::trans::common::*;
+use middle::trans::datum;
+use middle::trans::foreign;
+use middle::trans::machine;
+use middle::trans::meth;
+use middle::trans::shape;
 use middle::trans::type_of::type_of_fn_from_ty;
+use middle::trans::type_of;
+use middle::trans::type_use;
 use middle::ty::{FnTyBase, FnMeta, FnSig};
+use middle::typeck;
 
+use core::option;
+use core::vec;
 use syntax::ast;
 use syntax::ast_map::{path, path_mod, path_name};
 use syntax::ast_util::local_def;
@@ -42,7 +55,8 @@ fn monomorphic_fn(ccx: @crate_ctxt,
     for real_substs.each() |s| { assert !ty::type_has_params(*s); }
     for substs.each() |s| { assert !ty::type_has_params(*s); }
     let param_uses = type_use::type_uses_for(ccx, fn_id, substs.len());
-    let hash_id = make_mono_id(ccx, fn_id, substs, vtables, impl_did_opt,
+    // XXX: Bad copy.
+    let hash_id = make_mono_id(ccx, fn_id, copy substs, vtables, impl_did_opt,
                                Some(param_uses));
     if vec::any(hash_id.params,
                 |p| match *p { mono_precise(_, _) => false, _ => true }) {
@@ -125,7 +139,7 @@ fn monomorphic_fn(ccx: @crate_ctxt,
 
     ccx.stats.n_monos += 1;
 
-    let depth = option::get_default(ccx.monomorphizing.find(fn_id), 0u);
+    let depth = option::get_or_default(ccx.monomorphizing.find(fn_id), 0u);
     // Random cut-off -- code that needs to instantiate the same function
     // recursively more than ten times can probably safely be assumed to be
     // causing an infinite expansion.
@@ -135,17 +149,17 @@ fn monomorphic_fn(ccx: @crate_ctxt,
     }
     ccx.monomorphizing.insert(fn_id, depth + 1);
 
-    let pt = vec::append(*pt,
+    let pt = vec::append(/*bad*/copy *pt,
                          ~[path_name((ccx.names)(ccx.sess.str_of(name)))]);
-    let s = mangle_exported_name(ccx, pt, mono_ty);
+    let s = mangle_exported_name(ccx, /*bad*/copy pt, mono_ty);
 
-    let mk_lldecl = || {
-        let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, llfty);
+    let mk_lldecl = |/*bad*/copy s| {
+        let lldecl = decl_internal_cdecl_fn(ccx.llmod, /*bad*/copy s, llfty);
         ccx.monomorphized.insert(hash_id, lldecl);
         lldecl
     };
 
-    let psubsts = Some({
+    let psubsts = Some(param_substs {
         tys: substs,
         vtables: vtables,
         bounds: tpt.bounds,
@@ -154,11 +168,12 @@ fn monomorphic_fn(ccx: @crate_ctxt,
 
     let lldecl = match map_node {
       ast_map::node_item(i@@{
-                node: ast::item_fn(decl, _, _, ref body),
+                // XXX: Bad copy.
+                node: ast::item_fn(copy decl, _, _, ref body),
                 _
             }, _) => {
         let d = mk_lldecl();
-        set_inline_hint_if_appr(i.attrs, d);
+        set_inline_hint_if_appr(/*bad*/copy i.attrs, d);
         trans_fn(ccx, pt, decl, *body, d, no_self, psubsts, fn_id.node, None);
         d
       }
@@ -178,9 +193,9 @@ fn monomorphic_fn(ccx: @crate_ctxt,
         let d = mk_lldecl();
         set_inline_hint(d);
         match (*v).node.kind {
-            ast::tuple_variant_kind(args) => {
-                trans_enum_variant(ccx, enum_item.id, (*v), args,
-                                   this_tv.disr_val, (*tvs).len() == 1u,
+            ast::tuple_variant_kind(ref args) => {
+                trans_enum_variant(ccx, enum_item.id, *v, /*bad*/copy *args,
+                                   this_tv.disr_val, tvs.len() == 1u,
                                    psubsts, d);
             }
             ast::struct_variant_kind(_) =>
@@ -193,7 +208,7 @@ fn monomorphic_fn(ccx: @crate_ctxt,
       ast_map::node_method(mth, supplied_impl_did, _) => {
         // XXX: What should the self type be here?
         let d = mk_lldecl();
-        set_inline_hint_if_appr(mth.attrs, d);
+        set_inline_hint_if_appr(/*bad*/copy mth.attrs, d);
 
         // Override the impl def ID if necessary.
         let impl_did;
@@ -212,14 +227,14 @@ fn monomorphic_fn(ccx: @crate_ctxt,
                 None      => ccx.sess.span_bug(dtor.span, ~"Bad self ty in \
                                                             dtor")
         };
-        trans_struct_dtor(ccx, *pt, dtor.node.body,
+        trans_struct_dtor(ccx, /*bad*/copy *pt, dtor.node.body,
           dtor.node.id, psubsts, Some(hash_id), parent_id)
       }
       ast_map::node_trait_method(@ast::provided(mth), _, pt) => {
         let d = mk_lldecl();
-        set_inline_hint_if_appr(mth.attrs, d);
+        set_inline_hint_if_appr(/*bad*/copy mth.attrs, d);
         debug!("monomorphic_fn impl_did_opt is %?", impl_did_opt);
-        meth::trans_method(ccx, *pt, mth, psubsts, None, d,
+        meth::trans_method(ccx, /*bad*/copy *pt, mth, psubsts, None, d,
                            impl_did_opt.get());
         d
       }
@@ -227,7 +242,7 @@ fn monomorphic_fn(ccx: @crate_ctxt,
         let d = mk_lldecl();
         set_inline_hint(d);
         base::trans_tuple_struct(ccx,
-                                 struct_def.fields,
+                                 /*bad*/copy struct_def.fields,
                                  option::expect(struct_def.ctor_id,
                                                 ~"ast-mapped tuple struct \
                                                   didn't have a ctor id"),
@@ -266,8 +281,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> Option<ty::t> {
                                         proto: fty.meta.proto,
                                         onceness: ast::Many,
                                         region: ty::re_static,
-                                        bounds: @~[],
-                                        ret_style: ast::return_val},
+                                        bounds: @~[]},
                           sig: FnSig {inputs: ~[],
                                       output: ty::mk_nil(tcx)}}))
         }
@@ -278,8 +292,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> Option<ty::t> {
                                         proto: ast::ProtoBox,
                                         onceness: ast::Many,
                                         region: ty::re_static,
-                                        bounds: @~[],
-                                        ret_style: ast::return_val},
+                                        bounds: @~[]},
                           sig: FnSig {inputs: ~[],
                                       output: ty::mk_nil(tcx)}}))
         }
@@ -305,7 +318,7 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t],
             for bounds.each |bound| {
                 match *bound {
                   ty::bound_trait(_) => {
-                    v.push(meth::vtable_id(ccx, vts[i]));
+                    v.push(meth::vtable_id(ccx, /*bad*/copy vts[i]));
                     i += 1u;
                   }
                   _ => ()
@@ -319,15 +332,16 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t],
       }
     };
     let param_ids = match param_uses {
-      Some(uses) => {
-        vec::map2(precise_param_ids, uses, |id, uses| {
+      Some(ref uses) => {
+        vec::map2(precise_param_ids, *uses, |id, uses| {
             if ccx.sess.no_monomorphic_collapse() {
-                match *id {
+                match copy *id {
                     (a, b) => mono_precise(a, b)
                 }
             } else {
                 match *id {
-                    (a, b@Some(_)) => mono_precise(a, b),
+                    // XXX: Bad copy.
+                    (a, copy b@Some(_)) => mono_precise(a, b),
                     (subst, None) => {
                         if *uses == 0u {
                             mono_any
@@ -365,10 +379,10 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t],
       }
       None => {
           precise_param_ids.map(|x| {
-              let (a, b) = *x;
+              let (a, b) = copy *x;
               mono_precise(a, b)
           })
       }
     };
-    @{def: item, params: param_ids, impl_did_opt: impl_did_opt}
+    @mono_id_ {def: item, params: param_ids, impl_did_opt: impl_did_opt}
 }
index fbaa038b4cc9ae481cab23933d9fa3b362f37c48..5de7ebadb2b315c823af2d4ac66641f8fd5d75f8 100644 (file)
 // makes all other generics or inline functions that it references
 // reachable as well.
 
+
+use driver::session::*;
+use middle::resolve;
+use middle::ty;
+use middle::typeck;
+
+use core::vec;
+use std::map::HashMap;
 use syntax::ast::*;
-use syntax::{visit, ast_util, ast_map};
 use syntax::ast_util::def_id_of_def;
 use syntax::attr;
 use syntax::print::pprust::expr_to_str;
-use std::map::HashMap;
-use driver::session::*;
+use syntax::{visit, ast_util, ast_map};
 
 export map, find_reachable;
 
-type map = std::map::HashMap<node_id, ()>;
+type map = HashMap<node_id, ()>;
 
-type ctx = {exp_map2: resolve::ExportMap2,
-            tcx: ty::ctxt,
-            method_map: typeck::method_map,
-            rmap: map};
+struct ctx {
+    exp_map2: resolve::ExportMap2,
+    tcx: ty::ctxt,
+    method_map: typeck::method_map,
+    rmap: map
+}
 
 fn find_reachable(crate_mod: _mod, exp_map2: resolve::ExportMap2,
                   tcx: ty::ctxt, method_map: typeck::method_map) -> map {
-    let rmap = std::map::HashMap();
-    let cx = {exp_map2: exp_map2, tcx: tcx,
-              method_map: method_map, rmap: rmap};
+    let rmap = HashMap();
+    let cx = ctx {
+        exp_map2: exp_map2,
+        tcx: tcx,
+        method_map: method_map,
+        rmap: rmap
+    };
     traverse_public_mod(cx, ast::crate_node_id, crate_mod);
     traverse_all_resources_and_impls(cx, crate_mod);
     rmap
@@ -60,7 +72,7 @@ fn traverse_def_id(cx: ctx, did: def_id) {
     if did.crate != local_crate { return; }
     let n = match cx.tcx.items.find(did.node) {
         None => return, // This can happen for self, for example
-        Some(ref n) => (*n)
+        Some(ref n) => (/*bad*/copy *n)
     };
     match n {
       ast_map::node_item(item, _) => traverse_public_item(cx, item),
@@ -87,7 +99,7 @@ fn traverse_public_mod(cx: ctx, mod_id: node_id, m: _mod) {
 fn traverse_public_item(cx: ctx, item: @item) {
     if cx.rmap.contains_key(item.id) { return; }
     cx.rmap.insert(item.id, ());
-    match item.node {
+    match /*bad*/copy item.node {
       item_mod(m) => traverse_public_mod(cx, item.id, m),
       item_foreign_mod(nm) => {
           if !traverse_exports(cx, item.id) {
@@ -96,7 +108,7 @@ fn traverse_public_item(cx: ctx, item: @item) {
               }
           }
       }
-      item_fn(_, _, tps, ref blk) => {
+      item_fn(_, _, ref tps, ref blk) => {
         if tps.len() > 0u ||
            attr::find_inline_attr(item.attrs) != attr::ia_none {
             traverse_inline_body(cx, (*blk));
@@ -130,7 +142,8 @@ fn traverse_public_item(cx: ctx, item: @item) {
 }
 
 fn mk_ty_visitor() -> visit::vt<ctx> {
-    visit::mk_vt(@{visit_ty: traverse_ty, ..*visit::default_visitor()})
+    visit::mk_vt(@visit::Visitor {visit_ty: traverse_ty,
+                                  ..*visit::default_visitor()})
 }
 
 fn traverse_ty(ty: @Ty, cx: ctx, v: visit::vt<ctx>) {
@@ -197,7 +210,7 @@ fn traverse_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
     fn traverse_item(i: @item, cx: ctx, _v: visit::vt<ctx>) {
       traverse_public_item(cx, i);
     }
-     visit::visit_block(body, cx, visit::mk_vt(@{
+     visit::visit_block(body, cx, visit::mk_vt(@visit::Visitor {
         visit_expr: traverse_expr,
         visit_item: traverse_item,
          ..*visit::default_visitor()
@@ -205,21 +218,23 @@ fn traverse_item(i: @item, cx: ctx, _v: visit::vt<ctx>) {
 }
 
 fn traverse_all_resources_and_impls(cx: ctx, crate_mod: _mod) {
-    visit::visit_mod(crate_mod, ast_util::dummy_sp(), 0, cx, visit::mk_vt(@{
-        visit_expr: |_e, _cx, _v| { },
-        visit_item: |i, cx, v| {
-            visit::visit_item(i, cx, v);
-            match i.node {
-              item_struct(struct_def, _) if struct_def.dtor.is_some() => {
-                traverse_public_item(cx, i);
-              }
-              item_impl(*) => {
-                traverse_public_item(cx, i);
-              }
-              _ => ()
-            }
-        },
-        ..*visit::default_visitor()
-    }));
+    visit::visit_mod(
+        crate_mod, ast_util::dummy_sp(), 0, cx,
+        visit::mk_vt(@visit::Visitor {
+            visit_expr: |_e, _cx, _v| { },
+            visit_item: |i, cx, v| {
+                visit::visit_item(i, cx, v);
+                match i.node {
+                    item_struct(sdef, _) if sdef.dtor.is_some() => {
+                        traverse_public_item(cx, i);
+                    }
+                    item_impl(*) => {
+                        traverse_public_item(cx, i);
+                    }
+                    _ => ()
+                }
+            },
+            ..*visit::default_visitor()
+        }));
 }
 
index d15a9c101b9555e169c77502712d47aa56bfacc6..39ab5735dee3f023b997519081475d8cdf455250 100644 (file)
@@ -8,14 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 use back::abi;
 use lib::llvm::{TypeRef, ValueRef};
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::callee::{ArgVals, DontAutorefArg};
+use middle::trans::callee;
 use middle::trans::common::*;
 use middle::trans::datum::*;
 use middle::trans::expr::SaveIn;
+use middle::trans::glue;
+use middle::trans::meth;
+use middle::trans::shape;
 use middle::trans::type_of::*;
 use util::ppaux::ty_to_str;
 
@@ -41,9 +46,18 @@ fn c_int(i: int) -> ValueRef {
         C_int(self.bcx.ccx(), i)
     }
 
-    fn c_slice(s: ~str) -> ValueRef {
-        let ss = C_estr_slice(self.bcx.ccx(), s);
-        do_spill_noroot(self.bcx, ss)
+    fn c_slice(+s: ~str) -> ValueRef {
+        // We're careful to not use first class aggregates here because that
+        // will kick us off fast isel. (Issue #4352.)
+        let bcx = self.bcx;
+        let str_vstore = ty::vstore_slice(ty::re_static);
+        let str_ty = ty::mk_estr(bcx.tcx(), str_vstore);
+        let scratch = scratch_datum(bcx, str_ty, false);
+        let len = C_uint(bcx.ccx(), s.len() + 1);
+        let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), T_ptr(T_i8()));
+        Store(bcx, c_str, GEPi(bcx, scratch.val, [ 0, 0 ]));
+        Store(bcx, len, GEPi(bcx, scratch.val, [ 0, 1 ]));
+        scratch.val
     }
 
     fn c_size_and_align(t: ty::t) -> ~[ValueRef] {
@@ -72,7 +86,9 @@ fn visit(ty_name: ~str, args: ~[ValueRef]) {
             tcx.sess.ident_of(~"visit_" + ty_name),
             *self.visitor_methods).expect(fmt!("Couldn't find visit method \
                                                 for %s", ty_name));
-        let mth_ty = ty::mk_fn(tcx, self.visitor_methods[mth_idx].fty);
+        let mth_ty = ty::mk_fn(
+            tcx,
+            /*bad*/copy self.visitor_methods[mth_idx].fty);
         let v = self.visitor_val;
         debug!("passing %u args:", vec::len(args));
         let bcx = self.bcx;
@@ -97,16 +113,17 @@ fn visit(ty_name: ~str, args: ~[ValueRef]) {
         self.bcx = next_bcx
     }
 
-    fn bracketed(bracket_name: ~str, extra: ~[ValueRef],
+    fn bracketed(bracket_name: ~str, +extra: ~[ValueRef],
                  inner: fn()) {
-        self.visit(~"enter_" + bracket_name, extra);
+        // XXX: Bad copy.
+        self.visit(~"enter_" + bracket_name, copy extra);
         inner();
         self.visit(~"leave_" + bracket_name, extra);
     }
 
     fn vstore_name_and_extra(t: ty::t,
                              vstore: ty::vstore,
-                             f: fn(~str,~[ValueRef])) {
+                             f: fn(+s: ~str,+v: ~[ValueRef])) {
         match vstore {
           ty::vstore_fixed(n) => {
             let extra = vec::append(~[self.c_uint(n)],
@@ -119,7 +136,7 @@ fn vstore_name_and_extra(t: ty::t,
         }
     }
 
-    fn leaf(name: ~str) {
+    fn leaf(+name: ~str) {
         self.visit(name, ~[]);
     }
 
@@ -130,7 +147,7 @@ fn visit_ty(t: ty::t) {
         debug!("reflect::visit_ty %s",
                ty_to_str(bcx.ccx().tcx, t));
 
-        match ty::get(t).sty {
+        match /*bad*/copy ty::get(t).sty {
           ty::ty_bot => self.leaf(~"bot"),
           ty::ty_nil => self.leaf(~"nil"),
           ty::ty_bool => self.leaf(~"bool"),
@@ -202,15 +219,12 @@ fn visit_ty(t: ty::t) {
               ast::extern_fn => 3u
             };
             let protoval = ast_proto_constant(fty.meta.proto);
-            let retval = match fty.meta.ret_style {
-              ast::noreturn => 0u,
-              ast::return_val => 1u
-            };
+            let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u};
             let extra = ~[self.c_uint(pureval),
                           self.c_uint(protoval),
                           self.c_uint(vec::len(fty.sig.inputs)),
                           self.c_uint(retval)];
-            self.visit(~"enter_fn", extra);
+            self.visit(~"enter_fn", copy extra);    // XXX: Bad copy.
             for fty.sig.inputs.eachi |i, arg| {
                 let modeval = match arg.mode {
                   ast::infer(_) => 0u,
index 51c3cb9362f399972c862683fc8ab5a9a3930a3a..b6f2a00f520019090609902a25c18c8186c445d8 100644 (file)
 // A "shape" is a compact encoding of a type that is used by interpreted glue.
 // This substitutes for the runtime tags used by e.g. MLs.
 
+
 use back::abi;
 use lib::llvm::llvm;
 use lib::llvm::{True, False, ModuleRef, TypeRef, ValueRef};
 use middle::trans::base;
 use middle::trans::common::*;
 use middle::trans::machine::*;
+use middle::trans;
 use middle::ty::field;
 use middle::ty;
 use util::ppaux::ty_to_str;
 
 use core::dvec::DVec;
 use core::option::is_some;
+use core::vec;
 use std::map::HashMap;
 use syntax::ast;
 use syntax::ast_util::dummy_sp;
 
 fn mk_global(ccx: @crate_ctxt, name: ~str, llval: ValueRef, internal: bool) ->
    ValueRef {
-    let llglobal = do str::as_c_str(name) |buf| {
-        lib::llvm::llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf)
-    };
-    lib::llvm::llvm::LLVMSetInitializer(llglobal, llval);
-    lib::llvm::llvm::LLVMSetGlobalConstant(llglobal, True);
+    unsafe {
+        let llglobal = do str::as_c_str(name) |buf| {
+            llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf)
+        };
+        llvm::LLVMSetInitializer(llglobal, llval);
+        llvm::LLVMSetGlobalConstant(llglobal, True);
 
-    if internal {
-        lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
-    }
+        if internal {
+            ::lib::llvm::SetLinkage(llglobal,
+                                    ::lib::llvm::InternalLinkage);
+        }
 
-    return llglobal;
+        return llglobal;
+    }
 }
 
 fn mk_ctxt(llmod: ModuleRef) -> ctxt {
-    let llshapetablesty = trans::common::T_named_struct(~"shapes");
-    let _llshapetables = str::as_c_str(~"shapes", |buf| {
-        lib::llvm::llvm::LLVMAddGlobal(llmod, llshapetablesty, buf)
-    });
+    unsafe {
+        let llshapetablesty = trans::common::T_named_struct(~"shapes");
+        let _llshapetables = str::as_c_str(~"shapes", |buf| {
+            llvm::LLVMAddGlobal(llmod, llshapetablesty, buf)
+        });
 
-    return {mut next_tag_id: 0u16, pad: 0u16, pad2: 0u32};
+        return {mut next_tag_id: 0u16, pad: 0u16, pad2: 0u32};
+    }
 }
 
 /*
index 2eaf15818d89f5cee5257a1adb7d55f8e7f51df3..9db607773eb4a273361e6cb291ebadcf51c5f449 100644 (file)
@@ -8,13 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 use back::abi;
 use lib::llvm::{ValueRef, TypeRef};
 use middle::trans::build::*;
 use middle::trans::common::*;
 use middle::trans::datum::*;
 use middle::trans::expr::{Dest, Ignore, SaveIn};
-use middle::trans::shape::llsize_of;
+use middle::trans::expr;
+use middle::trans::glue;
+use middle::trans::shape::{llsize_of, nonzero_llsize_of};
+use middle::trans::type_of;
+use middle::ty;
 use util::common::indenter;
 use util::ppaux::ty_to_str;
 
@@ -91,7 +96,7 @@ fn alloc_vec(bcx: block, unit_ty: ty::t, elts: uint, heap: heap) -> Result {
     let _icx = bcx.insn_ctxt("tvec::alloc_uniq");
     let ccx = bcx.ccx();
     let llunitty = type_of::type_of(ccx, unit_ty);
-    let unit_sz = llsize_of(ccx, llunitty);
+    let unit_sz = nonzero_llsize_of(ccx, llunitty);
 
     let fill = Mul(bcx, C_uint(ccx, elts), unit_sz);
     let alloc = if elts < 4u { Mul(bcx, C_int(ccx, 4), unit_sz) }
@@ -192,7 +197,7 @@ fn trans_slice_vstore(bcx: block,
 
     // Handle the &"..." case:
     match content_expr.node {
-        ast::expr_lit(@{node: ast::lit_str(s), span: _}) => {
+        ast::expr_lit(@ast::spanned {node: ast::lit_str(s), span: _}) => {
             return trans_lit_str(bcx, content_expr, s, dest);
         }
         _ => {}
@@ -251,13 +256,20 @@ fn trans_lit_str(bcx: block,
     match dest {
         Ignore => bcx,
         SaveIn(lldest) => {
-            let bytes = lit_str.len() + 1; // count null-terminator too
-            let llbytes = C_uint(bcx.ccx(), bytes);
-            let llcstr = C_cstr(bcx.ccx(), *lit_str);
-            let llcstr = llvm::LLVMConstPointerCast(llcstr, T_ptr(T_i8()));
-            Store(bcx, llcstr, GEPi(bcx, lldest, [0u, abi::slice_elt_base]));
-            Store(bcx, llbytes, GEPi(bcx, lldest, [0u, abi::slice_elt_len]));
-            bcx
+            unsafe {
+                let bytes = lit_str.len() + 1; // count null-terminator too
+                let llbytes = C_uint(bcx.ccx(), bytes);
+                let llcstr = C_cstr(bcx.ccx(), /*bad*/copy *lit_str);
+                let llcstr = llvm::LLVMConstPointerCast(llcstr,
+                                                        T_ptr(T_i8()));
+                Store(bcx,
+                      llcstr,
+                      GEPi(bcx, lldest, [0u, abi::slice_elt_base]));
+                Store(bcx,
+                      llbytes,
+                      GEPi(bcx, lldest, [0u, abi::slice_elt_len]));
+                bcx
+            }
         }
     }
 }
@@ -310,8 +322,8 @@ fn write_content(bcx: block,
            bcx.expr_to_str(vstore_expr));
     let _indenter = indenter();
 
-    match content_expr.node {
-        ast::expr_lit(@{node: ast::lit_str(s), span: _}) => {
+    match /*bad*/copy content_expr.node {
+        ast::expr_lit(@ast::spanned { node: ast::lit_str(s), _ }) => {
             match dest {
                 Ignore => {
                     return bcx;
@@ -319,7 +331,7 @@ fn write_content(bcx: block,
                 SaveIn(lldest) => {
                     let bytes = s.len() + 1; // copy null-terminator too
                     let llbytes = C_uint(bcx.ccx(), bytes);
-                    let llcstr = C_cstr(bcx.ccx(), *s);
+                    let llcstr = C_cstr(bcx.ccx(), /*bad*/copy *s);
                     base::call_memcpy(bcx, lldest, llcstr, llbytes);
                     return bcx;
                 }
@@ -406,7 +418,8 @@ fn vec_types(bcx: block, vec_ty: ty::t) -> VecTypes {
     let ccx = bcx.ccx();
     let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
     let llunit_ty = type_of::type_of(ccx, unit_ty);
-    let llunit_size = llsize_of(ccx, llunit_ty);
+    let llunit_size = nonzero_llsize_of(ccx, llunit_ty);
+
     VecTypes {vec_ty: vec_ty,
               unit_ty: unit_ty,
               llunit_ty: llunit_ty,
@@ -416,8 +429,10 @@ fn vec_types(bcx: block, vec_ty: ty::t) -> VecTypes {
 fn elements_required(bcx: block, content_expr: @ast::expr) -> uint {
     //! Figure out the number of elements we need to store this content
 
-    match content_expr.node {
-        ast::expr_lit(@{node: ast::lit_str(s), span: _}) => s.len() + 1,
+    match /*bad*/copy content_expr.node {
+        ast::expr_lit(@ast::spanned { node: ast::lit_str(s), _ }) => {
+            s.len() + 1
+        },
         ast::expr_vec(es, _) => es.len(),
         ast::expr_repeat(_, count_expr, _) => {
             ty::eval_repeat_count(bcx.tcx(), count_expr, content_expr.span)
index f146d556a9d9a31b011d3f056f74dbe00f7cb4ad..c79cf45ec4bbaac26e5e5bc78c03398102af96c6 100644 (file)
@@ -8,9 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
 use lib::llvm::llvm;
 use lib::llvm::{TypeRef};
 use middle::trans::common::*;
+use middle::trans::common;
+use middle::trans::expr;
+use util::ppaux;
 
 use std::map::HashMap;
 use syntax::ast;
@@ -46,17 +50,19 @@ fn type_of_explicit_args(ccx: @crate_ctxt, inputs: ~[ty::arg]) -> ~[TypeRef] {
 
 fn type_of_fn(cx: @crate_ctxt, inputs: ~[ty::arg],
               output: ty::t) -> TypeRef {
-    let mut atys: ~[TypeRef] = ~[];
+    unsafe {
+        let mut atys: ~[TypeRef] = ~[];
 
-    // Arg 0: Output pointer.
-    atys.push(T_ptr(type_of(cx, output)));
+        // Arg 0: Output pointer.
+        atys.push(T_ptr(type_of(cx, output)));
 
-    // Arg 1: Environment
-    atys.push(T_opaque_box_ptr(cx));
+        // Arg 1: Environment
+        atys.push(T_opaque_box_ptr(cx));
 
-    // ... then explicit args.
-    atys.push_all(type_of_explicit_args(cx, inputs));
-    return T_fn(atys, llvm::LLVMVoidType());
+        // ... then explicit args.
+        atys.push_all(type_of_explicit_args(cx, inputs));
+        return T_fn(atys, llvm::LLVMVoidType());
+    }
 }
 
 // Given a function type and a count of ty params, construct an llvm type
@@ -104,7 +110,8 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
         return llty;
     }
 
-    let llty = match ty::get(t).sty {
+    // XXX: This is a terrible terrible copy.
+    let llty = match /*bad*/copy ty::get(t).sty {
       ty::ty_nil | ty::ty_bot => T_nil(),
       ty::ty_bool => T_bool(),
       ty::ty_int(t) => T_int_ty(cx, t),
@@ -119,7 +126,10 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
         // avoids creating more than one copy of the enum when one
         // of the enum's variants refers to the enum itself.
 
-        common::T_named_struct(llvm_type_name(cx, an_enum, did, substs.tps))
+        common::T_named_struct(llvm_type_name(cx,
+                                              an_enum,
+                                              did,
+                                              /*bad*/copy substs.tps))
       }
       ty::ty_estr(ty::vstore_box) => {
         T_box_ptr(T_box(cx, T_vec(cx, T_i8())))
@@ -184,7 +194,10 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
         // in *after* placing it into the type cache. This prevents
         // infinite recursion with recursive struct types.
 
-        common::T_named_struct(llvm_type_name(cx, a_struct, did, substs.tps))
+        common::T_named_struct(llvm_type_name(cx,
+                                              a_struct,
+                                              did,
+                                              /*bad*/ copy substs.tps))
       }
       ty::ty_self => cx.tcx.sess.unimpl(~"type_of: ty_self"),
       ty::ty_infer(*) => cx.tcx.sess.bug(~"type_of with ty_infer"),
@@ -227,7 +240,7 @@ fn fill_type_of_enum(cx: @crate_ctxt, did: ast::def_id, t: ty::t,
     debug!("type_of_enum %?: %?", t, ty::get(t));
 
     let lltys = {
-        let degen = (*ty::enum_variants(cx.tcx, did)).len() == 1u;
+        let degen = ty::enum_is_univariant(cx.tcx, did);
         let size = shape::static_size_of_enum(cx, t);
         if !degen {
             ~[T_enum_discrim(cx), T_array(T_i8(), size)]
@@ -258,7 +271,7 @@ fn llvm_type_name(cx: @crate_ctxt,
     return fmt!(
         "%s %s[#%d]",
           name,
-        util::ppaux::parameterized(
+        ppaux::parameterized(
             cx.tcx,
             ty::item_path_str(cx.tcx, did),
             None,
@@ -268,9 +281,11 @@ fn llvm_type_name(cx: @crate_ctxt,
 }
 
 fn type_of_dtor(ccx: @crate_ctxt, self_ty: ty::t) -> TypeRef {
-    T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))), // output pointer
-           T_ptr(type_of(ccx, self_ty))],            // self arg
-         llvm::LLVMVoidType())
+    unsafe {
+        T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))), // output pointer
+               T_ptr(type_of(ccx, self_ty))],            // self arg
+             llvm::LLVMVoidType())
+    }
 }
 
 fn type_of_rooted(ccx: @crate_ctxt, t: ty::t) -> TypeRef {
index 7f3b78359fec466904cc3db2389308bfb3b07b1c..e17a9c8c0ede77f68804239b2333d1fdc4e54ee3 100644 (file)
 // much information, but have the disadvantage of being very
 // invasive.)
 
+
 use metadata::csearch;
+use middle::freevars;
 use middle::trans::common::*;
+use middle::trans::inline;
 
+use core::option;
+use core::uint;
+use core::vec;
 use std::list::{List, Cons, Nil};
 use std::list;
 use std::map::HashMap;
@@ -79,11 +85,11 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
 
     if fn_id_loc.crate != local_crate {
         let uses = vec::from_mut(copy cx.uses);
-        ccx.type_use_cache.insert(fn_id, uses);
+        ccx.type_use_cache.insert(fn_id, copy uses);
         return uses;
     }
     let map_node = match ccx.tcx.items.find(fn_id_loc.node) {
-        Some(ref x) => (*x),
+        Some(ref x) => (/*bad*/copy *x),
         None    => ccx.sess.bug(fmt!("type_uses_for: unbound item ID %?",
                                      fn_id_loc))
     };
@@ -135,6 +141,8 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
                 ~"ctlz8" | ~"ctlz16" | ~"ctlz32" | ~"ctlz64" => 0,
                 ~"cttz8" | ~"cttz16" | ~"cttz32" | ~"cttz64" => 0,
 
+                ~"bswap16" | ~"bswap32" | ~"bswap64" => 0,
+
                 // would be cool to make these an enum instead of strings!
                 _ => fail ~"unknown intrinsic in type_use"
             };
@@ -158,7 +166,8 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
       }
     }
     let uses = vec::from_mut(copy cx.uses);
-    ccx.type_use_cache.insert(fn_id, uses);
+    // XXX: Bad copy, use @vec instead?
+    ccx.type_use_cache.insert(fn_id, copy uses);
     uses
 }
 
@@ -331,7 +340,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
 }
 
 fn handle_body(cx: ctx, body: blk) {
-    let v = visit::mk_vt(@{
+    let v = visit::mk_vt(@visit::Visitor {
         visit_expr: |e, cx, v| {
             visit::visit_expr(e, cx, v);
             mark_for_expr(cx, e);
index 30d47d60e589260cf8925e253dfbc4a3e721a64a..58853224891d8aafb7dade5dc1cbb3930cbea091 100644 (file)
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
+use back;
 use lib::llvm::ValueRef;
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::common::*;
 use middle::trans::datum::immediate_rvalue;
+use middle::trans::datum;
+use middle::trans::glue;
 
 use syntax::ast;
 
index dc2632156466c7dc5b7670e382709a309cabe5a6..319aff924a67b3dc665e1c851b88460cb4eaa004 100644 (file)
 
 #[warn(deprecated_pattern)];
 
-use core::dvec::DVec;
-use std::{map, smallintmap};
-use result::Result;
-use std::map::HashMap;
+use core::prelude::*;
+
 use driver::session;
-use session::Session;
-use syntax::{ast, ast_map};
-use syntax::ast_util;
-use syntax::ast_util::{is_local, local_def};
-use syntax::codemap::span;
 use metadata::csearch;
-use util::ppaux::{region_to_str, explain_region, vstore_to_str,
-                  note_and_explain_region, bound_region_to_str};
-use middle::lint;
+use metadata;
+use middle::const_eval;
+use middle::freevars;
 use middle::lint::{get_lint_level, allow};
-use syntax::ast::*;
-use syntax::print::pprust::*;
-use util::ppaux::{ty_to_str, proto_ty_to_str, tys_to_str};
+use middle::lint;
 use middle::resolve::{Impl, MethodInfo};
+use middle::resolve;
+use middle::ty;
+use middle::typeck;
+use middle;
+use session::Session;
+use util::ppaux::{note_and_explain_region, bound_region_to_str};
+use util::ppaux::{region_to_str, explain_region, vstore_to_str};
+use util::ppaux::{ty_to_str, proto_ty_to_str, tys_to_str};
+
+use core::cast;
+use core::cmp;
+use core::dvec::DVec;
+use core::dvec;
+use core::ops;
+use core::option;
+use core::ptr::to_unsafe_ptr;
+use core::result::Result;
+use core::result;
+use core::to_bytes;
+use core::uint;
+use core::vec;
+use std::map::HashMap;
+use std::{map, smallintmap};
+use syntax::ast::*;
+use syntax::ast_util::{is_local, local_def};
+use syntax::ast_util;
+use syntax::codemap::span;
+use syntax::print::pprust;
+use syntax::{ast, ast_map};
+use syntax;
 
 export ProvidedMethodSource;
 export ProvidedMethodInfo;
 export ProvidedMethodsMap;
 export InstantiatedTraitRef;
-export TyVid, IntVid, FloatVid, FnVid, RegionVid, vid;
+export TyVid, IntVid, FloatVid, FnVid, RegionVid, Vid;
 export br_hashmap;
 export is_instantiable;
 export node_id_to_type;
@@ -53,7 +74,7 @@
 export expr_is_lval, expr_kind;
 export ExprKind, LvalueExpr, RvalueDatumExpr, RvalueDpsExpr, RvalueStmtExpr;
 export field_ty;
-export fold_ty, fold_sty_to_ty, fold_region, fold_regions;
+export fold_ty, fold_sty_to_ty, fold_region, fold_regions, fold_sig;
 export apply_op_on_t_to_ty_fn;
 export fold_regions_and_ty, walk_regions_and_ty;
 export field;
 export ty_opaque_box, mk_opaque_box;
 export ty_float, mk_float, mk_mach_float, type_is_fp;
 export ty_fn, FnTy, FnTyBase, FnMeta, FnSig, mk_fn;
-export ty_fn_proto, ty_fn_purity, ty_fn_ret, ty_fn_ret_style, tys_in_fn_ty;
+export ty_fn_proto, ty_fn_purity, ty_fn_ret, tys_in_fn_sig;
+export replace_fn_return_type;
 export ty_int, mk_int, mk_mach_int, mk_char;
 export mk_i8, mk_u8, mk_i16, mk_u16, mk_i32, mk_u32, mk_i64, mk_u64;
 export mk_f32, mk_f64;
 export ty_type, mk_type;
 export ty_uint, mk_uint, mk_mach_uint;
 export ty_uniq, mk_uniq, mk_imm_uniq, type_is_unique_box;
-export ty_infer, mk_infer, type_is_ty_var, mk_var, mk_int_var, mk_float_var;
+export ty_infer, mk_infer, type_is_ty_var, mk_var, mk_int_var;
+export mk_float_var;
 export InferTy, TyVar, IntVar, FloatVar;
 export ValueMode, ReadValue, CopyValue, MoveValue;
 export ty_self, mk_self, type_has_self;
 export Region, bound_region, encl_region;
 export re_bound, re_free, re_scope, re_static, re_infer;
 export ReVar, ReSkolemized;
-export br_self, br_anon, br_named, br_cap_avoid;
+export br_self, br_anon, br_named, br_cap_avoid, br_fresh;
 export get, type_has_params, type_needs_infer, type_has_regions;
-export type_is_region_ptr;
+export type_contains_err, type_is_region_ptr;
 export type_id;
 export tbox_has_flag;
 export ty_var_id;
 export meta_kind, kind_lteq, type_kind, type_kind_ext;
 export operators;
 export type_err, terr_vstore_kind;
-export terr_mismatch, terr_onceness_mismatch;
+export terr_integer_as_char, terr_mismatch, terr_onceness_mismatch;
 export type_err_to_str, note_and_explain_type_err;
 export expected_found;
 export type_needs_drop;
+export type_is_char;
 export type_is_empty;
 export type_is_integral;
 export type_is_numeric;
 export terr_regions_insufficiently_polymorphic;
 export terr_regions_overly_polymorphic;
 export terr_proto_mismatch;
-export terr_ret_style_mismatch;
 export terr_fn, terr_trait;
-export purity_to_str;
 export onceness_to_str;
 export param_tys_in_type;
 export eval_repeat_count;
@@ -285,18 +307,22 @@ impl creader_cache_key : to_bytes::IterBytes {
     }
 }
 
-type intern_key = {sty: sty, o_def_id: Option<ast::def_id>};
+type intern_key = {sty: *sty, o_def_id: Option<ast::def_id>};
 
 impl intern_key : cmp::Eq {
     pure fn eq(&self, other: &intern_key) -> bool {
-        (*self).sty == (*other).sty && (*self).o_def_id == (*other).o_def_id
+        unsafe {
+            *self.sty == *other.sty && self.o_def_id == other.o_def_id
+        }
     }
     pure fn ne(&self, other: &intern_key) -> bool { !(*self).eq(other) }
 }
 
 impl intern_key : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
-        to_bytes::iter_bytes_2(&self.sty, &self.o_def_id, lsb0, f);
+        unsafe {
+            to_bytes::iter_bytes_2(&*self.sty, &self.o_def_id, lsb0, f);
+        }
     }
 }
 
@@ -449,6 +475,7 @@ enum tbox_flag {
     has_self = 2,
     needs_infer = 4,
     has_regions = 8,
+    has_ty_err = 16,
 
     // a meta-flag: subst may be required if the type has parameters, a self
     // type, or references bound regions
@@ -482,6 +509,7 @@ enum t_opaque {}
 pure fn type_has_self(t: t) -> bool { tbox_has_flag(get(t), has_self) }
 pure fn type_needs_infer(t: t) -> bool { tbox_has_flag(get(t), needs_infer) }
 pure fn type_has_regions(t: t) -> bool { tbox_has_flag(get(t), has_regions) }
+pure fn type_contains_err(t: t) -> bool { tbox_has_flag(get(t), has_ty_err) }
 pure fn type_def_id(t: t) -> Option<ast::def_id> { get(t).o_def_id }
 pure fn type_id(t: t) -> uint { get(t).id }
 
@@ -493,15 +521,14 @@ enum t_opaque {}
  * - `onceness` indicates whether the function can be called one time or many
  *   times.
  * - `region` is the region bound on the function's upvars (often &static).
- * - `bounds` is the parameter bounds on the function's upvars.
- * - `ret_style` indicates whether the function returns a value or fails. */
+ * - `bounds` is the parameter bounds on the function's upvars. */
+#[deriving_eq]
 struct FnMeta {
     purity: ast::purity,
     proto: ast::Proto,
     onceness: ast::Onceness,
     region: Region,
-    bounds: @~[param_bound],
-    ret_style: ret_style
+    bounds: @~[param_bound]
 }
 
 /**
@@ -510,6 +537,7 @@ struct FnMeta {
  *
  * - `inputs` is the list of arguments and their modes.
  * - `output` is the return type. */
+#[deriving_eq]
 struct FnSig {
     inputs: ~[arg],
     output: t
@@ -520,9 +548,16 @@ struct FnSig {
  * type signature.  This particular type is parameterized
  * by the meta information because, in some cases, the
  * meta information is inferred. */
+#[deriving_eq]
 struct FnTyBase<M: cmp::Eq> {
-    meta: M,
-    sig: FnSig
+    meta: M,        // Either FnMeta or FnVid
+    sig: FnSig      // Types of arguments/return type
+}
+
+impl<M: to_bytes::IterBytes> FnTyBase<M> : to_bytes::IterBytes {
+    pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
+        to_bytes::iter_bytes_2(&self.meta, &self.sig, lsb0, f)
+    }
 }
 
 type FnTy = FnTyBase<FnMeta>;
@@ -585,6 +620,9 @@ enum bound_region {
     /// Named region parameters for functions (a in &a/T)
     br_named(ast::ident),
 
+    /// Fresh bound identifiers created during GLB computations.
+    br_fresh(uint),
+
     /**
      * Handles capture-avoiding substitution in a rather subtle case.  If you
      * have a closure whose argument types are being inferred based on the
@@ -647,7 +685,7 @@ enum sty {
     ty_param(param_ty), // type parameter
     ty_self, // special, implicit `self` type parameter
 
-    ty_infer(InferTy), // soething used only during inference/typeck
+    ty_infer(InferTy), // something used only during inference/typeck
     ty_err, // Also only used during inference/typeck, to represent
             // the type of an erroneous expression (helps cut down
             // on non-useful type error messages)
@@ -671,7 +709,6 @@ struct expected_found<T> {
 // Data structures used in type unification
 enum type_err {
     terr_mismatch,
-    terr_ret_style_mismatch(expected_found<ast::ret_style>),
     terr_purity_mismatch(expected_found<purity>),
     terr_onceness_mismatch(expected_found<Onceness>),
     terr_mutability,
@@ -696,6 +733,7 @@ enum type_err {
     terr_in_field(@type_err, ast::ident),
     terr_sorts(expected_found<t>),
     terr_self_substs,
+    terr_integer_as_char,
     terr_no_integral_type,
     terr_no_floating_point_type,
 }
@@ -716,6 +754,7 @@ enum param_bound {
 #[auto_decode]
 enum RegionVid = uint;
 
+#[deriving_eq]
 enum InferTy {
     TyVar(TyVid),
     IntVar(IntVid),
@@ -727,7 +766,7 @@ impl InferTy : to_bytes::IterBytes {
         match *self {
           TyVar(ref tv) => to_bytes::iter_bytes_2(&0u8, tv, lsb0, f),
           IntVar(ref iv) => to_bytes::iter_bytes_2(&1u8, iv, lsb0, f),
-          FloatVar(ref fv) => to_bytes::iter_bytes_2(&2u8, fv, lsb0, f)
+          FloatVar(ref fv) => to_bytes::iter_bytes_2(&2u8, fv, lsb0, f),
         }
     }
 }
@@ -778,61 +817,64 @@ impl param_bound : to_bytes::IterBytes {
     }
 }
 
-trait vid {
+trait Vid {
     pure fn to_uint() -> uint;
-    pure fn to_str() -> ~str;
 }
 
-impl TyVid: vid {
+impl TyVid: Vid {
     pure fn to_uint() -> uint { *self }
+}
+
+impl TyVid: ToStr {
     pure fn to_str() -> ~str { fmt!("<V%u>", self.to_uint()) }
 }
 
-impl IntVid: vid {
+impl IntVid: Vid {
     pure fn to_uint() -> uint { *self }
+}
+
+impl IntVid: ToStr {
     pure fn to_str() -> ~str { fmt!("<VI%u>", self.to_uint()) }
 }
 
-impl FloatVid: vid {
+impl FloatVid: Vid {
     pure fn to_uint() -> uint { *self }
+}
+
+impl FloatVid: ToStr {
     pure fn to_str() -> ~str { fmt!("<VF%u>", self.to_uint()) }
 }
 
-impl FnVid: vid {
+impl FnVid: Vid {
     pure fn to_uint() -> uint { *self }
+}
+
+impl FnVid: ToStr {
     pure fn to_str() -> ~str { fmt!("<F%u>", self.to_uint()) }
 }
 
-impl RegionVid: vid {
+impl RegionVid: Vid {
     pure fn to_uint() -> uint { *self }
-    pure fn to_str() -> ~str { fmt!("%?", self) }
 }
 
-impl InferTy {
-    pure fn to_hash() -> uint {
-        match self {
-            TyVar(v) => v.to_uint() << 1,
-            IntVar(v) => (v.to_uint() << 1) + 1,
-            FloatVar(v) => (v.to_uint() << 1) + 2
-        }
-    }
+impl RegionVid: ToStr {
+    pure fn to_str() -> ~str { fmt!("%?", self) }
+}
 
+impl FnSig : ToStr {
     pure fn to_str() -> ~str {
-        match self {
-            TyVar(v) => v.to_str(),
-            IntVar(v) => v.to_str(),
-            FloatVar(v) => v.to_str()
-        }
+        // grr, without tcx not much we can do.
+        return ~"(...)";
     }
 }
 
-trait purity_to_str {
-    pure fn to_str() -> ~str;
-}
-
-impl purity: purity_to_str {
+impl InferTy: ToStr {
     pure fn to_str() -> ~str {
-        purity_to_str(self)
+        match self {
+            TyVar(ref v) => v.to_str(),
+            IntVar(ref v) => v.to_str(),
+            FloatVar(ref v) => v.to_str()
+        }
     }
 }
 
@@ -988,11 +1030,12 @@ fn mk_t(cx: ctxt, +st: sty) -> t { mk_t_with_id(cx, st, None) }
 // Interns a type/name combination, stores the resulting box in cx.interner,
 // and returns the box as cast to an unsafe ptr (see comments for t above).
 fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option<ast::def_id>) -> t {
-    let key = {sty: st, o_def_id: o_def_id};
+    let key = {sty: to_unsafe_ptr(&st), o_def_id: o_def_id};
     match cx.interner.find(key) {
       Some(t) => unsafe { return cast::reinterpret_cast(&t); },
       _ => ()
     }
+
     let mut flags = 0u;
     fn rflags(r: Region) -> uint {
         (has_regions as uint) | {
@@ -1008,42 +1051,47 @@ fn sflags(substs: &substs) -> uint {
         substs.self_r.iter(|r| f |= rflags(*r));
         return f;
     }
-    match st {
-      ty_estr(vstore_slice(r)) => {
+    match &st {
+      &ty_estr(vstore_slice(r)) => {
         flags |= rflags(r);
       }
-      ty_evec(mt, vstore_slice(r)) => {
+      &ty_evec(ref mt, vstore_slice(r)) => {
         flags |= rflags(r);
         flags |= get(mt.ty).flags;
       }
-      ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
-      ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) |
-      ty_opaque_box | ty_err => (),
-      ty_param(_) => flags |= has_params as uint,
-      ty_infer(_) => flags |= needs_infer as uint,
-      ty_self => flags |= has_self as uint,
-      ty_enum(_, ref substs) | ty_struct(_, ref substs)
-      | ty_trait(_, ref substs, _) => {
+      &ty_nil | &ty_bot | &ty_bool | &ty_int(_) | &ty_float(_) | &ty_uint(_) |
+      &ty_estr(_) | &ty_type | &ty_opaque_closure_ptr(_) |
+      &ty_opaque_box => (),
+      &ty_err => flags |= has_ty_err as uint,
+      &ty_param(_) => flags |= has_params as uint,
+      &ty_infer(_) => flags |= needs_infer as uint,
+      &ty_self => flags |= has_self as uint,
+      &ty_enum(_, ref substs) | &ty_struct(_, ref substs) |
+      &ty_trait(_, ref substs, _) => {
         flags |= sflags(substs);
       }
-      ty_box(m) | ty_uniq(m) | ty_evec(m, _) |
-      ty_ptr(m) | ty_unboxed_vec(m) => {
+      &ty_box(ref m) | &ty_uniq(ref m) | &ty_evec(ref m, _) |
+      &ty_ptr(ref m) | &ty_unboxed_vec(ref m) => {
         flags |= get(m.ty).flags;
       }
-      ty_rptr(r, m) => {
+      &ty_rptr(r, ref m) => {
         flags |= rflags(r);
         flags |= get(m.ty).flags;
       }
-      ty_rec(flds) => for flds.each |f| { flags |= get(f.mt.ty).flags; },
-      ty_tup(ts) => for ts.each |tt| { flags |= get(*tt).flags; },
-      ty_fn(ref f) => {
+      &ty_rec(ref flds) => for flds.each |f| { flags |= get(f.mt.ty).flags; },
+      &ty_tup(ref ts) => for ts.each |tt| { flags |= get(*tt).flags; },
+      &ty_fn(ref f) => {
         flags |= rflags(f.meta.region);
         for f.sig.inputs.each |a| { flags |= get(a.ty).flags; }
         flags |= get(f.sig.output).flags;
       }
     }
-    let t = @{sty: st, id: cx.next_id, flags: flags, o_def_id: o_def_id};
-    cx.interner.insert(key, t);
+
+    let t = @{sty: move st, id: cx.next_id, flags: flags, o_def_id: o_def_id};
+
+    let key = {sty: to_unsafe_ptr(&t.sty), o_def_id: o_def_id};
+    cx.interner.insert(move key, t);
+
     cx.next_id += 1u;
     unsafe { cast::reinterpret_cast(&t) }
 }
@@ -1142,9 +1190,9 @@ fn mk_mut_unboxed_vec(cx: ctxt, ty: t) -> t {
     mk_t(cx, ty_unboxed_vec({ty: ty, mutbl: ast::m_imm}))
 }
 
-fn mk_rec(cx: ctxt, fs: ~[field]) -> t { mk_t(cx, ty_rec(fs)) }
+fn mk_rec(cx: ctxt, +fs: ~[field]) -> t { mk_t(cx, ty_rec(fs)) }
 
-fn mk_tup(cx: ctxt, ts: ~[t]) -> t { mk_t(cx, ty_tup(ts)) }
+fn mk_tup(cx: ctxt, +ts: ~[t]) -> t { mk_t(cx, ty_tup(ts)) }
 
 // take a copy because we want to own the various vectors inside
 fn mk_fn(cx: ctxt, +fty: FnTy) -> t { mk_t(cx, ty_fn(fty)) }
@@ -1166,7 +1214,7 @@ fn mk_int_var(cx: ctxt, v: IntVid) -> t { mk_infer(cx, IntVar(v)) }
 
 fn mk_float_var(cx: ctxt, v: FloatVid) -> t { mk_infer(cx, FloatVar(v)) }
 
-fn mk_infer(cx: ctxt, it: InferTy) -> t { mk_t(cx, ty_infer(it)) }
+fn mk_infer(cx: ctxt, +it: InferTy) -> t { mk_t(cx, ty_infer(it)) }
 
 fn mk_self(cx: ctxt) -> t { mk_t(cx, ty_self) }
 
@@ -1183,7 +1231,7 @@ fn mk_opaque_closure_ptr(cx: ctxt, proto: ast::Proto) -> t {
 fn mk_opaque_box(cx: ctxt) -> t { mk_t(cx, ty_opaque_box) }
 
 fn mk_with_id(cx: ctxt, base: t, def_id: ast::def_id) -> t {
-    mk_t_with_id(cx, get(base).sty, Some(def_id))
+    mk_t_with_id(cx, /*bad*/copy get(base).sty, Some(def_id))
 }
 
 // Converts s to its machine type equivalent
@@ -1192,7 +1240,7 @@ fn mk_with_id(cx: ctxt, base: t, def_id: ast::def_id) -> t {
       ty_int(ast::ty_i) => ty_int(cfg.int_type),
       ty_uint(ast::ty_u) => ty_uint(cfg.uint_type),
       ty_float(ast::ty_f) => ty_float(cfg.float_type),
-      ref s => (*s)
+      ref s => (/*bad*/copy *s)
     }
 }
 
@@ -1256,7 +1304,7 @@ fn walk_ty(ty: t, f: fn(t)) {
 
 fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
     if !f(ty) { return; }
-    match get(ty).sty {
+    match /*bad*/copy get(ty).sty {
       ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
       ty_estr(_) | ty_type | ty_opaque_box | ty_self |
       ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => {
@@ -1285,6 +1333,17 @@ fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: fn(t) -> t) -> t {
     mk_t(tcx, fold_sty(sty, foldop))
 }
 
+fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig {
+    let args = do sig.inputs.map |arg| {
+        { mode: arg.mode, ty: fldop(arg.ty) }
+    };
+
+    FnSig {
+        inputs: move args,
+        output: fldop(sig.output)
+    }
+}
+
 fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty {
     fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs {
         {self_r: substs.self_r,
@@ -1292,7 +1351,7 @@ fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs {
          tps: substs.tps.map(|t| fldop(*t))}
     }
 
-    match *sty {
+    match /*bad*/copy *sty {
         ty_box(tm) => {
             ty_box({ty: fldop(tm.ty), mutbl: tm.mutbl})
         }
@@ -1327,15 +1386,8 @@ fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs {
             ty_tup(new_ts)
         }
         ty_fn(ref f) => {
-            let new_args = f.sig.inputs.map(|a| {
-                let new_ty = fldop(a.ty);
-                {mode: a.mode, ty: new_ty}
-            });
-            let new_output = fldop(f.sig.output);
-            ty_fn(FnTyBase {
-                meta: f.meta,
-                sig: FnSig {inputs: new_args, output: new_output}
-            })
+            let sig = fold_sig(&f.sig, fldop);
+            ty_fn(FnTyBase {meta: f.meta, sig: sig})
         }
         ty_rptr(r, tm) => {
             ty_rptr(r, {ty: fldop(tm.ty), mutbl: tm.mutbl})
@@ -1346,7 +1398,7 @@ fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs {
         ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
         ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) | ty_err |
         ty_opaque_box | ty_infer(_) | ty_param(*) | ty_self => {
-            *sty
+            /*bad*/copy *sty
         }
     }
 }
@@ -1382,8 +1434,8 @@ fn fold_regions_and_ty(
     fn fold_substs(
         substs: &substs,
         fldr: fn(r: Region) -> Region,
-        fldt: fn(t: t) -> t) -> substs {
-
+        fldt: fn(t: t) -> t) -> substs
+    {
         {self_r: substs.self_r.map(|r| fldr(*r)),
          self_ty: substs.self_ty.map(|t| fldt(*t)),
          tps: substs.tps.map(|t| fldt(*t))}
@@ -1415,18 +1467,9 @@ fn fold_substs(
         ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), vst)
       }
       ty_fn(ref f) => {
-          let new_region = fldr(f.meta.region);
-          let new_args = vec::map(f.sig.inputs, |a| {
-              let new_ty = fldfnt(a.ty);
-              {mode: a.mode, ty: new_ty}
-          });
-          let new_output = fldfnt(f.sig.output);
-          ty::mk_fn(cx, FnTyBase {
-              meta: FnMeta {region: new_region,
-                            ..f.meta},
-              sig: FnSig {inputs: new_args,
-                          output: new_output}
-          })
+          ty::mk_fn(cx, FnTyBase {meta: FnMeta {region: fldr(f.meta.region),
+                                                ..f.meta},
+                                  sig: fold_sig(&f.sig, fldfnt)})
       }
       ref sty => {
         fold_sty_to_ty(cx, sty, |t| fldt(t))
@@ -1446,7 +1489,7 @@ fn apply_op_on_t_to_ty_fn(
     f: &FnTy,
     t_op: fn(t) -> t) -> FnTy
 {
-    let t0 = ty::mk_fn(cx, *f);
+    let t0 = ty::mk_fn(cx, /*bad*/copy *f);
     let t1 = t_op(t0);
     match ty::get(t1).sty {
         ty::ty_fn(copy f) => {
@@ -1463,10 +1506,11 @@ fn apply_op_on_t_to_ty_fn(
 fn fold_regions(
     cx: ctxt,
     ty: t,
-    fldr: fn(r: Region, in_fn: bool) -> Region) -> t {
-
+    fldr: fn(r: Region, in_fn: bool) -> Region) -> t
+{
     fn do_fold(cx: ctxt, ty: t, in_fn: bool,
                fldr: fn(Region, bool) -> Region) -> t {
+        debug!("do_fold(ty=%s, in_fn=%b)", ty_to_str(cx, ty), in_fn);
         if !type_has_regions(ty) { return ty; }
         fold_regions_and_ty(
             cx, ty,
@@ -1542,17 +1586,18 @@ fn substs_is_noop(substs: &substs) -> bool {
 fn substs_to_str(cx: ctxt, substs: &substs) -> ~str {
     fmt!("substs(self_r=%s, self_ty=%s, tps=%?)",
          substs.self_r.map_default(~"none", |r| region_to_str(cx, *r)),
-         substs.self_ty.map_default(~"none", |t| ty_to_str(cx, *t)),
+         substs.self_ty.map_default(~"none",
+                                    |t| ::util::ppaux::ty_to_str(cx, *t)),
          tys_to_str(cx, substs.tps))
 }
 
 fn param_bound_to_str(cx: ctxt, pb: &param_bound) -> ~str {
     match *pb {
         bound_copy => ~"copy",
-        bound_durable => ~"durable",
+        bound_durable => ~"&static",
         bound_owned => ~"owned",
         bound_const => ~"const",
-        bound_trait(t) => ty_to_str(cx, t)
+        bound_trait(t) => ::util::ppaux::ty_to_str(cx, t)
     }
 }
 
@@ -1566,11 +1611,11 @@ fn subst(cx: ctxt,
 
     debug!("subst(substs=%s, typ=%s)",
            substs_to_str(cx, substs),
-           ty_to_str(cx, typ));
+           ::util::ppaux::ty_to_str(cx, typ));
 
     if substs_is_noop(substs) { return typ; }
     let r = do_subst(cx, substs, typ);
-    debug!("  r = %s", ty_to_str(cx, r));
+    debug!("  r = %s", ::util::ppaux::ty_to_str(cx, r));
     return r;
 
     fn do_subst(cx: ctxt,
@@ -1585,10 +1630,18 @@ fn do_subst(cx: ctxt,
             fold_regions_and_ty(
                 cx, typ,
                 |r| match r {
-                    re_bound(br_self) => substs.self_r.expect(
-                        fmt!("ty::subst: \
-                      Reference to self region when given substs with no \
-                      self region, ty = %s", ty_to_str(cx, typ))),
+                    re_bound(br_self) => {
+                        match substs.self_r {
+                            None => {
+                                cx.sess.bug(
+                                    fmt!("ty::subst: \
+                                  Reference to self region when given substs \
+                                  with no self region, ty = %s",
+                                  ::util::ppaux::ty_to_str(cx, typ)))
+                            }
+                            Some(self_r) => self_r
+                        }
+                    }
                     _ => r
                 },
                 |t| do_subst(cx, substs, t),
@@ -1662,7 +1715,7 @@ fn sequence_element_type(cx: ctxt, ty: t) -> t {
 }
 
 fn get_element_type(ty: t, i: uint) -> t {
-    match get(ty).sty {
+    match /*bad*/copy get(ty).sty {
       ty_rec(flds) => return flds[i].mt.ty,
       ty_tup(ts) => return ts[i],
       _ => fail ~"get_element_type called on invalid type"
@@ -1755,7 +1808,7 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
     }
 
     let mut accum = false;
-    let result = match get(ty).sty {
+    let result = match /*bad*/copy get(ty).sty {
       // scalar types
       ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
       ty_type | ty_ptr(_) | ty_rptr(_, _) |
@@ -2115,7 +2168,7 @@ fn type_kind_ext(cx: ctxt, ty: t, allow_ty_var: bool) -> Kind {
     // Insert a default in case we loop back on self recursively.
     cx.kind_cache.insert(ty, kind_top());
 
-    let mut result = match get(ty).sty {
+    let mut result = match /*bad*/copy get(ty).sty {
       // Scalar and unique types are sendable, constant, and owned
       ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
       ty_ptr(_) => {
@@ -2287,7 +2340,7 @@ fn type_implicitly_moves(cx: ctxt, ty: t) -> bool {
 /// gives a rough estimate of how much space it takes to represent
 /// an instance of `ty`.  Used for the mode transition.
 fn type_size(cx: ctxt, ty: t) -> uint {
-    match get(ty).sty {
+    match /*bad*/copy get(ty).sty {
       ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
       ty_ptr(_) | ty_box(_) | ty_uniq(_) | ty_estr(vstore_uniq) |
       ty_trait(*) | ty_rptr(*) | ty_evec(_, vstore_uniq) |
@@ -2351,8 +2404,8 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
     fn type_requires(cx: ctxt, seen: @mut ~[def_id],
                      r_ty: t, ty: t) -> bool {
         debug!("type_requires(%s, %s)?",
-               ty_to_str(cx, r_ty),
-               ty_to_str(cx, ty));
+               ::util::ppaux::ty_to_str(cx, r_ty),
+               ::util::ppaux::ty_to_str(cx, ty));
 
         let r = {
             get(r_ty).sty == get(ty).sty ||
@@ -2360,8 +2413,8 @@ fn type_requires(cx: ctxt, seen: @mut ~[def_id],
         };
 
         debug!("type_requires(%s, %s)? %b",
-               ty_to_str(cx, r_ty),
-               ty_to_str(cx, ty),
+               ::util::ppaux::ty_to_str(cx, r_ty),
+               ::util::ppaux::ty_to_str(cx, ty),
                r);
         return r;
     }
@@ -2369,10 +2422,10 @@ fn type_requires(cx: ctxt, seen: @mut ~[def_id],
     fn subtypes_require(cx: ctxt, seen: @mut ~[def_id],
                         r_ty: t, ty: t) -> bool {
         debug!("subtypes_require(%s, %s)?",
-               ty_to_str(cx, r_ty),
-               ty_to_str(cx, ty));
+               ::util::ppaux::ty_to_str(cx, r_ty),
+               ::util::ppaux::ty_to_str(cx, ty));
 
-        let r = match get(ty).sty {
+        let r = match /*bad*/copy get(ty).sty {
           ty_nil |
           ty_bot |
           ty_bool |
@@ -2447,8 +2500,8 @@ fn subtypes_require(cx: ctxt, seen: @mut ~[def_id],
         };
 
         debug!("subtypes_require(%s, %s)? %b",
-               ty_to_str(cx, r_ty),
-               ty_to_str(cx, ty),
+               ::util::ppaux::ty_to_str(cx, r_ty),
+               ::util::ppaux::ty_to_str(cx, ty),
                r);
 
         return r;
@@ -2461,9 +2514,10 @@ fn subtypes_require(cx: ctxt, seen: @mut ~[def_id],
 fn type_structurally_contains(cx: ctxt, ty: t, test: fn(x: &sty) -> bool) ->
    bool {
     let sty = &get(ty).sty;
-    debug!("type_structurally_contains: %s", ty_to_str(cx, ty));
+    debug!("type_structurally_contains: %s",
+           ::util::ppaux::ty_to_str(cx, ty));
     if test(sty) { return true; }
-    match *sty {
+    match /*bad*/copy *sty {
       ty_enum(did, ref substs) => {
         for vec::each(*enum_variants(cx, did)) |variant| {
             for variant.args.each |aty| {
@@ -2520,6 +2574,13 @@ fn type_is_integral(ty: t) -> bool {
     }
 }
 
+fn type_is_char(ty: t) -> bool {
+    match get(ty).sty {
+        ty_int(ty_char) => true,
+        _ => false
+    }
+}
+
 fn type_is_fp(ty: t) -> bool {
     match get(ty).sty {
       ty_infer(FloatVar(_)) | ty_float(_) => true,
@@ -2542,7 +2603,7 @@ fn type_is_signed(ty: t) -> bool {
 // that the cycle collector might care about.
 fn type_is_pod(cx: ctxt, ty: t) -> bool {
     let mut result = true;
-    match get(ty).sty {
+    match /*bad*/copy get(ty).sty {
       // Scalar types
       ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
       ty_type | ty_ptr(_) => result = true,
@@ -2555,7 +2616,7 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
       ty_enum(did, ref substs) => {
         let variants = enum_variants(cx, did);
         for vec::each(*variants) |variant| {
-            let tup_ty = mk_tup(cx, variant.args);
+            let tup_ty = mk_tup(cx, /*bad*/copy variant.args);
 
             // Perform any type parameter substitutions.
             let tup_ty = subst(cx, substs, tup_ty);
@@ -2701,7 +2762,10 @@ impl bound_region : to_bytes::IterBytes {
           to_bytes::iter_bytes_2(&2u8, ident, lsb0, f),
 
           ty::br_cap_avoid(ref id, ref br) =>
-          to_bytes::iter_bytes_3(&3u8, id, br, lsb0, f)
+          to_bytes::iter_bytes_3(&3u8, id, br, lsb0, f),
+
+          ty::br_fresh(ref x) =>
+          to_bytes::iter_bytes_2(&4u8, x, lsb0, f)
         }
     }
 }
@@ -2774,9 +2838,9 @@ impl FnMeta : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_5(&self.purity,
                                &self.proto,
+                               &self.onceness,
                                &self.region,
                                &self.bounds,
-                               &self.ret_style,
                                lsb0, f);
     }
 }
@@ -2826,10 +2890,7 @@ impl sty : to_bytes::IterBytes {
           to_bytes::iter_bytes_2(&11u8, fs, lsb0, f),
 
           ty_fn(ref ft) =>
-          to_bytes::iter_bytes_3(&12u8,
-                                 &ft.meta,
-                                 &ft.sig,
-                                 lsb0, f),
+          to_bytes::iter_bytes_2(&12u8, ft, lsb0, f),
 
           ty_self => 13u8.iter_bytes(lsb0, f),
 
@@ -2896,7 +2957,7 @@ fn node_id_has_type_params(cx: ctxt, id: ast::node_id) -> bool {
 // Type accessors for substructures of types
 fn ty_fn_args(fty: t) -> ~[arg] {
     match get(fty).sty {
-      ty_fn(ref f) => f.sig.inputs,
+      ty_fn(ref f) => /*bad*/copy f.sig.inputs,
       _ => fail ~"ty_fn_args() called on non-fn type"
     }
 }
@@ -2917,15 +2978,8 @@ fn ty_fn_purity(fty: t) -> ast::purity {
 
 pure fn ty_fn_ret(fty: t) -> t {
     match get(fty).sty {
-      ty_fn(ref f) => f.sig.output,
-      _ => fail ~"ty_fn_ret() called on non-fn type"
-    }
-}
-
-fn ty_fn_ret_style(fty: t) -> ast::ret_style {
-    match get(fty).sty {
-      ty_fn(ref f) => f.meta.ret_style,
-      _ => fail ~"ty_fn_ret_style() called on non-fn type"
+        ty_fn(ref f) => f.sig.output,
+        _ => fail ~"ty_fn_ret() called on non-fn type"
     }
 }
 
@@ -2943,9 +2997,30 @@ fn ty_region(ty: t) -> Region {
     }
 }
 
+fn replace_fn_return_type(tcx: ctxt, fn_type: t, ret_type: t) -> t {
+    /*!
+     *
+     * Returns a new function type based on `fn_type` but returning a value of
+     * type `ret_type` instead. */
+
+    match ty::get(fn_type).sty {
+        ty::ty_fn(ref fty) => {
+            ty::mk_fn(tcx, FnTyBase {
+                meta: fty.meta,
+                sig: FnSig {output: ret_type, ..copy fty.sig}
+            })
+        }
+        _ => {
+            tcx.sess.bug(fmt!(
+                "replace_fn_ret() invoked with non-fn-type: %s",
+                ty_to_str(tcx, fn_type)));
+        }
+    }
+}
+
 // Returns a vec of all the input and output types of fty.
-fn tys_in_fn_ty(fty: &FnTy) -> ~[t] {
-    vec::append_one(fty.sig.inputs.map(|a| a.ty), fty.sig.output)
+fn tys_in_fn_sig(sig: &FnSig) -> ~[t] {
+    vec::append_one(sig.inputs.map(|a| a.ty), sig.output)
 }
 
 // Just checks whether it's a fn that returns bool,
@@ -3007,8 +3082,8 @@ fn method_call_bounds(tcx: ctxt, method_map: typeck::method_map,
             // trait itself.  This ought to be harmonized.
             let trt_bounds =
                 ty::lookup_item_type(tcx, trt_id).bounds;
-            let mth = ty::trait_methods(tcx, trt_id)[n_mth];
-            @(vec::append(*trt_bounds, *mth.tps))
+            let mth = /*bad*/copy ty::trait_methods(tcx, trt_id)[n_mth];
+            @(vec::append(/*bad*/copy *trt_bounds, *mth.tps))
           }
         }
     }
@@ -3103,7 +3178,7 @@ fn expr_kind(tcx: ctxt,
         ast::expr_copy(*) |
         ast::expr_unary_move(*) |
         ast::expr_repeat(*) |
-        ast::expr_lit(@{node: lit_str(_), _}) |
+        ast::expr_lit(@ast::spanned {node: lit_str(_), _}) |
         ast::expr_vstore(_, ast::expr_vstore_slice) |
         ast::expr_vstore(_, ast::expr_vstore_mut_slice) |
         ast::expr_vstore(_, ast::expr_vstore_fixed(_)) |
@@ -3205,7 +3280,7 @@ fn get_field(tcx: ctxt, rec_ty: t, id: ast::ident) -> field {
 }
 
 fn get_fields(rec_ty:t) -> ~[field] {
-    match get(rec_ty).sty {
+    match /*bad*/copy get(rec_ty).sty {
       ty_rec(fields) => fields,
       // Can we check at the caller?
       _ => fail ~"get_fields: not a record type"
@@ -3260,8 +3335,8 @@ fn vars_in_type(ty: t) -> ~[TyVid] {
             tcx.sess.span_fatal
                 (sp, ~"type inference failed because I \
                      could not find a type\n that's both of the form "
-                 + ty_to_str(tcx, mk_var(tcx, vid)) +
-                 ~" and of the form " + ty_to_str(tcx, rt) +
+                 + ::util::ppaux::ty_to_str(tcx, mk_var(tcx, vid)) +
+                 ~" and of the form " + ::util::ppaux::ty_to_str(tcx, rt) +
                  ~" - such a type would have to be infinitely large.");
     }
 }
@@ -3343,7 +3418,7 @@ fn ty_sort_str(cx: ctxt, t: t) -> ~str {
       ty_nil | ty_bot | ty_bool | ty_int(_) |
       ty_uint(_) | ty_float(_) | ty_estr(_) |
       ty_type | ty_opaque_box | ty_opaque_closure_ptr(_) => {
-        ty_to_str(cx, t)
+        ::util::ppaux::ty_to_str(cx, t)
       }
 
       ty_enum(id, _) => fmt!("enum %s", item_path_str(cx, id)),
@@ -3388,31 +3463,18 @@ fn terr_vstore_kind_to_str(k: terr_vstore_kind) -> ~str {
 
     match *err {
         terr_mismatch => ~"types differ",
-        terr_ret_style_mismatch(values) => {
-            fn to_str(s: ast::ret_style) -> ~str {
-                match s {
-                    ast::noreturn => ~"non-returning",
-                    ast::return_val => ~"return-by-value"
-                }
-            }
-            fmt!("expected %s function, found %s function",
-                 to_str(values.expected),
-                 to_str(values.expected))
-        }
         terr_purity_mismatch(values) => {
             fmt!("expected %s fn but found %s fn",
-                 purity_to_str(values.expected),
-                 purity_to_str(values.found))
+                 values.expected.to_str(), values.found.to_str())
         }
         terr_onceness_mismatch(values) => {
             fmt!("expected %s fn but found %s fn",
-                 onceness_to_str(values.expected),
-                 onceness_to_str(values.found))
+                 values.expected.to_str(), values.found.to_str())
         }
         terr_proto_mismatch(values) => {
             fmt!("expected %s closure, found %s closure",
-                 proto_ty_to_str(cx, values.expected),
-                 proto_ty_to_str(cx, values.found))
+                 proto_ty_to_str(cx, values.expected, false),
+                 proto_ty_to_str(cx, values.found, false))
         }
         terr_mutability => ~"values differ in mutability",
         terr_box_mutability => ~"boxed values differ in mutability",
@@ -3446,7 +3508,8 @@ fn to_str(s: ast::ret_style) -> ~str {
         terr_arg_count => ~"incorrect number of function parameters",
         terr_mode_mismatch(values) => {
             fmt!("expected argument mode %s, but found %s",
-                 mode_to_str(values.expected), mode_to_str(values.found))
+                 pprust::mode_to_str(values.expected),
+                 pprust::mode_to_str(values.found))
         }
         terr_regions_does_not_outlive(*) => {
             fmt!("lifetime mismatch")
@@ -3489,6 +3552,10 @@ fn to_str(s: ast::ret_style) -> ~str {
             ~"couldn't determine an appropriate integral type for integer \
               literal"
         }
+        terr_integer_as_char => {
+            ~"integer literals can't be inferred to char type \
+              (try an explicit cast)"
+        }
         terr_no_floating_point_type => {
             ~"couldn't determine an appropriate floating point type for \
               floating point literal"
@@ -3546,7 +3613,7 @@ fn provided_trait_methods(cx: ctxt, id: ast::def_id) -> ~[ast::ident] {
                         node: item_trait(_, _, ref ms),
                         _
                     }, _)) =>
-                match ast_util::split_trait_methods((*ms)) {
+                match ast_util::split_trait_methods((/*bad*/copy *ms)) {
                    (_, p) => p.map(|method| method.ident)
                 },
             _ => cx.sess.bug(fmt!("provided_trait_methods: %? is not a trait",
@@ -3576,7 +3643,7 @@ fn trait_supertraits(cx: ctxt, id: ast::def_id) -> @~[InstantiatedTraitRef] {
             ty_trait(def_id, ref substs, _) => {
                 result.push(InstantiatedTraitRef {
                     def_id: def_id,
-                    tpt: { substs: (*substs), ty: *trait_type }
+                    tpt: { substs: (/*bad*/copy *substs), ty: *trait_type }
                 });
             }
             _ => cx.sess.bug(~"trait_supertraits: trait ref wasn't a trait")
@@ -3614,7 +3681,7 @@ fn vstoreify(cx: ctxt, ty: t, vstore: vstore) -> t {
         match ty::get(ty).sty {
             ty::ty_trait(_, _, trait_vstore) if vstore == trait_vstore => ty,
             ty::ty_trait(did, ref substs, _) => {
-                mk_trait(cx, did, (*substs), vstore)
+                mk_trait(cx, did, (/*bad*/copy *substs), vstore)
             }
             _ => cx.sess.bug(~"impl_traits: not a trait")
         }
@@ -3694,7 +3761,7 @@ fn substd_enum_variants(cx: ctxt,
         let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty);
 
         @VariantInfo_{args: substd_args, ctor_ty: substd_ctor_ty,
-                      ..**variant_info}
+                      ../*bad*/copy **variant_info}
     }
 }
 
@@ -3766,19 +3833,22 @@ fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
                 ast_map::path_name(item.ident)
               }
             };
-            vec::append_one(*path, item_elt)
+            vec::append_one(/*bad*/copy *path, item_elt)
           }
 
           ast_map::node_foreign_item(nitem, _, path) => {
-            vec::append_one(*path, ast_map::path_name(nitem.ident))
+            vec::append_one(/*bad*/copy *path,
+                            ast_map::path_name(nitem.ident))
           }
 
           ast_map::node_method(method, _, path) => {
-            vec::append_one(*path, ast_map::path_name(method.ident))
+            vec::append_one(/*bad*/copy *path,
+                            ast_map::path_name(method.ident))
           }
           ast_map::node_trait_method(trait_method, _, path) => {
             let method = ast_util::trait_method_to_ty_method(*trait_method);
-            vec::append_one(*path, ast_map::path_name(method.ident))
+            vec::append_one(/*bad*/copy *path,
+                            ast_map::path_name(method.ident))
           }
 
           ast_map::node_variant(ref variant, _, path) => {
@@ -3787,12 +3857,12 @@ fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
           }
 
           ast_map::node_dtor(_, _, _, path) => {
-            vec::append_one(*path, ast_map::path_name(
+            vec::append_one(/*bad*/copy *path, ast_map::path_name(
                 syntax::parse::token::special_idents::literally_dtor))
           }
 
           ast_map::node_struct_ctor(_, item, path) => {
-            vec::append_one(*path, ast_map::path_name(item.ident))
+            vec::append_one(/*bad*/copy *path, ast_map::path_name(item.ident))
           }
 
           ast_map::node_stmt(*) | ast_map::node_expr(*) |
@@ -3834,14 +3904,14 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] {
                     node: ast::item_enum(ref enum_definition, _),
                     _
                 }, _) => {
-            let variants = (*enum_definition).variants;
+            let variants = /*bad*/copy (*enum_definition).variants;
             let mut disr_val = -1;
             @vec::map(variants, |variant| {
                 match variant.node.kind {
-                    ast::tuple_variant_kind(args) => {
+                    ast::tuple_variant_kind(ref args) => {
                         let ctor_ty = node_id_to_type(cx, variant.node.id);
                         let arg_tys = {
-                            if vec::len(args) > 0u {
+                            if args.len() > 0u {
                                 ty_fn_args(ctor_ty).map(|a| a.ty)
                             } else {
                                 ~[]
@@ -3943,7 +4013,7 @@ fn lookup_struct_fields(cx: ctxt, did: ast::def_id) -> ~[field_ty] {
        Some(ast_map::node_item(i,_)) => {
          match i.node {
             ast::item_struct(struct_def, _) => {
-               struct_field_tys(struct_def.fields)
+               struct_field_tys(/*bad*/copy struct_def.fields)
             }
             _ => cx.sess.bug(~"struct ID bound to non-struct")
          }
@@ -3951,7 +4021,7 @@ fn lookup_struct_fields(cx: ctxt, did: ast::def_id) -> ~[field_ty] {
        Some(ast_map::node_variant(ref variant, _, _)) => {
           match (*variant).node.kind {
             ast::struct_variant_kind(struct_def) => {
-              struct_field_tys(struct_def.fields)
+              struct_field_tys(/*bad*/copy struct_def.fields)
             }
             _ => {
               cx.sess.bug(~"struct ID bound to enum variant that isn't \
@@ -4160,7 +4230,7 @@ fn normalize_vstore(vstore: vstore) -> vstore {
                     region: ty::re_static,
                     ..fn_ty.meta
                 },
-                sig: fn_ty.sig
+                sig: /*bad*/copy fn_ty.sig
             })
         }
 
@@ -4171,7 +4241,7 @@ fn normalize_vstore(vstore: vstore) -> vstore {
                     mk_enum(cx, did,
                      {self_r: Some(ty::re_static),
                       self_ty: None,
-                      tps: (*r).tps}),
+                      tps: /*bad*/copy (*r).tps}),
                 None =>
                     t
             },
@@ -4182,7 +4252,7 @@ fn normalize_vstore(vstore: vstore) -> vstore {
                 // Ditto.
                 mk_struct(cx, did, {self_r: Some(ty::re_static),
                                     self_ty: None,
-                                    tps: (*r).tps}),
+                                    tps: /*bad*/copy (*r).tps}),
               None =>
                 t
             },
@@ -4348,31 +4418,6 @@ impl vstore : cmp::Eq {
     pure fn ne(&self, other: &vstore) -> bool { !(*self).eq(other) }
 }
 
-impl FnMeta : cmp::Eq {
-    pure fn eq(&self, other: &FnMeta) -> bool {
-        (*self).purity == (*other).purity &&
-        (*self).proto == (*other).proto &&
-        (*self).bounds == (*other).bounds &&
-        (*self).ret_style == (*other).ret_style
-    }
-    pure fn ne(&self, other: &FnMeta) -> bool { !(*self).eq(other) }
-}
-
-impl FnSig : cmp::Eq {
-    pure fn eq(&self, other: &FnSig) -> bool {
-        (*self).inputs == (*other).inputs &&
-        (*self).output == (*other).output
-    }
-    pure fn ne(&self, other: &FnSig) -> bool { !(*self).eq(other) }
-}
-
-impl<M: cmp::Eq> FnTyBase<M> : cmp::Eq {
-    pure fn eq(&self, other: &FnTyBase<M>) -> bool {
-        (*self).meta == (*other).meta && (*self).sig == (*other).sig
-    }
-    pure fn ne(&self, other: &FnTyBase<M>) -> bool { !(*self).eq(other) }
-}
-
 impl TyVid : cmp::Eq {
     pure fn eq(&self, other: &TyVid) -> bool { *(*self) == *(*other) }
     pure fn ne(&self, other: &TyVid) -> bool { *(*self) != *(*other) }
@@ -4463,6 +4508,12 @@ impl bound_region : cmp::Eq {
                     _ => false
                 }
             }
+            br_fresh(e0a) => {
+                match (*other) {
+                    br_fresh(e0b) => e0a == e0b,
+                    _ => false
+                }
+            }
         }
     }
     pure fn ne(&self, other: &bound_region) -> bool { !(*self).eq(other) }
@@ -4477,16 +4528,9 @@ impl substs : cmp::Eq {
     pure fn ne(&self, other: &substs) -> bool { !(*self).eq(other) }
 }
 
-impl InferTy : cmp::Eq {
-    pure fn eq(&self, other: &InferTy) -> bool {
-        (*self).to_hash() == (*other).to_hash()
-    }
-    pure fn ne(&self, other: &InferTy) -> bool { !(*self).eq(other) }
-}
-
 impl sty : cmp::Eq {
     pure fn eq(&self, other: &sty) -> bool {
-        match (*self) {
+        match (/*bad*/copy *self) {
             ty_nil => {
                 match (*other) {
                     ty_nil => true,
@@ -4566,7 +4610,7 @@ impl sty : cmp::Eq {
                 }
             }
             ty_rec(e0a) => {
-                match (*other) {
+                match (/*bad*/copy *other) {
                     ty_rec(e0b) => e0a == e0b,
                     _ => false
                 }
@@ -4591,14 +4635,14 @@ impl sty : cmp::Eq {
                 }
             }
             ty_tup(e0a) => {
-                match (*other) {
+                match (/*bad*/copy *other) {
                     ty_tup(e0b) => e0a == e0b,
                     _ => false
                 }
             }
-            ty_infer(e0a) => {
+            ty_infer(ref e0a) => {
                 match (*other) {
-                    ty_infer(e0b) => e0a == e0b,
+                    ty_infer(ref e0b) => *e0a == *e0b,
                     _ => false
                 }
             }
index 4c44642b325a1628833be30cca34f510877cdc22..043ff3fbec48bc63d31fee52348fcd7ce988d7a4 100644 (file)
  * an rptr (`&r.T`) use the region `r` that appears in the rptr.
  */
 
-use middle::ty::{FnTyBase, FnMeta, FnSig};
+use core::prelude::*;
+
+use middle::pat_util::pat_id_map;
+use middle::ty::{FnTyBase, FnMeta, FnSig, ty_param_substs_and_ty};
+use middle::ty;
 use middle::typeck::check::fn_ctxt;
+use middle::typeck::collect;
 use middle::typeck::rscope::{anon_rscope, binding_rscope, empty_rscope};
 use middle::typeck::rscope::{in_anon_rscope, in_binding_rscope};
 use middle::typeck::rscope::{region_scope, type_rscope};
+use middle::typeck::{crate_ctxt, write_substs_to_tcx, write_ty_to_tcx};
+
+use core::result;
+use core::vec;
+use syntax::ast;
+use syntax::codemap::span;
+use syntax::print::pprust::path_to_str;
+use util::common::indent;
 
 pub trait ast_conv {
     fn tcx() -> ty::ctxt;
@@ -74,7 +87,7 @@ fn get_region_reporting_err(tcx: ty::ctxt,
     match res {
       result::Ok(r) => r,
       result::Err(ref e) => {
-        tcx.sess.span_err(span, (*e));
+        tcx.sess.span_err(span, (/*bad*/copy *e));
         ty::re_static
       }
     }
@@ -139,7 +152,8 @@ fn ast_path_to_substs_and_ty<AC: ast_conv, RS: region_scope Copy Durable>(
     let tps = path.types.map(|a_t| ast_ty_to_ty(self, rscope, *a_t));
 
     let substs = {self_r:self_r, self_ty:None, tps:tps};
-    {substs: substs, ty: ty::subst(tcx, &substs, decl_ty)}
+    let ty = ty::subst(tcx, &substs, decl_ty);
+    {substs: substs, ty: ty}
 }
 
 pub fn ast_path_to_ty<AC: ast_conv, RS: region_scope Copy Durable>(
@@ -155,7 +169,7 @@ pub fn ast_path_to_ty<AC: ast_conv, RS: region_scope Copy Durable>(
     let {substs: substs, ty: ty} =
         ast_path_to_substs_and_ty(self, rscope, did, path);
     write_ty_to_tcx(tcx, path_id, ty);
-    write_substs_to_tcx(tcx, path_id, substs.tps);
+    write_substs_to_tcx(tcx, path_id, /*bad*/copy substs.tps);
     return {substs: substs, ty: ty};
 }
 
@@ -219,7 +233,7 @@ fn mk_pointer<AC: ast_conv, RS: region_scope Copy Durable>(
                                     }
                                 }
                                 return ty::mk_trait(tcx, trait_def_id,
-                                                    (*substs), vst);
+                                                    /*bad*/copy *substs, vst);
 
                             }
                             _ => {}
@@ -268,7 +282,7 @@ fn check_path_args(tcx: ty::ctxt,
     }
 
     tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::atttce_unresolved);
-    let typ = match ast_ty.node {
+    let typ = match /*bad*/copy ast_ty.node {
       ast::ty_nil => ty::mk_nil(tcx),
       ast::ty_bot => ty::mk_bot(tcx),
       ast::ty_box(mt) => {
@@ -499,8 +513,7 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope Copy Durable>(
                           proto: ast_proto,
                           onceness: onceness,
                           region: bound_region,
-                          bounds: bounds,
-                          ret_style: decl.cf},
+                          bounds: bounds},
             sig: FnSig {inputs: input_tys,
                         output: output_ty}
         }
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
new file mode 100644 (file)
index 0000000..5514d2f
--- /dev/null
@@ -0,0 +1,588 @@
+// 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 core::prelude::*;
+
+use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding, pat_is_const};
+use middle::pat_util::{pat_is_variant_or_struct};
+use middle::ty;
+use middle::typeck::check::demand;
+use middle::typeck::check::{check_block, check_expr_with, fn_ctxt};
+use middle::typeck::check::{instantiate_path, lookup_def, lookup_local};
+use middle::typeck::check::{structure_of, valid_range_bounds};
+use middle::typeck::require_same_types;
+
+use core::vec;
+use std::map::HashMap;
+use syntax::ast;
+use syntax::ast_util::walk_pat;
+use syntax::ast_util;
+use syntax::codemap::span;
+use syntax::print::pprust;
+
+fn check_match(fcx: @fn_ctxt,
+               expr: @ast::expr,
+               discrim: @ast::expr,
+               arms: ~[ast::arm]) -> bool {
+    let tcx = fcx.ccx.tcx;
+    let mut bot;
+
+    let pattern_ty = fcx.infcx().next_ty_var();
+    bot = check_expr_with(fcx, discrim, pattern_ty);
+
+    // Typecheck the patterns first, so that we get types for all the
+    // bindings.
+    for arms.each |arm| {
+        let pcx = pat_ctxt {
+            fcx: fcx,
+            map: pat_id_map(tcx.def_map, arm.pats[0]),
+            match_region: ty::re_scope(expr.id),
+            block_region: ty::re_scope(arm.body.node.id)
+        };
+
+        for arm.pats.each |p| { check_pat(pcx, *p, pattern_ty);}
+    }
+
+    // Now typecheck the blocks.
+    let mut result_ty = fcx.infcx().next_ty_var();
+    let mut arm_non_bot = false;
+    for arms.each |arm| {
+        match arm.guard {
+          Some(e) => { check_expr_with(fcx, e, ty::mk_bool(tcx)); },
+          None => ()
+        }
+        if !check_block(fcx, arm.body) { arm_non_bot = true; }
+        let bty = fcx.node_ty(arm.body.node.id);
+        demand::suptype(fcx, arm.body.span, result_ty, bty);
+    }
+    bot |= !arm_non_bot;
+    if !arm_non_bot { result_ty = ty::mk_bot(tcx); }
+    fcx.write_ty(expr.id, result_ty);
+    return bot;
+}
+
+struct pat_ctxt {
+    fcx: @fn_ctxt,
+    map: PatIdMap,
+    match_region: ty::Region, // Region for the match as a whole
+    block_region: ty::Region, // Region for the block of the arm
+}
+
+fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
+                     +subpats: Option<~[@ast::pat]>, expected: ty::t) {
+
+    // Typecheck the path.
+    let fcx = pcx.fcx;
+    let tcx = pcx.fcx.ccx.tcx;
+
+    let arg_types, kind_name;
+
+    // structure_of requires type variables to be resolved.
+    // So when we pass in <expected>, it's an error if it
+    // contains type variables.
+
+    // Check to see whether this is an enum or a struct.
+    match structure_of(pcx.fcx, pat.span, expected) {
+        ty::ty_enum(_, ref expected_substs) => {
+            // Lookup the enum and variant def ids:
+            let v_def = lookup_def(pcx.fcx, path.span, pat.id);
+            let v_def_ids = ast_util::variant_def_ids(v_def);
+
+            // Assign the pattern the type of the *enum*, not the variant.
+            let enum_tpt = ty::lookup_item_type(tcx, v_def_ids.enm);
+            instantiate_path(pcx.fcx, path, enum_tpt, pat.span, pat.id,
+                             pcx.block_region);
+
+            // check that the type of the value being matched is a subtype
+            // of the type of the pattern:
+            let pat_ty = fcx.node_ty(pat.id);
+            demand::suptype(fcx, pat.span, pat_ty, expected);
+
+            // Get the expected types of the arguments.
+            arg_types = {
+                let vinfo =
+                    ty::enum_variant_with_id(
+                        tcx, v_def_ids.enm, v_def_ids.var);
+                let var_tpt = ty::lookup_item_type(tcx, v_def_ids.var);
+                vinfo.args.map(|t| {
+                    if var_tpt.bounds.len() == expected_substs.tps.len() {
+                        ty::subst(tcx, expected_substs, *t)
+                    }
+                    else {
+                        *t // In this case, an error was already signaled
+                           // anyway
+                    }
+                })
+            };
+
+            kind_name = "variant";
+        }
+        ty::ty_struct(struct_def_id, ref expected_substs) => {
+            // Assign the pattern the type of the struct.
+            let struct_tpt = ty::lookup_item_type(tcx, struct_def_id);
+            instantiate_path(pcx.fcx, path, struct_tpt, pat.span, pat.id,
+                             pcx.block_region);
+
+            // Check that the type of the value being matched is a subtype of
+            // the type of the pattern.
+            let pat_ty = fcx.node_ty(pat.id);
+            demand::suptype(fcx, pat.span, pat_ty, expected);
+
+            // Get the expected types of the arguments.
+            let class_fields = ty::struct_fields(
+                tcx, struct_def_id, expected_substs);
+            arg_types = class_fields.map(|field| field.mt.ty);
+
+            kind_name = "structure";
+        }
+        _ => {
+            tcx.sess.span_fatal(
+                pat.span,
+                fmt!("mismatched types: expected enum or structure but \
+                      found `%s`",
+                     fcx.infcx().ty_to_str(expected)));
+        }
+    }
+
+    let arg_len = arg_types.len();
+
+    // Count the number of subpatterns.
+    let subpats_len;
+    match subpats {
+        None => subpats_len = arg_len,
+        Some(ref subpats) => subpats_len = subpats.len()
+    }
+
+    if arg_len > 0u {
+        // N-ary variant.
+        if arg_len != subpats_len {
+            let s = fmt!("this pattern has %u field%s, but the corresponding \
+                          %s has %u field%s",
+                         subpats_len,
+                         if subpats_len == 1u { ~"" } else { ~"s" },
+                         kind_name,
+                         arg_len,
+                         if arg_len == 1u { ~"" } else { ~"s" });
+            // XXX: This should not be fatal.
+            tcx.sess.span_fatal(pat.span, s);
+        }
+
+        do subpats.iter() |pats| {
+            for vec::each2(*pats, arg_types) |subpat, arg_ty| {
+              check_pat(pcx, *subpat, *arg_ty);
+            }
+        };
+    } else if subpats_len > 0u {
+        tcx.sess.span_fatal
+            (pat.span, fmt!("this pattern has %u field%s, but the \
+                             corresponding %s has no fields",
+                            subpats_len,
+                            if subpats_len == 1u { ~"" }
+                            else { ~"s" },
+                            kind_name));
+    }
+}
+
+/// `path` is the AST path item naming the type of this struct.
+/// `fields` is the field patterns of the struct pattern.
+/// `class_fields` describes the type of each field of the struct.
+/// `class_id` is the ID of the struct.
+/// `substitutions` are the type substitutions applied to this struct type
+/// (e.g. K,V in HashMap<K,V>).
+/// `etc` is true if the pattern said '...' and false otherwise.
+fn check_struct_pat_fields(pcx: pat_ctxt,
+                           span: span,
+                           path: @ast::path,
+                           fields: ~[ast::field_pat],
+                           class_fields: ~[ty::field_ty],
+                           class_id: ast::def_id,
+                           substitutions: &ty::substs,
+                           etc: bool) {
+    let tcx = pcx.fcx.ccx.tcx;
+
+    // Index the class fields.
+    let field_map = HashMap();
+    for class_fields.eachi |i, class_field| {
+        field_map.insert(class_field.ident, i);
+    }
+
+    // Typecheck each field.
+    let found_fields = HashMap();
+    for fields.each |field| {
+        match field_map.find(field.ident) {
+            Some(index) => {
+                let class_field = class_fields[index];
+                let field_type = ty::lookup_field_type(tcx,
+                                                       class_id,
+                                                       class_field.id,
+                                                       substitutions);
+                check_pat(pcx, field.pat, field_type);
+                found_fields.insert(index, ());
+            }
+            None => {
+                let name = pprust::path_to_str(path, tcx.sess.intr());
+                tcx.sess.span_err(span,
+                                  fmt!("struct `%s` does not have a field
+                                        named `%s`", name,
+                                       tcx.sess.str_of(field.ident)));
+            }
+        }
+    }
+
+    // Report an error if not all the fields were specified.
+    if !etc {
+        for class_fields.eachi |i, field| {
+            if found_fields.contains_key(i) {
+                loop;
+            }
+            tcx.sess.span_err(span,
+                              fmt!("pattern does not mention field `%s`",
+                                   tcx.sess.str_of(field.ident)));
+        }
+    }
+}
+
+fn check_struct_pat(pcx: pat_ctxt, pat_id: ast::node_id, span: span,
+                    expected: ty::t, path: @ast::path,
+                    +fields: ~[ast::field_pat], etc: bool,
+                    class_id: ast::def_id, substitutions: &ty::substs) {
+    let fcx = pcx.fcx;
+    let tcx = pcx.fcx.ccx.tcx;
+
+    let class_fields = ty::lookup_struct_fields(tcx, class_id);
+
+    // Check to ensure that the struct is the one specified.
+    match tcx.def_map.find(pat_id) {
+        Some(ast::def_struct(supplied_def_id))
+                if supplied_def_id == class_id => {
+            // OK.
+        }
+        Some(ast::def_struct(*)) | Some(ast::def_variant(*)) => {
+            let name = pprust::path_to_str(path, tcx.sess.intr());
+            tcx.sess.span_err(span,
+                              fmt!("mismatched types: expected `%s` but \
+                                    found `%s`",
+                                   fcx.infcx().ty_to_str(expected),
+                                   name));
+        }
+        _ => {
+            tcx.sess.span_bug(span, ~"resolve didn't write in class");
+        }
+    }
+
+    // Forbid pattern-matching structs with destructors.
+    if ty::has_dtor(tcx, class_id) {
+        tcx.sess.span_err(span, ~"deconstructing struct not allowed in \
+                                  pattern (it has a destructor)");
+    }
+
+    check_struct_pat_fields(pcx, span, path, fields, class_fields, class_id,
+                            substitutions, etc);
+}
+
+fn check_struct_like_enum_variant_pat(pcx: pat_ctxt,
+                                      pat_id: ast::node_id,
+                                      span: span,
+                                      expected: ty::t,
+                                      path: @ast::path,
+                                      +fields: ~[ast::field_pat],
+                                      etc: bool,
+                                      enum_id: ast::def_id,
+                                      substitutions: &ty::substs) {
+    let fcx = pcx.fcx;
+    let tcx = pcx.fcx.ccx.tcx;
+
+    // Find the variant that was specified.
+    match tcx.def_map.find(pat_id) {
+        Some(ast::def_variant(found_enum_id, variant_id))
+                if found_enum_id == enum_id => {
+            // Get the struct fields from this struct-like enum variant.
+            let class_fields = ty::lookup_struct_fields(tcx, variant_id);
+
+            check_struct_pat_fields(pcx, span, path, fields, class_fields,
+                                    variant_id, substitutions, etc);
+        }
+        Some(ast::def_struct(*)) | Some(ast::def_variant(*)) => {
+            let name = pprust::path_to_str(path, tcx.sess.intr());
+            tcx.sess.span_err(span,
+                              fmt!("mismatched types: expected `%s` but \
+                                    found `%s`",
+                                   fcx.infcx().ty_to_str(expected),
+                                   name));
+        }
+        _ => {
+            tcx.sess.span_bug(span, ~"resolve didn't write in variant");
+        }
+    }
+}
+
+// Pattern checking is top-down rather than bottom-up so that bindings get
+// their types immediately.
+fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
+    let fcx = pcx.fcx;
+    let tcx = pcx.fcx.ccx.tcx;
+
+    match /*bad*/copy pat.node {
+      ast::pat_wild => {
+        fcx.write_ty(pat.id, expected);
+      }
+      ast::pat_lit(lt) => {
+        check_expr_with(fcx, lt, expected);
+        fcx.write_ty(pat.id, fcx.expr_ty(lt));
+      }
+      ast::pat_range(begin, end) => {
+        check_expr_with(fcx, begin, expected);
+        check_expr_with(fcx, end, expected);
+        let b_ty =
+            fcx.infcx().resolve_type_vars_if_possible(fcx.expr_ty(begin));
+        let e_ty =
+            fcx.infcx().resolve_type_vars_if_possible(fcx.expr_ty(end));
+        debug!("pat_range beginning type: %?", b_ty);
+        debug!("pat_range ending type: %?", e_ty);
+        if !require_same_types(
+            tcx, Some(fcx.infcx()), false, pat.span, b_ty, e_ty,
+            || ~"mismatched types in range")
+        {
+            // no-op
+        } else if !ty::type_is_numeric(b_ty) {
+            tcx.sess.span_err(pat.span, ~"non-numeric type used in range");
+        } else if !valid_range_bounds(fcx.ccx, begin, end) {
+            tcx.sess.span_err(begin.span, ~"lower range bound must be less \
+                                           than upper");
+        }
+        fcx.write_ty(pat.id, b_ty);
+      }
+      ast::pat_ident(*) if pat_is_const(tcx.def_map, pat) => {
+        let const_did = ast_util::def_id_of_def(tcx.def_map.get(pat.id));
+        let const_tpt = ty::lookup_item_type(tcx, const_did);
+        fcx.write_ty(pat.id, const_tpt.ty);
+      }
+      ast::pat_ident(bm, name, sub) if pat_is_binding(tcx.def_map, pat) => {
+        let vid = lookup_local(fcx, pat.span, pat.id);
+        let mut typ = ty::mk_var(tcx, vid);
+
+        match bm {
+          ast::bind_by_ref(mutbl) => {
+            // if the binding is like
+            //    ref x | ref const x | ref mut x
+            // then the type of x is &M T where M is the mutability
+            // and T is the expected type
+            let region_var =
+                fcx.infcx().next_region_var_with_lb(
+                    pat.span, pcx.block_region);
+            let mt = {ty: expected, mutbl: mutbl};
+            let region_ty = ty::mk_rptr(tcx, region_var, mt);
+            demand::eqtype(fcx, pat.span, region_ty, typ);
+          }
+          // otherwise the type of x is the expected type T
+          ast::bind_by_value | ast::bind_by_move | ast::bind_infer => {
+            demand::eqtype(fcx, pat.span, expected, typ);
+          }
+        }
+
+        let canon_id = pcx.map.get(ast_util::path_to_ident(name));
+        if canon_id != pat.id {
+            let tv_id = lookup_local(fcx, pat.span, canon_id);
+            let ct = ty::mk_var(tcx, tv_id);
+            demand::eqtype(fcx, pat.span, ct, typ);
+        }
+        fcx.write_ty(pat.id, typ);
+
+        debug!("(checking match) writing type for pat id %d", pat.id);
+
+        match sub {
+          Some(p) => check_pat(pcx, p, expected),
+          _ => ()
+        }
+      }
+      ast::pat_ident(_, path, _) => {
+        check_pat_variant(pcx, pat, path, Some(~[]), expected);
+      }
+      ast::pat_enum(path, subpats) => {
+        check_pat_variant(pcx, pat, path, subpats, expected);
+      }
+      ast::pat_rec(fields, etc) => {
+        let ex_fields = match structure_of(fcx, pat.span, expected) {
+          ty::ty_rec(fields) => fields,
+          _ => {
+            tcx.sess.span_fatal
+                (pat.span,
+                fmt!("mismatched types: expected `%s` but found record",
+                     fcx.infcx().ty_to_str(expected)));
+          }
+        };
+        let f_count = vec::len(fields);
+        let ex_f_count = vec::len(ex_fields);
+        if ex_f_count < f_count || !etc && ex_f_count > f_count {
+            tcx.sess.span_fatal
+                (pat.span, fmt!("mismatched types: expected a record \
+                      with %u fields, found one with %u \
+                      fields",
+                                ex_f_count, f_count));
+        }
+
+        for fields.each |f| {
+            match vec::find(ex_fields, |a| f.ident == a.ident) {
+              Some(field) => {
+                check_pat(pcx, f.pat, field.mt.ty);
+              }
+              None => {
+                tcx.sess.span_fatal(pat.span,
+                                    fmt!("mismatched types: did not \
+                                          expect a record with a field `%s`",
+                                          tcx.sess.str_of(f.ident)));
+              }
+            }
+        }
+        fcx.write_ty(pat.id, expected);
+      }
+      ast::pat_struct(path, fields, etc) => {
+        // Grab the class data that we care about.
+        let structure = structure_of(fcx, pat.span, expected);
+        match structure {
+            ty::ty_struct(cid, ref substs) => {
+                check_struct_pat(pcx, pat.id, pat.span, expected, path,
+                                 fields, etc, cid, substs);
+            }
+            ty::ty_enum(eid, ref substs) => {
+                check_struct_like_enum_variant_pat(
+                    pcx, pat.id, pat.span, expected, path, fields, etc, eid,
+                    substs);
+            }
+            _ => {
+                // XXX: This should not be fatal.
+                tcx.sess.span_fatal(pat.span,
+                                    fmt!("mismatched types: expected `%s` \
+                                          but found struct",
+                                         fcx.infcx().ty_to_str(expected)));
+            }
+        }
+
+        // Finally, write in the type.
+        fcx.write_ty(pat.id, expected);
+      }
+      ast::pat_tup(elts) => {
+        let ex_elts = match structure_of(fcx, pat.span, expected) {
+          ty::ty_tup(elts) => elts,
+          _ => {
+            tcx.sess.span_fatal
+                (pat.span,
+                 fmt!("mismatched types: expected `%s`, found tuple",
+                      fcx.infcx().ty_to_str(expected)));
+          }
+        };
+        let e_count = vec::len(elts);
+        if e_count != vec::len(ex_elts) {
+            tcx.sess.span_fatal
+                (pat.span, fmt!("mismatched types: expected a tuple \
+                      with %u fields, found one with %u \
+                      fields", vec::len(ex_elts), e_count));
+        }
+        let mut i = 0u;
+        for elts.each |elt| {
+            check_pat(pcx, *elt, ex_elts[i]);
+            i += 1u;
+        }
+
+        fcx.write_ty(pat.id, expected);
+      }
+      ast::pat_box(inner) => {
+        match structure_of(fcx, pat.span, expected) {
+          ty::ty_box(e_inner) => {
+            check_pat(pcx, inner, e_inner.ty);
+            fcx.write_ty(pat.id, expected);
+          }
+          _ => {
+            tcx.sess.span_fatal(
+                pat.span,
+                ~"mismatched types: expected `" +
+                fcx.infcx().ty_to_str(expected) +
+                ~"` found box");
+          }
+        }
+      }
+      ast::pat_uniq(inner) => {
+        match structure_of(fcx, pat.span, expected) {
+          ty::ty_uniq(e_inner) => {
+            check_pat(pcx, inner, e_inner.ty);
+            fcx.write_ty(pat.id, expected);
+          }
+          _ => {
+            tcx.sess.span_fatal(
+                pat.span,
+                ~"mismatched types: expected `" +
+                fcx.infcx().ty_to_str(expected) +
+                ~"` found uniq");
+          }
+        }
+      }
+      ast::pat_region(inner) => {
+        match structure_of(fcx, pat.span, expected) {
+          ty::ty_rptr(_, e_inner) => {
+            check_pat(pcx, inner, e_inner.ty);
+            fcx.write_ty(pat.id, expected);
+          }
+          _ => {
+            tcx.sess.span_fatal(
+                pat.span,
+                ~"mismatched types: expected `" +
+                fcx.infcx().ty_to_str(expected) +
+                ~"` found borrowed pointer");
+          }
+        }
+      }
+      ast::pat_vec(elts, tail) => {
+        let default_region_var =
+            fcx.infcx().next_region_var_with_lb(
+                pat.span, pcx.block_region
+            );
+
+        let (elt_type, region_var) = match structure_of(
+          fcx, pat.span, expected
+        ) {
+          ty::ty_evec(mt, vstore) => {
+            let region_var = match vstore {
+                ty::vstore_slice(r) => r,
+                ty::vstore_box | ty::vstore_uniq | ty::vstore_fixed(_) => {
+                    default_region_var
+                }
+            };
+            (mt, region_var)
+          }
+          ty::ty_unboxed_vec(mt) => {
+            (mt, default_region_var)
+          },
+          _ => {
+            tcx.sess.span_fatal(
+                pat.span,
+                fmt!("mismatched type: expected `%s` but found vector",
+                     fcx.infcx().ty_to_str(expected))
+            );
+          }
+        };
+        for elts.each |elt| {
+            check_pat(pcx, *elt, elt_type.ty);
+        }
+        fcx.write_ty(pat.id, expected);
+
+        match tail {
+            Some(tail_pat) => {
+                let slice_ty = ty::mk_evec(tcx,
+                    {ty: elt_type.ty, mutbl: elt_type.mutbl},
+                    ty::vstore_slice(region_var)
+                );
+                check_pat(pcx, tail_pat, slice_ty);
+            }
+            None => ()
+        }
+      }
+    }
+}
+
diff --git a/src/librustc/middle/typeck/check/alt.rs b/src/librustc/middle/typeck/check/alt.rs
deleted file mode 100644 (file)
index 95f44af..0000000
+++ /dev/null
@@ -1,575 +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 middle::pat_util::{pat_is_binding, pat_is_const};
-use middle::pat_util::{pat_is_variant_or_struct};
-
-use syntax::ast_util::walk_pat;
-use syntax::print::pprust;
-
-fn check_alt(fcx: @fn_ctxt,
-             expr: @ast::expr,
-             discrim: @ast::expr,
-             arms: ~[ast::arm]) -> bool {
-    let tcx = fcx.ccx.tcx;
-    let mut bot;
-
-    let pattern_ty = fcx.infcx().next_ty_var();
-    bot = check_expr_with(fcx, discrim, pattern_ty);
-
-    // Typecheck the patterns first, so that we get types for all the
-    // bindings.
-    for arms.each |arm| {
-        let pcx = {
-            fcx: fcx,
-            map: pat_id_map(tcx.def_map, arm.pats[0]),
-            alt_region: ty::re_scope(expr.id),
-            block_region: ty::re_scope(arm.body.node.id)
-        };
-
-        for arm.pats.each |p| { check_pat(pcx, *p, pattern_ty);}
-    }
-
-    // Now typecheck the blocks.
-    let mut result_ty = fcx.infcx().next_ty_var();
-    let mut arm_non_bot = false;
-    for arms.each |arm| {
-        match arm.guard {
-          Some(e) => { check_expr_with(fcx, e, ty::mk_bool(tcx)); },
-          None => ()
-        }
-        if !check_block(fcx, arm.body) { arm_non_bot = true; }
-        let bty = fcx.node_ty(arm.body.node.id);
-        demand::suptype(fcx, arm.body.span, result_ty, bty);
-    }
-    bot |= !arm_non_bot;
-    if !arm_non_bot { result_ty = ty::mk_bot(tcx); }
-    fcx.write_ty(expr.id, result_ty);
-    return bot;
-}
-
-type pat_ctxt = {
-    fcx: @fn_ctxt,
-    map: PatIdMap,
-    alt_region: ty::Region,   // Region for the alt as a whole
-    block_region: ty::Region, // Region for the block of the arm
-};
-
-fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
-                     subpats: Option<~[@ast::pat]>, expected: ty::t) {
-
-    // Typecheck the path.
-    let fcx = pcx.fcx;
-    let tcx = pcx.fcx.ccx.tcx;
-
-    let arg_types, kind_name;
-
-    // structure_of requires type variables to be resolved.
-    // So when we pass in <expected>, it's an error if it
-    // contains type variables.
-
-    // Check to see whether this is an enum or a struct.
-    match structure_of(pcx.fcx, pat.span, expected) {
-        ty::ty_enum(_, ref expected_substs) => {
-            // Lookup the enum and variant def ids:
-            let v_def = lookup_def(pcx.fcx, path.span, pat.id);
-            let v_def_ids = ast_util::variant_def_ids(v_def);
-
-            // Assign the pattern the type of the *enum*, not the variant.
-            let enum_tpt = ty::lookup_item_type(tcx, v_def_ids.enm);
-            instantiate_path(pcx.fcx, path, enum_tpt, pat.span, pat.id,
-                             pcx.block_region);
-
-            // check that the type of the value being matched is a subtype
-            // of the type of the pattern:
-            let pat_ty = fcx.node_ty(pat.id);
-            demand::suptype(fcx, pat.span, pat_ty, expected);
-
-            // Get the expected types of the arguments.
-            arg_types = {
-                let vinfo =
-                    ty::enum_variant_with_id(
-                        tcx, v_def_ids.enm, v_def_ids.var);
-                let var_tpt = ty::lookup_item_type(tcx, v_def_ids.var);
-                vinfo.args.map(|t| {
-                    if var_tpt.bounds.len() == expected_substs.tps.len() {
-                        ty::subst(tcx, expected_substs, *t)
-                    }
-                    else {
-                        *t // In this case, an error was already signaled
-                           // anyway
-                    }
-                })
-            };
-
-            kind_name = "variant";
-        }
-        ty::ty_struct(struct_def_id, ref expected_substs) => {
-            // Assign the pattern the type of the struct.
-            let struct_tpt = ty::lookup_item_type(tcx, struct_def_id);
-            instantiate_path(pcx.fcx, path, struct_tpt, pat.span, pat.id,
-                             pcx.block_region);
-
-            // Check that the type of the value being matched is a subtype of
-            // the type of the pattern.
-            let pat_ty = fcx.node_ty(pat.id);
-            demand::suptype(fcx, pat.span, pat_ty, expected);
-
-            // Get the expected types of the arguments.
-            let class_fields = ty::struct_fields(
-                tcx, struct_def_id, expected_substs);
-            arg_types = class_fields.map(|field| field.mt.ty);
-
-            kind_name = "structure";
-        }
-        _ => {
-            tcx.sess.span_fatal(
-                pat.span,
-                fmt!("mismatched types: expected enum or structure but \
-                      found `%s`",
-                     fcx.infcx().ty_to_str(expected)));
-        }
-    }
-
-    let arg_len = arg_types.len();
-
-    // Count the number of subpatterns.
-    let subpats_len;
-    match subpats {
-        None => subpats_len = arg_len,
-        Some(subpats) => subpats_len = subpats.len()
-    }
-
-    if arg_len > 0u {
-        // N-ary variant.
-        if arg_len != subpats_len {
-            let s = fmt!("this pattern has %u field%s, but the corresponding \
-                          %s has %u field%s",
-                         subpats_len,
-                         if subpats_len == 1u { ~"" } else { ~"s" },
-                         kind_name,
-                         arg_len,
-                         if arg_len == 1u { ~"" } else { ~"s" });
-            // XXX: This should not be fatal.
-            tcx.sess.span_fatal(pat.span, s);
-        }
-
-        do subpats.iter() |pats| {
-            for vec::each2(*pats, arg_types) |subpat, arg_ty| {
-              check_pat(pcx, *subpat, *arg_ty);
-            }
-        };
-    } else if subpats_len > 0u {
-        tcx.sess.span_fatal
-            (pat.span, fmt!("this pattern has %u field%s, but the \
-                             corresponding %s has no fields",
-                            subpats_len,
-                            if subpats_len == 1u { ~"" }
-                            else { ~"s" },
-                            kind_name));
-    }
-}
-
-/// `path` is the AST path item naming the type of this struct.
-/// `fields` is the field patterns of the struct pattern.
-/// `class_fields` describes the type of each field of the struct.
-/// `class_id` is the ID of the struct.
-/// `substitutions` are the type substitutions applied to this struct type
-/// (e.g. K,V in HashMap<K,V>).
-/// `etc` is true if the pattern said '...' and false otherwise.
-fn check_struct_pat_fields(pcx: pat_ctxt,
-                           span: span,
-                           path: @ast::path,
-                           fields: ~[ast::field_pat],
-                           class_fields: ~[ty::field_ty],
-                           class_id: ast::def_id,
-                           substitutions: &ty::substs,
-                           etc: bool) {
-    let tcx = pcx.fcx.ccx.tcx;
-
-    // Index the class fields.
-    let field_map = std::map::HashMap();
-    for class_fields.eachi |i, class_field| {
-        field_map.insert(class_field.ident, i);
-    }
-
-    // Typecheck each field.
-    let found_fields = std::map::HashMap();
-    for fields.each |field| {
-        match field_map.find(field.ident) {
-            Some(index) => {
-                let class_field = class_fields[index];
-                let field_type = ty::lookup_field_type(tcx,
-                                                       class_id,
-                                                       class_field.id,
-                                                       substitutions);
-                check_pat(pcx, field.pat, field_type);
-                found_fields.insert(index, ());
-            }
-            None => {
-                let name = pprust::path_to_str(path, tcx.sess.intr());
-                tcx.sess.span_err(span,
-                                  fmt!("struct `%s` does not have a field
-                                        named `%s`", name,
-                                       tcx.sess.str_of(field.ident)));
-            }
-        }
-    }
-
-    // Report an error if not all the fields were specified.
-    if !etc {
-        for class_fields.eachi |i, field| {
-            if found_fields.contains_key(i) {
-                loop;
-            }
-            tcx.sess.span_err(span,
-                              fmt!("pattern does not mention field `%s`",
-                                   tcx.sess.str_of(field.ident)));
-        }
-    }
-}
-
-fn check_struct_pat(pcx: pat_ctxt, pat_id: ast::node_id, span: span,
-                    expected: ty::t, path: @ast::path,
-                    fields: ~[ast::field_pat], etc: bool,
-                    class_id: ast::def_id, substitutions: &ty::substs) {
-    let fcx = pcx.fcx;
-    let tcx = pcx.fcx.ccx.tcx;
-
-    let class_fields = ty::lookup_struct_fields(tcx, class_id);
-
-    // Check to ensure that the struct is the one specified.
-    match tcx.def_map.find(pat_id) {
-        Some(ast::def_struct(supplied_def_id))
-                if supplied_def_id == class_id => {
-            // OK.
-        }
-        Some(ast::def_struct(*)) | Some(ast::def_variant(*)) => {
-            let name = pprust::path_to_str(path, tcx.sess.intr());
-            tcx.sess.span_err(span,
-                              fmt!("mismatched types: expected `%s` but \
-                                    found `%s`",
-                                   fcx.infcx().ty_to_str(expected),
-                                   name));
-        }
-        _ => {
-            tcx.sess.span_bug(span, ~"resolve didn't write in class");
-        }
-    }
-
-    // Forbid pattern-matching structs with destructors.
-    if ty::has_dtor(tcx, class_id) {
-        tcx.sess.span_err(span, ~"deconstructing struct not allowed in \
-                                  pattern (it has a destructor)");
-    }
-
-    check_struct_pat_fields(pcx, span, path, fields, class_fields, class_id,
-                            substitutions, etc);
-}
-
-fn check_struct_like_enum_variant_pat(pcx: pat_ctxt,
-                                      pat_id: ast::node_id,
-                                      span: span,
-                                      expected: ty::t,
-                                      path: @ast::path,
-                                      fields: ~[ast::field_pat],
-                                      etc: bool,
-                                      enum_id: ast::def_id,
-                                      substitutions: &ty::substs) {
-    let fcx = pcx.fcx;
-    let tcx = pcx.fcx.ccx.tcx;
-
-    // Find the variant that was specified.
-    match tcx.def_map.find(pat_id) {
-        Some(ast::def_variant(found_enum_id, variant_id))
-                if found_enum_id == enum_id => {
-            // Get the struct fields from this struct-like enum variant.
-            let class_fields = ty::lookup_struct_fields(tcx, variant_id);
-
-            check_struct_pat_fields(pcx, span, path, fields, class_fields,
-                                    variant_id, substitutions, etc);
-        }
-        Some(ast::def_struct(*)) | Some(ast::def_variant(*)) => {
-            let name = pprust::path_to_str(path, tcx.sess.intr());
-            tcx.sess.span_err(span,
-                              fmt!("mismatched types: expected `%s` but \
-                                    found `%s`",
-                                   fcx.infcx().ty_to_str(expected),
-                                   name));
-        }
-        _ => {
-            tcx.sess.span_bug(span, ~"resolve didn't write in variant");
-        }
-    }
-}
-
-// Pattern checking is top-down rather than bottom-up so that bindings get
-// their types immediately.
-fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
-    let fcx = pcx.fcx;
-    let tcx = pcx.fcx.ccx.tcx;
-
-    match pat.node {
-      ast::pat_wild => {
-        fcx.write_ty(pat.id, expected);
-      }
-      ast::pat_lit(lt) => {
-        check_expr_with(fcx, lt, expected);
-        fcx.write_ty(pat.id, fcx.expr_ty(lt));
-      }
-      ast::pat_range(begin, end) => {
-        check_expr_with(fcx, begin, expected);
-        check_expr_with(fcx, end, expected);
-        let b_ty =
-            fcx.infcx().resolve_type_vars_if_possible(fcx.expr_ty(begin));
-        let e_ty =
-            fcx.infcx().resolve_type_vars_if_possible(fcx.expr_ty(end));
-        debug!("pat_range beginning type: %?", b_ty);
-        debug!("pat_range ending type: %?", e_ty);
-        if !require_same_types(
-            tcx, Some(fcx.infcx()), false, pat.span, b_ty, e_ty,
-            || ~"mismatched types in range")
-        {
-            // no-op
-        } else if !ty::type_is_numeric(b_ty) {
-            tcx.sess.span_err(pat.span, ~"non-numeric type used in range");
-        } else if !valid_range_bounds(fcx.ccx, begin, end) {
-            tcx.sess.span_err(begin.span, ~"lower range bound must be less \
-                                           than upper");
-        }
-        fcx.write_ty(pat.id, b_ty);
-      }
-      ast::pat_ident(*) if pat_is_const(tcx.def_map, pat) => {
-        let const_did = ast_util::def_id_of_def(tcx.def_map.get(pat.id));
-        let const_tpt = ty::lookup_item_type(tcx, const_did);
-        fcx.write_ty(pat.id, const_tpt.ty);
-      }
-      ast::pat_ident(bm, name, sub) if pat_is_binding(tcx.def_map, pat) => {
-        let vid = lookup_local(fcx, pat.span, pat.id);
-        let mut typ = ty::mk_var(tcx, vid);
-
-        match bm {
-          ast::bind_by_ref(mutbl) => {
-            // if the binding is like
-            //    ref x | ref const x | ref mut x
-            // then the type of x is &M T where M is the mutability
-            // and T is the expected type
-            let region_var =
-                fcx.infcx().next_region_var_with_lb(
-                    pat.span, pcx.block_region);
-            let mt = {ty: expected, mutbl: mutbl};
-            let region_ty = ty::mk_rptr(tcx, region_var, mt);
-            demand::eqtype(fcx, pat.span, region_ty, typ);
-          }
-          // otherwise the type of x is the expected type T
-          ast::bind_by_value | ast::bind_by_move | ast::bind_infer => {
-            demand::eqtype(fcx, pat.span, expected, typ);
-          }
-        }
-
-        let canon_id = pcx.map.get(ast_util::path_to_ident(name));
-        if canon_id != pat.id {
-            let tv_id = lookup_local(fcx, pat.span, canon_id);
-            let ct = ty::mk_var(tcx, tv_id);
-            demand::eqtype(fcx, pat.span, ct, typ);
-        }
-        fcx.write_ty(pat.id, typ);
-
-        debug!("(checking alt) writing type for pat id %d", pat.id);
-
-        match sub {
-          Some(p) => check_pat(pcx, p, expected),
-          _ => ()
-        }
-      }
-      ast::pat_ident(_, path, _) => {
-        check_pat_variant(pcx, pat, path, Some(~[]), expected);
-      }
-      ast::pat_enum(path, subpats) => {
-        check_pat_variant(pcx, pat, path, subpats, expected);
-      }
-      ast::pat_rec(fields, etc) => {
-        let ex_fields = match structure_of(fcx, pat.span, expected) {
-          ty::ty_rec(fields) => fields,
-          _ => {
-            tcx.sess.span_fatal
-                (pat.span,
-                fmt!("mismatched types: expected `%s` but found record",
-                     fcx.infcx().ty_to_str(expected)));
-          }
-        };
-        let f_count = vec::len(fields);
-        let ex_f_count = vec::len(ex_fields);
-        if ex_f_count < f_count || !etc && ex_f_count > f_count {
-            tcx.sess.span_fatal
-                (pat.span, fmt!("mismatched types: expected a record \
-                      with %u fields, found one with %u \
-                      fields",
-                                ex_f_count, f_count));
-        }
-
-        for fields.each |f| {
-            match vec::find(ex_fields, |a| f.ident == a.ident) {
-              Some(field) => {
-                check_pat(pcx, f.pat, field.mt.ty);
-              }
-              None => {
-                tcx.sess.span_fatal(pat.span,
-                                    fmt!("mismatched types: did not \
-                                          expect a record with a field `%s`",
-                                          tcx.sess.str_of(f.ident)));
-              }
-            }
-        }
-        fcx.write_ty(pat.id, expected);
-      }
-      ast::pat_struct(path, fields, etc) => {
-        // Grab the class data that we care about.
-        let structure = structure_of(fcx, pat.span, expected);
-        match structure {
-            ty::ty_struct(cid, ref substs) => {
-                check_struct_pat(pcx, pat.id, pat.span, expected, path,
-                                 fields, etc, cid, substs);
-            }
-            ty::ty_enum(eid, ref substs) => {
-                check_struct_like_enum_variant_pat(
-                    pcx, pat.id, pat.span, expected, path, fields, etc, eid,
-                    substs);
-            }
-            _ => {
-                // XXX: This should not be fatal.
-                tcx.sess.span_fatal(pat.span,
-                                    fmt!("mismatched types: expected `%s` \
-                                          but found struct",
-                                         fcx.infcx().ty_to_str(expected)));
-            }
-        }
-
-        // Finally, write in the type.
-        fcx.write_ty(pat.id, expected);
-      }
-      ast::pat_tup(elts) => {
-        let ex_elts = match structure_of(fcx, pat.span, expected) {
-          ty::ty_tup(elts) => elts,
-          _ => {
-            tcx.sess.span_fatal
-                (pat.span,
-                 fmt!("mismatched types: expected `%s`, found tuple",
-                      fcx.infcx().ty_to_str(expected)));
-          }
-        };
-        let e_count = vec::len(elts);
-        if e_count != vec::len(ex_elts) {
-            tcx.sess.span_fatal
-                (pat.span, fmt!("mismatched types: expected a tuple \
-                      with %u fields, found one with %u \
-                      fields", vec::len(ex_elts), e_count));
-        }
-        let mut i = 0u;
-        for elts.each |elt| {
-            check_pat(pcx, *elt, ex_elts[i]);
-            i += 1u;
-        }
-
-        fcx.write_ty(pat.id, expected);
-      }
-      ast::pat_box(inner) => {
-        match structure_of(fcx, pat.span, expected) {
-          ty::ty_box(e_inner) => {
-            check_pat(pcx, inner, e_inner.ty);
-            fcx.write_ty(pat.id, expected);
-          }
-          _ => {
-            tcx.sess.span_fatal(
-                pat.span,
-                ~"mismatched types: expected `" +
-                fcx.infcx().ty_to_str(expected) +
-                ~"` found box");
-          }
-        }
-      }
-      ast::pat_uniq(inner) => {
-        match structure_of(fcx, pat.span, expected) {
-          ty::ty_uniq(e_inner) => {
-            check_pat(pcx, inner, e_inner.ty);
-            fcx.write_ty(pat.id, expected);
-          }
-          _ => {
-            tcx.sess.span_fatal(
-                pat.span,
-                ~"mismatched types: expected `" +
-                fcx.infcx().ty_to_str(expected) +
-                ~"` found uniq");
-          }
-        }
-      }
-      ast::pat_region(inner) => {
-        match structure_of(fcx, pat.span, expected) {
-          ty::ty_rptr(_, e_inner) => {
-            check_pat(pcx, inner, e_inner.ty);
-            fcx.write_ty(pat.id, expected);
-          }
-          _ => {
-            tcx.sess.span_fatal(
-                pat.span,
-                ~"mismatched types: expected `" +
-                fcx.infcx().ty_to_str(expected) +
-                ~"` found borrowed pointer");
-          }
-        }
-      }
-      ast::pat_vec(elts, tail) => {
-        let default_region_var =
-            fcx.infcx().next_region_var_with_lb(
-                pat.span, pcx.block_region
-            );
-
-        let (elt_type, region_var) = match structure_of(
-          fcx, pat.span, expected
-        ) {
-          ty::ty_evec(mt, vstore) => {
-            let region_var = match vstore {
-                ty::vstore_slice(r) => r,
-                ty::vstore_box | ty::vstore_uniq | ty::vstore_fixed(_) => {
-                    default_region_var
-                }
-            };
-            (mt, region_var)
-          }
-          ty::ty_unboxed_vec(mt) => {
-            (mt, default_region_var)
-          },
-          _ => {
-            tcx.sess.span_fatal(
-                pat.span,
-                fmt!("mismatched type: expected `%s` but found vector",
-                     fcx.infcx().ty_to_str(expected))
-            );
-          }
-        };
-        for elts.each |elt| {
-            check_pat(pcx, *elt, elt_type.ty);
-        }
-        fcx.write_ty(pat.id, expected);
-
-        match tail {
-            Some(tail_pat) => {
-                let slice_ty = ty::mk_evec(tcx,
-                    {ty: elt_type.ty, mutbl: elt_type.mutbl},
-                    ty::vstore_slice(region_var)
-                );
-                check_pat(pcx, tail_pat, slice_ty);
-            }
-            None => ()
-        }
-      }
-    }
-}
-
index 89726e22283d9523011b8251f87b0402851b9441..e4b232500bbf76656fd86ca7542a03b1e6e09eee 100644 (file)
@@ -8,7 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
+use middle::ty;
 use middle::typeck::check::fn_ctxt;
+use middle::typeck::infer;
+
+use core::result::{Err, Ok};
+use core::result;
+use syntax::ast;
+use syntax::codemap::span;
 
 // Requires that the two types unify, and prints an error message if they
 // don't.
index 765bf0cfdff4d3eecde5e9edba3757f76cc6afd1..05061ccfa13ffc674d9d959b05db4094a767455b 100644 (file)
@@ -79,18 +79,37 @@ trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
 
 */
 
+use core::prelude::*;
+
 use middle::resolve::{Impl, MethodInfo};
+use middle::resolve;
 use middle::ty::*;
+use middle::ty;
+use middle::typeck::check::{fn_ctxt, impl_self_ty};
+use middle::typeck::check::{structurally_resolved_type};
+use middle::typeck::check::vtable::VtableContext;
+use middle::typeck::check::vtable;
 use middle::typeck::check;
 use middle::typeck::coherence::get_base_type_def_id;
+use middle::typeck::infer;
+use middle::typeck::{method_map_entry, method_origin, method_param};
+use middle::typeck::{method_self, method_static, method_trait};
+use util::common::indenter;
+use util::ppaux::expr_repr;
 
 use core::dvec::DVec;
+use core::result;
+use core::uint;
+use core::vec;
+use std::map::HashMap;
 use syntax::ast::{def_id, sty_by_ref, sty_value, sty_region, sty_box};
 use syntax::ast::{sty_uniq, sty_static, node_id, by_copy, by_ref};
 use syntax::ast::{m_const, m_mutbl, m_imm};
+use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_map::node_id_to_str;
 use syntax::ast_util::dummy_sp;
+use syntax::codemap::span;
 
 fn lookup(
     fcx: @fn_ctxt,
@@ -273,8 +292,9 @@ fn push_inherent_candidates(&self, self_ty: ty::t) {
                 ty_self => {
                     // Call is of the form "self.foo()" and appears in one
                     // of a trait's default method implementations.
-                    let self_did = self.fcx.self_impl_def_id.expect(
-                        ~"unexpected `none` for self_impl_def_id");
+                    let self_did = self.fcx.self_info.expect(
+                        ~"self_impl_def_id is undefined (`self` may not \
+                          be in scope here").def_id;
                     let substs = {self_r: None, self_ty: None, tps: ~[]};
                     self.push_inherent_candidates_from_self(
                         self_ty, self_did, &substs);
@@ -350,7 +370,7 @@ fn push_inherent_candidates_from_param(&self,
 
 
             let bound_substs = match ty::get(bound_trait_ty).sty {
-                ty::ty_trait(_, ref substs, _) => (*substs),
+                ty::ty_trait(_, ref substs, _) => (/*bad*/copy *substs),
                 _ => {
                     self.bug(fmt!("add_candidates_from_param: \
                                    non-trait bound %s",
@@ -378,7 +398,7 @@ fn push_inherent_candidates_from_param(&self,
 
             let mut i = 0;
             while i < worklist.len() {
-                let (init_trait_ty, init_substs) = worklist[i];
+                let (init_trait_ty, init_substs) = /*bad*/copy worklist[i];
                 i += 1;
 
                 let init_trait_id = ty::ty_to_def_id(init_trait_ty).get();
@@ -483,7 +503,7 @@ fn push_inherent_candidates_from_trait(&self,
         // `trait_ty` for `self` here, because it allows the compiler
         // to soldier on.  An error will be reported should this
         // candidate be selected if the method refers to `self`.
-        let rcvr_substs = {self_ty: Some(self_ty), ..*substs};
+        let rcvr_substs = {self_ty: Some(self_ty), ../*bad*/copy *substs};
 
         let (rcvr_ty, rcvr_substs) =
             self.create_rcvr_ty_and_substs_for_method(method.self_ty,
@@ -514,7 +534,7 @@ fn push_inherent_candidates_from_self(&self,
         }
         let method = &methods[index];
 
-        let rcvr_substs = { self_ty: Some(self_ty), ..*substs };
+        let rcvr_substs = { self_ty: Some(self_ty), ../*bad*/copy *substs };
         let (rcvr_ty, rcvr_substs) =
             self.create_rcvr_ty_and_substs_for_method(
                 method.self_ty,
@@ -885,13 +905,13 @@ fn merge_candidates(&self, candidates: &[Candidate]) -> ~[Candidate] {
         let mut merged = ~[];
         let mut i = 0;
         while i < candidates.len() {
-            let candidate_a = candidates[i];
+            let candidate_a = /*bad*/copy candidates[i];
 
             let mut skip = false;
 
             let mut j = i + 1;
             while j < candidates.len() {
-                let candidate_b = candidates[j];
+                let candidate_b = /*bad*/copy candidates[j];
                 debug!("attempting to merge %? and %?",
                        candidate_a, candidate_b);
                 let candidates_same = match (&candidate_a.origin,
@@ -977,9 +997,11 @@ fn confirm_candidate(&self,
 
         // Construct the full set of type parameters for the method,
         // which is equal to the class tps + the method tps.
-        let all_substs = {tps: vec::append(candidate.rcvr_substs.tps,
-                                           m_substs),
-                          ..candidate.rcvr_substs};
+        let all_substs = {
+            tps: vec::append(/*bad*/copy candidate.rcvr_substs.tps,
+                             m_substs),
+            ../*bad*/copy candidate.rcvr_substs
+        };
 
         self.fcx.write_ty_substs(self.callee_id, fty, all_substs);
         return {self_arg: {mode: ast::expl(candidate.self_mode),
@@ -1064,7 +1086,7 @@ fn type_of_trait_method(tcx: ty::ctxt,
                                 trait_did: def_id,
                                 method_num: uint) -> ty::t {
             let trait_methods = ty::trait_methods(tcx, trait_did);
-            ty::mk_fn(tcx, trait_methods[method_num].fty)
+            ty::mk_fn(tcx, /*bad*/copy trait_methods[method_num].fty)
         }
     }
 
@@ -1115,7 +1137,7 @@ fn report_trait_candidate(&self, idx: uint, did: def_id) {
                  ty::item_path_str(self.tcx(), did)));
     }
 
-    fn infcx(&self) -> infer::infer_ctxt {
+    fn infcx(&self) -> @infer::InferCtxt {
         self.fcx.inh.infcx
     }
 
@@ -1139,7 +1161,7 @@ fn did_to_str(&self, did: def_id) -> ~str {
         ty::item_path_str(self.tcx(), did)
     }
 
-    fn bug(&self, s: ~str) -> ! {
+    fn bug(&self, +s: ~str) -> ! {
         self.tcx().sess.bug(s)
     }
 }
index 93bdfd5ccda631a6d046a6311fc2a9b179961369..ae39c674030a860b6b049c3c71a626e27766c0e3 100644 (file)
 
 */
 
-use middle::ty::{TyVid, vid, FnTyBase, FnMeta, FnSig, VariantInfo_};
+use core::prelude::*;
+
+use middle::capture;
+use middle::const_eval;
+use middle::pat_util::pat_id_map;
+use middle::pat_util;
+use middle::ty::{TyVid, Vid, FnTyBase, FnMeta, FnSig, VariantInfo_, field};
+use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty};
+use middle::ty::{re_bound, br_cap_avoid};
+use middle::ty;
 use middle::typeck::astconv::{ast_conv, ast_path_to_ty};
 use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty};
+use middle::typeck::astconv;
+use middle::typeck::check::_match::pat_ctxt;
 use middle::typeck::check::method::TransformTypeNormally;
 use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_ty;
+use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
 use middle::typeck::check::vtable::{LocationInfo, VtableContext};
+use middle::typeck::crate_ctxt;
 use middle::typeck::infer::{resolve_type, force_tvar};
+use middle::typeck::infer;
 use middle::typeck::rscope::{anon_rscope, binding_rscope, bound_self_region};
 use middle::typeck::rscope::{empty_rscope, in_anon_rscope};
 use middle::typeck::rscope::{in_binding_rscope, region_scope, type_rscope};
+use middle::typeck::rscope;
+use middle::typeck::{isr_alist, lookup_def_ccx, method_map_entry};
+use middle::typeck::{method_origin, method_self, method_trait, no_params};
+use middle::typeck::{require_same_types};
+use util::common::{block_query, indenter, loop_query};
+use util::ppaux::{bound_region_to_str, expr_repr};
 use util::ppaux;
 
+use core::either;
+use core::option;
+use core::ptr;
 use core::result::{Result, Ok, Err};
+use core::result;
+use core::str;
+use core::vec;
+use std::list::Nil;
 use std::map::HashMap;
-use syntax::ast::ty_i;
-use syntax::ast_util::{is_local, visibility_to_privacy, Private, Public};
+use std::map;
+use syntax::ast::{provided, required, spanned, ty_i};
+use syntax::ast;
+use syntax::ast_map;
+use syntax::ast_util::{Private, Public, is_local, local_def, respan};
+use syntax::ast_util::{visibility_to_privacy};
+use syntax::ast_util;
+use syntax::codemap::span;
+use syntax::codemap;
 use syntax::parse::token::special_idents;
+use syntax::print::pprust::{expr_to_str, pat_to_str};
 use syntax::print::pprust;
+use syntax::visit;
+use syntax;
 
-export alt;
+export _match;
 export vtable;
 export writeback;
 export regionmanip;
 export DontDerefArgs;
 export DoDerefArgs;
 export check_item_types;
+export check_block;
+export check_expr_with;
+export fn_ctxt;
+export lookup_def;
+export structure_of;
+export self_info;
+export structurally_resolved_type;
+export instantiate_path;
+export valid_range_bounds;
 
 #[legacy_exports]
-pub mod alt;
+pub mod _match;
 #[legacy_exports]
 pub mod vtable;
 #[legacy_exports]
 /// `bar()` will each have their own `fn_ctxt`, but they will
 /// share the inherited fields.
 struct inherited {
-    infcx: infer::infer_ctxt,
+    infcx: @infer::InferCtxt,
     locals: HashMap<ast::node_id, TyVid>,
     node_types: HashMap<ast::node_id, ty::t>,
     node_type_substs: HashMap<ast::node_id, ty::substs>,
@@ -156,7 +202,10 @@ pub struct fn_ctxt {
     // var_bindings, locals and next_var_id are shared
     // with any nested functions that capture the environment
     // (and with any functions whose environment is being captured).
-    self_impl_def_id: Option<ast::def_id>,
+
+    // Refers to whichever `self` is in scope, even this fn_ctxt is
+    // for a nested closure that captures `self`
+    self_info: Option<self_info>,
     ret_ty: ty::t,
     // Used by loop bodies that return from the outer function
     indirect_ret_ty: Option<ty::t>,
@@ -205,7 +254,7 @@ fn blank_fn_ctxt(ccx: @crate_ctxt, rty: ty::t,
 // It's kind of a kludge to manufacture a fake function context
 // and statement context, but we might as well do write the code only once
     @fn_ctxt {
-        self_impl_def_id: None,
+        self_info: None,
         ret_ty: rty,
         indirect_ret_ty: None,
         purity: ast::pure_fn,
@@ -218,7 +267,7 @@ fn blank_fn_ctxt(ccx: @crate_ctxt, rty: ty::t,
 }
 
 fn check_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
-    let visit = visit::mk_simple_visitor(@{
+    let visit = visit::mk_simple_visitor(@visit::SimpleVisitor {
         visit_item: |a| check_item(ccx, a),
         .. *visit::default_simple_visitor()
     });
@@ -226,7 +275,7 @@ fn check_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
 }
 
 fn check_bare_fn(ccx: @crate_ctxt,
-                 decl: ast::fn_decl,
+                 decl: &ast::fn_decl,
                  body: ast::blk,
                  id: ast::node_id,
                  self_info: Option<self_info>) {
@@ -243,7 +292,7 @@ fn check_bare_fn(ccx: @crate_ctxt,
 fn check_fn(ccx: @crate_ctxt,
             self_info: Option<self_info>,
             fn_ty: &ty::FnTy,
-            decl: ast::fn_decl,
+            decl: &ast::fn_decl,
             body: ast::blk,
             fn_kind: FnKind,
             old_fcx: Option<@fn_ctxt>) {
@@ -258,15 +307,15 @@ fn check_fn(ccx: @crate_ctxt,
     // types with free ones.  The free region references will be bound
     // the node_id of the body block.
 
-    let {isr: isr, self_info: self_info, fn_ty: fn_ty} = {
+    let {isr, self_info, fn_sig} = {
         let old_isr = option::map_default(&old_fcx, @Nil,
-                                         |fcx| fcx.in_scope_regions);
-        replace_bound_regions_in_fn_ty(tcx, old_isr, self_info, fn_ty,
-                                       |br| ty::re_free(body.node.id, br))
+                                          |fcx| fcx.in_scope_regions);
+        replace_bound_regions_in_fn_sig(tcx, old_isr, self_info, &fn_ty.sig,
+                                        |br| ty::re_free(body.node.id, br))
     };
 
-    let arg_tys = fn_ty.sig.inputs.map(|a| a.ty);
-    let ret_ty = fn_ty.sig.output;
+    let arg_tys = fn_sig.inputs.map(|a| a.ty);
+    let ret_ty = fn_sig.output;
 
     debug!("check_fn(arg_tys=%?, ret_ty=%?, self_info.self_ty=%?)",
            arg_tys.map(|a| ppaux::ty_to_str(tcx, *a)),
@@ -298,7 +347,7 @@ fn check_fn(ccx: @crate_ctxt,
         } else { None };
 
         @fn_ctxt {
-            self_impl_def_id: self_info.map(|self_info| self_info.def_id),
+            self_info: self_info,
             ret_ty: ret_ty,
             indirect_ret_ty: indirect_ret_ty,
             purity: purity,
@@ -328,7 +377,8 @@ fn check_fn(ccx: @crate_ctxt,
         }
     };
 
-    gather_locals(fcx, decl, body, arg_tys, self_info);
+    // XXX: Bad copy.
+    gather_locals(fcx, decl, body, copy arg_tys, self_info);
     check_block(fcx, body);
 
     // We unify the tail expr's type with the
@@ -358,12 +408,12 @@ fn check_fn(ccx: @crate_ctxt,
     // resolved when the enclosing scope finishes up.
     if old_fcx.is_none() {
         vtable::resolve_in_block(fcx, body);
-        regionck::regionck_fn(fcx, decl, body);
+        regionck::regionck_fn(fcx, body);
         writeback::resolve_type_vars_in_fn(fcx, decl, body, self_info);
     }
 
     fn gather_locals(fcx: @fn_ctxt,
-                     decl: ast::fn_decl,
+                     decl: &ast::fn_decl,
                      body: ast::blk,
                      arg_tys: ~[ty::t],
                      self_info: Option<self_info>) {
@@ -401,13 +451,13 @@ fn gather_locals(fcx: @fn_ctxt,
 
             // Check the pattern.
             let region = fcx.block_region();
-            let pcx = {
+            let pcx = pat_ctxt {
                 fcx: fcx,
                 map: pat_id_map(tcx.def_map, input.pat),
-                alt_region: region,
+                match_region: region,
                 block_region: region,
             };
-            alt::check_pat(pcx, input.pat, *arg_ty);
+            _match::check_pat(pcx, input.pat, *arg_ty);
         }
 
         // Add explicitly-declared locals.
@@ -455,12 +505,13 @@ fn visit_fn(_fk: visit::fn_kind, _decl: ast::fn_decl,
         }
         fn visit_item(_i: @ast::item, &&_e: (), _v: visit::vt<()>) { }
 
-        let visit = visit::mk_vt(@{visit_local: visit_local,
-                                   visit_pat: visit_pat,
-                                   visit_fn: visit_fn,
-                                   visit_item: visit_item,
-                                   visit_block: visit_block,
-                                   .. *visit::default_visitor()});
+        let visit = visit::mk_vt(
+            @visit::Visitor {visit_local: visit_local,
+                             visit_pat: visit_pat,
+                             visit_fn: visit_fn,
+                             visit_item: visit_item,
+                             visit_block: visit_block,
+                             ..*visit::default_visitor()});
 
         (visit.visit_block)(body, (), visit);
     }
@@ -472,7 +523,7 @@ fn check_method(ccx: @crate_ctxt, method: @ast::method,
                      self_id: method.self_id,
                      def_id: self_impl_def_id,
                      explicit_self: method.self_ty };
-    check_bare_fn(ccx, method.decl, method.body, method.id, Some(self_info));
+    check_bare_fn(ccx, &method.decl, method.body, method.id, Some(self_info));
 }
 
 fn check_no_duplicate_fields(tcx: ty::ctxt, fields:
@@ -504,13 +555,15 @@ fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def,
     let self_ty = ty::node_id_to_type(tcx, id);
 
     do struct_def.dtor.iter() |dtor| {
-        let class_t = {self_ty: self_ty,
-                       self_id: dtor.node.self_id,
-                       def_id: local_def(id),
-                       explicit_self: {node: ast::sty_by_ref,
-                                       span: ast_util::dummy_sp()}};
+        let class_t = { self_ty: self_ty,
+                        self_id: dtor.node.self_id,
+                        def_id: local_def(id),
+                        explicit_self:
+                            spanned { node: ast::sty_by_ref,
+                                      span: ast_util::dummy_sp() } };
         // typecheck the dtor
-        check_bare_fn(ccx, ast_util::dtor_dec(),
+        let dtor_dec = ast_util::dtor_dec();
+        check_bare_fn(ccx, &dtor_dec,
                       dtor.node.body, dtor.node.id,
                       Some(class_t));
     };
@@ -525,12 +578,15 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
            ty::item_path_str(ccx.tcx, local_def(it.id)));
     let _indenter = indenter();
 
-    match it.node {
+    match /*bad*/copy it.node {
       ast::item_const(_, e) => check_const(ccx, it.span, e, it.id),
       ast::item_enum(ref enum_definition, _) => {
-        check_enum_variants(ccx, it.span, (*enum_definition).variants, it.id);
+        check_enum_variants(ccx,
+                            it.span,
+                            /*bad*/copy (*enum_definition).variants,
+                            it.id);
       }
-      ast::item_fn(decl, _, _, ref body) => {
+      ast::item_fn(ref decl, _, _, ref body) => {
         check_bare_fn(ccx, decl, (*body), it.id, None);
       }
       ast::item_impl(_, _, ty, ms) => {
@@ -605,7 +661,7 @@ fn ty_infer(_span: span) -> ty::t {
 }
 
 impl @fn_ctxt {
-    fn infcx() -> infer::infer_ctxt { self.inh.infcx }
+    fn infcx() -> @infer::InferCtxt { self.inh.infcx }
     fn search_in_scope_regions(br: ty::bound_region)
         -> Result<ty::Region, ~str>
     {
@@ -722,7 +778,7 @@ fn node_ty(id: ast::node_id) -> ty::t {
     }
     fn node_ty_substs(id: ast::node_id) -> ty::substs {
         match self.inh.node_type_substs.find(id) {
-            Some(ref ts) => (*ts),
+            Some(ref ts) => (/*bad*/copy *ts),
             None => {
                 self.tcx().sess.bug(
                     fmt!("no type substs for node %d: %s in fcx %s",
@@ -952,13 +1008,13 @@ pub fn impl_self_ty(vcx: &VtableContext,
     let {n_tps, region_param, raw_ty} = if did.crate == ast::local_crate {
         let region_param = tcx.region_paramd_items.find(did.node);
         match tcx.items.find(did.node) {
-          Some(ast_map::node_item(@{node: ast::item_impl(ts, _, st, _),
+          Some(ast_map::node_item(@{node: ast::item_impl(ref ts, _, st, _),
                                   _}, _)) => {
             {n_tps: ts.len(),
              region_param: region_param,
              raw_ty: vcx.ccx.to_ty(rscope::type_rscope(region_param), st)}
           }
-          Some(ast_map::node_item(@{node: ast::item_struct(_, ts),
+          Some(ast_map::node_item(@{node: ast::item_struct(_, ref ts),
                                     id: class_id, _},_)) => {
               /* If the impl is a class, the self ty is just the class ty
                  (doing a no-op subst for the ty params; in the next step,
@@ -969,7 +1025,7 @@ pub fn impl_self_ty(vcx: &VtableContext,
                raw_ty: ty::mk_struct(tcx, local_def(class_id),
                       {self_r: rscope::bound_self_region(region_param),
                        self_ty: None,
-                       tps: ty::ty_params_to_tys(tcx, ts)})}
+                       tps: ty::ty_params_to_tys(tcx, /*bad*/copy *ts)})}
           }
           _ => { tcx.sess.bug(~"impl_self_ty: unbound item or item that \
                doesn't have a self_ty"); }
@@ -1015,6 +1071,10 @@ pub enum DerefArgs {
     DoDerefArgs
 }
 
+fn break_here() {
+    debug!("break here!");
+}
+
 fn check_expr_with_unifier(fcx: @fn_ctxt,
                            expr: @ast::expr,
                            expected: Option<ty::t>,
@@ -1051,12 +1111,15 @@ fn check_call_inner(
         let fty =
             match structure_of(fcx, sp, in_fty) {
               ty::ty_fn(ref fn_ty) => {
-                  let fn_ty = replace_bound_regions_in_fn_ty(tcx, @Nil,
+                  let fn_ty =
+                    /*bad*/copy replace_bound_regions_in_fn_ty(tcx, @Nil,
                       None, fn_ty, |_br| fcx.infcx().next_region_var(sp,
                                                       call_expr_id)).fn_ty;
 
                   let supplied_arg_count = args.len();
 
+                  bot |= ty::type_is_bot(fn_ty.sig.output);
+
                   // Grab the argument types, supplying fresh type variables
                   // if the wrong number of arguments were supplied
                   let expected_arg_count = fn_ty.sig.inputs.len();
@@ -1168,7 +1231,7 @@ fn check_call_or_method(fcx: @fn_ctxt,
                             call_expr_id: ast::node_id,
                             fn_ty: ty::t,
                             expr: @ast::expr,
-                            args: ~[@ast::expr],
+                            +args: ~[@ast::expr],
                             bot: bool)
                          -> bool {
         let mut bot = bot;
@@ -1184,7 +1247,6 @@ fn check_call_or_method(fcx: @fn_ctxt,
         // Pull the return type out of the type of the function.
         match structure_of(fcx, sp, fty) {
           ty::ty_fn(ref f) => {
-              bot |= (f.meta.ret_style == ast::noreturn);
               fcx.write_ty(call_expr_id, f.sig.output);
               return bot;
           }
@@ -1199,11 +1261,10 @@ fn check_call_or_method(fcx: @fn_ctxt,
 
     // A generic function for doing all of the checking for call expressions
     fn check_call(fcx: @fn_ctxt, sp: span, call_expr_id: ast::node_id,
-                  f: @ast::expr, args: ~[@ast::expr]) -> bool {
-
+                  f: @ast::expr, +args: ~[@ast::expr]) -> bool {
         // Index expressions need to be handled separately, to inform them
         // that they appear in call position.
-        let mut bot = match f.node {
+        let mut bot = match /*bad*/copy f.node {
             ast::expr_field(base, field, tys) => {
                 check_field(fcx, f, true, base, field, tys)
             }
@@ -1224,7 +1285,7 @@ fn check_method_call(fcx: @fn_ctxt,
                          expr: @ast::expr,
                          rcvr: @ast::expr,
                          method_name: ast::ident,
-                         args: ~[@ast::expr],
+                         +args: ~[@ast::expr],
                          tps: ~[@ast::Ty])
                       -> bool {
         let bot = check_expr(fcx, rcvr, None);
@@ -1310,7 +1371,7 @@ fn check_then_else(fcx: @fn_ctxt, thn: ast::blk,
 
     fn lookup_op_method(fcx: @fn_ctxt, op_ex: @ast::expr,
                         self_ex: @ast::expr, self_t: ty::t,
-                        opname: ast::ident, args: ~[@ast::expr],
+                        opname: ast::ident, +args: ~[@ast::expr],
                         +deref_args: DerefArgs)
         -> Option<(ty::t, bool)>
     {
@@ -1446,12 +1507,12 @@ fn check_user_unop(fcx: @fn_ctxt, op_str: ~str, mname: ~str,
     // resolution is not possible (e.g., no constraints yet present), just
     // returns `none`.
     fn unpack_expected<O: Copy>(fcx: @fn_ctxt, expected: Option<ty::t>,
-                                unpack: fn(ty::sty) -> Option<O>)
+                                unpack: fn(&ty::sty) -> Option<O>)
         -> Option<O> {
         match expected {
             Some(t) => {
                 match resolve_type(fcx.infcx(), t, force_tvar) {
-                    Ok(t) => unpack(ty::get(t).sty),
+                    Ok(t) => unpack(&ty::get(t).sty),
                     _ => None
                 }
             }
@@ -1462,7 +1523,7 @@ fn unpack_expected<O: Copy>(fcx: @fn_ctxt, expected: Option<ty::t>,
     fn check_expr_fn(fcx: @fn_ctxt,
                      expr: @ast::expr,
                      ast_proto_opt: Option<ast::Proto>,
-                     decl: ast::fn_decl,
+                     decl: &ast::fn_decl,
                      body: ast::blk,
                      fn_kind: FnKind,
                      expected: Option<ty::t>) {
@@ -1476,7 +1537,7 @@ fn check_expr_fn(fcx: @fn_ctxt,
         // to impure and block. Note that we only will use those for
         // block syntax lambdas; that is, lambdas without explicit
         // protos.
-        let expected_sty = unpack_expected(fcx, expected, |x| Some(x));
+        let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
         let (expected_tys,
              expected_purity,
              expected_proto,
@@ -1488,7 +1549,7 @@ fn check_expr_fn(fcx: @fn_ctxt,
                         replace_bound_regions_in_fn_ty(
                             tcx, @Nil, None, fn_ty,
                             |br| ty::re_bound(ty::br_cap_avoid(id, @br)));
-                    (Some({inputs: fn_ty.sig.inputs,
+                    (Some({inputs: /*bad*/copy fn_ty.sig.inputs,
                            output: fn_ty.sig.output}),
                      fn_ty.meta.purity,
                      fn_ty.meta.proto,
@@ -1512,9 +1573,10 @@ fn check_expr_fn(fcx: @fn_ctxt,
             fcx, fcx,
             proto, purity, expected_onceness,
             /*bounds:*/ @~[], /*opt_region:*/ None,
-            decl, expected_tys, expr.span);
+            *decl, expected_tys, expr.span);
 
-        let fty = ty::mk_fn(tcx, fn_ty);
+        // XXX: Bad copy.
+        let fty = ty::mk_fn(tcx, copy fn_ty);
 
         debug!("check_expr_fn_with_unifier %s fty=%s",
                expr_to_str(expr, tcx.sess.intr()),
@@ -1522,7 +1584,9 @@ fn check_expr_fn(fcx: @fn_ctxt,
 
         fcx.write_ty(expr.id, fty);
 
-        check_fn(fcx.ccx, None, &fn_ty, decl, body,
+        // We inherit the same self info as the enclosing scope,
+        // since the function we're checking might capture `self`
+        check_fn(fcx.ccx, fcx.self_info, &fn_ty, decl, body,
                  fn_kind, Some(fcx));
     }
 
@@ -1648,9 +1712,11 @@ fn check_struct_or_variant_fields(fcx: @fn_ctxt,
                     let expected_field_type =
                         ty::lookup_field_type(
                             tcx, class_id, field_id, substitutions);
-                    bot |= check_expr(fcx,
-                                      field.node.expr,
-                                      Some(expected_field_type));
+                    bot |=
+                        check_expr_with_assignability(
+                            fcx,
+                            field.node.expr,
+                            expected_field_type);
                     class_field_map.insert(
                         field.node.ident, (field_id, true));
                     fields_found += 1;
@@ -1688,7 +1754,7 @@ fn check_struct_or_variant_fields(fcx: @fn_ctxt,
 
     fn check_struct_constructor(fcx: @fn_ctxt,
                                 id: ast::node_id,
-                                span: syntax::codemap::span,
+                                span: codemap::span,
                                 class_id: ast::def_id,
                                 fields: ~[ast::field],
                                 base_expr: Option<@ast::expr>) -> bool {
@@ -1703,7 +1769,7 @@ fn check_struct_constructor(fcx: @fn_ctxt,
                 tcx.region_paramd_items.find(class_id.node);
             match tcx.items.find(class_id.node) {
                 Some(ast_map::node_item(@{
-                        node: ast::item_struct(_, type_parameters),
+                        node: ast::item_struct(_, ref type_parameters),
                         _
                     }, _)) => {
 
@@ -1715,7 +1781,9 @@ fn check_struct_constructor(fcx: @fn_ctxt,
                     raw_type = ty::mk_struct(tcx, class_id, {
                         self_r: self_region,
                         self_ty: None,
-                        tps: ty::ty_params_to_tys(tcx, type_parameters)
+                        tps: ty::ty_params_to_tys(
+                            tcx,
+                            /*bad*/copy *type_parameters)
                     });
                 }
                 _ => {
@@ -1769,7 +1837,7 @@ fn check_struct_constructor(fcx: @fn_ctxt,
 
     fn check_struct_enum_variant(fcx: @fn_ctxt,
                                  id: ast::node_id,
-                                 span: syntax::codemap::span,
+                                 span: codemap::span,
                                  enum_id: ast::def_id,
                                  variant_id: ast::def_id,
                                  fields: ~[ast::field]) -> bool {
@@ -1784,7 +1852,7 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
                 tcx.region_paramd_items.find(enum_id.node);
             match tcx.items.find(enum_id.node) {
                 Some(ast_map::node_item(@{
-                        node: ast::item_enum(_, type_parameters),
+                        node: ast::item_enum(_, ref type_parameters),
                         _
                     }, _)) => {
 
@@ -1796,7 +1864,9 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
                     raw_type = ty::mk_enum(tcx, enum_id, {
                         self_r: self_region,
                         self_ty: None,
-                        tps: ty::ty_params_to_tys(tcx, type_parameters)
+                        tps: ty::ty_params_to_tys(
+                            tcx,
+                            /*bad*/copy *type_parameters)
                     });
                 }
                 _ => {
@@ -1843,10 +1913,10 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
     let tcx = fcx.ccx.tcx;
     let id = expr.id;
     let mut bot = false;
-    match expr.node {
+    match /*bad*/copy expr.node {
       ast::expr_vstore(ev, vst) => {
-        let typ = match ev.node {
-          ast::expr_lit(@{node: ast::lit_str(s), span:_}) => {
+        let typ = match /*bad*/copy ev.node {
+          ast::expr_lit(@ast::spanned { node: ast::lit_str(s), _ }) => {
             let tt = ast_expr_vstore_to_vstore(fcx, ev, str::len(*s), vst);
             ty::mk_estr(tcx, tt)
           }
@@ -1899,8 +1969,8 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
       ast::expr_unary(unop, oprnd) => {
         let exp_inner = do unpack_expected(fcx, expected) |sty| {
             match unop {
-              ast::box(_) | ast::uniq(_) => match sty {
-                ty::ty_box(mt) | ty::ty_uniq(mt) => Some(mt.ty),
+              ast::box(_) | ast::uniq(_) => match *sty {
+                ty::ty_box(ref mt) | ty::ty_uniq(ref mt) => Some(mt.ty),
                 _ => None
               },
               ast::not | ast::neg => expected,
@@ -1980,8 +2050,8 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
         fcx.write_ty(id, oprnd_t);
       }
       ast::expr_addr_of(mutbl, oprnd) => {
-        bot = check_expr(fcx, oprnd, unpack_expected(fcx, expected, |ty|
-            match ty { ty::ty_rptr(_, mt) => Some(mt.ty), _ => None }
+        bot = check_expr(fcx, oprnd, unpack_expected(fcx, expected, |sty|
+            match *sty { ty::ty_rptr(_, ref mt) => Some(mt.ty), _ => None }
         ));
 
         // Note: at this point, we cannot say what the best lifetime
@@ -2087,14 +2157,14 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
         bot = !may_break(tcx, expr.id, (*body));
       }
       ast::expr_match(discrim, ref arms) => {
-        bot = alt::check_alt(fcx, expr, discrim, (*arms));
+        bot = _match::check_match(fcx, expr, discrim, (/*bad*/copy *arms));
       }
-      ast::expr_fn(proto, decl, ref body, cap_clause) => {
+      ast::expr_fn(proto, ref decl, ref body, cap_clause) => {
         check_expr_fn(fcx, expr, Some(proto),
                       decl, (*body), Vanilla, expected);
         capture::check_capture_clause(tcx, expr.id, cap_clause);
       }
-      ast::expr_fn_block(decl, ref body, cap_clause) => {
+      ast::expr_fn_block(ref decl, ref body, cap_clause) => {
         check_expr_fn(fcx, expr, None,
                       decl, (*body), Vanilla, expected);
         capture::check_capture_clause(tcx, expr.id, cap_clause);
@@ -2107,7 +2177,7 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
         // 1. a closure that returns a bool is expected
         // 2. the closure that was given returns unit
         let mut err_happened = false;
-        let expected_sty = unpack_expected(fcx, expected, |x| Some(x));
+        let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
         let inner_ty = match expected_sty {
           Some(ty::ty_fn(ref fty)) => {
             match fcx.mk_subty(false, expr.span,
@@ -2127,7 +2197,7 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
             ty::mk_fn(tcx, FnTyBase {
                 meta: (*fty).meta,
                 sig: FnSig {output: ty::mk_nil(tcx),
-                            ..(*fty).sig}
+                            ../*bad*/copy (*fty).sig}
             })
           }
           _ =>
@@ -2150,9 +2220,9 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
               }
         };
         match b.node {
-          ast::expr_fn_block(decl, ref body, cap_clause) => {
+          ast::expr_fn_block(ref decl, ref body, cap_clause) => {
             check_expr_fn(fcx, b, None,
-                          decl, (*body), ForLoop, Some(inner_ty));
+                          decl, *body, ForLoop, Some(inner_ty));
             demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
             capture::check_capture_clause(tcx, b.id, cap_clause);
           }
@@ -2161,27 +2231,19 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
         }
         let block_ty = structurally_resolved_type(
             fcx, expr.span, fcx.node_ty(b.id));
-        match ty::get(block_ty).sty {
-          ty::ty_fn(ref fty) => {
-              if !err_happened {
-                  fcx.write_ty(expr.id, ty::mk_fn(tcx, FnTyBase {
-                      meta: (*fty).meta,
-                      sig: FnSig {output: ty::mk_bool(tcx),
-                                  ..(*fty).sig}
-                  }));
-              }
-              else {
-                  fcx.write_ty(expr.id, ty::mk_err(fcx.tcx()));
-              }
-          }
-          _ => fail ~"expected fn type"
+        if err_happened {
+            fcx.write_ty(expr.id, ty::mk_err(fcx.tcx()));
+        } else {
+            let loop_body_ty = ty::replace_fn_return_type(tcx, block_ty,
+                                                          ty::mk_bool(tcx));
+            fcx.write_ty(expr.id, loop_body_ty);
         }
       }
       ast::expr_do_body(b) => {
-        let expected_sty = unpack_expected(fcx, expected, |x| Some(x));
+        let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
         let inner_ty = match expected_sty {
           Some(ty::ty_fn(ref fty)) => {
-              ty::mk_fn(tcx, (*fty))
+              ty::mk_fn(tcx, (/*bad*/copy *fty))
           }
           _ => match expected {
                   Some(expected_t) => {
@@ -2199,23 +2261,16 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
               }
         };
         match b.node {
-          ast::expr_fn_block(decl, ref body, cap_clause) => {
+          ast::expr_fn_block(ref decl, ref body, cap_clause) => {
             check_expr_fn(fcx, b, None,
-                          decl, (*body), DoBlock, Some(inner_ty));
+                          decl, *body, DoBlock, Some(inner_ty));
             demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
             capture::check_capture_clause(tcx, b.id, cap_clause);
           }
           // argh
           _ => fail ~"expected fn ty"
         }
-        let block_ty = structurally_resolved_type(
-            fcx, expr.span, fcx.node_ty(b.id));
-        match ty::get(block_ty).sty {
-          ty::ty_fn(ref fty) => {
-            fcx.write_ty(expr.id, ty::mk_fn(tcx, (*fty)));
-          }
-          _ => fail ~"expected fn ty"
-        }
+        fcx.write_ty(expr.id, fcx.node_ty(b.id));
       }
       ast::expr_block(ref b) => {
         // If this is an unchecked block, turn off purity-checking
@@ -2294,7 +2349,7 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
       }
       ast::expr_tup(elts) => {
         let flds = unpack_expected(fcx, expected, |sty| {
-            match sty { ty::ty_tup(flds) => Some(flds), _ => None }
+            match *sty { ty::ty_tup(ref flds) => Some(copy *flds), _ => None }
         });
         let elt_ts = do elts.mapi |i, e| {
             check_expr(fcx, *e, flds.map(|fs| fs[i]));
@@ -2309,7 +2364,10 @@ fn check_struct_enum_variant(fcx: @fn_ctxt,
             Some(fcx.expr_ty(base.get()))
         } else { expected };
         let flds = unpack_expected(fcx, expected, |sty|
-            match sty { ty::ty_rec(flds) => Some(flds), _ => None }
+            match *sty {
+                ty::ty_rec(ref flds) => Some(copy *flds),
+                _ => None
+            }
         );
         let fields_t = vec::map((*fields), |f| {
             bot |= check_expr(fcx, f.node.expr, flds.chain_ref(|flds|
@@ -2371,11 +2429,11 @@ fn get_node(f: &spanned<field>) -> field { f.node }
         match tcx.def_map.find(id) {
             Some(ast::def_struct(type_def_id)) => {
                 check_struct_constructor(fcx, id, expr.span, type_def_id,
-                                         (*fields), base_expr);
+                                         (/*bad*/copy *fields), base_expr);
             }
             Some(ast::def_variant(enum_id, variant_id)) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
-                                          variant_id, (*fields));
+                                          variant_id, (/*bad*/copy *fields));
             }
             _ => {
                 tcx.sess.span_bug(path.span, ~"structure constructor does \
@@ -2420,8 +2478,9 @@ fn get_node(f: &spanned<field>) -> field { f.node }
     }
     if bot { fcx.write_bot(expr.id); }
 
-    debug!("type of expr %s is %s, expected is %s",
-           syntax::print::pprust::expr_to_str(expr, tcx.sess.intr()),
+    debug!("type of expr %s is...",
+           syntax::print::pprust::expr_to_str(expr, tcx.sess.intr()));
+    debug!("... %s, expected is %s",
            ppaux::ty_to_str(tcx, fcx.expr_ty(expr)),
            match expected {
                Some(t) => ppaux::ty_to_str(tcx, t),
@@ -2465,13 +2524,13 @@ fn check_decl_local(fcx: @fn_ctxt, local: @ast::local) -> bool {
 
     let region =
         ty::re_scope(tcx.region_map.get(local.node.id));
-    let pcx = {
+    let pcx = pat_ctxt {
         fcx: fcx,
         map: pat_id_map(tcx.def_map, local.node.pat),
-        alt_region: region,
+        match_region: region,
         block_region: region,
     };
-    alt::check_pat(pcx, local.node.pat, t);
+    _match::check_pat(pcx, local.node.pat, t);
     return bot;
 }
 
@@ -2481,7 +2540,7 @@ fn check_stmt(fcx: @fn_ctxt, stmt: @ast::stmt) -> bool {
     match stmt.node {
       ast::stmt_decl(decl, id) => {
         node_id = id;
-        match decl.node {
+        match /*bad*/copy decl.node {
           ast::decl_local(ls) => for ls.each |l| {
             bot |= check_decl_local(fcx, *l);
           },
@@ -2523,7 +2582,8 @@ fn check_block(fcx0: @fn_ctxt, blk: ast::blk) -> bool {
         for blk.node.stmts.each |s| {
             if bot && !warned &&
                 match s.node {
-                  ast::stmt_decl(@{node: ast::decl_local(_), _}, _) |
+                  ast::stmt_decl(@ast::spanned { node: ast::decl_local(_),
+                                                 _}, _) |
                   ast::stmt_expr(_, _) | ast::stmt_semi(_, _) => {
                     true
                   }
@@ -2593,7 +2653,7 @@ fn check_instantiable(tcx: ty::ctxt,
 
 fn check_enum_variants(ccx: @crate_ctxt,
                        sp: span,
-                       vs: ~[ast::variant],
+                       +vs: ~[ast::variant],
                        id: ast::node_id) {
     fn do_check(ccx: @crate_ctxt, sp: span, vs: ~[ast::variant],
                 id: ast::node_id, disr_vals: &mut ~[int], disr_val: &mut int,
@@ -2638,7 +2698,7 @@ fn do_check(ccx: @crate_ctxt, sp: span, vs: ~[ast::variant],
             *disr_val += 1;
 
             match v.node.kind {
-                ast::tuple_variant_kind(args) if args.len() > 0u => {
+                ast::tuple_variant_kind(ref args) if args.len() > 0u => {
                     arg_tys = Some(ty::ty_fn_args(ctor_ty).map(|a| a.ty));
                 }
                 ast::tuple_variant_kind(_) => {
@@ -2651,7 +2711,13 @@ fn do_check(ccx: @crate_ctxt, sp: span, vs: ~[ast::variant],
                 }
                 ast::enum_variant_kind(_) => {
                     arg_tys = None;
-                    do_check(ccx, sp, vs, id, disr_vals, disr_val, variants);
+                    do_check(ccx,
+                             sp,
+                             /*bad*/copy vs,
+                             id,
+                             disr_vals,
+                             disr_val,
+                             variants);
                 }
             }
 
@@ -2788,6 +2854,8 @@ fn instantiate_path(fcx: @fn_ctxt,
                     span: span,
                     node_id: ast::node_id,
                     region_lb: ty::Region) {
+    debug!(">>> instantiate_path");
+
     let ty_param_count = vec::len(*tpt.bounds);
     let ty_substs_len = vec::len(pth.types);
 
@@ -2834,6 +2902,8 @@ fn instantiate_path(fcx: @fn_ctxt,
 
     let substs = {self_r: self_r, self_ty: None, tps: tps};
     fcx.write_ty_substs(node_id, tpt.ty, substs);
+
+    debug!("<<<");
 }
 
 // Resolves `typ` by a single level if `typ` is a type variable.  If no
@@ -2852,7 +2922,7 @@ fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t {
 
 // Returns the one-level-deep structure of the given type.
 fn structure_of(fcx: @fn_ctxt, sp: span, typ: ty::t) -> ty::sty {
-    ty::get(structurally_resolved_type(fcx, sp, typ)).sty
+    /*bad*/copy ty::get(structurally_resolved_type(fcx, sp, typ)).sty
 }
 
 fn type_is_integral(fcx: @fn_ctxt, sp: span, typ: ty::t) -> bool {
@@ -2997,7 +3067,7 @@ fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
         (1u, ~[], ty::mk_nil_ptr(tcx))
       }
       ~"visit_tydesc" => {
-          let tydesc_name = syntax::parse::token::special_idents::tydesc;
+          let tydesc_name = special_idents::tydesc;
           let ty_visitor_name = tcx.sess.ident_of(~"TyVisitor");
           assert tcx.intrinsic_defs.contains_key(tydesc_name);
           assert ccx.tcx.intrinsic_defs.contains_key(ty_visitor_name);
@@ -3014,8 +3084,7 @@ fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
                           proto: ast::ProtoBorrowed,
                           onceness: ast::Once,
                           region: ty::re_bound(ty::br_anon(0)),
-                          bounds: @~[],
-                          ret_style: ast::return_val},
+                          bounds: @~[]},
             sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
                                    ty: ty::mk_imm_ptr(
                                        ccx.tcx,
@@ -3204,6 +3273,18 @@ fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
          (0u, ~[arg(ast::by_copy, ty::mk_i64(tcx))],
          ty::mk_i64(tcx))
      }
+     ~"bswap16" => {
+         (0u, ~[arg(ast::by_copy, ty::mk_i16(tcx))],
+         ty::mk_i16(tcx))
+     }
+     ~"bswap32" => {
+         (0u, ~[arg(ast::by_copy, ty::mk_i32(tcx))],
+         ty::mk_i32(tcx))
+     }
+     ~"bswap64" => {
+         (0u, ~[arg(ast::by_copy, ty::mk_i64(tcx))],
+         ty::mk_i64(tcx))
+     }
      ref other => {
         tcx.sess.span_err(it.span, ~"unrecognized intrinsic function: `" +
                           (*other) + ~"`");
@@ -3215,8 +3296,7 @@ fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
                       proto: ast::ProtoBare,
                       onceness: ast::Many,
                       region: ty::re_static,
-                      bounds: @~[],
-                      ret_style: ast::return_val},
+                      bounds: @~[]},
         sig: FnSig {inputs: inputs,
                     output: output}
     });
index 5467eae82662e979097f3bf921731547358ad0b6..3901752ac6834ec147943cb15f2104e127bd5c6a 100644 (file)
 
 */
 
+use core::prelude::*;
+
 use middle::freevars::get_freevars;
 use middle::pat_util::pat_bindings;
 use middle::ty::{encl_region, re_scope};
 use middle::ty::{ty_fn_proto, vstore_box, vstore_fixed, vstore_slice};
 use middle::ty::{vstore_uniq};
-use middle::typeck::infer::{resolve_and_force_all_but_regions, fres};
+use middle::ty;
+use middle::typeck::check::fn_ctxt;
+use middle::typeck::check::lookup_def;
+use middle::typeck::infer::{fres, resolve_and_force_all_but_regions};
+use middle::typeck::infer::{resolve_type};
 use util::ppaux::{note_and_explain_region, ty_to_str};
 
+use core::result;
 use syntax::ast::{ProtoBare, ProtoBox, ProtoUniq, ProtoBorrowed};
 use syntax::ast::{def_arg, def_binding, def_local, def_self, def_upvar};
+use syntax::ast;
+use syntax::codemap::span;
 use syntax::print::pprust;
+use syntax::visit;
 
 enum rcx { rcx_({fcx: @fn_ctxt, mut errors_reported: uint}) }
 type rvt = visit::vt<@rcx>;
@@ -104,7 +114,6 @@ fn regionck_expr(fcx: @fn_ctxt, e: @ast::expr) {
 }
 
 fn regionck_fn(fcx: @fn_ctxt,
-               _decl: ast::fn_decl,
                blk: ast::blk) {
     let rcx = rcx_({fcx:fcx, mut errors_reported: 0});
     let v = regionck_visitor();
@@ -113,12 +122,12 @@ fn regionck_fn(fcx: @fn_ctxt,
 }
 
 fn regionck_visitor() -> rvt {
-    visit::mk_vt(@{visit_item: visit_item,
-                   visit_stmt: visit_stmt,
-                   visit_expr: visit_expr,
-                   visit_block: visit_block,
-                   visit_local: visit_local,
-                   .. *visit::default_visitor()})
+    visit::mk_vt(@visit::Visitor {visit_item: visit_item,
+                                  visit_stmt: visit_stmt,
+                                  visit_expr: visit_expr,
+                                  visit_block: visit_block,
+                                  visit_local: visit_local,
+                                  .. *visit::default_visitor()})
 }
 
 fn visit_item(_item: @ast::item, &&_rcx: @rcx, _v: rvt) {
@@ -164,7 +173,7 @@ fn visit_expr(expr: @ast::expr, &&rcx: @rcx, v: rvt) {
     debug!("visit_expr(e=%s)",
            pprust::expr_to_str(expr, rcx.fcx.tcx().sess.intr()));
 
-    match expr.node {
+    match /*bad*/copy expr.node {
         ast::expr_path(*) => {
             // Avoid checking the use of local variables, as we
             // already check their definitions.  The def'n always
index 0bcb032d8259cdc14afc16ab26ad749c660f3b6f..8097b0eca840e46d867c0d5ab387b74564478033 100644 (file)
@@ -9,33 +9,58 @@
 // except according to those terms.
 
 // #[warn(deprecated_mode)];
-// #[warn(deprecated_pattern)];
 
+use core::prelude::*;
+
+use middle::ty::{FnTyBase};
+use middle::ty;
+use middle::typeck::check::self_info;
+use middle::typeck::isr_alist;
+use util::common::indenter;
+use util::ppaux::region_to_str;
 use util::ppaux;
 
+use std::list::Cons;
+use syntax::ast;
 use syntax::print::pprust::{expr_to_str};
 
 // Helper functions related to manipulating region types.
 
-fn replace_bound_regions_in_fn_ty(
+pub fn replace_bound_regions_in_fn_ty(
     tcx: ty::ctxt,
     isr: isr_alist,
     self_info: Option<self_info>,
     fn_ty: &ty::FnTy,
     mapf: fn(ty::bound_region) -> ty::Region) ->
-    {isr: isr_alist, self_info: Option<self_info>, fn_ty: ty::FnTy} {
+    {isr: isr_alist, self_info: Option<self_info>, fn_ty: ty::FnTy}
+{
+    let {isr, self_info, fn_sig} =
+        replace_bound_regions_in_fn_sig(
+            tcx, isr, self_info, &fn_ty.sig, mapf);
+    {isr: isr,
+     self_info: self_info,
+     fn_ty: FnTyBase {meta: fn_ty.meta,
+                      sig: fn_sig}}
+}
 
+pub fn replace_bound_regions_in_fn_sig(
+    tcx: ty::ctxt,
+    isr: isr_alist,
+    self_info: Option<self_info>,
+    fn_sig: &ty::FnSig,
+    mapf: fn(ty::bound_region) -> ty::Region) ->
+    {isr: isr_alist, self_info: Option<self_info>, fn_sig: ty::FnSig}
+{
     // Take self_info apart; the self_ty part is the only one we want
     // to update here.
-    let (self_ty, rebuild_self_info) = match self_info {
-      Some(copy s) => (Some(s.self_ty), |t| Some({self_ty: t,.. s})),
-      None => (None, |_t| None)
-    };
+    let self_ty = self_info.map(|s| s.self_ty);
+    let rebuild_self_info = |t| self_info.map(|s| {self_ty: t, ..*s});
 
-    let mut all_tys = ty::tys_in_fn_ty(fn_ty);
+    let mut all_tys = ty::tys_in_fn_sig(fn_sig);
 
     match self_info {
-      Some({explicit_self: {node: ast::sty_region(m), _}, _}) => {
+      Some({explicit_self: ast::spanned { node: ast::sty_region(m),
+                                          _}, _}) => {
         let region = ty::re_bound(ty::br_self);
         let ty = ty::mk_rptr(tcx, region,
                              { ty: ty::mk_self(tcx), mutbl: m });
@@ -47,10 +72,10 @@ fn replace_bound_regions_in_fn_ty(
 
     for self_ty.each |t| { all_tys.push(*t) }
 
-    debug!("replace_bound_regions_in_fn_ty(self_info.self_ty=%?, fn_ty=%s, \
-                all_tys=%?)",
+    debug!("replace_bound_regions_in_fn_sig(self_info.self_ty=%?, fn_sig=%s, \
+            all_tys=%?)",
            self_ty.map(|t| ppaux::ty_to_str(tcx, *t)),
-           ppaux::ty_to_str(tcx, ty::mk_fn(tcx, *fn_ty)),
+           ppaux::fn_sig_to_str(tcx, fn_sig),
            all_tys.map(|t| ppaux::ty_to_str(tcx, *t)));
     let _i = indenter();
 
@@ -58,17 +83,15 @@ fn replace_bound_regions_in_fn_ty(
         debug!("br=%?", br);
         mapf(br)
     };
-    let ty_fn = ty::ty_fn(*fn_ty);
-    let t_fn = ty::fold_sty_to_ty(tcx, &ty_fn, |t| {
+    let new_fn_sig = ty::fold_sig(fn_sig, |t| {
         replace_bound_regions(tcx, isr, t)
     });
     let t_self = self_ty.map(|t| replace_bound_regions(tcx, isr, *t));
 
-    debug!("result of replace_bound_regions_in_fn_ty: self_info.self_ty=%?, \
-                fn_ty=%s",
+    debug!("result of replace_bound_regions_in_fn_sig: self_info.self_ty=%?, \
+                fn_sig=%s",
            t_self.map(|t| ppaux::ty_to_str(tcx, *t)),
-           ppaux::ty_to_str(tcx, t_fn));
-
+           ppaux::fn_sig_to_str(tcx, &new_fn_sig));
 
     // Glue updated self_ty back together with its original def_id.
     let new_self_info: Option<self_info> = match t_self {
@@ -77,10 +100,8 @@ fn replace_bound_regions_in_fn_ty(
     };
 
     return {isr: isr,
-         self_info: new_self_info,
-         fn_ty: match ty::get(t_fn).sty { ty::ty_fn(ref o) => (*o),
-          _ => tcx.sess.bug(~"replace_bound_regions_in_fn_ty: impossible")}};
-
+            self_info: new_self_info,
+            fn_sig: new_fn_sig};
 
     // Takes `isr`, a (possibly empty) mapping from in-scope region
     // names ("isr"s) to their corresponding regions; `tys`, a list of
@@ -149,7 +170,7 @@ fn replace_bound_regions(
         ty: ty::t) -> ty::t {
 
         do ty::fold_regions(tcx, ty) |r, in_fn| {
-            match r {
+            let r1 = match r {
               // As long as we are not within a fn() type, `&T` is
               // mapped to the free region anon_r.  But within a fn
               // type, it remains bound.
@@ -178,7 +199,8 @@ fn replace_bound_regions(
               ty::re_scope(_) |
               ty::re_free(_, _) |
               ty::re_infer(_) => r
-            }
+            };
+            r1
         }
     }
 }
index 5751a462760641127c5e6df39ba7ba2ca77ce540..9d309d4996bdd9ffaac0c24e902941f7513459a9 100644 (file)
@@ -8,15 +8,32 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use middle::resolve;
+use middle::ty;
 use middle::typeck::check::{fn_ctxt, impl_self_ty};
-use middle::typeck::infer::{fixup_err_to_str, infer_ctxt};
+use middle::typeck::check::{structurally_resolved_type};
+use middle::typeck::infer::{fixup_err_to_str, InferCtxt};
 use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type};
+use middle::typeck::infer;
+use middle::typeck::{crate_ctxt, vtable_origin, vtable_param, vtable_res};
+use middle::typeck::{vtable_static, vtable_trait};
 use util::common::indenter;
+use util::ppaux::tys_to_str;
 use util::ppaux;
 
+use core::result;
+use core::uint;
+use core::vec;
 use result::{Result, Ok, Err};
+use std::map::HashMap;
+use syntax::ast;
+use syntax::ast_util;
 use syntax::codemap::span;
+use syntax::print::pprust::expr_to_str;
 use syntax::print::pprust;
+use syntax::visit;
 
 // vtable resolution looks for places where trait bounds are
 // subsituted in and figures out which vtable is used. There is some
@@ -46,7 +63,7 @@ struct LocationInfo {
 /// callback function to call in case of type error.
 struct VtableContext {
     ccx: @crate_ctxt,
-    infcx: infer::infer_ctxt
+    infcx: @infer::InferCtxt
 }
 
 impl VtableContext {
@@ -86,7 +103,7 @@ fn lookup_vtables(vcx: &VtableContext,
                    ppaux::ty_to_str(tcx, trait_ty),
                    ty::substs_to_str(tcx, substs));
 
-            let new_substs = {self_ty: Some(*ty), ..*substs};
+            let new_substs = {self_ty: Some(*ty), ../*bad*/copy *substs};
             let trait_ty = ty::subst(tcx, &new_substs, trait_ty);
 
             debug!("after subst: %?",
@@ -120,14 +137,14 @@ trait %s for %s",
 }
 
 fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo,
-                id: ast::def_id, substs: ty::substs,
+                id: ast::def_id, +substs: ty::substs,
                 is_early: bool) -> Option<ty::substs> {
     let tcx = vcx.tcx();
     // use a dummy type just to package up the substs that need fixing up
     let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static));
     do fixup_ty(vcx, location_info, t, is_early).map |t_f| {
         match ty::get(*t_f).sty {
-          ty::ty_trait(_, ref substs_f, _) => (*substs_f),
+          ty::ty_trait(_, ref substs_f, _) => (/*bad*/copy *substs_f),
           _ => fail ~"t_f should be a trait"
         }
     }
@@ -153,7 +170,8 @@ fn lookup_vtable(vcx: &VtableContext,
 
     let tcx = vcx.tcx();
     let (trait_id, trait_substs, trait_vstore) = match ty::get(trait_ty).sty {
-        ty::ty_trait(did, ref substs, vstore) => (did, (*substs), vstore),
+        ty::ty_trait(did, ref substs, vstore) =>
+            (did, (/*bad*/copy *substs), vstore),
         _ => tcx.sess.impossible_case(location_info.span,
                                       "lookup_vtable: \
                                        don't know how to handle a non-trait")
@@ -212,7 +230,7 @@ fn lookup_vtable(vcx: &VtableContext,
             relate_trait_tys(vcx, location_info, trait_ty, ty);
             if !allow_unsafe && !is_early {
                 for vec::each(*ty::trait_methods(tcx, did)) |m| {
-                    if ty::type_has_self(ty::mk_fn(tcx, m.fty)) {
+                    if ty::type_has_self(ty::mk_fn(tcx, /*bad*/copy m.fty)) {
                         tcx.sess.span_err(
                             location_info.span,
                             ~"a boxed trait with self types may not be \
@@ -226,7 +244,7 @@ fn lookup_vtable(vcx: &VtableContext,
                     }
                 }
             }
-            return Some(vtable_trait(did, (*substs).tps));
+            return Some(vtable_trait(did, /*bad*/copy (*substs).tps));
         }
 
         _ => {
@@ -340,7 +358,7 @@ fn lookup_vtable(vcx: &VtableContext,
                             // trait_substs. Now we extract out the
                             // types themselves from trait_substs.
 
-                            let trait_tps = trait_substs.tps;
+                            let trait_tps = /*bad*/copy trait_substs.tps;
 
                             debug!("Casting to a trait ty whose substs \
                                     (trait_tps) are %s",
@@ -359,7 +377,7 @@ fn lookup_vtable(vcx: &VtableContext,
                                                               trait_id,
                                                               substs,
                                                               is_early) {
-                                Some(ref substs) => (*substs),
+                                Some(ref substs) => (/*bad*/copy *substs),
                                 None => {
                                     assert is_early;
                                     // Bail out with a bogus answer
@@ -384,7 +402,7 @@ fn lookup_vtable(vcx: &VtableContext,
                                                              im.did).bounds;
                             connect_trait_tps(vcx,
                                               location_info,
-                                              substs_f.tps,
+                                              /*bad*/copy substs_f.tps,
                                               trait_tps,
                                               im.did,
                                               trait_vstore);
@@ -398,7 +416,8 @@ fn lookup_vtable(vcx: &VtableContext,
                             // of type substitutions for the target
                             // trait.
                             found.push(
-                                vtable_static(im.did, substs_f.tps,
+                                vtable_static(im.did,
+                                              /*bad*/copy substs_f.tps,
                                               subres));
                         }
                     }
@@ -407,14 +426,14 @@ fn lookup_vtable(vcx: &VtableContext,
 
             match found.len() {
                 0 => { /* fallthrough */ }
-                1 => { return Some(found[0]); }
+                1 => { return Some(/*bad*/copy found[0]); }
                 _ => {
                     if !is_early {
                         vcx.tcx().sess.span_err(
                             location_info.span,
                             ~"multiple applicable methods in scope");
                     }
-                    return Some(found[0]);
+                    return Some(/*bad*/copy found[0]);
                 }
             }
         }
@@ -509,7 +528,7 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
             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));
-            if has_trait_bounds(*item_ty.bounds) {
+            if has_trait_bounds(/*bad*/copy *item_ty.bounds) {
                 for item_ty.bounds.each |bounds| {
                     debug!("early_resolve_expr: looking up vtables for bound \
                             %s",
@@ -536,7 +555,7 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
       ast::expr_index(*) | ast::expr_method_call(*) => {
         match ty::method_call_bounds(cx.tcx, cx.method_map, ex.id) {
           Some(bounds) => {
-            if has_trait_bounds(*bounds) {
+            if has_trait_bounds(/*bad*/copy *bounds) {
                 let callee_id = match ex.node {
                   ast::expr_field(_, _, _) => ex.id,
                   _ => ex.callee_id
@@ -666,8 +685,8 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
                             ex.span,
                             fmt!("failed to find an implementation of trait \
                                   %s for %s",
-                                 ppaux::ty_to_str(fcx.tcx(), target_ty),
-                                 ppaux::ty_to_str(fcx.tcx(), ty)));
+                                 fcx.infcx().ty_to_str(target_ty),
+                                 fcx.infcx().ty_to_str(ty)));
                     }
                 }
                 Some(vtable) => {
@@ -695,7 +714,7 @@ fn resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, v: visit::vt<@fn_ctxt>) {
 // Detect points where a trait-bounded type parameter is
 // instantiated, resolve the impls for the parameters.
 fn resolve_in_block(fcx: @fn_ctxt, bl: ast::blk) {
-    visit::visit_block(bl, fcx, visit::mk_vt(@{
+    visit::visit_block(bl, fcx, visit::mk_vt(@visit::Visitor {
         visit_expr: resolve_expr,
         visit_item: fn@(_i: @ast::item, &&_e: @fn_ctxt,
                         _v: visit::vt<@fn_ctxt>) {},
index dd3f240f3434326e041bb05628780a7c080d19da..b00a3306ceb03d7f84e18e1b9c314413c7a9cb0e 100644 (file)
 // unresolved type variables and replaces "ty_var" types with their
 // substitutions.
 
-use middle::typeck::check::{fn_ctxt, lookup_local};
+use core::prelude::*;
+
+use middle::pat_util;
+use middle::ty;
+use middle::typeck::check::{fn_ctxt, lookup_local, self_info};
 use middle::typeck::infer::{force_all, resolve_all, resolve_region};
 use middle::typeck::infer::{resolve_type};
+use middle::typeck::infer;
+use middle::typeck::{vtable_param, vtable_trait, write_substs_to_tcx};
+use middle::typeck::{write_ty_to_tcx};
 use util::ppaux;
 
-use result::{Result, Ok, Err};
+use core::result::{Result, Ok, Err};
+use core::vec;
+use std::map::HashMap;
+use syntax::ast;
+use syntax::codemap::span;
+use syntax::print::pprust::pat_to_str;
+use syntax::visit;
 
 export resolve_type_vars_in_fn;
 export resolve_type_vars_in_expr;
@@ -149,8 +162,7 @@ fn visit_expr(e: @ast::expr, wbcx: wb_ctxt, v: wb_vt) {
     resolve_method_map_entry(wbcx.fcx, e.span, e.id);
     resolve_method_map_entry(wbcx.fcx, e.span, e.callee_id);
     match e.node {
-      ast::expr_fn(_, decl, _, _) |
-      ast::expr_fn_block(decl, _, _) => {
+      ast::expr_fn_block(ref decl, _, _) => {
           for vec::each(decl.inputs) |input| {
               let r_ty = resolve_type_vars_for_node(wbcx, e.span, input.id);
 
@@ -224,13 +236,13 @@ fn visit_item(_item: @ast::item, _wbcx: wb_ctxt, _v: wb_vt) {
 }
 
 fn mk_visitor() -> visit::vt<wb_ctxt> {
-    visit::mk_vt(@{visit_item: visit_item,
-                   visit_stmt: visit_stmt,
-                   visit_expr: visit_expr,
-                   visit_block: visit_block,
-                   visit_pat: visit_pat,
-                   visit_local: visit_local,
-                   .. *visit::default_visitor()})
+    visit::mk_vt(@visit::Visitor {visit_item: visit_item,
+                                  visit_stmt: visit_stmt,
+                                  visit_expr: visit_expr,
+                                  visit_block: visit_block,
+                                  visit_pat: visit_pat,
+                                  visit_local: visit_local,
+                                  .. *visit::default_visitor()})
 }
 
 fn resolve_type_vars_in_expr(fcx: @fn_ctxt, e: @ast::expr) -> bool {
@@ -241,7 +253,7 @@ fn resolve_type_vars_in_expr(fcx: @fn_ctxt, e: @ast::expr) -> bool {
 }
 
 fn resolve_type_vars_in_fn(fcx: @fn_ctxt,
-                           decl: ast::fn_decl,
+                           decl: &ast::fn_decl,
                            blk: ast::blk,
                            self_info: Option<self_info>) -> bool {
     let wbcx = {fcx: fcx, mut success: true};
index 15edea5213934296ae24dc878c0d4db68ee0742e..9fa78f01265dfdaebfeb8fdaeaa7005cf38bbd4c 100644 (file)
 // has at most one implementation for each type. Then we build a mapping from
 // each trait in the system to its implementations.
 
+use core::prelude::*;
+
+use driver;
 use metadata::csearch::{ProvidedTraitMethodInfo, each_path, get_impl_traits};
 use metadata::csearch::{get_impls_for_mod};
+use metadata::csearch;
 use metadata::cstore::{CStore, iter_crate_data};
 use metadata::decoder::{dl_def, dl_field, dl_impl};
 use middle::resolve::{Impl, MethodInfo};
 use middle::ty::{ProvidedMethodSource, ProvidedMethodInfo, bound_copy, get};
 use middle::ty::{kind_can_be_copied, lookup_item_type, param_bounds, subst};
 use middle::ty::{t, ty_bool, ty_bot, ty_box, ty_enum, ty_err, ty_estr};
-use middle::ty::{ty_evec, ty_float, ty_fn, ty_infer, ty_int, ty_nil, ty_ptr};
-use middle::ty::{ty_rec, ty_rptr, ty_struct, ty_trait, ty_tup, ty_uint};
-use middle::ty::{ty_param, ty_self, ty_type, ty_opaque_box, ty_uniq};
+use middle::ty::{ty_evec, ty_float, ty_fn, ty_infer, ty_int, ty_nil};
+use middle::ty::{ty_opaque_box, ty_param, ty_param_bounds_and_ty, ty_ptr};
+use middle::ty::{ty_rec, ty_rptr, ty_self, ty_struct, ty_trait, ty_tup};
+use middle::ty::{ty_type, ty_uint, ty_uniq};
 use middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec, type_kind_ext};
 use middle::ty::{type_is_ty_var};
-use middle::typeck::infer::{infer_ctxt, can_mk_subty};
+use middle::ty;
+use middle::typeck::crate_ctxt;
+use middle::typeck::infer::{InferCtxt, can_mk_subty};
 use middle::typeck::infer::{new_infer_ctxt, resolve_ivar};
 use middle::typeck::infer::{resolve_nested_tvar, resolve_type};
 use syntax::ast::{crate, def_id, def_mod, def_ty};
 use syntax::ast::{item_foreign_mod, item_impl, item_mac, item_mod};
 use syntax::ast::{item_trait, item_ty, local_crate, method, node_id};
 use syntax::ast::{trait_ref};
+use syntax::ast;
 use syntax::ast_map::node_item;
-use syntax::ast_util::{def_id_of_def, dummy_sp};
+use syntax::ast_map;
+use syntax::ast_util::{def_id_of_def, dummy_sp, local_def};
 use syntax::attr;
 use syntax::codemap::span;
+use syntax::parse;
 use syntax::visit::{default_simple_visitor, default_visitor};
 use syntax::visit::{mk_simple_visitor, mk_vt, visit_crate, visit_item};
+use syntax::visit::{Visitor, SimpleVisitor};
 use syntax::visit::{visit_mod};
 use util::ppaux::ty_to_str;
 
 use core::dvec::DVec;
 use core::result::Ok;
-use std::map::HashMap;
+use core::send_map;
 use core::uint::range;
+use core::uint;
 use core::vec::{len, push};
+use core::vec;
+use std::map::HashMap;
 
 struct UniversalQuantificationResult {
     monotype: t,
@@ -56,7 +70,7 @@ struct UniversalQuantificationResult {
     bounds: @~[param_bounds]
 }
 
-fn get_base_type(inference_context: infer_ctxt, span: span, original_type: t)
+fn get_base_type(inference_context: @InferCtxt, span: span, original_type: t)
               -> Option<t> {
 
     let resolved_type;
@@ -103,7 +117,7 @@ fn get_base_type(inference_context: infer_ctxt, span: span, original_type: t)
 }
 
 // Returns the def ID of the base type, if there is one.
-fn get_base_type_def_id(inference_context: infer_ctxt,
+fn get_base_type_def_id(inference_context: @InferCtxt,
                         span: span,
                         original_type: t)
                      -> Option<def_id> {
@@ -168,7 +182,7 @@ fn CoherenceChecker(crate_context: @crate_ctxt) -> CoherenceChecker {
 
 struct CoherenceChecker {
     crate_context: @crate_ctxt,
-    inference_context: infer_ctxt,
+    inference_context: @InferCtxt,
 
     // A mapping from implementations to the corresponding base type
     // definition ID.
@@ -186,7 +200,7 @@ fn check_coherence(crate: @crate) {
         // Check implementations and traits. This populates the tables
         // containing the inherent methods and extension methods. It also
         // builds up the trait inheritance table.
-        visit_crate(*crate, (), mk_simple_visitor(@{
+        visit_crate(*crate, (), mk_simple_visitor(@SimpleVisitor {
             visit_item: |item| {
                 debug!("(checking coherence) item '%s'",
                        self.crate_context.tcx.sess.str_of(item.ident));
@@ -307,7 +321,7 @@ fn instantiate_default_methods(impl_id: ast::node_id,
         for self.each_provided_trait_method(trait_did) |trait_method| {
             // Synthesize an ID.
             let tcx = self.crate_context.tcx;
-            let new_id = syntax::parse::next_node_id(tcx.sess.parse_sess);
+            let new_id = parse::next_node_id(tcx.sess.parse_sess);
             let new_did = local_def(new_id);
 
             // XXX: Perform substitutions.
@@ -501,10 +515,13 @@ fn universally_quantify_polytype(polytype: ty_param_bounds_and_ty)
             self_ty: None,
             tps: type_parameters
         };
-
         let monotype = subst(self.crate_context.tcx,
                              &substitutions,
                              polytype.ty);
+
+        // Get our type parameters back.
+        let { self_r: _, self_ty: _, tps: type_parameters } = substitutions;
+
         UniversalQuantificationResult {
             monotype: monotype,
             type_variables: move type_parameters,
@@ -572,9 +589,9 @@ fn get_self_type_for_implementation(implementation: @Impl)
 
     // Privileged scope checking
     fn check_privileged_scopes(crate: @crate) {
-        visit_crate(*crate, (), mk_vt(@{
+        visit_crate(*crate, (), mk_vt(@Visitor {
             visit_item: |item, _context, visitor| {
-                match item.node {
+                match /*bad*/copy item.node {
                     item_mod(module_) => {
                         // Then visit the module items.
                         visit_mod(module_, item.span, item.id, (), visitor);
@@ -708,7 +725,7 @@ fn add_provided_methods(all_methods: &mut ~[@MethodInfo],
             }
         }
 
-        match item.node {
+        match /*bad*/copy item.node {
             item_impl(_, trait_refs, _, ast_methods) => {
                 let mut methods = ~[];
                 for ast_methods.each |ast_method| {
@@ -883,7 +900,7 @@ fn add_default_methods_for_external_trait(trait_def_id: ast::def_id) {
 
             // Create a new def ID for this provided method.
             let parse_sess = &self.crate_context.tcx.sess.parse_sess;
-            let new_did = local_def(syntax::parse::next_node_id(*parse_sess));
+            let new_did = local_def(parse::next_node_id(*parse_sess));
 
             let provided_method_info =
                 @ProvidedMethodInfo {
@@ -947,7 +964,7 @@ fn add_external_crates() {
     fn populate_destructor_table() {
         let coherence_info = &self.crate_context.coherence_info;
         let tcx = self.crate_context.tcx;
-        let drop_trait = tcx.lang_items.drop_trait.get();
+        let drop_trait = tcx.lang_items.drop_trait();
         let impls_opt = coherence_info.extension_methods.find(drop_trait);
 
         let impls;
index b4ba9c3d6544727eeecfbf7c462e31ee2efe1e6b..3743a5e0129115875312337916bb02bbb89188af 100644 (file)
 
 */
 
+use core::prelude::*;
+
+use metadata::csearch;
 use middle::ty::{FnMeta, FnSig, FnTyBase, InstantiatedTraitRef};
+use middle::ty::{ty_param_substs_and_ty};
+use middle::ty;
 use middle::typeck::astconv::{ast_conv, ty_of_fn_decl, ty_of_arg};
 use middle::typeck::astconv::{ast_ty_to_ty};
+use middle::typeck::astconv;
+use middle::typeck::infer;
 use middle::typeck::rscope::*;
-use util::common::pluralize;
+use middle::typeck::rscope;
+use middle::typeck::{crate_ctxt, lookup_def_tcx, no_params, write_ty_to_tcx};
+use util::common::{indenter, pluralize};
 use util::ppaux;
 use util::ppaux::bound_to_str;
 
-use syntax::ast_util::trait_method_to_ty_method;
+use core::dvec;
+use core::option;
+use core::vec;
+use syntax::ast::{RegionTyParamBound, TraitTyParamBound};
+use syntax::ast;
+use syntax::ast_map;
+use syntax::ast_util::{local_def, split_trait_methods};
+use syntax::ast_util::{trait_method_to_ty_method};
+use syntax::ast_util;
+use syntax::codemap::span;
+use syntax::codemap;
+use syntax::print::pprust::path_to_str;
+use syntax::visit;
 
 fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
 
@@ -47,9 +68,9 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
 
     for crate.node.module.items.each |crate_item| {
         if crate_item.ident
-            == syntax::parse::token::special_idents::intrinsic {
+            == ::syntax::parse::token::special_idents::intrinsic {
 
-            match crate_item.node {
+            match /*bad*/copy crate_item.node {
               ast::item_mod(m) => {
                 for m.items.each |intrinsic_item| {
                     let def_id = { crate: ast::local_crate,
@@ -80,11 +101,13 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
         }
     }
 
-    visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
-        visit_item: |a|convert(ccx, a),
-        visit_foreign_item: |a|convert_foreign(ccx, a),
-        .. *visit::default_simple_visitor()
-    }));
+    visit::visit_crate(
+        *crate, (),
+        visit::mk_simple_visitor(@visit::SimpleVisitor {
+            visit_item: |a|convert(ccx, a),
+            visit_foreign_item: |a|convert_foreign(ccx, a),
+            .. *visit::default_simple_visitor()
+        }));
 }
 
 impl @crate_ctxt {
@@ -137,7 +160,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
         // constructors get turned into functions.
         let result_ty;
         match variant.node.kind {
-            ast::tuple_variant_kind(args) if args.len() > 0 => {
+            ast::tuple_variant_kind(ref args) if args.len() > 0 => {
                 let rs = type_rscope(rp);
                 let args = args.map(|va| {
                     let arg_ty = ccx.to_ty(rs, va.ty);
@@ -148,8 +171,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
                                   proto: ast::ProtoBare,
                                   onceness: ast::Many,
                                   bounds: @~[],
-                                  region: ty::re_static,
-                                  ret_style: ast::return_val},
+                                  region: ty::re_static},
                     sig: FnSig {inputs: args,
                                 output: enum_ty}
                 }));
@@ -158,19 +180,38 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
                 result_ty = Some(enum_ty);
             }
             ast::struct_variant_kind(struct_def) => {
-                result_ty = Some(enum_ty);
                 // XXX: Merge with computation of the the same value below?
-                let tpt = {bounds: ty_param_bounds(ccx, ty_params),
-                           region_param: rp,
-                           ty: enum_ty};
+                let tpt = {
+                    bounds: ty_param_bounds(ccx, /*bad*/copy ty_params),
+                    region_param: rp,
+                    ty: enum_ty
+                };
                 convert_struct(
-                    ccx, rp, struct_def, ty_params, tpt, variant.node.id);
+                    ccx,
+                    rp,
+                    struct_def,
+                    /*bad*/copy ty_params,
+                    tpt,
+                    variant.node.id);
+                // Compute the ctor arg types from the struct fields
+                let struct_fields = do struct_def.fields.map |struct_field| {
+                    {mode: ast::expl(ast::by_val),
+                     ty: ty::node_id_to_type(ccx.tcx, (*struct_field).node.id)
+                    }
+                };
+                result_ty = Some(ty::mk_fn(tcx, FnTyBase {
+                    meta: FnMeta {purity: ast::pure_fn,
+                                  proto: ast::ProtoBare,
+                                  onceness: ast::Many,
+                                  bounds: @~[],
+                                  region: ty::re_static},
+                    sig: FnSig {inputs: struct_fields, output: enum_ty }}));
             }
             ast::enum_variant_kind(ref enum_definition) => {
                 get_enum_variant_types(ccx,
                                        enum_ty,
-                                       enum_definition.variants,
-                                       ty_params,
+                                       /*bad*/copy enum_definition.variants,
+                                       /*bad*/copy ty_params,
                                        rp);
                 result_ty = None;
             }
@@ -179,9 +220,11 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
         match result_ty {
             None => {}
             Some(result_ty) => {
-                let tpt = {bounds: ty_param_bounds(ccx, ty_params),
-                           region_param: rp,
-                           ty: result_ty};
+                let tpt = {
+                    bounds: ty_param_bounds(ccx, /*bad*/copy ty_params),
+                    region_param: rp,
+                    ty: result_ty
+                };
                 tcx.tcache.insert(local_def(variant.node.id), tpt);
                 write_ty_to_tcx(tcx, variant.node.id, result_ty);
             }
@@ -191,7 +234,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
 
 fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id, trait_ty: ty::t) {
     fn store_methods<T>(ccx: @crate_ctxt, id: ast::node_id,
-                        stuff: ~[T], f: fn@(v: &T) -> ty::method) {
+                        stuff: ~[T], f: &fn(v: &T) -> ty::method) {
         ty::store_trait_methods(ccx.tcx, id, @vec::map(stuff, f));
     }
 
@@ -224,7 +267,9 @@ fn make_static_method_ty(ccx: @crate_ctxt,
 
         let substs = { self_r: None, self_ty: Some(self_param),
                        tps: non_shifted_trait_tps + shifted_method_tps };
-        let ty = ty::subst(ccx.tcx, &substs, ty::mk_fn(ccx.tcx, m.fty));
+        let ty = ty::subst(ccx.tcx,
+                           &substs,
+                           ty::mk_fn(ccx.tcx, /*bad*/copy m.fty));
         let bounds = @(*trait_bounds + ~[@~[ty::bound_trait(trait_ty)]]
                        + *m.tps);
         ccx.tcx.tcache.insert(local_def(am.id),
@@ -238,10 +283,10 @@ fn make_static_method_ty(ccx: @crate_ctxt,
     let region_paramd = tcx.region_paramd_items.find(id);
     match tcx.items.get(id) {
       ast_map::node_item(@{
-                node: ast::item_trait(params, _, ref ms),
+                node: ast::item_trait(ref params, _, ref ms),
                 _
             }, _) => {
-        store_methods::<ast::trait_method>(ccx, id, (*ms), |m| {
+        store_methods::<ast::trait_method>(ccx, id, (/*bad*/copy *ms), |m| {
             let def_id;
             match *m {
                 ast::required(ref ty_method) => {
@@ -250,7 +295,7 @@ fn make_static_method_ty(ccx: @crate_ctxt,
                 ast::provided(method) => def_id = local_def(method.id)
             }
 
-            let trait_bounds = ty_param_bounds(ccx, params);
+            let trait_bounds = ty_param_bounds(ccx, copy *params);
             let ty_m = trait_method_to_ty_method(*m);
             let method_ty = ty_of_ty_method(ccx, ty_m, region_paramd, def_id);
             if ty_m.self_ty.node == ast::sty_static {
@@ -404,7 +449,7 @@ fn compare_impl_method(tcx: ty::ctxt,
     //   that correspond to the parameters we will find on the impl
     // - replace self region with a fresh, dummy region
     let impl_fty = {
-        let impl_fty = ty::mk_fn(tcx, impl_m.fty);
+        let impl_fty = ty::mk_fn(tcx, /*bad*/copy impl_m.fty);
         debug!("impl_fty (pre-subst): %s", ppaux::ty_to_str(tcx, impl_fty));
         replace_bound_self(tcx, impl_fty, dummy_self_r)
     };
@@ -422,7 +467,7 @@ fn compare_impl_method(tcx: ty::ctxt,
             self_ty: Some(self_ty),
             tps: vec::append(trait_tps, dummy_tps)
         };
-        let trait_fty = ty::mk_fn(tcx, trait_m.fty);
+        let trait_fty = ty::mk_fn(tcx, /*bad*/copy trait_m.fty);
         debug!("trait_fty (pre-subst): %s", ppaux::ty_to_str(tcx, trait_fty));
         ty::subst(tcx, &substs, trait_fty)
     };
@@ -528,15 +573,15 @@ fn convert_methods(ccx: @crate_ctxt,
 
     let tcx = ccx.tcx;
     do vec::map(ms) |m| {
-        let bounds = ty_param_bounds(ccx, m.tps);
+        let bounds = ty_param_bounds(ccx, /*bad*/copy m.tps);
         let mty = ty_of_method(ccx, *m, rp);
-        let fty = ty::mk_fn(tcx, mty.fty);
+        let fty = ty::mk_fn(tcx, /*bad*/copy mty.fty);
         tcx.tcache.insert(
             local_def(m.id),
 
             // n.b.: the type of a method is parameterized by both
             // the tps on the receiver and those on the method itself
-            {bounds: @(vec::append(*rcvr_bounds, *bounds)),
+            {bounds: @(vec::append(/*bad*/copy *rcvr_bounds, *bounds)),
              region_param: rp,
              ty: fty});
         write_ty_to_tcx(tcx, m.id, fty);
@@ -550,17 +595,19 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
     let rp = tcx.region_paramd_items.find(it.id);
     debug!("convert: item %s with id %d rp %?",
            tcx.sess.str_of(it.ident), it.id, rp);
-    match it.node {
+    match /*bad*/copy it.node {
       // These don't define types.
       ast::item_foreign_mod(_) | ast::item_mod(_) => {}
-      ast::item_enum(ref enum_definition, ty_params) => {
+      ast::item_enum(ref enum_definition, ref ty_params) => {
         let tpt = ty_of_item(ccx, it);
         write_ty_to_tcx(tcx, it.id, tpt.ty);
-        get_enum_variant_types(ccx, tpt.ty, (*enum_definition).variants,
-                               ty_params, rp);
+        get_enum_variant_types(ccx,
+                               tpt.ty,
+                               /*bad*/copy (*enum_definition).variants,
+                               /*bad*/copy *ty_params, rp);
       }
-      ast::item_impl(tps, trait_ref, selfty, ms) => {
-        let i_bounds = ty_param_bounds(ccx, tps);
+      ast::item_impl(ref tps, trait_ref, selfty, ref ms) => {
+        let i_bounds = ty_param_bounds(ccx, /*bad*/copy *tps);
         let selfty = ccx.to_ty(type_rscope(rp), selfty);
         write_ty_to_tcx(tcx, it.id, selfty);
         tcx.tcache.insert(local_def(it.id),
@@ -568,21 +615,24 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
                            region_param: rp,
                            ty: selfty});
 
-        let cms = convert_methods(ccx, ms, rp, i_bounds);
+        // XXX: Bad copy of `ms` below.
+        let cms = convert_methods(ccx, /*bad*/copy *ms, rp, i_bounds);
         for trait_ref.each |t| {
-            check_methods_against_trait(ccx, tps, rp, selfty, *t, cms);
+            check_methods_against_trait(ccx, /*bad*/copy *tps, rp, selfty,
+                                        *t, /*bad*/copy cms);
         }
       }
-      ast::item_trait(tps, supertraits, ref trait_methods) => {
+      ast::item_trait(ref tps, ref supertraits, ref trait_methods) => {
         let tpt = ty_of_item(ccx, it);
         debug!("item_trait(it.id=%d, tpt.ty=%s)",
                it.id, ppaux::ty_to_str(tcx, tpt.ty));
         write_ty_to_tcx(tcx, it.id, tpt.ty);
         ensure_trait_methods(ccx, it.id, tpt.ty);
-        ensure_supertraits(ccx, it.id, it.span, rp, supertraits);
+        ensure_supertraits(ccx, it.id, it.span, rp, *supertraits);
 
-        let (_, provided_methods) = split_trait_methods((*trait_methods));
-        let {bounds, _} = mk_substs(ccx, tps, rp);
+        let (_, provided_methods) =
+            split_trait_methods(/*bad*/copy *trait_methods);
+        let {bounds, _} = mk_substs(ccx, /*bad*/copy *tps, rp);
         let _cms = convert_methods(ccx, provided_methods, rp, bounds);
         // FIXME (#2616): something like this, when we start having
         // trait inheritance?
@@ -611,7 +661,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
 fn convert_struct(ccx: @crate_ctxt,
                   rp: Option<ty::region_variance>,
                   struct_def: @ast::struct_def,
-                  tps: ~[ast::ty_param],
+                  +tps: ~[ast::ty_param],
                   tpt: ty::ty_param_bounds_and_ty,
                   id: ast::node_id) {
     let tcx = ccx.tcx;
@@ -656,8 +706,7 @@ fn convert_struct(ccx: @crate_ctxt,
                         proto: ast::ProtoBare,
                         onceness: ast::Many,
                         bounds: @~[],
-                        region: ty::re_static,
-                        ret_style: ast::return_val,
+                        region: ty::re_static
                     },
                     sig: FnSig {
                         inputs: do struct_def.fields.map |field| {
@@ -694,7 +743,7 @@ fn ty_of_method(ccx: @crate_ctxt,
                 m: @ast::method,
                 rp: Option<ty::region_variance>) -> ty::method {
     {ident: m.ident,
-     tps: ty_param_bounds(ccx, m.tps),
+     tps: ty_param_bounds(ccx, /*bad*/copy m.tps),
      fty: ty_of_fn_decl(ccx, type_rscope(rp), ast::ProtoBare,
                         m.purity, ast::Many,
                         /*bounds:*/ @~[], /*opt_region:*/ None,
@@ -709,7 +758,7 @@ fn ty_of_ty_method(self: @crate_ctxt,
                    rp: Option<ty::region_variance>,
                    id: ast::def_id) -> ty::method {
     {ident: m.ident,
-     tps: ty_param_bounds(self, m.tps),
+     tps: ty_param_bounds(self, /*bad*/copy m.tps),
      fty: ty_of_fn_decl(self, type_rscope(rp), ast::ProtoBare,
                         m.purity, ast::Many,
                         /*bounds:*/ @~[], /*opt_region:*/ None,
@@ -759,7 +808,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
       _ => {}
     }
     let rp = tcx.region_paramd_items.find(it.id);
-    match it.node {
+    match /*bad*/copy it.node {
       ast::item_const(t, _) => {
         let typ = ccx.to_ty(empty_rscope, t);
         let tpt = no_params(typ);
@@ -844,7 +893,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
 
 fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
     -> ty::ty_param_bounds_and_ty {
-    match it.node {
+    match /*bad*/copy it.node {
       ast::foreign_item_fn(fn_decl, purity, params) => {
         return ty_of_foreign_fn_decl(ccx, fn_decl, purity, params,
                                      local_def(it.id));
@@ -860,41 +909,42 @@ fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
     }
 }
 
-// Translate the AST's notion of ty param bounds (which are just newtyped Tys)
-// to ty's notion of ty param bounds, which can either be user-defined traits,
-// or one of the four built-in traits (formerly known as kinds): Const, Copy,
-// Durable, and Send.
+// Translate the AST's notion of ty param bounds (which are an enum consisting
+// of a newtyped Ty or a region) to ty's notion of ty param bounds, which can
+// either be user-defined traits, or one of the four built-in traits (formerly
+// known as kinds): Const, Copy, Durable, and Send.
 fn compute_bounds(ccx: @crate_ctxt,
-                  ast_bounds: @~[ast::ty_param_bound]) -> ty::param_bounds {
+                  ast_bounds: @~[ast::ty_param_bound])
+               -> ty::param_bounds {
     @do vec::flat_map(*ast_bounds) |b| {
-        let li = &ccx.tcx.lang_items;
-        let ity = ast_ty_to_ty(ccx, empty_rscope, **b);
-        match ty::get(ity).sty {
-            ty::ty_trait(did, _, _) => {
-                let d = Some(did);
-                if d == li.owned_trait {
-                    ~[ty::bound_owned]
-                }
-                else if d == li.copy_trait {
-                    ~[ty::bound_copy]
-                }
-                else if d == li.const_trait {
-                    ~[ty::bound_const]
-                }
-                else if d == li.durable_trait {
-                    ~[ty::bound_durable]
-                }
-                else {
-                    // Must be a user-defined trait
-                    ~[ty::bound_trait(ity)]
+        match b {
+            &TraitTyParamBound(b) => {
+                let li = &ccx.tcx.lang_items;
+                let ity = ast_ty_to_ty(ccx, empty_rscope, b);
+                match ty::get(ity).sty {
+                    ty::ty_trait(did, _, _) => {
+                        if did == li.owned_trait() {
+                            ~[ty::bound_owned]
+                        } else if did == li.copy_trait() {
+                            ~[ty::bound_copy]
+                        } else if did == li.const_trait() {
+                            ~[ty::bound_const]
+                        } else if did == li.durable_trait() {
+                            ~[ty::bound_durable]
+                        } else {
+                            // Must be a user-defined trait
+                            ~[ty::bound_trait(ity)]
+                        }
+                    }
+                    _ => {
+                        ccx.tcx.sess.span_err(
+                            (*b).span, ~"type parameter bounds must be \
+                                         trait types");
+                        ~[]
+                    }
                 }
             }
-            _ => {
-                ccx.tcx.sess.span_err(
-                    (*b).span, ~"type parameter bounds must be \
-                                 trait types");
-                ~[]
-            }
+            &RegionTyParamBound => ~[ty::bound_durable]
         }
     }
 }
@@ -918,9 +968,8 @@ fn ty_param_bounds(ccx: @crate_ctxt,
 fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
                          decl: ast::fn_decl,
                          purity: ast::purity,
-                         ty_params: ~[ast::ty_param],
+                         +ty_params: ~[ast::ty_param],
                          def_id: ast::def_id) -> ty::ty_param_bounds_and_ty {
-
     let bounds = ty_param_bounds(ccx, ty_params);
     let rb = in_binding_rscope(empty_rscope);
     let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, rb, *a, None) );
@@ -931,8 +980,7 @@ fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
                       onceness: ast::Many,
                       proto: ast::ProtoBare,
                       bounds: @~[],
-                      region: ty::re_static,
-                      ret_style: ast::return_val},
+                      region: ty::re_static},
         sig: FnSig {inputs: input_tys,
                     output: output_ty}
     });
@@ -945,7 +993,8 @@ fn mk_ty_params(ccx: @crate_ctxt, atps: ~[ast::ty_param])
     -> {bounds: @~[ty::param_bounds], params: ~[ty::t]} {
 
     let mut i = 0u;
-    let bounds = ty_param_bounds(ccx, atps);
+    // XXX: Bad copy.
+    let bounds = ty_param_bounds(ccx, copy atps);
     {bounds: bounds,
      params: vec::map(atps, |atp| {
          let t = ty::mk_param(ccx.tcx, i, local_def(atp.id));
@@ -954,10 +1003,10 @@ fn mk_ty_params(ccx: @crate_ctxt, atps: ~[ast::ty_param])
      })}
 }
 
-fn mk_substs(ccx: @crate_ctxt, atps: ~[ast::ty_param],
+fn mk_substs(ccx: @crate_ctxt,
+             +atps: ~[ast::ty_param],
              rp: Option<ty::region_variance>)
-    -> {bounds: @~[ty::param_bounds], substs: ty::substs} {
-
+          -> {bounds: @~[ty::param_bounds], substs: ty::substs} {
     let {bounds, params} = mk_ty_params(ccx, atps);
     let self_r = rscope::bound_self_region(rp);
     {bounds: bounds, substs: {self_r: self_r, self_ty: None, tps: params}}
index 1abe2156a1ebb50fe8dda0363a134aeb09ae1369..62080f4db35887f1fe029487e585228f10c5711b 100644 (file)
 // A.  But this upper-bound might be stricter than what is truly
 // needed.
 
-use middle::typeck::infer::combine::combine_fields;
-use middle::typeck::infer::to_str::ToStr;
+use core::prelude::*;
 
-fn to_ares(+c: cres<ty::t>) -> ares {
+use middle::ty::TyVar;
+use middle::ty;
+use middle::typeck::infer::{ares, cres};
+use middle::typeck::infer::combine::CombineFields;
+use middle::typeck::infer::sub::Sub;
+use middle::typeck::infer::to_str::InferStr;
+use util::common::{indent, indenter};
+
+use core::option;
+use syntax::ast::{m_const, m_imm, m_mutbl};
+use syntax::ast;
+
+fn to_ares<T>(+c: cres<T>) -> ares {
     match c {
         Ok(_) => Ok(None),
         Err(ref e) => Err((*e))
@@ -71,16 +82,22 @@ fn to_ares(+c: cres<ty::t>) -> ares {
 // Note: Assign is not actually a combiner, in that it does not
 // conform to the same interface, though it performs a similar
 // function.
-enum Assign = combine_fields;
+enum Assign = CombineFields;
 
 impl Assign {
     fn tys(a: ty::t, b: ty::t) -> ares {
-        debug!("Assign.tys(%s -> %s)",
-               a.to_str(self.infcx),
-               b.to_str(self.infcx));
+        debug!("Assign.tys(%s => %s)",
+               a.inf_str(self.infcx),
+               b.inf_str(self.infcx));
         let _r = indenter();
 
-        match (ty::get(a).sty, ty::get(b).sty) {
+        debug!("Assign.tys: copying first type");
+        let copy_a = copy ty::get(a).sty;
+        debug!("Assign.tys: copying second type");
+        let copy_b = copy ty::get(b).sty;
+        debug!("Assign.tys: performing match");
+
+        let r = match (copy_a, copy_b) {
             (ty::ty_bot, _) => {
                 Ok(None)
             }
@@ -115,7 +132,11 @@ fn tys(a: ty::t, b: ty::t) -> ares {
             (_, _) => {
                 self.assign_tys_or_sub(a, b, Some(a), Some(b))
             }
-        }
+        };
+
+        debug!("Assign.tys end");
+
+        move r
     }
 }
 
@@ -124,9 +145,9 @@ fn assign_tys_or_sub(
         a: ty::t, b: ty::t,
         +a_bnd: Option<ty::t>, +b_bnd: Option<ty::t>) -> ares {
 
-        debug!("Assign.assign_tys_or_sub(%s -> %s, %s -> %s)",
-               a.to_str(self.infcx), b.to_str(self.infcx),
-               a_bnd.to_str(self.infcx), b_bnd.to_str(self.infcx));
+        debug!("Assign.assign_tys_or_sub(%s => %s, %s => %s)",
+               a.inf_str(self.infcx), b.inf_str(self.infcx),
+               a_bnd.inf_str(self.infcx), b_bnd.inf_str(self.infcx));
         let _r = indenter();
 
         fn is_borrowable(v: ty::vstore) -> bool {
@@ -146,7 +167,8 @@ fn borrowable_protos(a_p: ast::Proto, b_p: ast::Proto) -> bool {
 
         match (a_bnd, b_bnd) {
             (Some(a_bnd), Some(b_bnd)) => {
-                match (ty::get(a_bnd).sty, ty::get(b_bnd).sty) {
+                match (/*bad*/copy ty::get(a_bnd).sty,
+                       /*bad*/copy ty::get(b_bnd).sty) {
                     // check for a case where a non-region pointer (@, ~) is
                     // being assigned to a region pointer:
                     (ty::ty_box(_), ty::ty_rptr(r_b, mt_b)) => {
@@ -188,18 +210,28 @@ fn borrowable_protos(a_p: ast::Proto, b_p: ast::Proto) -> bool {
                         let nr_b = ty::mk_fn(self.infcx.tcx, ty::FnTyBase {
                             meta: ty::FnMeta {proto: a_f.meta.proto,
                                               ..b_f.meta},
-                            sig: b_f.sig
+                            sig: copy b_f.sig
                         });
                         self.try_assign(0, ty::AutoBorrowFn,
                                         a, nr_b, m_imm, b_f.meta.region)
                     }
 
+                    (ty::ty_fn(ref a_f), ty::ty_fn(ref b_f))
+                    if a_f.meta.proto == ast::ProtoBare => {
+                        let b1_f = ty::FnTyBase {
+                            meta: ty::FnMeta {proto: ast::ProtoBare,
+                                              ..b_f.meta},
+                            sig: copy b_f.sig
+                        };
+                        // Eventually we will need to add some sort of
+                        // adjustment here so that trans can add an
+                        // extra NULL env pointer:
+                        to_ares(Sub(*self).fns(a_f, &b1_f))
+                    }
+
                     // check for &T being assigned to *T:
                     (ty::ty_rptr(_, ref a_t), ty::ty_ptr(ref b_t)) => {
-                        match Sub(*self).mts(*a_t, *b_t) {
-                            Ok(_) => Ok(None),
-                            Err(ref e) => Err((*e))
-                        }
+                        to_ares(Sub(*self).mts(*a_t, *b_t))
                     }
 
                     // otherwise, assignment follows normal subtype rules:
@@ -230,10 +262,10 @@ fn try_assign(autoderefs: uint,
                   r_b: ty::Region) -> ares {
 
         debug!("try_assign(a=%s, nr_b=%s, m=%?, r_b=%s)",
-               a.to_str(self.infcx),
-               nr_b.to_str(self.infcx),
+               a.inf_str(self.infcx),
+               nr_b.inf_str(self.infcx),
                m,
-               r_b.to_str(self.infcx));
+               r_b.inf_str(self.infcx));
 
         do indent {
             let sub = Sub(*self);
index da66ecd922b687c239c92e126b5fdae070b115b8..c5e99bc5c03623a0673cce0f5a0456fbfa9eb207 100644 (file)
 // terms of error reporting, although we do not do that properly right
 // now.
 
-use middle::ty::{FnTyBase, FnMeta, FnSig};
-use middle::typeck::infer::to_str::ToStr;
-
-use syntax::ast::Onceness;
+use core::prelude::*;
+
+use middle::ty::{FloatVar, FnTyBase, FnMeta, FnSig, IntVar, TyVar};
+use middle::ty;
+use middle::typeck::infer::glb::Glb;
+use middle::typeck::infer::lub::Lub;
+use middle::typeck::infer::sub::Sub;
+use middle::typeck::infer::to_str::InferStr;
+use middle::typeck::infer::{cres, InferCtxt, ures, IntType, UintType};
+use util::common::indent;
+
+use core::result::{iter_vec2, map_vec2};
+use core::vec;
+use syntax::ast::{Onceness, purity, ret_style};
+use syntax::ast;
+use syntax::codemap::span;
 
 fn macros() { include!("macros.rs"); } // FIXME(#3114): Macro import/export.
 
-trait combine {
-    fn infcx() -> infer_ctxt;
+trait Combine {
+    fn infcx() -> @InferCtxt;
     fn tag() -> ~str;
     fn a_is_expected() -> bool;
+    fn span() -> span;
 
     fn sub() -> Sub;
     fn lub() -> Lub;
@@ -84,7 +97,6 @@ fn substs(did: ast::def_id, as_: &ty::substs,
     fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode>;
     fn args(a: ty::arg, b: ty::arg) -> cres<ty::arg>;
     fn protos(p1: ast::Proto, p2: ast::Proto) -> cres<ast::Proto>;
-    fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style>;
     fn purities(a: purity, b: purity) -> cres<purity>;
     fn oncenesses(a: Onceness, b: Onceness) -> cres<Onceness>;
     fn contraregions(a: ty::Region, b: ty::Region) -> cres<ty::Region>;
@@ -93,13 +105,13 @@ fn vstores(vk: ty::terr_vstore_kind,
                a: ty::vstore, b: ty::vstore) -> cres<ty::vstore>;
 }
 
-pub struct combine_fields {
-    infcx: infer_ctxt,
+pub struct CombineFields {
+    infcx: @InferCtxt,
     a_is_expected: bool,
     span: span,
 }
 
-fn expected_found<C: combine,T>(
+fn expected_found<C:Combine,T>(
     self: &C, +a: T, +b: T) -> ty::expected_found<T> {
 
     if self.a_is_expected() {
@@ -109,7 +121,7 @@ fn expected_found<C: combine,T>(
     }
 }
 
-pub fn eq_tys<C: combine>(self: &C, a: ty::t, b: ty::t) -> ures {
+pub fn eq_tys<C:Combine>(self: &C, a: ty::t, b: ty::t) -> ures {
     let suber = self.sub();
     do self.infcx().try {
         do suber.tys(a, b).chain |_ok| {
@@ -118,10 +130,10 @@ pub fn eq_tys<C: combine>(self: &C, a: ty::t, b: ty::t) -> ures {
     }
 }
 
-fn eq_regions<C: combine>(self: &C, a: ty::Region, b: ty::Region) -> ures {
+fn eq_regions<C:Combine>(self: &C, a: ty::Region, b: ty::Region) -> ures {
     debug!("eq_regions(%s, %s)",
-           a.to_str(self.infcx()),
-           b.to_str(self.infcx()));
+           a.inf_str(self.infcx()),
+           b.inf_str(self.infcx()));
     let sub = self.sub();
     do indent {
         self.infcx().try(|| {
@@ -140,7 +152,7 @@ fn eq_regions<C: combine>(self: &C, a: ty::Region, b: ty::Region) -> ures {
     }
 }
 
-fn eq_opt_regions<C:combine>(
+fn eq_opt_regions<C:Combine>(
     self: &C,
     a: Option<ty::Region>,
     b: Option<ty::Region>) -> cres<Option<ty::Region>> {
@@ -162,17 +174,17 @@ fn eq_opt_regions<C:combine>(
         self.infcx().tcx.sess.bug(
             fmt!("substitution a had opt_region %s and \
                   b had opt_region %s",
-                 a.to_str(self.infcx()),
-                 b.to_str(self.infcx())));
+                 a.inf_str(self.infcx()),
+                 b.inf_str(self.infcx())));
       }
     }
 }
 
-fn super_substs<C:combine>(
+fn super_substs<C:Combine>(
     self: &C, did: ast::def_id,
     a: &ty::substs, b: &ty::substs) -> cres<ty::substs> {
 
-    fn relate_region_param<C:combine>(
+    fn relate_region_param<C:Combine>(
         self: &C,
         did: ast::def_id,
         a: Option<ty::Region>,
@@ -208,8 +220,8 @@ fn relate_region_param<C:combine>(
             self.infcx().tcx.sess.bug(
                 fmt!("substitution a had opt_region %s and \
                       b had opt_region %s with variance %?",
-                      a.to_str(self.infcx()),
-                      b.to_str(self.infcx()),
+                      a.inf_str(self.infcx()),
+                      b.inf_str(self.infcx()),
                       polyty.region_param));
           }
         }
@@ -220,13 +232,13 @@ fn relate_region_param<C:combine>(
             do relate_region_param(self, did,
                                    a.self_r, b.self_r).chain |self_r|
             {
-                Ok({self_r: self_r, self_ty: self_ty, tps: tps})
+                Ok({self_r: self_r, self_ty: self_ty, tps: /*bad*/copy tps})
             }
         }
     }
 }
 
-fn super_tps<C:combine>(
+fn super_tps<C:Combine>(
     self: &C, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
 
     // Note: type parameters are always treated as *invariant*
@@ -244,7 +256,7 @@ fn super_tps<C:combine>(
     }
 }
 
-fn super_self_tys<C:combine>(
+fn super_self_tys<C:Combine>(
     self: &C, a: Option<ty::t>, b: Option<ty::t>) -> cres<Option<ty::t>> {
 
     // Note: the self type parameter is (currently) always treated as
@@ -267,7 +279,17 @@ fn super_self_tys<C:combine>(
     }
 }
 
-fn super_flds<C:combine>(
+fn super_protos<C: Combine>(
+    self: &C, p1: ast::Proto, p2: ast::Proto) -> cres<ast::Proto>
+{
+    if p1 == p2 {
+        Ok(p1)
+    } else {
+        Err(ty::terr_proto_mismatch(expected_found(self, p1, p2)))
+    }
+}
+
+fn super_flds<C:Combine>(
     self: &C, a: ty::field, b: ty::field) -> cres<ty::field> {
 
     if a.ident == b.ident {
@@ -280,7 +302,7 @@ fn super_flds<C:combine>(
     }
 }
 
-fn super_modes<C:combine>(
+fn super_modes<C:Combine>(
     self: &C, a: ast::mode, b: ast::mode)
     -> cres<ast::mode> {
 
@@ -288,7 +310,7 @@ fn super_modes<C:combine>(
     ty::unify_mode(tcx, expected_found(self, a, b))
 }
 
-fn super_args<C:combine>(
+fn super_args<C:Combine>(
     self: &C, a: ty::arg, b: ty::arg)
     -> cres<ty::arg> {
 
@@ -299,7 +321,7 @@ fn super_args<C:combine>(
     }
 }
 
-fn super_vstores<C:combine>(
+fn super_vstores<C:Combine>(
     self: &C, vk: ty::terr_vstore_kind,
     a: ty::vstore, b: ty::vstore) -> cres<ty::vstore>
 {
@@ -322,28 +344,27 @@ fn super_vstores<C:combine>(
     }
 }
 
-fn super_fn_metas<C:combine>(
+fn super_fn_metas<C:Combine>(
     self: &C, a_f: &ty::FnMeta, b_f: &ty::FnMeta) -> cres<ty::FnMeta>
 {
     let p = if_ok!(self.protos(a_f.proto, b_f.proto));
     let r = if_ok!(self.contraregions(a_f.region, b_f.region));
-    let rs = if_ok!(self.ret_styles(a_f.ret_style, b_f.ret_style));
     let purity = if_ok!(self.purities(a_f.purity, b_f.purity));
     let onceness = if_ok!(self.oncenesses(a_f.onceness, b_f.onceness));
     Ok(FnMeta {purity: purity,
                proto: p,
-               region: r,
                onceness: onceness,
-               bounds: a_f.bounds, // XXX: This is wrong!
-               ret_style: rs})
+               region: r,
+               bounds: a_f.bounds}) // XXX: This is wrong!
 }
 
-fn super_fn_sigs<C:combine>(
+fn super_fn_sigs<C:Combine>(
     self: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres<ty::FnSig>
 {
-    fn argvecs<C:combine>(self: &C, a_args: ~[ty::arg],
-                          b_args: ~[ty::arg]) -> cres<~[ty::arg]> {
-
+    fn argvecs<C:Combine>(self: &C,
+                          +a_args: ~[ty::arg],
+                          +b_args: ~[ty::arg]) -> cres<~[ty::arg]>
+    {
         if vec::same_length(a_args, b_args) {
             map_vec2(a_args, b_args, |a, b| self.args(*a, *b))
         } else {
@@ -351,28 +372,27 @@ fn argvecs<C:combine>(self: &C, a_args: ~[ty::arg],
         }
     }
 
-    do argvecs(self, a_f.inputs, b_f.inputs).chain |inputs| {
+    do argvecs(self, /*bad*/copy a_f.inputs, /*bad*/copy b_f.inputs)
+            .chain |inputs| {
         do self.tys(a_f.output, b_f.output).chain |output| {
-            Ok(FnSig {inputs: inputs, output: output})
+            Ok(FnSig {inputs: /*bad*/copy inputs, output: output})
         }
     }
 }
 
-fn super_fns<C:combine>(
+fn super_fns<C:Combine>(
     self: &C, a_f: &ty::FnTy, b_f: &ty::FnTy) -> cres<ty::FnTy>
 {
-    do self.fn_metas(&a_f.meta, &b_f.meta).chain |m| {
-        do self.fn_sigs(&a_f.sig, &b_f.sig).chain |s| {
-            Ok(FnTyBase {meta: m, sig: s})
-        }
-    }
+    let m = if_ok!(self.fn_metas(&a_f.meta, &b_f.meta));
+    let s = if_ok!(self.fn_sigs(&a_f.sig, &b_f.sig));
+    Ok(FnTyBase {meta: m, sig: s})
 }
 
-fn super_tys<C:combine>(
-    self: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
-
+fn super_tys<C:Combine>(
+    self: &C, a: ty::t, b: ty::t) -> cres<ty::t>
+{
     let tcx = self.infcx().tcx;
-    match (ty::get(a).sty, ty::get(b).sty) {
+    match (/*bad*/copy ty::get(a).sty, /*bad*/copy ty::get(b).sty) {
       // The "subtype" ought to be handling cases involving bot or var:
       (ty::ty_bot, _) |
       (_, ty::ty_bot) |
@@ -381,39 +401,56 @@ fn super_tys<C:combine>(
         tcx.sess.bug(
             fmt!("%s: bot and var types should have been handled (%s,%s)",
                  self.tag(),
-                 a.to_str(self.infcx()),
-                 b.to_str(self.infcx())));
+                 a.inf_str(self.infcx()),
+                 b.inf_str(self.infcx())));
       }
 
       // Relate integral variables to other types
       (ty::ty_infer(IntVar(a_id)), ty::ty_infer(IntVar(b_id))) => {
-        self.infcx().int_vars(a_id, b_id).then(|| Ok(a) )
+        if_ok!(self.infcx().simple_vars(&self.infcx().int_var_bindings,
+                                        ty::terr_no_integral_type,
+                                        a_id, b_id));
+        Ok(a)
       }
-      (ty::ty_infer(IntVar(a_id)), ty::ty_int(_)) |
-      (ty::ty_infer(IntVar(a_id)), ty::ty_uint(_)) => {
-        self.infcx().int_var_sub_t(a_id, b).then(|| Ok(a) )
+      (ty::ty_infer(IntVar(v_id)), ty::ty_int(v)) |
+      (ty::ty_int(v), ty::ty_infer(IntVar(v_id))) => {
+        if v == ast::ty_char {
+            Err(ty::terr_integer_as_char)
+        } else {
+            if_ok!(self.infcx().simple_var_t(&self.infcx().int_var_bindings,
+                                             ty::terr_no_integral_type,
+                                             v_id, IntType(v)));
+            Ok(ty::mk_mach_int(tcx, v))
+        }
       }
-      (ty::ty_int(_), ty::ty_infer(IntVar(b_id))) |
-      (ty::ty_uint(_), ty::ty_infer(IntVar(b_id))) => {
-        self.infcx().t_sub_int_var(a, b_id).then(|| Ok(a) )
+      (ty::ty_infer(IntVar(v_id)), ty::ty_uint(v)) |
+      (ty::ty_uint(v), ty::ty_infer(IntVar(v_id))) => {
+        if_ok!(self.infcx().simple_var_t(&self.infcx().int_var_bindings,
+                                         ty::terr_no_integral_type,
+                                         v_id, UintType(v)));
+        Ok(ty::mk_mach_uint(tcx, v))
       }
 
       // Relate floating-point variables to other types
       (ty::ty_infer(FloatVar(a_id)), ty::ty_infer(FloatVar(b_id))) => {
-        self.infcx().float_vars(a_id, b_id).then(|| Ok(a) )
-      }
-      (ty::ty_infer(FloatVar(a_id)), ty::ty_float(_)) => {
-        self.infcx().float_var_sub_t(a_id, b).then(|| Ok(a) )
+        if_ok!(self.infcx().simple_vars(&self.infcx().float_var_bindings,
+                                        ty::terr_no_floating_point_type,
+                                        a_id, b_id));
+        Ok(a)
       }
-      (ty::ty_float(_), ty::ty_infer(FloatVar(b_id))) => {
-        self.infcx().t_sub_float_var(a, b_id).then(|| Ok(a) )
+      (ty::ty_infer(FloatVar(v_id)), ty::ty_float(v)) |
+      (ty::ty_float(v), ty::ty_infer(FloatVar(v_id))) => {
+        if_ok!(self.infcx().simple_var_t(&self.infcx().float_var_bindings,
+                                         ty::terr_no_floating_point_type,
+                                         v_id, v));
+        Ok(ty::mk_mach_float(tcx, v))
       }
 
       (ty::ty_int(_), _) |
       (ty::ty_uint(_), _) |
       (ty::ty_float(_), _) => {
-        let as_ = ty::get(a).sty;
-        let bs = ty::get(b).sty;
+        let as_ = /*bad*/copy ty::get(a).sty;
+        let bs = /*bad*/copy ty::get(b).sty;
         if as_ == bs {
             Ok(a)
         } else {
@@ -448,7 +485,7 @@ fn super_tys<C:combine>(
       if a_id == b_id => {
         do self.substs(a_id, a_substs, b_substs).chain |substs| {
             do self.vstores(ty::terr_trait, a_vstore, b_vstore).chain |vs| {
-                Ok(ty::mk_trait(tcx, a_id, substs, vs))
+                Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, vs))
             }
         }
       }
diff --git a/src/librustc/middle/typeck/infer/floating.rs b/src/librustc/middle/typeck/infer/floating.rs
deleted file mode 100644 (file)
index 9537325..0000000
+++ /dev/null
@@ -1,58 +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.
-
-/*!
-
-Code related to floating-point type inference.
-
-*/
-
-use middle::ty::ty_float;
-use middle::typeck::infer::to_str::ToStr;
-
-// Bitvector to represent sets of floating-point types.
-pub enum float_ty_set = uint;
-
-// Constants representing singleton sets containing each of the floating-point
-// types.
-pub const FLOAT_TY_SET_EMPTY: uint = 0b000u;
-pub const FLOAT_TY_SET_FLOAT: uint = 0b001u;
-pub const FLOAT_TY_SET_F32:   uint = 0b010u;
-pub const FLOAT_TY_SET_F64:   uint = 0b100u;
-
-pub fn float_ty_set_all() -> float_ty_set {
-    float_ty_set(FLOAT_TY_SET_FLOAT | FLOAT_TY_SET_F32 | FLOAT_TY_SET_F64)
-}
-
-pub fn intersection(a: float_ty_set, b: float_ty_set) -> float_ty_set {
-    float_ty_set(*a & *b)
-}
-
-pub fn single_type_contained_in(tcx: ty::ctxt, a: float_ty_set)
-                             -> Option<ty::t> {
-    debug!("single_type_contained_in(a=%s)", uint::to_str(*a, 10));
-
-    if *a == FLOAT_TY_SET_FLOAT { return Some(ty::mk_float(tcx)); }
-    if *a == FLOAT_TY_SET_F32   { return Some(ty::mk_f32(tcx));   }
-    if *a == FLOAT_TY_SET_F64   { return Some(ty::mk_f64(tcx));   }
-    return None;
-}
-
-pub fn convert_floating_point_ty_to_float_ty_set(tcx: ty::ctxt, t: ty::t)
-                                              -> float_ty_set {
-    match get(t).sty {
-        ty::ty_float(ast::ty_f)     => float_ty_set(FLOAT_TY_SET_FLOAT),
-        ty::ty_float(ast::ty_f32)   => float_ty_set(FLOAT_TY_SET_F32),
-        ty::ty_float(ast::ty_f64)   => float_ty_set(FLOAT_TY_SET_F64),
-        _ => tcx.sess.bug(~"non-floating-point type passed to \
-                            convert_floating_point_ty_to_float_ty_set()")
-    }
-}
-
index b6e179d27a91b9c52d41f902d04d9f3a168de7f2..4d697ad3433e86cfabb3babb96e278f503a85416 100644 (file)
@@ -8,18 +8,30 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use middle::ty::RegionVid;
+use middle::ty;
 use middle::typeck::infer::combine::*;
+use middle::typeck::infer::glb::Glb;
 use middle::typeck::infer::lattice::*;
-use middle::typeck::infer::to_str::ToStr;
+use middle::typeck::infer::lub::Lub;
+use middle::typeck::infer::sub::Sub;
+use middle::typeck::infer::to_str::InferStr;
+use middle::typeck::isr_alist;
+use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl};
+use syntax::ast::{noreturn, pure_fn, ret_style, return_val, unsafe_fn};
+use util::ppaux::mt_to_str;
 
-use syntax::ast::{Many, Once};
+use std::list;
 
-enum Glb = combine_fields;  // "greatest lower bound" (common subtype)
+enum Glb = CombineFields;  // "greatest lower bound" (common subtype)
 
-impl Glb: combine {
-    fn infcx() -> infer_ctxt { self.infcx }
+impl Glb: Combine {
+    fn infcx() -> @InferCtxt { self.infcx }
     fn tag() -> ~str { ~"glb" }
     fn a_is_expected() -> bool { self.a_is_expected }
+    fn span() -> span { self.span }
 
     fn sub() -> Sub { Sub(*self) }
     fn lub() -> Lub { Lub(*self) }
@@ -82,10 +94,6 @@ fn contratys(a: ty::t, b: ty::t) -> cres<ty::t> {
         Lub(*self).tys(a, b)
     }
 
-    fn protos(p1: ast::Proto, p2: ast::Proto) -> cres<ast::Proto> {
-        if p1 == p2 {Ok(p1)} else {Ok(ast::ProtoBare)}
-    }
-
     fn purities(a: purity, b: purity) -> cres<purity> {
         match (a, b) {
           (pure_fn, _) | (_, pure_fn) => Ok(pure_fn),
@@ -102,23 +110,11 @@ fn oncenesses(a: Onceness, b: Onceness) -> cres<Onceness> {
         }
     }
 
-    fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
-        match (r1, r2) {
-          (ast::return_val, ast::return_val) => {
-            Ok(ast::return_val)
-          }
-          (ast::noreturn, _) |
-          (_, ast::noreturn) => {
-            Ok(ast::noreturn)
-          }
-        }
-    }
-
     fn regions(a: ty::Region, b: ty::Region) -> cres<ty::Region> {
         debug!("%s.regions(%?, %?)",
                self.tag(),
-               a.to_str(self.infcx),
-               b.to_str(self.infcx));
+               a.inf_str(self.infcx),
+               b.inf_str(self.infcx));
 
         do indent {
             self.infcx.region_vars.glb_regions(self.span, a, b)
@@ -130,7 +126,7 @@ fn contraregions(a: ty::Region, b: ty::Region) -> cres<ty::Region> {
     }
 
     fn tys(a: ty::t, b: ty::t) -> cres<ty::t> {
-        lattice_tys(&self, a, b)
+        super_lattice_tys(&self, a, b)
     }
 
     // Traits please (FIXME: #2794):
@@ -152,6 +148,129 @@ fn args(a: ty::arg, b: ty::arg) -> cres<ty::arg> {
         super_args(&self, a, b)
     }
 
+    fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
+        // Note: this is a subtle algorithm.  For a full explanation,
+        // please see the large comment in `region_inference.rs`.
+
+        debug!("%s.fn_sigs(%?, %?)",
+               self.tag(), a.inf_str(self.infcx), b.inf_str(self.infcx));
+        let _indenter = indenter();
+
+        // Take a snapshot.  We'll never roll this back, but in later
+        // phases we do want to be able to examine "all bindings that
+        // were created as part of this type comparison", and making a
+        // snapshot is a convenient way to do that.
+        let snapshot = self.infcx.region_vars.start_snapshot();
+
+        // Instantiate each bound region with a fresh region variable.
+        let (a_with_fresh, a_isr) =
+            self.infcx.replace_bound_regions_with_fresh_regions(
+                self.span, a);
+        let a_vars = var_ids(&self, a_isr);
+        let (b_with_fresh, b_isr) =
+            self.infcx.replace_bound_regions_with_fresh_regions(
+                self.span, b);
+        let b_vars = var_ids(&self, b_isr);
+
+        // Collect constraints.
+        let sig0 = if_ok!(super_fn_sigs(&self, &a_with_fresh, &b_with_fresh));
+        debug!("sig0 = %s", sig0.inf_str(self.infcx));
+
+        // Generalize the regions appearing in fn_ty0 if possible
+        let new_vars =
+            self.infcx.region_vars.vars_created_since_snapshot(snapshot);
+        let sig1 =
+            self.infcx.fold_regions_in_sig(
+                &sig0,
+                |r, _in_fn| generalize_region(&self, snapshot,
+                                              new_vars, a_isr, a_vars, b_vars,
+                                              r));
+        debug!("sig1 = %s", sig1.inf_str(self.infcx));
+        return Ok(move sig1);
+
+        fn generalize_region(self: &Glb,
+                             snapshot: uint,
+                             new_vars: &[RegionVid],
+                             a_isr: isr_alist,
+                             a_vars: &[RegionVid],
+                             b_vars: &[RegionVid],
+                             r0: ty::Region) -> ty::Region {
+            if !is_var_in_set(new_vars, r0) {
+                return r0;
+            }
+
+            let tainted = self.infcx.region_vars.tainted(snapshot, r0);
+
+            let mut a_r = None, b_r = None, only_new_vars = true;
+            for tainted.each |r| {
+                if is_var_in_set(a_vars, *r) {
+                    if a_r.is_some() {
+                        return fresh_bound_variable(self);
+                    } else {
+                        a_r = Some(*r);
+                    }
+                } else if is_var_in_set(b_vars, *r) {
+                    if b_r.is_some() {
+                        return fresh_bound_variable(self);
+                    } else {
+                        b_r = Some(*r);
+                    }
+                } else if !is_var_in_set(new_vars, *r) {
+                    only_new_vars = false;
+                }
+            }
+
+                // NB---I do not believe this algorithm computes
+                // (necessarily) the GLB.  As written it can
+                // spuriously fail.  In particular, if there is a case
+                // like: fn(fn(&a)) and fn(fn(&b)), where a and b are
+                // free, it will return fn(&c) where c = GLB(a,b).  If
+                // however this GLB is not defined, then the result is
+                // an error, even though something like
+                // "fn<X>(fn(&X))" where X is bound would be a
+                // subtype of both of those.
+                //
+                // The problem is that if we were to return a bound
+                // variable, we'd be computing a lower-bound, but not
+                // necessarily the *greatest* lower-bound.
+
+            if a_r.is_some() && b_r.is_some() && only_new_vars {
+                // Related to exactly one bound variable from each fn:
+                return rev_lookup(self, a_isr, a_r.get());
+            } else if a_r.is_none() && b_r.is_none() {
+                // Not related to bound variables from either fn:
+                return r0;
+            } else {
+                // Other:
+                return fresh_bound_variable(self);
+            }
+        }
+
+        fn rev_lookup(self: &Glb,
+                      a_isr: isr_alist,
+                      r: ty::Region) -> ty::Region
+        {
+            for list::each(a_isr) |pair| {
+                let (a_br, a_r) = *pair;
+                if a_r == r {
+                    return ty::re_bound(a_br);
+                }
+            }
+
+            self.infcx.tcx.sess.span_bug(
+                self.span,
+                fmt!("could not find original bound region for %?", r));
+        }
+
+        fn fresh_bound_variable(self: &Glb) -> ty::Region {
+            self.infcx.region_vars.new_bound()
+        }
+    }
+
+    fn protos(p1: ast::Proto, p2: ast::Proto) -> cres<ast::Proto> {
+        super_protos(&self, p1, p2)
+    }
+
     fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
         super_fns(&self, a, b)
     }
@@ -160,10 +279,6 @@ fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres<ty::FnMeta> {
         super_fn_metas(&self, a, b)
     }
 
-    fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
-        super_fn_sigs(&self, a, b)
-    }
-
     fn substs(did: ast::def_id,
               as_: &ty::substs,
               bs: &ty::substs) -> cres<ty::substs> {
diff --git a/src/librustc/middle/typeck/infer/integral.rs b/src/librustc/middle/typeck/infer/integral.rs
deleted file mode 100644 (file)
index f3e5e1a..0000000
+++ /dev/null
@@ -1,88 +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.
-
-/*!
-
-Code related to integral type inference.
-
-*/
-
-use middle::typeck::infer::to_str::ToStr;
-
-// Bitvector to represent sets of integral types
-enum int_ty_set = uint;
-
-// Constants representing singleton sets containing each of the
-// integral types
-const INT_TY_SET_EMPTY : uint = 0b00_0000_0000u;
-const INT_TY_SET_i8    : uint = 0b00_0000_0001u;
-const INT_TY_SET_u8    : uint = 0b00_0000_0010u;
-const INT_TY_SET_i16   : uint = 0b00_0000_0100u;
-const INT_TY_SET_u16   : uint = 0b00_0000_1000u;
-const INT_TY_SET_i32   : uint = 0b00_0001_0000u;
-const INT_TY_SET_u32   : uint = 0b00_0010_0000u;
-const INT_TY_SET_i64   : uint = 0b00_0100_0000u;
-const INT_TY_SET_u64   : uint = 0b00_1000_0000u;
-const INT_TY_SET_i     : uint = 0b01_0000_0000u;
-const INT_TY_SET_u     : uint = 0b10_0000_0000u;
-
-fn int_ty_set_all()  -> int_ty_set {
-    int_ty_set(INT_TY_SET_i8  | INT_TY_SET_u8 |
-               INT_TY_SET_i16 | INT_TY_SET_u16 |
-               INT_TY_SET_i32 | INT_TY_SET_u32 |
-               INT_TY_SET_i64 | INT_TY_SET_u64 |
-               INT_TY_SET_i   | INT_TY_SET_u)
-}
-
-fn intersection(a: int_ty_set, b: int_ty_set) -> int_ty_set {
-    int_ty_set(*a & *b)
-}
-
-fn single_type_contained_in(tcx: ty::ctxt, a: int_ty_set) ->
-    Option<ty::t> {
-    debug!("single_type_contained_in(a=%s)", uint::to_str(*a, 10u));
-
-    if *a == INT_TY_SET_i8    { return Some(ty::mk_i8(tcx)); }
-    if *a == INT_TY_SET_u8    { return Some(ty::mk_u8(tcx)); }
-    if *a == INT_TY_SET_i16   { return Some(ty::mk_i16(tcx)); }
-    if *a == INT_TY_SET_u16   { return Some(ty::mk_u16(tcx)); }
-    if *a == INT_TY_SET_i32   { return Some(ty::mk_i32(tcx)); }
-    if *a == INT_TY_SET_u32   { return Some(ty::mk_u32(tcx)); }
-    if *a == INT_TY_SET_i64   { return Some(ty::mk_i64(tcx)); }
-    if *a == INT_TY_SET_u64   { return Some(ty::mk_u64(tcx)); }
-    if *a == INT_TY_SET_i     { return Some(ty::mk_int(tcx)); }
-    if *a == INT_TY_SET_u     { return Some(ty::mk_uint(tcx)); }
-    return None;
-}
-
-fn convert_integral_ty_to_int_ty_set(tcx: ty::ctxt, t: ty::t)
-    -> int_ty_set {
-
-    match get(t).sty {
-      ty_int(int_ty) => match int_ty {
-        ast::ty_i8   => int_ty_set(INT_TY_SET_i8),
-        ast::ty_i16  => int_ty_set(INT_TY_SET_i16),
-        ast::ty_i32  => int_ty_set(INT_TY_SET_i32),
-        ast::ty_i64  => int_ty_set(INT_TY_SET_i64),
-        ast::ty_i    => int_ty_set(INT_TY_SET_i),
-        ast::ty_char => tcx.sess.bug(
-            ~"char type passed to convert_integral_ty_to_int_ty_set()")
-      },
-      ty_uint(uint_ty) => match uint_ty {
-        ast::ty_u8  => int_ty_set(INT_TY_SET_u8),
-        ast::ty_u16 => int_ty_set(INT_TY_SET_u16),
-        ast::ty_u32 => int_ty_set(INT_TY_SET_u32),
-        ast::ty_u64 => int_ty_set(INT_TY_SET_u64),
-        ast::ty_u   => int_ty_set(INT_TY_SET_u)
-      },
-      _ => tcx.sess.bug(~"non-integral type passed to \
-                          convert_integral_ty_to_int_ty_set()")
-    }
-}
index b47dd2064522e2ba72501b5124eaccabab0fa668..9783aee0848c9213b46c9bd1e0a8604784412f28 100644 (file)
@@ -8,9 +8,301 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+/*!
+ *
+ * # Lattice Variables
+ *
+ * This file contains generic code for operating on inference variables
+ * that are characterized by an upper- and lower-bound.  The logic and
+ * reasoning is explained in detail in the large comment in `infer.rs`.
+ *
+ * The code in here is defined quite generically so that it can be
+ * applied both to type variables, which represent types being inferred,
+ * and fn variables, which represent function types being inferred.
+ * It may eventually be applied to ther types as well, who knows.
+ * In some cases, the functions are also generic with respect to the
+ * operation on the lattice (GLB vs LUB).
+ *
+ * Although all the functions are generic, we generally write the
+ * comments in a way that is specific to type variables and the LUB
+ * operation.  It's just easier that way.
+ *
+ * In general all of the functions are defined parametrically
+ * over a `LatticeValue`, which is a value defined with respect to
+ * a lattice.
+ */
+
+use core::prelude::*;
+
+use middle::ty::{RegionVid, TyVar};
+use middle::ty;
+use middle::typeck::isr_alist;
+use middle::typeck::infer::*;
 use middle::typeck::infer::combine::*;
+use middle::typeck::infer::glb::Glb;
+use middle::typeck::infer::lub::Lub;
 use middle::typeck::infer::unify::*;
-use middle::typeck::infer::to_str::ToStr;
+use middle::typeck::infer::sub::Sub;
+use middle::typeck::infer::lub::Lub;
+use middle::typeck::infer::glb::Glb;
+use middle::typeck::infer::to_str::InferStr;
+
+use std::list;
+
+trait LatticeValue {
+    static fn sub(cf: &CombineFields, a: &self, b: &self) -> ures;
+    static fn lub(cf: &CombineFields, a: &self, b: &self) -> cres<self>;
+    static fn glb(cf: &CombineFields, a: &self, b: &self) -> cres<self>;
+}
+
+type LatticeOp<T> = &fn(cf: &CombineFields, a: &T, b: &T) -> cres<T>;
+
+impl ty::t: LatticeValue {
+    static fn sub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures {
+        Sub(*cf).tys(*a, *b).to_ures()
+    }
+
+    static fn lub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres<ty::t> {
+        Lub(*cf).tys(*a, *b)
+    }
+
+    static fn glb(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres<ty::t> {
+        Glb(*cf).tys(*a, *b)
+    }
+}
+
+impl FnMeta: LatticeValue {
+    static fn sub(cf: &CombineFields,
+                  a: &FnMeta, b: &FnMeta) -> ures {
+        Sub(*cf).fn_metas(a, b).to_ures()
+    }
+
+    static fn lub(cf: &CombineFields,
+                  a: &FnMeta, b: &FnMeta) -> cres<FnMeta> {
+        Lub(*cf).fn_metas(a, b)
+    }
+
+    static fn glb(cf: &CombineFields,
+                  a: &FnMeta, b: &FnMeta) -> cres<FnMeta> {
+        Glb(*cf).fn_metas(a, b)
+    }
+}
+
+impl CombineFields {
+    fn var_sub_var<V:Copy Eq Vid ToStr, T:Copy InferStr LatticeValue>(
+        &self,
+        vb: &ValsAndBindings<V, Bounds<T>>,
+        +a_id: V,
+        +b_id: V) -> ures
+    {
+        /*!
+         *
+         * Make one variable a subtype of another variable.  This is a
+         * subtle and tricky process, as described in detail at the
+         * top of infer.rs*/
+
+        // Need to make sub_id a subtype of sup_id.
+        let node_a = self.infcx.get(vb, a_id);
+        let node_b = self.infcx.get(vb, b_id);
+        let a_id = node_a.root;
+        let b_id = node_b.root;
+        let a_bounds = node_a.possible_types;
+        let b_bounds = node_b.possible_types;
+
+        debug!("vars(%s=%s <: %s=%s)",
+               a_id.to_str(), a_bounds.inf_str(self.infcx),
+               b_id.to_str(), b_bounds.inf_str(self.infcx));
+
+        if a_id == b_id { return uok(); }
+
+        // If both A's UB and B's LB have already been bound to types,
+        // see if we can make those types subtypes.
+        match (a_bounds.ub, b_bounds.lb) {
+            (Some(ref a_ub), Some(ref b_lb)) => {
+                let r = self.infcx.try(
+                    || LatticeValue::sub(self, a_ub, b_lb));
+                match r {
+                    Ok(()) => {
+                        return Ok(());
+                    }
+                    Err(_) => { /*fallthrough */ }
+                }
+            }
+            _ => { /*fallthrough*/ }
+        }
+
+        // Otherwise, we need to merge A and B so as to guarantee that
+        // A remains a subtype of B.  Actually, there are other options,
+        // but that's the route we choose to take.
+
+        self.infcx.unify(vb, &node_a, &node_b, |new_root, new_rank| {
+            self.set_var_to_merged_bounds(vb, new_root,
+                                          &a_bounds, &b_bounds,
+                                          new_rank)
+        })
+    }
+
+    /// make variable a subtype of T
+    fn var_sub_t<V:Copy Eq Vid ToStr, T:Copy InferStr LatticeValue>(
+        &self,
+        vb: &ValsAndBindings<V, Bounds<T>>,
+        +a_id: V,
+        +b: T) -> ures
+    {
+        /*!
+         *
+         * Make a variable (`a_id`) a subtype of the concrete type `b` */
+
+        let node_a = self.infcx.get(vb, a_id);
+        let a_id = node_a.root;
+        let a_bounds = &node_a.possible_types;
+        let b_bounds = &{lb: None, ub: Some(b)};
+
+        debug!("var_sub_t(%s=%s <: %s)",
+               a_id.to_str(),
+               a_bounds.inf_str(self.infcx),
+               b.inf_str(self.infcx));
+
+        self.set_var_to_merged_bounds(
+            vb, a_id, a_bounds, b_bounds, node_a.rank)
+    }
+
+    fn t_sub_var<V:Copy Eq Vid ToStr, T:Copy InferStr LatticeValue>(
+        &self,
+        vb: &ValsAndBindings<V, Bounds<T>>,
+        +a: T,
+        +b_id: V) -> ures
+    {
+        /*!
+         *
+         * Make a concrete type (`a`) a subtype of the variable `b_id` */
+
+        let a_bounds = &{lb: Some(a), ub: None};
+        let node_b = self.infcx.get(vb, b_id);
+        let b_id = node_b.root;
+        let b_bounds = &node_b.possible_types;
+
+        debug!("t_sub_var(%s <: %s=%s)",
+               a.inf_str(self.infcx),
+               b_id.to_str(),
+               b_bounds.inf_str(self.infcx));
+
+        self.set_var_to_merged_bounds(
+            vb, b_id, a_bounds, b_bounds, node_b.rank)
+    }
+
+    fn merge_bnd<T:Copy InferStr LatticeValue>(
+        &self,
+        a: &Bound<T>,
+        b: &Bound<T>,
+        lattice_op: LatticeOp<T>)
+        -> cres<Bound<T>>
+    {
+        /*!
+         *
+         * Combines two bounds into a more general bound. */
+
+        debug!("merge_bnd(%s,%s)",
+               a.inf_str(self.infcx),
+               b.inf_str(self.infcx));
+        let _r = indenter();
+
+        match (*a, *b) {
+            (None,          None) => Ok(None),
+            (Some(_),       None) => Ok(*a),
+            (None,          Some(_)) => Ok(*b),
+            (Some(ref v_a), Some(ref v_b)) => {
+                do lattice_op(self, v_a, v_b).chain |v| {
+                    Ok(Some(v))
+                }
+            }
+        }
+    }
+
+    fn set_var_to_merged_bounds<V:Copy Eq Vid ToStr,
+                                T:Copy InferStr LatticeValue>(
+        &self,
+        vb: &ValsAndBindings<V, Bounds<T>>,
+        +v_id: V,
+        a: &Bounds<T>,
+        b: &Bounds<T>,
+        rank: uint) -> ures
+    {
+        /*!
+         *
+         * Updates the bounds for the variable `v_id` to be the intersection
+         * of `a` and `b`.  That is, the new bounds for `v_id` will be
+         * a bounds c such that:
+         *    c.ub <: a.ub
+         *    c.ub <: b.ub
+         *    a.lb <: c.lb
+         *    b.lb <: c.lb
+         * If this cannot be achieved, the result is failure. */
+
+        // Think of the two diamonds, we want to find the
+        // intersection.  There are basically four possibilities (you
+        // can swap A/B in these pictures):
+        //
+        //       A         A
+        //      / \       / \
+        //     / B \     / B \
+        //    / / \ \   / / \ \
+        //   * *   * * * /   * *
+        //    \ \ / /   \   / /
+        //     \ B /   / \ / /
+        //      \ /   *   \ /
+        //       A     \ / A
+        //              B
+
+        debug!("merge(%s,%s,%s)",
+               v_id.to_str(),
+               a.inf_str(self.infcx),
+               b.inf_str(self.infcx));
+        let _indent = indenter();
+
+        // First, relate the lower/upper bounds of A and B.
+        // Note that these relations *must* hold for us to
+        // to be able to merge A and B at all, and relating
+        // them explicitly gives the type inferencer more
+        // information and helps to produce tighter bounds
+        // when necessary.
+        let () = if_ok!(self.bnds(&a.lb, &b.ub));
+        let () = if_ok!(self.bnds(&b.lb, &a.ub));
+        let ub = if_ok!(self.merge_bnd(&a.ub, &b.ub, LatticeValue::glb));
+        let lb = if_ok!(self.merge_bnd(&a.lb, &b.lb, LatticeValue::lub));
+        let bounds = {lb: lb, ub: ub};
+        debug!("merge(%s): bounds=%s",
+               v_id.to_str(),
+               bounds.inf_str(self.infcx));
+
+        // the new bounds must themselves
+        // be relatable:
+        let () = if_ok!(self.bnds(&bounds.lb, &bounds.ub));
+        self.infcx.set(vb, v_id, Root(bounds, rank));
+        uok()
+    }
+
+    fn bnds<T:Copy InferStr LatticeValue>(
+        &self,
+        a: &Bound<T>,
+        b: &Bound<T>) -> ures
+    {
+        debug!("bnds(%s <: %s)", a.inf_str(self.infcx),
+               b.inf_str(self.infcx));
+        let _r = indenter();
+
+        match (*a, *b) {
+            (None, None) |
+            (Some(_), None) |
+            (None, Some(_)) => {
+                uok()
+            }
+            (Some(ref t_a), Some(ref t_b)) => {
+                LatticeValue::sub(self, t_a, t_b)
+            }
+        }
+    }
+}
 
 // ______________________________________________________________________
 // Lattice operations on variables
 // This is common code used by both LUB and GLB to compute the LUB/GLB
 // for pairs of variables or for variables and values.
 
-trait lattice_ops {
-    fn bnd(b: bounds<ty::t>) -> Option<ty::t>;
-    fn with_bnd(b: bounds<ty::t>, t: ty::t) -> bounds<ty::t>;
+trait LatticeDir {
+    fn combine_fields() -> CombineFields;
+    fn bnd<T:Copy>(b: &Bounds<T>) -> Option<T>;
+    fn with_bnd<T:Copy>(b: &Bounds<T>, +t: T) -> Bounds<T>;
+}
+
+trait TyLatticeDir {
     fn ty_bot(t: ty::t) -> cres<ty::t>;
 }
 
-impl Lub: lattice_ops {
-    fn bnd(b: bounds<ty::t>) -> Option<ty::t> { b.ub }
-    fn with_bnd(b: bounds<ty::t>, t: ty::t) -> bounds<ty::t> {
-        {ub: Some(t),.. b}
+impl Lub: LatticeDir {
+    fn combine_fields() -> CombineFields { *self }
+    fn bnd<T:Copy>(b: &Bounds<T>) -> Option<T> { b.ub }
+    fn with_bnd<T:Copy>(b: &Bounds<T>, +t: T) -> Bounds<T> {
+        {ub: Some(t), ..*b}
     }
+}
+
+impl Lub: TyLatticeDir {
     fn ty_bot(t: ty::t) -> cres<ty::t> {
         Ok(t)
     }
 }
 
-impl Glb: lattice_ops {
-    fn bnd(b: bounds<ty::t>) -> Option<ty::t> { b.lb }
-    fn with_bnd(b: bounds<ty::t>, t: ty::t) -> bounds<ty::t> {
-        {lb: Some(t),.. b}
+impl Glb: LatticeDir {
+    fn combine_fields() -> CombineFields { *self }
+    fn bnd<T:Copy>(b: &Bounds<T>) -> Option<T> { b.lb }
+    fn with_bnd<T:Copy>(b: &Bounds<T>, +t: T) -> Bounds<T> {
+        {lb: Some(t), ..*b}
     }
+}
+
+impl Glb: TyLatticeDir {
     fn ty_bot(_t: ty::t) -> cres<ty::t> {
         Ok(ty::mk_bot(self.infcx.tcx))
     }
 }
 
-fn lattice_tys<L:lattice_ops combine>(
-    self: &L, a: ty::t, b: ty::t) -> cres<ty::t> {
-
+fn super_lattice_tys<L:LatticeDir TyLatticeDir Combine>(
+    self: &L,
+    a: ty::t,
+    b: ty::t) -> cres<ty::t>
+{
     debug!("%s.lattice_tys(%s, %s)", self.tag(),
-           a.to_str(self.infcx()),
-           b.to_str(self.infcx()));
-    if a == b { return Ok(a); }
-    do indent {
-        match (ty::get(a).sty, ty::get(b).sty) {
-          (ty::ty_bot, _) => self.ty_bot(b),
-          (_, ty::ty_bot) => self.ty_bot(a),
-
-          (ty::ty_infer(TyVar(a_id)), ty::ty_infer(TyVar(b_id))) => {
-            lattice_vars(self, a, a_id, b_id,
-                         |x, y| self.tys(x, y) )
-          }
-
-          (ty::ty_infer(TyVar(a_id)), _) => {
-            lattice_var_and_t(self, a_id, b,
-                              |x, y| self.tys(x, y) )
-          }
-
-          (_, ty::ty_infer(TyVar(b_id))) => {
-            lattice_var_and_t(self, b_id, a,
-                              |x, y| self.tys(x, y) )
-          }
-          _ => {
-            super_tys(self, a, b)
-          }
+           a.inf_str(self.infcx()),
+           b.inf_str(self.infcx()));
+    let _r = indenter();
+
+    if a == b {
+        return Ok(a);
+    }
+
+    let tcx = self.infcx().tcx;
+
+    match (ty::get(a).sty, ty::get(b).sty) {
+        (ty::ty_bot, _) => { return self.ty_bot(b); }
+        (_, ty::ty_bot) => { return self.ty_bot(a); }
+
+        (ty::ty_infer(TyVar(a_id)), ty::ty_infer(TyVar(b_id))) => {
+            let r = if_ok!(lattice_vars(self, &self.infcx().ty_var_bindings,
+                                        a_id, b_id,
+                                        |x, y| self.tys(*x, *y)));
+            return match r {
+                VarResult(v) => Ok(ty::mk_var(tcx, v)),
+                ValueResult(t) => Ok(t)
+            };
+        }
+
+        (ty::ty_infer(TyVar(a_id)), _) => {
+            return lattice_var_and_t(self, &self.infcx().ty_var_bindings,
+                                     a_id, &b,
+                                     |x, y| self.tys(*x, *y));
+        }
+
+        (_, ty::ty_infer(TyVar(b_id))) => {
+            return lattice_var_and_t(self, &self.infcx().ty_var_bindings,
+                                     b_id, &a,
+                                     |x, y| self.tys(*x, *y));
+        }
+
+        _ => {
+            return super_tys(self, a, b);
         }
     }
 }
 
-fn lattice_vars<L:lattice_ops combine>(
-    self: &L, +a_t: ty::t, +a_vid: ty::TyVid, +b_vid: ty::TyVid,
-    c_ts: fn(ty::t, ty::t) -> cres<ty::t>) -> cres<ty::t> {
+type LatticeDirOp<T> = &fn(a: &T, b: &T) -> cres<T>;
 
-    // The comments in this function are written for LUB and types,
-    // but they apply equally well to GLB and regions if you inverse
-    // upper/lower/sub/super/etc.
+enum LatticeVarResult<V,T> {
+    VarResult(V),
+    ValueResult(T)
+}
 
-    // Need to find a type that is a supertype of both a and b:
-    let vb = &self.infcx().ty_var_bindings;
+/**
+ * Computes the LUB or GLB of two bounded variables.  These could be any
+ * sort of variables, but in the comments on this function I'll assume
+ * we are doing an LUB on two type variables.
+ *
+ * This computation can be done in one of two ways:
+ *
+ * - If both variables have an upper bound, we may just compute the
+ *   LUB of those bounds and return that, in which case we are
+ *   returning a type.  This is indicated with a `ValueResult` return.
+ *
+ * - 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. */
+fn lattice_vars<L:LatticeDir Combine,
+                V:Copy Eq Vid ToStr,
+                T:Copy InferStr LatticeValue>(
+    self: &L,                           // defines whether we want LUB or GLB
+    vb: &ValsAndBindings<V, Bounds<T>>, // relevant variable bindings
+    +a_vid: V,                          // first variable
+    +b_vid: V,                          // second variable
+    lattice_dir_op: LatticeDirOp<T>)    // LUB or GLB operation on types
+    -> cres<LatticeVarResult<V,T>>
+{
     let nde_a = self.infcx().get(vb, a_vid);
     let nde_b = self.infcx().get(vb, b_vid);
     let a_vid = nde_a.root;
     let b_vid = nde_b.root;
-    let a_bounds = nde_a.possible_types;
-    let b_bounds = nde_b.possible_types;
+    let a_bounds = &nde_a.possible_types;
+    let b_bounds = &nde_b.possible_types;
 
     debug!("%s.lattice_vars(%s=%s <: %s=%s)",
            self.tag(),
-           a_vid.to_str(), a_bounds.to_str(self.infcx()),
-           b_vid.to_str(), b_bounds.to_str(self.infcx()));
+           a_vid.to_str(), a_bounds.inf_str(self.infcx()),
+           b_vid.to_str(), b_bounds.inf_str(self.infcx()));
 
+    // Same variable: the easy case.
     if a_vid == b_vid {
-        return Ok(a_t);
+        return Ok(VarResult(a_vid));
     }
 
     // If both A and B have an UB type, then we can just compute the
     // LUB of those types:
     let a_bnd = self.bnd(a_bounds), b_bnd = self.bnd(b_bounds);
     match (a_bnd, b_bnd) {
-      (Some(a_ty), Some(b_ty)) => {
-        match self.infcx().try(|| c_ts(a_ty, b_ty) ) {
-            Ok(t) => return Ok(t),
-            Err(_) => { /*fallthrough */ }
+        (Some(ref a_ty), Some(ref b_ty)) => {
+            match self.infcx().try(|| lattice_dir_op(a_ty, b_ty) ) {
+                Ok(t) => return Ok(ValueResult(t)),
+                Err(_) => { /*fallthrough */ }
+            }
         }
-      }
-      _ => {/*fallthrough*/}
+        _ => {/*fallthrough*/}
     }
 
     // Otherwise, we need to merge A and B into one variable.  We can
     // then use either variable as an upper bound:
-    var_sub_var(self, a_vid, b_vid).then(|| Ok(a_t) )
+    let cf = self.combine_fields();
+    do cf.var_sub_var(vb, a_vid, b_vid).then {
+        Ok(VarResult(a_vid))
+    }
 }
 
-fn lattice_var_and_t<L:lattice_ops combine>(
-    self: &L, a_id: ty::TyVid, b: ty::t,
-    c_ts: fn(ty::t, ty::t) -> cres<ty::t>) -> cres<ty::t> {
-
-    let vb = &self.infcx().ty_var_bindings;
+fn lattice_var_and_t<L:LatticeDir Combine,
+                     V:Copy Eq Vid ToStr,
+                     T:Copy InferStr LatticeValue>(
+    self: &L,
+    vb: &ValsAndBindings<V, Bounds<T>>,
+    +a_id: V,
+    b: &T,
+    lattice_dir_op: LatticeDirOp<T>)
+    -> cres<T>
+{
     let nde_a = self.infcx().get(vb, a_id);
     let a_id = nde_a.root;
-    let a_bounds = nde_a.possible_types;
+    let a_bounds = &nde_a.possible_types;
 
     // The comments in this function are written for LUB, but they
     // apply equally well to GLB if you inverse upper/lower/sub/super/etc.
 
     debug!("%s.lattice_var_and_t(%s=%s <: %s)",
            self.tag(),
-           a_id.to_str(), a_bounds.to_str(self.infcx()),
-           b.to_str(self.infcx()));
+           a_id.to_str(),
+           a_bounds.inf_str(self.infcx()),
+           b.inf_str(self.infcx()));
 
     match self.bnd(a_bounds) {
-      Some(a_bnd) => {
-        // If a has an upper bound, return the LUB(a.ub, b)
-        debug!("bnd=some(%s)", a_bnd.to_str(self.infcx()));
-        return c_ts(a_bnd, b);
-      }
-      None => {
-        // If a does not have an upper bound, make b the upper bound of a
-        // and then return b.
-        debug!("bnd=none");
-        let a_bounds = self.with_bnd(a_bounds, b);
-        do bnds(self, a_bounds.lb, a_bounds.ub).then {
-            self.infcx().set(vb, a_id, root(a_bounds, nde_a.rank));
-            Ok(b)
+        Some(ref a_bnd) => {
+            // If a has an upper bound, return the LUB(a.ub, b)
+            debug!("bnd=some(%s)", a_bnd.inf_str(self.infcx()));
+            lattice_dir_op(a_bnd, b)
+        }
+        None => {
+            // If a does not have an upper bound, make b the upper bound of a
+            // and then return b.
+            debug!("bnd=none");
+            let a_bounds = self.with_bnd(a_bounds, *b);
+            do self.combine_fields().bnds(&a_bounds.lb, &a_bounds.ub).then {
+                self.infcx().set(vb, a_id, Root(a_bounds, nde_a.rank));
+                Ok(*b)
+            }
+        }
+    }
+}
+
+// ___________________________________________________________________________
+// Random utility functions used by LUB/GLB when computing LUB/GLB of
+// fn types
+
+fn var_ids<T: Combine>(self: &T, isr: isr_alist) -> ~[RegionVid] {
+    let mut result = ~[];
+    for list::each(isr) |pair| {
+        match pair.second() {
+            ty::re_infer(ty::ReVar(r)) => { result.push(r); }
+            r => {
+                self.infcx().tcx.sess.span_bug(
+                    self.span(),
+                    fmt!("Found non-region-vid: %?", r));
+            }
         }
-      }
+    }
+    return result;
+}
+
+fn is_var_in_set(new_vars: &[RegionVid], r: ty::Region) -> bool {
+    match r {
+        ty::re_infer(ty::ReVar(ref v)) => new_vars.contains(v),
+        _ => false
     }
 }
index cfb93e93a65ba26efbf9b66b2903c82cfdfd08e2..ac6c4473999c3bb1773ce1f39e24965bf5f63b3f 100644 (file)
@@ -8,25 +8,36 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use middle::ty::RegionVid;
+use middle::ty;
 use middle::typeck::infer::combine::*;
+use middle::typeck::infer::glb::Glb;
 use middle::typeck::infer::lattice::*;
-use middle::typeck::infer::to_str::ToStr;
+use middle::typeck::infer::sub::Sub;
+use middle::typeck::infer::to_str::InferStr;
+use middle::typeck::isr_alist;
+use util::ppaux::mt_to_str;
 
-use syntax::ast::{Many, Once};
+use std::list;
+use syntax::ast::{Many, Once, extern_fn, m_const, impure_fn, noreturn};
+use syntax::ast::{pure_fn, ret_style, return_val, unsafe_fn};
 
 fn macros() { include!("macros.rs"); } // FIXME(#3114): Macro import/export.
 
-enum Lub = combine_fields;  // "subtype", "subregion" etc
+enum Lub = CombineFields;  // least-upper-bound: common supertype
 
 impl Lub {
     fn bot_ty(b: ty::t) -> cres<ty::t> { Ok(b) }
     fn ty_bot(b: ty::t) -> cres<ty::t> { self.bot_ty(b) } // commutative
 }
 
-impl Lub: combine {
-    fn infcx() -> infer_ctxt { self.infcx }
+impl Lub: Combine {
+    fn infcx() -> @InferCtxt { self.infcx }
     fn tag() -> ~str { ~"lub" }
     fn a_is_expected() -> bool { self.a_is_expected }
+    fn span() -> span { self.span }
 
     fn sub() -> Sub { Sub(*self) }
     fn lub() -> Lub { Lub(*self) }
@@ -69,15 +80,6 @@ fn contratys(a: ty::t, b: ty::t) -> cres<ty::t> {
         Glb(*self).tys(a, b)
     }
 
-    fn protos(p1: ast::Proto, p2: ast::Proto) -> cres<ast::Proto> {
-        match (p1, p2) {
-            (ast::ProtoBare, _) => Ok(p2),
-            (_, ast::ProtoBare) => Ok(p1),
-            _ if p1 == p2 => Ok(p1),
-            _ => Err(ty::terr_proto_mismatch(expected_found(&self, p1, p2)))
-        }
-    }
-
     fn purities(a: purity, b: purity) -> cres<purity> {
         match (a, b) {
           (unsafe_fn, _) | (_, unsafe_fn) => Ok(unsafe_fn),
@@ -94,14 +96,6 @@ fn oncenesses(a: Onceness, b: Onceness) -> cres<Onceness> {
         }
     }
 
-    fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
-        match (r1, r2) {
-          (ast::return_val, _) |
-          (_, ast::return_val) => Ok(ast::return_val),
-          (ast::noreturn, ast::noreturn) => Ok(ast::noreturn)
-        }
-    }
-
     fn contraregions(a: ty::Region, b: ty::Region) -> cres<ty::Region> {
         return Glb(*self).regions(a, b);
     }
@@ -109,15 +103,15 @@ fn contraregions(a: ty::Region, b: ty::Region) -> cres<ty::Region> {
     fn regions(a: ty::Region, b: ty::Region) -> cres<ty::Region> {
         debug!("%s.regions(%?, %?)",
                self.tag(),
-               a.to_str(self.infcx),
-               b.to_str(self.infcx));
+               a.inf_str(self.infcx),
+               b.inf_str(self.infcx));
 
         do indent {
             self.infcx.region_vars.lub_regions(self.span, a, b)
         }
     }
 
-    fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
+    fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
         // Note: this is a subtle algorithm.  For a full explanation,
         // please see the large comment in `region_inference.rs`.
 
@@ -136,20 +130,18 @@ fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
                 self.span, b);
 
         // Collect constraints.
-        let fn_ty0 = if_ok!(super_fns(&self, &a_with_fresh, &b_with_fresh));
-        debug!("fn_ty0 = %s", fn_ty0.to_str(self.infcx));
+        let sig0 = if_ok!(super_fn_sigs(&self, &a_with_fresh, &b_with_fresh));
+        debug!("sig0 = %s", sig0.inf_str(self.infcx));
 
-        // Generalize the regions appearing in fn_ty0 if possible
+        // Generalize the regions appearing in sig0 if possible
         let new_vars =
             self.infcx.region_vars.vars_created_since_snapshot(snapshot);
-        let fn_ty1 =
-            ty::apply_op_on_t_to_ty_fn(
-                self.infcx.tcx, &fn_ty0,
-                |t| ty::fold_regions(
-                    self.infcx.tcx, t,
-                    |r, _in_fn| generalize_region(&self, snapshot,
-                                                  new_vars, a_isr, r)));
-        return Ok(move fn_ty1);
+        let sig1 =
+            self.infcx.fold_regions_in_sig(
+                &sig0,
+                |r, _in_fn| generalize_region(&self, snapshot, new_vars,
+                                              a_isr, r));
+        return Ok(move sig1);
 
         fn generalize_region(self: &Lub,
                              snapshot: uint,
@@ -157,7 +149,7 @@ fn generalize_region(self: &Lub,
                              a_isr: isr_alist,
                              r0: ty::Region) -> ty::Region {
             // Regions that pre-dated the LUB computation stay as they are.
-            if !is_new_var(new_vars, r0) {
+            if !is_var_in_set(new_vars, r0) {
                 debug!("generalize_region(r0=%?): not new variable", r0);
                 return r0;
             }
@@ -167,7 +159,7 @@ fn generalize_region(self: &Lub,
             // Variables created during LUB computation which are
             // *related* to regions that pre-date the LUB computation
             // stay as they are.
-            if !tainted.all(|r| is_new_var(new_vars, *r)) {
+            if !tainted.all(|r| is_var_in_set(new_vars, *r)) {
                 debug!("generalize_region(r0=%?): \
                         non-new-variables found in %?",
                        r0, tainted);
@@ -194,27 +186,24 @@ fn generalize_region(self: &Lub,
                 fmt!("Region %? is not associated with \
                       any bound region from A!", r0));
         }
+    }
 
-        fn is_new_var(new_vars: &[RegionVid], r: ty::Region) -> bool {
-            match r {
-                ty::re_infer(ty::ReVar(ref v)) => new_vars.contains(v),
-                _ => false
-            }
-        }
+    fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
+        super_fns(&self, a, b)
     }
 
     fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres<ty::FnMeta> {
         super_fn_metas(&self, a, b)
     }
 
-    fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
-        super_fn_sigs(&self, a, b)
-    }
-
     // Traits please (FIXME: #2794):
 
+    fn protos(p1: ast::Proto, p2: ast::Proto) -> cres<ast::Proto> {
+        super_protos(&self, p1, p2)
+    }
+
     fn tys(a: ty::t, b: ty::t) -> cres<ty::t> {
-        lattice_tys(&self, a, b)
+        super_lattice_tys(&self, a, b)
     }
 
     fn flds(a: ty::field, b: ty::field) -> cres<ty::field> {
index 616df1e72c5b1432ec1c5af6a58ab736fd7431d2..8cccf75d6dc4ef092284b6e1d11839deca676f98 100644 (file)
@@ -19,4 +19,4 @@ macro_rules! if_ok(
     )
 );
 
-}
\ No newline at end of file
+}
index fb8ca5632910eeed5d135c0d9904c3fcce76cec9..ec5de2b4f261bb6df37b1d0db6f04ebef734d2a1 100644 (file)
@@ -197,29 +197,16 @@ fn bar() {
 the regions for outer block scopes are superregions of those for inner
 block scopes.
 
-## Integral type variables
+## Integral and floating-point type variables
 
 There is a third variety of type variable that we use only for
 inferring the types of unsuffixed integer literals.  Integral type
 variables differ from general-purpose type variables in that there's
 no subtyping relationship among the various integral types, so instead
-of associating each variable with an upper and lower bound, we
-represent the set of possible integral types it can take on with an
-`int_ty_set`, which is a bitvector with one bit for each integral
-type.  Because intersecting these sets with each other is simpler than
-merging bounds, we don't need to do so transactionally as we do for
-general-purpose type variables.
-
-We could conceivably define a subtyping relationship among integral
-types based on their ranges, but we choose not to open that particular
-can of worms.  Our strategy is to treat integral type variables as
-unknown until the typing context constrains them to a unique integral
-type, at which point they take on that type.  If the typing context
-overconstrains the type, it's a type error; if we reach the point at
-which type variables must be resolved and an integral type variable is
-still underconstrained, it defaults to `int` as a last resort.
-
-Floating point types are handled similarly to integral types.
+of associating each variable with an upper and lower bound, we just
+use simple unification.  Each integer variable is associated with at
+most one integer type.  Floating point types are handled similarly to
+integral types.
 
 ## GLB/LUB
 
@@ -259,16 +246,16 @@ fn bar() {
 #[warn(deprecated_mode)];
 #[warn(deprecated_pattern)];
 
-use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, vid};
+use core::prelude::*;
+
+use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, Vid};
 use middle::ty::{mk_fn, type_is_bot};
 use middle::ty::{ty_int, ty_uint, get, terr_fn, TyVar, IntVar, FloatVar};
 use middle::ty;
-use middle::typeck::check::regionmanip::{replace_bound_regions_in_fn_ty};
+use middle::typeck::check::regionmanip::{replace_bound_regions_in_fn_sig};
 use middle::typeck::infer::assignment::Assign;
-use middle::typeck::infer::combine::{combine_fields, eq_tys};
-use middle::typeck::infer::floating::{float_ty_set, float_ty_set_all};
+use middle::typeck::infer::combine::{CombineFields, eq_tys};
 use middle::typeck::infer::glb::Glb;
-use middle::typeck::infer::integral::{int_ty_set, int_ty_set_all};
 use middle::typeck::infer::lub::Lub;
 use middle::typeck::infer::region_inference::{RegionVarBindings};
 use middle::typeck::infer::resolve::{force_all, not_regions};
@@ -278,23 +265,29 @@ fn bar() {
 use middle::typeck::infer::resolve::{resolve_nested_tvar, resolve_rvar};
 use middle::typeck::infer::resolve::{resolver};
 use middle::typeck::infer::sub::Sub;
-use middle::typeck::infer::to_str::ToStr;
-use middle::typeck::infer::unify::{vals_and_bindings, root};
+use middle::typeck::infer::to_str::InferStr;
+use middle::typeck::infer::unify::{ValsAndBindings, Root};
+use middle::typeck::isr_alist;
 use util::common::{indent, indenter};
-use util::ppaux::{ty_to_str, mt_to_str};
+use util::ppaux::{bound_region_to_str, ty_to_str, mt_to_str};
 
 use core::cmp::Eq;
 use core::dvec::DVec;
 use core::result::{Result, Ok, Err, map_vec, map_vec2, iter_vec2};
+use core::result;
+use core::vec;
+use std::list::Nil;
 use std::map::HashMap;
 use std::smallintmap;
 use syntax::ast::{ret_style, purity};
 use syntax::ast::{m_const, m_imm, m_mutbl};
 use syntax::ast::{unsafe_fn, impure_fn, pure_fn, extern_fn};
+use syntax::ast;
 use syntax::ast_util::dummy_sp;
-use syntax::{ast, ast_util};
+use syntax::ast_util;
+use syntax::codemap::span;
 
-export infer_ctxt;
+export InferCtxt;
 export new_infer_ctxt;
 export mk_subty, can_mk_subty;
 export mk_subr;
@@ -305,15 +298,12 @@ fn bar() {
 export resolve_and_force_all_but_regions, not_regions;
 export resolve_type, resolve_region;
 export resolve_borrowings;
-export methods; // for infer_ctxt
-export unify_methods; // for infer_ctxt
 export cres, fres, fixup_err, fixup_err_to_str;
 export assignment;
 export root, to_str;
 export int_ty_set_all;
 export assignment;
 export combine;
-export floating;
 export glb;
 export integral;
 export lattice;
@@ -323,6 +313,14 @@ fn bar() {
 export sub;
 export to_str;
 export unify;
+export uok;
+export cyclic_ty, unresolved_ty, region_var_bound_by_region_var;
+export Bound, Bounds;
+export ures;
+export ares;
+export infer_ctxt;
+export fixup_err;
+export IntVarValue, IntType, UintType;
 
 #[legacy_exports]
 mod assignment;
@@ -331,9 +329,6 @@ fn bar() {
 #[legacy_exports]
 mod glb;
 #[legacy_exports]
-mod integral;
-mod floating;
-#[legacy_exports]
 mod lattice;
 #[legacy_exports]
 mod lub;
@@ -348,39 +343,48 @@ fn bar() {
 #[legacy_exports]
 mod unify;
 
-type bound<T:Copy> = Option<T>;
-type bounds<T:Copy> = {lb: bound<T>, ub: bound<T>};
+type Bound<T> = Option<T>;
+type Bounds<T> = {lb: Bound<T>, ub: Bound<T>};
 
 type cres<T> = Result<T,ty::type_err>; // "combine result"
 type ures = cres<()>; // "unify result"
 type fres<T> = Result<T, fixup_err>; // "fixup result"
 type ares = cres<Option<@ty::AutoAdjustment>>; // "assignment result"
 
-enum infer_ctxt = @{
+#[deriving_eq]
+enum IntVarValue {
+    IntType(ast::int_ty),
+    UintType(ast::uint_ty),
+}
+
+struct InferCtxt {
     tcx: ty::ctxt,
 
-    // We instantiate vals_and_bindings with bounds<ty::t> because the
+    // We instantiate ValsAndBindings with bounds<ty::t> because the
     // types that might instantiate a general type variable have an
     // order, represented by its upper and lower bounds.
-    ty_var_bindings: vals_and_bindings<ty::TyVid, bounds<ty::t>>,
+    ty_var_bindings: ValsAndBindings<ty::TyVid, Bounds<ty::t>>,
+
+    // Number of type variables created thus far.
+    mut ty_var_counter: uint,
 
     // The types that might instantiate an integral type variable are
     // represented by an int_ty_set.
-    int_var_bindings: vals_and_bindings<ty::IntVid, int_ty_set>,
+    int_var_bindings: ValsAndBindings<ty::IntVid, Option<IntVarValue>>,
+
+    // Number of integral variables created thus far.
+    mut int_var_counter: uint,
 
     // The types that might instantiate a floating-point type variable are
     // represented by an float_ty_set.
-    float_var_bindings: vals_and_bindings<ty::FloatVid, float_ty_set>,
+    float_var_bindings: ValsAndBindings<ty::FloatVid, Option<ast::float_ty>>,
+
+    // Number of floating-point variables created thus far.
+    mut float_var_counter: uint,
 
     // For region variables.
     region_vars: RegionVarBindings,
-
-    // For keeping track of existing type and region variables.
-    ty_var_counter: @mut uint,
-    int_var_counter: @mut uint,
-    float_var_counter: @mut uint,
-    region_var_counter: @mut uint
-};
+}
 
 enum fixup_err {
     unresolved_int_ty(IntVid),
@@ -403,27 +407,33 @@ fn fixup_err_to_str(f: fixup_err) -> ~str {
     }
 }
 
-fn new_vals_and_bindings<V:Copy, T:Copy>() -> vals_and_bindings<V, T> {
-    vals_and_bindings {
+fn new_ValsAndBindings<V:Copy, T:Copy>() -> ValsAndBindings<V, T> {
+    ValsAndBindings {
         vals: smallintmap::mk(),
         mut bindings: ~[]
     }
 }
 
-fn new_infer_ctxt(tcx: ty::ctxt) -> infer_ctxt {
-    infer_ctxt(@{tcx: tcx,
-                 ty_var_bindings: new_vals_and_bindings(),
-                 int_var_bindings: new_vals_and_bindings(),
-                 float_var_bindings: new_vals_and_bindings(),
-                 region_vars: RegionVarBindings(tcx),
-                 ty_var_counter: @mut 0u,
-                 int_var_counter: @mut 0u,
-                 float_var_counter: @mut 0u,
-                 region_var_counter: @mut 0u})}
-
-fn mk_subty(cx: infer_ctxt, a_is_expected: bool, span: span,
+fn new_infer_ctxt(tcx: ty::ctxt) -> @InferCtxt {
+    @InferCtxt {
+        tcx: tcx,
+
+        ty_var_bindings: new_ValsAndBindings(),
+        ty_var_counter: 0,
+
+        int_var_bindings: new_ValsAndBindings(),
+        int_var_counter: 0,
+
+        float_var_bindings: new_ValsAndBindings(),
+        float_var_counter: 0,
+
+        region_vars: RegionVarBindings(tcx),
+    }
+}
+
+fn mk_subty(cx: @InferCtxt, a_is_expected: bool, span: span,
             a: ty::t, b: ty::t) -> ures {
-    debug!("mk_subty(%s <: %s)", a.to_str(cx), b.to_str(cx));
+    debug!("mk_subty(%s <: %s)", a.inf_str(cx), b.inf_str(cx));
     do indent {
         do cx.commit {
             cx.sub(a_is_expected, span).tys(a, b)
@@ -431,8 +441,8 @@ fn mk_subty(cx: infer_ctxt, a_is_expected: bool, span: span,
     }.to_ures()
 }
 
-fn can_mk_subty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
-    debug!("can_mk_subty(%s <: %s)", a.to_str(cx), b.to_str(cx));
+fn can_mk_subty(cx: @InferCtxt, a: ty::t, b: ty::t) -> ures {
+    debug!("can_mk_subty(%s <: %s)", a.inf_str(cx), b.inf_str(cx));
     do indent {
         do cx.probe {
             cx.sub(true, ast_util::dummy_sp()).tys(a, b)
@@ -440,9 +450,9 @@ fn can_mk_subty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
     }.to_ures()
 }
 
-fn mk_subr(cx: infer_ctxt, a_is_expected: bool, span: span,
+fn mk_subr(cx: @InferCtxt, a_is_expected: bool, span: span,
            a: ty::Region, b: ty::Region) -> ures {
-    debug!("mk_subr(%s <: %s)", a.to_str(cx), b.to_str(cx));
+    debug!("mk_subr(%s <: %s)", a.inf_str(cx), b.inf_str(cx));
     do indent {
         do cx.commit {
             cx.sub(a_is_expected, span).regions(a, b)
@@ -450,9 +460,9 @@ fn mk_subr(cx: infer_ctxt, a_is_expected: bool, span: span,
     }.to_ures()
 }
 
-fn mk_eqty(cx: infer_ctxt, a_is_expected: bool, span: span,
+fn mk_eqty(cx: @InferCtxt, a_is_expected: bool, span: span,
            a: ty::t, b: ty::t) -> ures {
-    debug!("mk_eqty(%s <: %s)", a.to_str(cx), b.to_str(cx));
+    debug!("mk_eqty(%s <: %s)", a.inf_str(cx), b.inf_str(cx));
     do indent {
         do cx.commit {
             let suber = cx.sub(a_is_expected, span);
@@ -461,9 +471,9 @@ fn mk_eqty(cx: infer_ctxt, a_is_expected: bool, span: span,
     }.to_ures()
 }
 
-fn mk_assignty(cx: infer_ctxt, a_is_expected: bool, span: span,
+fn mk_assignty(cx: @InferCtxt, a_is_expected: bool, span: span,
                a: ty::t, b: ty::t) -> ares {
-    debug!("mk_assignty(%s -> %s)", a.to_str(cx), b.to_str(cx));
+    debug!("mk_assignty(%s -> %s)", a.inf_str(cx), b.inf_str(cx));
     do indent {
         do cx.commit {
             Assign(cx.combine_fields(a_is_expected, span)).tys(a, b)
@@ -471,8 +481,8 @@ fn mk_assignty(cx: infer_ctxt, a_is_expected: bool, span: span,
     }
 }
 
-fn can_mk_assignty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
-    debug!("can_mk_assignty(%s -> %s)", a.to_str(cx), b.to_str(cx));
+fn can_mk_assignty(cx: @InferCtxt, a: ty::t, b: ty::t) -> ures {
+    debug!("can_mk_assignty(%s -> %s)", a.inf_str(cx), b.inf_str(cx));
     do indent {
         do cx.probe {
             let span = ast_util::dummy_sp();
@@ -482,18 +492,18 @@ fn can_mk_assignty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
 }
 
 // See comment on the type `resolve_state` below
-fn resolve_type(cx: infer_ctxt, a: ty::t, modes: uint)
+fn resolve_type(cx: @InferCtxt, a: ty::t, modes: uint)
     -> fres<ty::t> {
     resolver(cx, modes).resolve_type_chk(a)
 }
 
-fn resolve_region(cx: infer_ctxt, r: ty::Region, modes: uint)
+fn resolve_region(cx: @InferCtxt, r: ty::Region, modes: uint)
     -> fres<ty::Region> {
     resolver(cx, modes).resolve_region_chk(r)
 }
 
 /*
-fn resolve_borrowings(cx: infer_ctxt) {
+fn resolve_borrowings(cx: @InferCtxt) {
     for cx.borrowings.each |item| {
         match resolve_region(cx, item.scope, resolve_all|force_all) {
           Ok(region) => {
@@ -555,13 +565,14 @@ fn compare(t: T, f: fn() -> ty::type_err) -> cres<T> {
     }
 }
 
-fn uok() -> ures {
+pub fn uok() -> ures {
     Ok(())
 }
 
-fn rollback_to<V:Copy vid, T:Copy>(
-    vb: &vals_and_bindings<V, T>, len: uint) {
-
+fn rollback_to<V:Copy Vid, T:Copy>(
+    vb: &ValsAndBindings<V, T>,
+    len: uint)
+{
     while vb.bindings.len() != len {
         let (vid, old_v) = vb.bindings.pop();
         vb.vals.insert(vid.to_uint(), old_v);
@@ -574,12 +585,12 @@ struct Snapshot {
     region_vars_snapshot: uint,
 }
 
-impl infer_ctxt {
+impl @InferCtxt {
     fn combine_fields(a_is_expected: bool,
-                      span: span) -> combine_fields {
-        combine_fields {infcx: self,
-                        a_is_expected: a_is_expected,
-                        span: span}
+                      span: span) -> CombineFields {
+        CombineFields {infcx: self,
+                       a_is_expected: a_is_expected,
+                       span: span}
     }
 
     fn sub(a_is_expected: bool, span: span) -> Sub {
@@ -609,8 +620,7 @@ fn rollback_to(snapshot: &Snapshot) {
         //rollback_to(&self.int_var_bindings,
         //            snapshot.int_var_bindings_len);
 
-        self.region_vars.rollback_to(
-            snapshot.region_vars_snapshot);
+        self.region_vars.rollback_to(snapshot.region_vars_snapshot);
     }
 
     /// Execute `f` and commit the bindings if successful
@@ -654,12 +664,12 @@ fn probe<T,E>(f: fn() -> Result<T,E>) -> Result<T,E> {
     }
 }
 
-impl infer_ctxt {
+impl @InferCtxt {
     fn next_ty_var_id() -> TyVid {
-        let id = *self.ty_var_counter;
-        *self.ty_var_counter += 1u;
+        let id = self.ty_var_counter;
+        self.ty_var_counter += 1;
         self.ty_var_bindings.vals.insert(id,
-                                         root({lb: None, ub: None}, 0u));
+                                         Root({lb: None, ub: None}, 0u));
         return TyVid(id);
     }
 
@@ -672,11 +682,10 @@ fn next_ty_vars(n: uint) -> ~[ty::t] {
     }
 
     fn next_int_var_id() -> IntVid {
-        let id = *self.int_var_counter;
-        *self.int_var_counter += 1u;
+        let id = self.int_var_counter;
+        self.int_var_counter += 1;
 
-        self.int_var_bindings.vals.insert(id,
-                              root(int_ty_set_all(), 0u));
+        self.int_var_bindings.vals.insert(id, Root(None, 0));
         return IntVid(id);
     }
 
@@ -685,10 +694,10 @@ fn next_int_var() -> ty::t {
     }
 
     fn next_float_var_id() -> FloatVid {
-        let id = *self.float_var_counter;
-        *self.float_var_counter += 1;
+        let id = self.float_var_counter;
+        self.float_var_counter += 1;
 
-        self.float_var_bindings.vals.insert(id, root(float_ty_set_all(), 0));
+        self.float_var_bindings.vals.insert(id, Root(None, 0));
         return FloatVid(id);
     }
 
@@ -737,9 +746,8 @@ fn type_error_message(sp: span, mk_msg: fn(~str) -> ~str,
         let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
 
         // Don't report an error if actual type is ty_err.
-        match ty::get(actual_ty).sty {
-            ty::ty_err => return,
-            _           => ()
+        if ty::type_contains_err(actual_ty) {
+            return;
         }
         let error_str = err.map_default(~"", |t_err|
                          fmt!(" (%s)",
@@ -771,10 +779,10 @@ fn report_mismatched_types(sp: span, e: ty::t, a: ty::t,
 
     fn replace_bound_regions_with_fresh_regions(
         &self, span: span,
-        fty: &ty::FnTy) -> (ty::FnTy, isr_alist)
+        fsig: &ty::FnSig) -> (ty::FnSig, isr_alist)
     {
-        let {fn_ty: fn_ty, isr: isr, _} =
-            replace_bound_regions_in_fn_ty(self.tcx, @Nil, None, fty, |br| {
+        let {fn_sig: fn_sig, isr: isr, _} =
+            replace_bound_regions_in_fn_sig(self.tcx, @Nil, None, fsig, |br| {
                 // N.B.: The name of the bound region doesn't have anything to
                 // do with the region variable that's created for it.  The
                 // only thing we're doing with `br` here is using it in the
@@ -785,7 +793,17 @@ fn replace_bound_regions_with_fresh_regions(
                        rvar);
                 rvar
             });
-        (fn_ty, isr)
+        (fn_sig, isr)
+    }
+
+    fn fold_regions_in_sig(
+        &self,
+        fn_sig: &ty::FnSig,
+        fldr: &fn(r: ty::Region, in_fn: bool) -> ty::Region) -> ty::FnSig
+    {
+        do ty::fold_sig(fn_sig) |t| {
+            ty::fold_regions(self.tcx, t, fldr)
+        }
     }
 
 }
index 99d636559dbc26c05ed771c47480a2ce859a287d..54854bed65e31e72c6152431cf5808110605b12f 100644 (file)
@@ -337,6 +337,61 @@ fn<a>(&a/T) <: fn<b>(&b/T)
 LUB or GLB computation.  We have to consider this.  Here is the
 algorithm I implemented.
 
+First though, let's discuss what we are trying to compute in more
+detail.  The LUB is basically the "common supertype" and the GLB is
+"common subtype"; one catch is that the LUB should be the
+*most-specific* common supertype and the GLB should be *most general*
+common subtype (as opposed to any common supertype or any common
+subtype).
+
+Anyway, to help clarify, here is a table containing some
+function pairs and their LUB/GLB:
+
+```
+Type 1              Type 2              LUB               GLB
+fn<a>(&a)           fn(&X)              fn(&X)            fn<a>(&a)
+fn(&A)              fn(&X)              --                fn<a>(&a)
+fn<a,b>(&a, &b)     fn<x>(&x, &x)       fn<a>(&a, &a)     fn<a,b>(&a, &b)
+fn<a,b>(&a, &b, &a) fn<x,y>(&x, &y, &y) fn<a>(&a, &a, &a) fn<a,b,c>(&a,&b,&c)
+```
+
+### Conventions
+
+I use lower-case letters (e.g., `&a`) for bound regions and upper-case
+letters for free regions (`&A`).  Region variables written with a
+dollar-sign (e.g., `$a`).  I will try to remember to enumerate the
+bound-regions on the fn type as well (e.g., `fn<a>(&a)`).
+
+### High-level summary
+
+Both the LUB and the GLB algorithms work in a similar fashion.  They
+begin by replacing all bound regions (on both sides) with fresh region
+inference variables.  Therefore, both functions are converted to types
+that contain only free regions.  We can then compute the LUB/GLB in a
+straightforward way, as described in `combine.rs`.  This results in an
+interim type T.  The algorithms then examine the regions that appear
+in T and try to, in some cases, replace them with bound regions to
+yield the final result.
+
+To decide whether to replace a region `R` that appears in `T` with a
+bound region, the algorithms make use of two bits of information.
+First is a set `V` that contains all region variables created as part
+of the LUB/GLB computation. `V` will contain the region variables
+created to replace the bound regions in the input types, but it also
+contains 'intermediate' variables created to represent the LUB/GLB of
+individual regions.  Basically, when asked to compute the LUB/GLB of a
+region variable with another region, the inferencer cannot oblige
+immediately since the valuese of that variables are not known.
+Therefore, it creates a new variable that is related to the two
+regions.  For example, the LUB of two variables `$x` and `$y` is a
+fresh variable `$z` that is constrained such that `$x <= $z` and `$y
+<= $z`.  So `V` will contain these intermediate variables as well.
+
+The other important factor in deciding how to replace a region in T is
+the function `Tainted($r)` which, for a region variable, identifies
+all regions that the region variable is related to in some way
+(`Tainted()` made an appearance in the subtype computation as well).
+
 ### LUB
 
 The LUB algorithm proceeds in three steps:
@@ -345,47 +400,28 @@ fn<a>(&a/T) <: fn<b>(&b/T)
    inference variables.
 2. Compute the LUB "as normal", meaning compute the GLB of each
    pair of argument types and the LUB of the return types and
-   so forth.  Combine those to a new function type F.
-3. Map the regions appearing in `F` using the procedure described below.
-
-For each region `R` that appears in `F`, we may need to replace it
-with a bound region.  Let `V` be the set of fresh variables created as
-part of the LUB procedure (either in step 1 or step 2).  You may be
-wondering how variables can be created in step 2.  The answer is that
-when we are asked to compute the LUB or GLB of two region variables,
-we do so by producing a new region variable that is related to those
-two variables.  i.e., The LUB of two variables `$x` and `$y` is a
-fresh variable `$z` that is constrained such that `$x <= $z` and `$y
-<= $z`.
-
-To decide how to replace a region `R`, we must examine `Tainted(R)`.
-This function searches through the constraints which were generated
-when computing the bounds of all the argument and return types and
-produces a list of all regions to which `R` is related, directly or
-indirectly.
-
-If `R` is not in `V` or `Tainted(R)` contains any region that is not
-in `V`, then `R` is not replaced (that is, `R` is mapped to itself).
-Otherwise, if `Tainted(R)` is a subset of `V`, then we select the
-earliest variable in `Tainted(R)` that originates from the left-hand
-side and replace `R` with a bound version of that variable.
-
-So, let's work through the simplest example: `fn(&A)` and `fn(&a)`.
-In this case, `&a` will be replaced with `$a` (the $ indicates an
-inference variable) which will be linked to the free region `&A`, and
-hence `V = { $a }` and `Tainted($a) = { &A }`.  Since `$a` is not a
-member of `V`, we leave `$a` as is.  When region inference happens,
-`$a` will be resolved to `&A`, as we wanted.
-
-So, let's work through the simplest example: `fn(&A)` and `fn(&a)`.
-In this case, `&a` will be replaced with `$a` (the $ indicates an
-inference variable) which will be linked to the free region `&A`, and
-hence `V = { $a }` and `Tainted($a) = { $a, &A }`.  Since `&A` is not a
-member of `V`, we leave `$a` as is.  When region inference happens,
-`$a` will be resolved to `&A`, as we wanted.
-
-Let's look at a more complex one: `fn(&a, &b)` and `fn(&x, &x)`.
-In this case, we'll end up with a graph that looks like:
+   so forth.  Combine those to a new function type `F`.
+3. Replace each region `R` that appears in `F` as follows:
+   - Let `V` be the set of variables created during the LUB
+     computational steps 1 and 2, as described in the previous section.
+   - If `R` is not in `V`, replace `R` with itself.
+   - If `Tainted(R)` contains a region that is not in `V`,
+     replace `R` with itself.
+   - Otherwise, select the earliest variable in `Tainted(R)` that originates
+     from the left-hand side and replace `R` with the bound region that
+     this variable was a replacement for.
+
+So, let's work through the simplest example: `fn(&A)` and `fn<a>(&a)`.
+In this case, `&a` will be replaced with `$a` and the interim LUB type
+`fn($b)` will be computed, where `$b=GLB(&A,$a)`.  Therefore, `V =
+{$a, $b}` and `Tainted($b) = { $b, $a, &A }`.  When we go to replace
+`$b`, we find that since `&A \in Tainted($b)` is not a member of `V`,
+we leave `$b` as is.  When region inference happens, `$b` will be
+resolved to `&A`, as we wanted.
+
+Let's look at a more complex one: `fn(&a, &b)` and `fn(&x, &x)`.  In
+this case, we'll end up with a (pre-replacement) LUB type of `fn(&g,
+&h)` and a graph that looks like:
 
 ```
      $a        $b     *--$x
@@ -399,8 +435,8 @@ fn<a>(&a/T) <: fn<b>(&b/T)
 `Tainted` will look like:
 
 ```
-V = {$a, $b, $x}
-Tainted($g) = Tainted($h) = { $a, $b, $h, $x }
+V = {$a, $b, $g, $h, $x}
+Tainted($g) = Tainted($h) = { $a, $b, $h, $g, $x }
 ```
 
 Therefore we replace both `$g` and `$h` with `$a`, and end up
@@ -413,59 +449,121 @@ fn<a>(&a/T) <: fn<b>(&b/T)
 region `R` that appears in the type `F`, we again compute `Tainted(R)`
 and examine the results:
 
-1. If `Tainted(R) = {R}` is a singleton set, replace `R` with itself.
+1. If `R` is not in `V`, it is not replaced.
 2. Else, if `Tainted(R)` contains only variables in `V`, and it
    contains exactly one variable from the LHS and one variable from
    the RHS, then `R` can be mapped to the bound version of the
    variable from the LHS.
-3. Else, `R` is mapped to a fresh bound variable.
+3. Else, if `Tainted(R)` contains no variable from the LHS and no
+   variable from the RHS, then `R` can be mapped to itself.
+4. Else, `R` is mapped to a fresh bound variable.
 
 These rules are pretty complex.  Let's look at some examples to see
 how they play out.
 
-Out first example was `fn(&a)` and `fn(&X)`---in
-this case, the LUB will be a variable `$g`, and `Tainted($g) =
-{$g,$a,$x}`.  By these rules, we'll replace `$g` with a fresh bound
-variable, so the result is `fn(&z)`, which is fine.
-
-The next example is `fn(&A)` and `fn(&Z)`. XXX
-
-The next example is `fn(&a, &b)` and `fn(&x, &x)`. In this case, as
-before, we'll end up with `F=fn(&g, &h)` where `Tainted($g) =
-Tainted($h) = {$g, $a, $b, $x}`.  This means that we'll select fresh
-bound varibales `g` and `h` and wind up with `fn(&g, &h)`.
+Out first example was `fn(&a)` and `fn(&X)`.  In this case, `&a` will
+be replaced with `$a` and we will ultimately compute a
+(pre-replacement) GLB type of `fn($g)` where `$g=LUB($a,&X)`.
+Therefore, `V={$a,$g}` and `Tainted($g)={$g,$a,&X}.  To find the
+replacement for `$g` we consult the rules above:
+- Rule (1) does not apply because `$g \in V`
+- Rule (2) does not apply because `&X \in Tainted($g)`
+- Rule (3) does not apply because `$a \in Tainted($g)`
+- Hence, by rule (4), we replace `$g` with a fresh bound variable `&z`.
+So our final result is `fn(&z)`, which is correct.
+
+The next example is `fn(&A)` and `fn(&Z)`. In this case, we will again
+have a (pre-replacement) GLB of `fn(&g)`, where `$g = LUB(&A,&Z)`.
+Therefore, `V={$g}` and `Tainted($g) = {$g, &A, &Z}`.  In this case,
+by rule (3), `$g` is mapped to itself, and hence the result is
+`fn($g)`.  This result is correct (in this case, at least), but it is
+indicative of a case that *can* lead us into concluding that there is
+no GLB when in fact a GLB does exist.  See the section "Questionable
+Results" below for more details.
+
+The next example is `fn(&a, &b)` and `fn(&c, &c)`. In this case, as
+before, we'll end up with `F=fn($g, $h)` where `Tainted($g) =
+Tainted($h) = {$g, $h, $a, $b, $c}`.  Only rule (4) applies and hence
+we'll select fresh bound variables `y` and `z` and wind up with
+`fn(&y, &z)`.
 
 For the last example, let's consider what may seem trivial, but is
-not: `fn(&a, &a)` and `fn(&x, &x)`.  In this case, we'll get `F=fn(&g,
-&h)` where `Tainted($g) = {$g, $a, $x}` and `Tainted($h) = {$h, $a,
+not: `fn(&a, &a)` and `fn(&b, &b)`.  In this case, we'll get `F=fn($g,
+$h)` where `Tainted($g) = {$g, $a, $x}` and `Tainted($h) = {$h, $a,
 $x}`.  Both of these sets contain exactly one bound variable from each
-side, so we'll map them both to `&a`, resulting in `fn(&a, &a)`.
-Horray!
-
-### Why are these correct?
-
-You may be wondering whether this algorithm is correct.  So am I.  But
-I believe it is.  (Justification forthcoming, haven't had time to
-write it)
+side, so we'll map them both to `&a`, resulting in `fn(&a, &a)`, which
+is the desired result.
+
+### Shortcomings and correctness
+
+You may be wondering whether this algorithm is correct.  The answer is
+"sort of".  There are definitely cases where they fail to compute a
+result even though a correct result exists.  I believe, though, that
+if they succeed, then the result is valid, and I will attempt to
+convince you.  The basic argument is that the "pre-replacement" step
+computes a set of constraints.  The replacements, then, attempt to
+satisfy those constraints, using bound identifiers where needed.
+
+For now I will briefly go over the cases for LUB/GLB and identify
+their intent:
+
+- LUB:
+  - The region variables that are substituted in place of bound regions
+    are intended to collect constraints on those bound regions.
+  - If Tainted(R) contains only values in V, then this region is unconstrained
+    and can therefore be generalized, otherwise it cannot.
+- GLB:
+  - The region variables that are substituted in place of bound regions
+    are intended to collect constraints on those bound regions.
+  - If Tainted(R) contains exactly one variable from each side, and
+    only variables in V, that indicates that those two bound regions
+    must be equated.
+  - Otherwise, if Tainted(R) references any variables from left or right
+    side, then it is trying to combine a bound region with a free one or
+    multiple bound regions, so we need to select fresh bound regions.
+
+Sorry this is more of a shorthand to myself.  I will try to write up something
+more convincing in the future.
+
+#### Where are the algorithms wrong?
+
+- The pre-replacement computation can fail even though using a
+  bound-region would have succeeded.
+- We will compute GLB(fn(fn($a)), fn(fn($b))) as fn($c) where $c is the
+  GLB of $a and $b.  But if inference finds that $a and $b must be mapped
+  to regions without a GLB, then this is effectively a failure to compute
+  the GLB.  However, the result `fn<$c>(fn($c))` is a valid GLB.
 
 */
 
 #[warn(deprecated_mode)];
 #[warn(deprecated_pattern)];
 
+use core::prelude::*;
+
 use middle::region::is_subregion_of;
+use middle::region;
+use middle::ty;
 use middle::ty::{Region, RegionVid, re_static, re_infer, re_free, re_bound};
-use middle::ty::{re_scope, ReVar, ReSkolemized};
-use middle::typeck::infer::to_str::ToStr;
+use middle::ty::{re_scope, ReVar, ReSkolemized, br_fresh};
+use middle::typeck::infer::to_str::InferStr;
+use middle::typeck::infer::cres;
 use syntax::codemap;
+use util::common::indenter;
 use util::ppaux::note_and_explain_region;
 
+use core::cmp;
 use core::dvec::DVec;
+use core::to_bytes;
+use core::uint;
+use core::vec;
 use result::Result;
 use result::{Ok, Err};
 use std::map::HashMap;
 use std::cell::{Cell, empty_cell};
 use std::list::{List, Nil, Cons};
+use syntax::codemap::span;
+use syntax::codemap;
 
 export RegionVarBindings;
 export make_subregion;
@@ -547,6 +645,7 @@ struct RegionVarBindings {
     lubs: CombineMap,
     glbs: CombineMap,
     mut skolemization_count: uint,
+    mut bound_count: uint,
 
     // The undo log records actions that might later be undone.
     //
@@ -573,6 +672,7 @@ fn RegionVarBindings(tcx: ty::ctxt) -> RegionVarBindings {
         lubs: CombineMap(),
         glbs: CombineMap(),
         skolemization_count: 0,
+        bound_count: 0,
         undo_log: ~[]
     }
 }
@@ -649,6 +749,26 @@ fn new_skolemized(&self, br: ty::bound_region) -> Region {
         re_infer(ReSkolemized(sc, br))
     }
 
+    fn new_bound(&self) -> Region {
+        // Creates a fresh bound variable for use in GLB computations.
+        // See discussion of GLB computation in the large comment at
+        // the top of this file for more details.
+        //
+        // This computation is mildly wrong in the face of rollover.
+        // It's conceivable, if unlikely, that one might wind up with
+        // accidental capture for nested functions in that case, if
+        // the outer function had bound regions created a very long
+        // time before and the inner function somehow wound up rolling
+        // over such that supposedly fresh identifiers were in fact
+        // shadowed.  We should convert our bound_region
+        // representation to use deBruijn indices or something like
+        // that to eliminate that possibility.
+
+        let sc = self.bound_count;
+        self.bound_count += 1;
+        re_bound(br_fresh(sc))
+    }
+
     fn add_constraint(&self, +constraint: Constraint, span: span) {
         // cannot add constraints once regions are resolved
         assert self.values.is_empty();
@@ -681,6 +801,16 @@ fn make_subregion(&self, span: span,
             self.add_constraint(ConstrainVarSubReg(sub_id, r), span);
             Ok(())
           }
+          (re_bound(br), _) => {
+            self.tcx.sess.span_bug(
+                span,
+                fmt!("Cannot relate bound region as subregion: %?", br));
+          }
+          (_, re_bound(br)) => {
+            self.tcx.sess.span_bug(
+                span,
+                fmt!("Cannot relate bound region as superregion: %?", br));
+          }
           _ => {
             if self.is_subregion_of(sub, sup) {
                 Ok(())
index 91689ff06ddc9e6e850423132c8bcb17531afc8d..23be3b208271c55d0fac4884e2e6c3378503ced4 100644 (file)
 // future).  If you want to resolve everything but one type, you are
 // probably better off writing `resolve_all - resolve_ivar`.
 
-use middle::typeck::infer::floating::*;
-use middle::typeck::infer::integral::*;
-use middle::typeck::infer::to_str::ToStr;
-
-const resolve_nested_tvar: uint = 0b00000001;
-const resolve_rvar: uint        = 0b00000010;
-const resolve_ivar: uint        = 0b00000100;
-const resolve_fvar: uint        = 0b00001000;
-const resolve_all: uint         = 0b00001111;
-const force_tvar: uint          = 0b00010000;
-const force_rvar: uint          = 0b00100000;
-const force_ivar: uint          = 0b01000000;
-const force_fvar: uint          = 0b11000000;
-const force_all: uint           = 0b11110000;
+use core::prelude::*;
+
+use middle::ty::{FloatVar, FloatVid, IntVar, IntVid, RegionVid, TyVar, TyVid};
+use middle::ty::{type_is_bot};
+use middle::ty;
+use middle::typeck::infer::{cyclic_ty, fixup_err, fres, InferCtxt};
+use middle::typeck::infer::{region_var_bound_by_region_var, unresolved_ty};
+use middle::typeck::infer::{IntType, UintType};
+use middle::typeck::infer::to_str::InferStr;
+use middle::typeck::infer::unify::Root;
+use util::common::{indent, indenter};
+use util::ppaux::ty_to_str;
+
+use syntax::ast;
+
+use core::uint;
+use core::vec;
+
+const resolve_nested_tvar: uint = 0b0000000001;
+const resolve_rvar: uint        = 0b0000000010;
+const resolve_ivar: uint        = 0b0000000100;
+const resolve_fvar: uint        = 0b0000001000;
+const resolve_fnvar: uint       = 0b0000010000;
+const resolve_all: uint         = 0b0000011111;
+const force_tvar: uint          = 0b0000100000;
+const force_rvar: uint          = 0b0001000000;
+const force_ivar: uint          = 0b0010000000;
+const force_fvar: uint          = 0b0100000000;
+const force_fnvar: uint         = 0b1000000000;
+const force_all: uint           = 0b1111100000;
 
 const not_regions: uint         = !(force_rvar | resolve_rvar);
 
 const resolve_and_force_all_but_regions: uint =
     (resolve_all | force_all) & not_regions;
 
-type resolve_state_ = {
-    infcx: infer_ctxt,
+struct ResolveState {
+    infcx: @InferCtxt,
     modes: uint,
     mut err: Option<fixup_err>,
-    mut v_seen: ~[TyVid]
-};
-
-enum resolve_state {
-    resolve_state_(@resolve_state_)
+    mut v_seen: ~[TyVid],
+    mut type_depth: uint
 }
 
-fn resolver(infcx: infer_ctxt, modes: uint) -> resolve_state {
-    resolve_state_(@{infcx: infcx,
-                     modes: modes,
-                     mut err: None,
-                     mut v_seen: ~[]})
+fn resolver(infcx: @InferCtxt, modes: uint) -> ResolveState {
+    ResolveState {
+        infcx: infcx,
+        modes: modes,
+        err: None,
+        v_seen: ~[],
+        type_depth: 0
+    }
 }
 
-impl resolve_state {
-    fn should(mode: uint) -> bool {
+impl ResolveState {
+    fn should(&self, mode: uint) -> bool {
         (self.modes & mode) == mode
     }
 
-    fn resolve_type_chk(typ: ty::t) -> fres<ty::t> {
+    fn resolve_type_chk(&self, typ: ty::t) -> fres<ty::t> {
         self.err = None;
 
         debug!("Resolving %s (modes=%x)",
@@ -104,7 +120,8 @@ fn resolve_type_chk(typ: ty::t) -> fres<ty::t> {
         assert vec::is_empty(self.v_seen);
         match self.err {
           None => {
-            debug!("Resolved to %s (modes=%x)",
+            debug!("Resolved to %s + %s (modes=%x)",
+                   ty_to_str(self.infcx.tcx, rty),
                    ty_to_str(self.infcx.tcx, rty),
                    self.modes);
             return Ok(rty);
@@ -113,7 +130,7 @@ fn resolve_type_chk(typ: ty::t) -> fres<ty::t> {
         }
     }
 
-    fn resolve_region_chk(orig: ty::Region) -> fres<ty::Region> {
+    fn resolve_region_chk(&self, orig: ty::Region) -> fres<ty::Region> {
         self.err = None;
         let resolved = indent(|| self.resolve_region(orig) );
         match self.err {
@@ -122,63 +139,64 @@ fn resolve_region_chk(orig: ty::Region) -> fres<ty::Region> {
         }
     }
 
-    fn resolve_type(typ: ty::t) -> ty::t {
-        debug!("resolve_type(%s)", typ.to_str(self.infcx));
-        indent(fn&() -> ty::t {
-            if !ty::type_needs_infer(typ) { return typ; }
+    fn resolve_type(&self, typ: ty::t) -> ty::t {
+        debug!("resolve_type(%s)", typ.inf_str(self.infcx));
+        let _i = indenter();
+
+        if !ty::type_needs_infer(typ) {
+            return typ;
+        }
+
+        if self.type_depth > 0 && !self.should(resolve_nested_tvar) {
+            return typ;
+        }
 
-            match ty::get(typ).sty {
-              ty::ty_infer(TyVar(vid)) => {
+        match /*bad*/ copy ty::get(typ).sty {
+            ty::ty_infer(TyVar(vid)) => {
                 self.resolve_ty_var(vid)
-              }
-              ty::ty_infer(IntVar(vid)) => {
+            }
+            ty::ty_infer(IntVar(vid)) => {
                 self.resolve_int_var(vid)
-              }
-              ty::ty_infer(FloatVar(vid)) => {
+            }
+            ty::ty_infer(FloatVar(vid)) => {
                 self.resolve_float_var(vid)
-              }
-              _ => {
-                if !self.should(resolve_rvar) &&
-                    !self.should(resolve_nested_tvar) {
-                    // shortcircuit for efficiency
+            }
+            _ => {
+                if self.modes & resolve_all == 0 {
+                    // if we are only resolving top-level type
+                    // variables, and this is not a top-level type
+                    // variable, then shortcircuit for efficiency
                     typ
                 } else {
-                    ty::fold_regions_and_ty(
+                    self.type_depth += 1;
+                    let result = ty::fold_regions_and_ty(
                         self.infcx.tcx, typ,
                         |r| self.resolve_region(r),
-                        |t| self.resolve_nested_tvar(t),
-                        |t| self.resolve_nested_tvar(t))
+                        |t| self.resolve_type(t),
+                        |t| self.resolve_type(t));
+                    self.type_depth -= 1;
+                    result
                 }
-              }
             }
-        })
-    }
-
-    fn resolve_nested_tvar(typ: ty::t) -> ty::t {
-        debug!("Resolve_if_deep(%s)", typ.to_str(self.infcx));
-        if !self.should(resolve_nested_tvar) {
-            typ
-        } else {
-            self.resolve_type(typ)
         }
     }
 
-    fn resolve_region(orig: ty::Region) -> ty::Region {
-        debug!("Resolve_region(%s)", orig.to_str(self.infcx));
+    fn resolve_region(&self, orig: ty::Region) -> ty::Region {
+        debug!("Resolve_region(%s)", orig.inf_str(self.infcx));
         match orig {
           ty::re_infer(ty::ReVar(rid)) => self.resolve_region_var(rid),
           _ => orig
         }
     }
 
-    fn resolve_region_var(rid: RegionVid) -> ty::Region {
+    fn resolve_region_var(&self, rid: RegionVid) -> ty::Region {
         if !self.should(resolve_rvar) {
             return ty::re_infer(ty::ReVar(rid));
         }
         self.infcx.region_vars.resolve_var(rid)
     }
 
-    fn assert_not_rvar(rid: RegionVid, r: ty::Region) {
+    fn assert_not_rvar(&self, rid: RegionVid, r: ty::Region) {
         match r {
           ty::re_infer(ty::ReVar(rid2)) => {
             self.err = Some(region_var_bound_by_region_var(rid, rid2));
@@ -187,7 +205,7 @@ fn assert_not_rvar(rid: RegionVid, r: ty::Region) {
         }
     }
 
-    fn resolve_ty_var(vid: TyVid) -> ty::t {
+    fn resolve_ty_var(&self, vid: TyVid) -> ty::t {
         if vec::contains(self.v_seen, &vid) {
             self.err = Some(cyclic_ty(vid));
             return ty::mk_var(self.infcx.tcx, vid);
@@ -220,27 +238,22 @@ fn resolve_ty_var(vid: TyVid) -> ty::t {
         }
     }
 
-    fn resolve_int_var(vid: IntVid) -> ty::t {
+    fn resolve_int_var(&self, vid: IntVid) -> ty::t {
         if !self.should(resolve_ivar) {
             return ty::mk_int_var(self.infcx.tcx, vid);
         }
 
-        let nde = self.infcx.get(&self.infcx.int_var_bindings, vid);
-        let pt = nde.possible_types;
-
-        // If there's only one type in the set of possible types, then
-        // that's the answer.
-        match integral::single_type_contained_in(self.infcx.tcx, pt) {
-          Some(t) => t,
+        let node = self.infcx.get(&self.infcx.int_var_bindings, vid);
+        match node.possible_types {
+          Some(IntType(t)) => ty::mk_mach_int(self.infcx.tcx, t),
+          Some(UintType(t)) => ty::mk_mach_uint(self.infcx.tcx, t),
           None => {
             if self.should(force_ivar) {
                 // As a last resort, default to int.
                 let ty = ty::mk_int(self.infcx.tcx);
                 self.infcx.set(
                     &self.infcx.int_var_bindings, vid,
-                    root(convert_integral_ty_to_int_ty_set(self.infcx.tcx,
-                                                           ty),
-                        nde.rank));
+                    Root(Some(IntType(ast::ty_i)), node.rank));
                 ty
             } else {
                 ty::mk_int_var(self.infcx.tcx, vid)
@@ -249,18 +262,14 @@ fn resolve_int_var(vid: IntVid) -> ty::t {
         }
     }
 
-    fn resolve_float_var(vid: FloatVid) -> ty::t {
+    fn resolve_float_var(&self, vid: FloatVid) -> ty::t {
         if !self.should(resolve_fvar) {
             return ty::mk_float_var(self.infcx.tcx, vid);
         }
 
-        let nde = self.infcx.get(&self.infcx.float_var_bindings, vid);
-        let pt = nde.possible_types;
-
-        // If there's only one type in the set of possible types, then
-        // that's the answer.
-        match floating::single_type_contained_in(self.infcx.tcx, pt) {
-          Some(t) => t,
+        let node = self.infcx.get(&self.infcx.float_var_bindings, vid);
+        match node.possible_types {
+          Some(t) => ty::mk_mach_float(self.infcx.tcx, t),
           None => {
             if self.should(force_fvar) {
                 // As a last resort, default to float.
@@ -268,10 +277,7 @@ fn resolve_float_var(vid: FloatVid) -> ty::t {
                 self.infcx.set(
                     &self.infcx.float_var_bindings,
                     vid,
-                    root(
-                        convert_floating_point_ty_to_float_ty_set(
-                            self.infcx.tcx, ty),
-                        nde.rank));
+                    Root(Some(ast::ty_f), node.rank));
                 ty
             } else {
                 ty::mk_float_var(self.infcx.tcx, vid)
index 1cec971f15629ede46f38c6fe8353ada1b214385..aa6721fb2298390811f731ef9af8d71a05e9bc73 100644 (file)
@@ -8,34 +8,46 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use middle::ty;
+use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
 use middle::typeck::infer::combine::*;
-use middle::typeck::infer::to_str::ToStr;
+use middle::typeck::infer::cres;
+use middle::typeck::infer::glb::Glb;
+use middle::typeck::infer::InferCtxt;
+use middle::typeck::infer::lub::Lub;
+use middle::typeck::infer::to_str::InferStr;
 use middle::typeck::infer::unify::*;
+use util::ppaux::bound_region_to_str;
 
+use std::list::Nil;
 use std::list;
+use syntax::ast::{m_const, purity, ret_style};
 
 fn macros() { include!("macros.rs"); } // FIXME(#3114): Macro import/export.
 
-enum Sub = combine_fields;  // "subtype", "subregion" etc
+enum Sub = CombineFields;  // "subtype", "subregion" etc
 
-impl Sub: combine {
-    fn infcx() -> infer_ctxt { self.infcx }
+impl Sub: Combine {
+    fn infcx() -> @InferCtxt { self.infcx }
     fn tag() -> ~str { ~"sub" }
     fn a_is_expected() -> bool { self.a_is_expected }
+    fn span() -> span { self.span }
 
     fn sub() -> Sub { Sub(*self) }
     fn lub() -> Lub { Lub(*self) }
     fn glb() -> Glb { Glb(*self) }
 
     fn contratys(a: ty::t, b: ty::t) -> cres<ty::t> {
-        let opp = combine_fields {
+        let opp = CombineFields {
             a_is_expected: !self.a_is_expected,.. *self
         };
         Sub(opp).tys(b, a)
     }
 
     fn contraregions(a: ty::Region, b: ty::Region) -> cres<ty::Region> {
-        let opp = combine_fields {
+        let opp = CombineFields {
             a_is_expected: !self.a_is_expected,.. *self
         };
         Sub(opp).regions(b, a)
@@ -44,8 +56,8 @@ fn contraregions(a: ty::Region, b: ty::Region) -> cres<ty::Region> {
     fn regions(a: ty::Region, b: ty::Region) -> cres<ty::Region> {
         debug!("%s.regions(%s, %s)",
                self.tag(),
-               a.to_str(self.infcx),
-               b.to_str(self.infcx));
+               a.inf_str(self.infcx),
+               b.inf_str(self.infcx));
         do indent {
             match self.infcx.region_vars.make_subregion(self.span, a, b) {
               Ok(()) => Ok(a),
@@ -55,7 +67,7 @@ fn regions(a: ty::Region, b: ty::Region) -> cres<ty::Region> {
     }
 
     fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
-        debug!("mts(%s <: %s)", a.to_str(self.infcx), b.to_str(self.infcx));
+        debug!("mts(%s <: %s)", a.inf_str(self.infcx), b.inf_str(self.infcx));
 
         if a.mutbl != b.mutbl && b.mutbl != m_const {
             return Err(ty::terr_mutability);
@@ -74,14 +86,6 @@ fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
         }
     }
 
-    fn protos(p1: ast::Proto, p2: ast::Proto) -> cres<ast::Proto> {
-        match (p1, p2) {
-            (ast::ProtoBare, _) => Ok(p1),
-            _ if p1 == p2 => Ok(p1),
-            _ => Err(ty::terr_proto_mismatch(expected_found(&self, p1, p2)))
-        }
-    }
-
     fn purities(a: purity, b: purity) -> cres<purity> {
         self.lub().purities(a, b).compare(b, || {
             ty::terr_purity_mismatch(expected_found(&self, a, b))
@@ -94,42 +98,49 @@ fn oncenesses(a: Onceness, b: Onceness) -> cres<Onceness> {
         })
     }
 
-    fn ret_styles(a: ret_style, b: ret_style) -> cres<ret_style> {
-        self.lub().ret_styles(a, b).compare(b, || {
-            ty::terr_ret_style_mismatch(expected_found(&self, a, b))
-        })
-    }
-
     fn tys(a: ty::t, b: ty::t) -> cres<ty::t> {
         debug!("%s.tys(%s, %s)", self.tag(),
-               a.to_str(self.infcx), b.to_str(self.infcx));
+               a.inf_str(self.infcx), b.inf_str(self.infcx));
         if a == b { return Ok(a); }
         do indent {
             match (ty::get(a).sty, ty::get(b).sty) {
-              (ty::ty_bot, _) => {
-                Ok(a)
-              }
-              (ty::ty_infer(TyVar(a_id)), ty::ty_infer(TyVar(b_id))) => {
-                var_sub_var(&self, a_id, b_id).then(|| Ok(a) )
-              }
-              (ty::ty_infer(TyVar(a_id)), _) => {
-                var_sub_t(&self, a_id, b).then(|| Ok(a) )
-              }
-              (_, ty::ty_infer(TyVar(b_id))) => {
-                t_sub_var(&self, a, b_id).then(|| Ok(a) )
-              }
-              (_, ty::ty_bot) => {
-                Err(ty::terr_sorts(expected_found(&self, a, b)))
-              }
-              _ => {
-                super_tys(&self, a, b)
-              }
+                (ty::ty_bot, _) => {
+                    Ok(a)
+                }
+
+                (ty::ty_infer(TyVar(a_id)), ty::ty_infer(TyVar(b_id))) => {
+                    do self.var_sub_var(&self.infcx.ty_var_bindings,
+                                        a_id, b_id).then {
+                        Ok(a)
+                    }
+                }
+                (ty::ty_infer(TyVar(a_id)), _) => {
+                    do self.var_sub_t(&self.infcx.ty_var_bindings,
+                                      a_id, b).then {
+                        Ok(a)
+                    }
+                }
+                (_, ty::ty_infer(TyVar(b_id))) => {
+                    do self.t_sub_var(&self.infcx.ty_var_bindings,
+                                      a, b_id).then {
+                        Ok(a)
+                    }
+                }
+
+                (_, ty::ty_bot) => {
+                    Err(ty::terr_sorts(expected_found(&self, a, b)))
+                }
+
+                _ => {
+                    super_tys(&self, a, b)
+                }
             }
         }
     }
 
-    fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
-        debug!("fns(a=%s, b=%s)", a.to_str(self.infcx), b.to_str(self.infcx));
+    fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
+        debug!("fn_sigs(a=%s, b=%s)",
+               a.inf_str(self.infcx), b.inf_str(self.infcx));
         let _indenter = indenter();
 
         // Rather than checking the subtype relationship between `a` and `b`
@@ -147,14 +158,14 @@ fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
 
         // First, we instantiate each bound region in the subtype with a fresh
         // region variable.
-        let (a_fn_ty, _) =
+        let (a_sig, _) =
             self.infcx.replace_bound_regions_with_fresh_regions(
                 self.span, a);
 
         // Second, we instantiate each bound region in the supertype with a
         // fresh concrete region.
-        let {fn_ty: b_fn_ty, isr: skol_isr, _} = {
-            do replace_bound_regions_in_fn_ty(self.infcx.tcx, @Nil,
+        let {fn_sig: b_sig, isr: skol_isr, _} = {
+            do replace_bound_regions_in_fn_sig(self.infcx.tcx, @Nil,
                                               None, b) |br| {
                 let skol = self.infcx.region_vars.new_skolemized(br);
                 debug!("Bound region %s skolemized to %?",
@@ -164,11 +175,11 @@ fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
             }
         };
 
-        debug!("a_fn_ty=%s", a_fn_ty.to_str(self.infcx));
-        debug!("b_fn_ty=%s", b_fn_ty.to_str(self.infcx));
+        debug!("a_sig=%s", a_sig.inf_str(self.infcx));
+        debug!("b_sig=%s", b_sig.inf_str(self.infcx));
 
         // Compare types now that bound regions have been replaced.
-        let fn_ty = if_ok!(super_fns(&self, &a_fn_ty, &b_fn_ty));
+        let sig = if_ok!(super_fn_sigs(&self, &a_sig, &b_sig));
 
         // Presuming type comparison succeeds, we need to check
         // that the skolemized regions do not "leak".
@@ -200,21 +211,25 @@ fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
             }
         }
 
-        return Ok(fn_ty)
+        return Ok(sig);
     }
 
     // Traits please (FIXME: #2794):
 
+    fn protos(p1: ast::Proto, p2: ast::Proto) -> cres<ast::Proto> {
+        super_protos(&self, p1, p2)
+    }
+
     fn flds(a: ty::field, b: ty::field) -> cres<ty::field> {
         super_flds(&self, a, b)
     }
 
-    fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres<ty::FnMeta> {
-        super_fn_metas(&self, a, b)
+    fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
+        super_fns(&self, a, b)
     }
 
-    fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
-        super_fn_sigs(&self, a, b)
+    fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres<ty::FnMeta> {
+        super_fn_metas(&self, a, b)
     }
 
     fn vstores(vk: ty::terr_vstore_kind,
index c585b45e7ac00b6f9193a7ea00a5e460aef810a0..5f85d6c4268e2ce0d2b1a362fd42f5e789bc8343 100644 (file)
 
 */
 
-use std::getopts;
-use std::map::HashMap;
-use std::getopts;
-use std::getopts::{opt_present};
-use std::getopts::groups;
-use std::getopts::groups::{optopt, optmulti, optflag, optflagopt, getopts};
-use driver::driver::{optgroups, build_session_options, build_session,
-                     str_input, build_configuration};
+use core::prelude::*;
+
 use driver::diagnostic;
-use syntax::{ast, attr, parse};
-use syntax::parse::parse_crate_from_source_str;
+use driver::driver::{optgroups, build_session_options, build_session};
+use driver::driver::{str_input, build_configuration};
 use middle::lang_items::{LanguageItems, language_items};
+use middle::ty::{FnTyBase, FnMeta, FnSig};
 use util::ppaux::ty_to_str;
+
+use std::getopts::groups::{optopt, optmulti, optflag, optflagopt, getopts};
+use std::getopts::groups;
+use std::getopts::{opt_present};
+use std::getopts;
+use std::getopts;
+use std::map::HashMap;
 use syntax::ast_util::dummy_sp;
-use middle::ty::{FnTyBase, FnMeta, FnSig};
+use syntax::parse::parse_crate_from_source_str;
+use syntax::{ast, attr, parse};
 
 struct Env {
     crate: @ast::crate,
     tcx: ty::ctxt,
-    infcx: infer::infer_ctxt
+    infcx: infer::infer_ctxt,
+    err_messages: @DVec<~str>
 }
 
 struct RH {
@@ -43,17 +47,21 @@ struct RH {
     sub: &[RH]
 }
 
+const EMPTY_SOURCE_STR: &str = "/* Hello, world! */";
+
 fn setup_env(test_name: &str, source_string: &str) -> Env {
-    let matches = &getopts(~[~"-Z", ~"verbose"], optgroups()).get();
-    let sessopts = build_session_options(~"rustc", matches, diagnostic::emit);
-    let sess = build_session(sessopts, diagnostic::emit);
+    let messages = @DVec();
+    let matches = getopts(~[~"-Z", ~"verbose"], optgroups()).get();
+    let diag = diagnostic::collect(messages);
+    let sessopts = build_session_options(~"rustc", &matches, diag);
+    let sess = build_session(sessopts, diag);
     let cfg = build_configuration(sess, ~"whatever", str_input(~""));
     let dm = HashMap();
     let amap = HashMap();
     let freevars = HashMap();
     let region_paramd_items = HashMap();
     let region_map = HashMap();
-    let lang_items = language_items::make();
+    let lang_items = LanguageItems::new();
 
     let parse_sess = parse::new_parse_sess(None);
     let crate = parse_crate_from_source_str(
@@ -65,7 +73,10 @@ fn setup_env(test_name: &str, source_string: &str) -> Env {
 
     let infcx = infer::new_infer_ctxt(tcx);
 
-    return Env { crate: crate, tcx: tcx, infcx: infcx };
+    return Env {crate: crate,
+                tcx: tcx,
+                infcx: infcx,
+                err_messages: messages};
 }
 
 impl Env {
@@ -180,8 +191,7 @@ fn t_fn(&self, input_tys: &[ty::t], output_ty: ty::t) -> ty::t {
                           proto: ast::ProtoBare,
                           onceness: ast::Many,
                           region: ty::re_static,
-                          bounds: @~[],
-                          ret_style: ast::return_val},
+                          bounds: @~[]},
             sig: FnSig {inputs: move inputs,
                         output: output_ty}
         })
@@ -210,6 +220,22 @@ fn t_rptr_static(&self) -> ty::t {
 
     fn lub() -> Lub { Lub(self.infcx.combine_fields(true, dummy_sp())) }
 
+    fn glb() -> Glb { Glb(self.infcx.combine_fields(true, dummy_sp())) }
+
+    fn resolve_regions(exp_count: uint) {
+        debug!("resolve_regions(%u)", exp_count);
+
+        self.infcx.resolve_regions();
+        if self.err_messages.len() != exp_count {
+            for self.err_messages.each |msg| {
+                debug!("Error encountered: %s", *msg);
+            }
+            fmt!("Resolving regions encountered %u errors but expected %u!",
+                 self.err_messages.len(),
+                 exp_count);
+        }
+    }
+
     /// Checks that `LUB(t1,t2) == t_lub`
     fn check_lub(&self, t1: ty::t, t2: ty::t, t_lub: ty::t) {
         match self.lub().tys(t1, t2) {
@@ -222,6 +248,30 @@ fn check_lub(&self, t1: ty::t, t2: ty::t, t_lub: ty::t) {
                 // sanity check for good measure:
                 self.assert_subtype(t1, t);
                 self.assert_subtype(t2, t);
+
+                self.resolve_regions(0);
+            }
+        }
+    }
+
+    /// Checks that `GLB(t1,t2) == t_glb`
+    fn check_glb(&self, t1: ty::t, t2: ty::t, t_glb: ty::t) {
+        debug!("check_glb(t1=%s, t2=%s, t_glb=%s)",
+               self.ty_to_str(t1),
+               self.ty_to_str(t2),
+               self.ty_to_str(t_glb));
+        match self.glb().tys(t1, t2) {
+            Err(e) => {
+                fail fmt!("Unexpected error computing LUB: %?", e)
+            }
+            Ok(t) => {
+                self.assert_eq(t, t_glb);
+
+                // sanity check for good measure:
+                self.assert_subtype(t, t1);
+                self.assert_subtype(t, t2);
+
+                self.resolve_regions(0);
             }
         }
     }
@@ -236,11 +286,22 @@ fn check_no_lub(&self, t1: ty::t, t2: ty::t) {
             }
         }
     }
+
+    /// Checks that `GLB(t1,t2)` is undefined
+    fn check_no_glb(&self, t1: ty::t, t2: ty::t) {
+        match self.glb().tys(t1, t2) {
+            Err(_) => {}
+            Ok(t) => {
+                fail fmt!("Unexpected success computing GLB: %?",
+                          self.ty_to_str(t))
+            }
+        }
+    }
 }
 
 #[test]
 fn contravariant_region_ptr() {
-    let env = setup_env("contravariant_region_ptr", "");
+    let env = setup_env("contravariant_region_ptr", EMPTY_SOURCE_STR);
     env.create_simple_region_hierarchy();
     let t_rptr1 = env.t_rptr_scope(1);
     let t_rptr10 = env.t_rptr_scope(10);
@@ -251,7 +312,7 @@ fn contravariant_region_ptr() {
 
 #[test]
 fn lub_bound_bound() {
-    let env = setup_env("lub_bound_bound", "");
+    let env = setup_env("lub_bound_bound", EMPTY_SOURCE_STR);
     let t_rptr_bound1 = env.t_rptr_bound(1);
     let t_rptr_bound2 = env.t_rptr_bound(2);
     env.check_lub(env.t_fn([t_rptr_bound1], env.t_int()),
@@ -261,7 +322,7 @@ fn lub_bound_bound() {
 
 #[test]
 fn lub_bound_free() {
-    let env = setup_env("lub_bound_free", "");
+    let env = setup_env("lub_bound_free", EMPTY_SOURCE_STR);
     let t_rptr_bound1 = env.t_rptr_bound(1);
     let t_rptr_free1 = env.t_rptr_free(0, 1);
     env.check_lub(env.t_fn([t_rptr_bound1], env.t_int()),
@@ -271,7 +332,7 @@ fn lub_bound_free() {
 
 #[test]
 fn lub_bound_static() {
-    let env = setup_env("lub_bound_static", "");
+    let env = setup_env("lub_bound_static", EMPTY_SOURCE_STR);
     let t_rptr_bound1 = env.t_rptr_bound(1);
     let t_rptr_static = env.t_rptr_static();
     env.check_lub(env.t_fn([t_rptr_bound1], env.t_int()),
@@ -281,7 +342,7 @@ fn lub_bound_static() {
 
 #[test]
 fn lub_bound_bound_inverse_order() {
-    let env = setup_env("lub_bound_bound_inverse_order", "");
+    let env = setup_env("lub_bound_bound_inverse_order", EMPTY_SOURCE_STR);
     let t_rptr_bound1 = env.t_rptr_bound(1);
     let t_rptr_bound2 = env.t_rptr_bound(2);
     env.check_lub(env.t_fn([t_rptr_bound1, t_rptr_bound2], t_rptr_bound1),
@@ -291,7 +352,7 @@ fn lub_bound_bound_inverse_order() {
 
 #[test]
 fn lub_free_free() {
-    let env = setup_env("lub_free_free", "");
+    let env = setup_env("lub_free_free", EMPTY_SOURCE_STR);
     let t_rptr_free1 = env.t_rptr_free(0, 1);
     let t_rptr_free2 = env.t_rptr_free(0, 2);
     let t_rptr_static = env.t_rptr_static();
@@ -302,10 +363,50 @@ fn lub_free_free() {
 
 #[test]
 fn lub_returning_scope() {
-    let env = setup_env("lub_returning_scope", "");
+    let env = setup_env("lub_returning_scope", EMPTY_SOURCE_STR);
     let t_rptr_scope10 = env.t_rptr_scope(10);
     let t_rptr_scope11 = env.t_rptr_scope(11);
     env.check_no_lub(env.t_fn([], t_rptr_scope10),
                      env.t_fn([], t_rptr_scope11));
 }
 
+#[test]
+fn glb_free_free_with_common_scope() {
+    let env = setup_env("glb_free_free", EMPTY_SOURCE_STR);
+    let t_rptr_free1 = env.t_rptr_free(0, 1);
+    let t_rptr_free2 = env.t_rptr_free(0, 2);
+    let t_rptr_scope = env.t_rptr_scope(0);
+    env.check_glb(env.t_fn([t_rptr_free1], env.t_int()),
+                  env.t_fn([t_rptr_free2], env.t_int()),
+                  env.t_fn([t_rptr_scope], env.t_int()));
+}
+
+#[test]
+fn glb_bound_bound() {
+    let env = setup_env("glb_bound_bound", EMPTY_SOURCE_STR);
+    let t_rptr_bound1 = env.t_rptr_bound(1);
+    let t_rptr_bound2 = env.t_rptr_bound(2);
+    env.check_glb(env.t_fn([t_rptr_bound1], env.t_int()),
+                  env.t_fn([t_rptr_bound2], env.t_int()),
+                  env.t_fn([t_rptr_bound1], env.t_int()));
+}
+
+#[test]
+fn glb_bound_free() {
+    let env = setup_env("glb_bound_free", EMPTY_SOURCE_STR);
+    let t_rptr_bound1 = env.t_rptr_bound(1);
+    let t_rptr_free1 = env.t_rptr_free(0, 1);
+    env.check_glb(env.t_fn([t_rptr_bound1], env.t_int()),
+                  env.t_fn([t_rptr_free1], env.t_int()),
+                  env.t_fn([t_rptr_bound1], env.t_int()));
+}
+
+#[test]
+fn glb_bound_static() {
+    let env = setup_env("glb_bound_static", EMPTY_SOURCE_STR);
+    let t_rptr_bound1 = env.t_rptr_bound(1);
+    let t_rptr_static = env.t_rptr_static();
+    env.check_glb(env.t_fn([t_rptr_bound1], env.t_int()),
+                  env.t_fn([t_rptr_static], env.t_int()),
+                  env.t_fn([t_rptr_bound1], env.t_int()));
+}
index 166907ba7a86207a769eb55750338dbc5f58d7d2..42f516fe6d8803b0190ff08a0c20cd2fcfed288f 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use middle::typeck::infer::integral::int_ty_set;
-use middle::typeck::infer::floating::float_ty_set;
-use middle::typeck::infer::unify::{redirect, root, var_value};
+use core::prelude::*;
 
-trait ToStr {
-    fn to_str(cx: infer_ctxt) -> ~str;
+use middle::ty::{FnMeta, FnTyBase, FnSig, FnVid, Vid};
+use middle::ty;
+use middle::typeck::infer::{Bound, Bounds};
+use middle::typeck::infer::{IntVarValue, IntType, UintType};
+use middle::typeck::infer::InferCtxt;
+use middle::typeck::infer::unify::{Redirect, Root, VarValue};
+use util::ppaux::{mt_to_str, ty_to_str};
+use util::ppaux;
+
+use syntax::{ast, ast_util};
+
+use core::uint;
+use core::str;
+
+pub trait InferStr {
+    fn inf_str(cx: @InferCtxt) -> ~str;
 }
 
-impl ty::t: ToStr {
-    fn to_str(cx: infer_ctxt) -> ~str {
+impl ty::t : InferStr {
+    fn inf_str(cx: @InferCtxt) -> ~str {
         ty_to_str(cx.tcx, self)
     }
 }
 
-impl ty::mt: ToStr {
-    fn to_str(cx: infer_ctxt) -> ~str {
-        mt_to_str(cx.tcx, self)
+impl FnMeta : InferStr {
+    fn inf_str(_cx: @InferCtxt) -> ~str {
+        fmt!("%?", self)
     }
 }
 
-impl ty::Region: ToStr {
-    fn to_str(cx: infer_ctxt) -> ~str {
-        util::ppaux::region_to_str(cx.tcx, self)
+impl FnSig : InferStr {
+    fn inf_str(cx: @InferCtxt) -> ~str {
+        fmt!("(%s) -> %s",
+             str::connect(self.inputs.map(|a| a.ty.inf_str(cx)), ", "),
+             self.output.inf_str(cx))
     }
 }
 
-impl ty::FnTy: ToStr {
-    fn to_str(cx: infer_ctxt) -> ~str {
-        ty::mk_fn(cx.tcx, self).to_str(cx)
+impl<M:InferStr> FnTyBase<M> : InferStr {
+    fn inf_str(cx: @InferCtxt) -> ~str {
+        fmt!("%s%s", self.meta.inf_str(cx), self.sig.inf_str(cx))
+    }
+}
+
+impl ty::mt : InferStr {
+    fn inf_str(cx: @InferCtxt) -> ~str {
+        mt_to_str(cx.tcx, self)
     }
 }
 
-impl<V:Copy ToStr> bound<V>: ToStr {
-    fn to_str(cx: infer_ctxt) -> ~str {
+impl ty::Region : InferStr {
+    fn inf_str(_cx: @InferCtxt) -> ~str {
+        fmt!("%?", self)
+    }
+}
+
+impl<V:InferStr> Bound<V> : InferStr {
+    fn inf_str(cx: @InferCtxt) -> ~str {
         match self {
-          Some(ref v) => (*v).to_str(cx),
+          Some(ref v) => v.inf_str(cx),
           None => ~"none"
         }
     }
 }
 
-impl<T:Copy ToStr> bounds<T>: ToStr {
-    fn to_str(cx: infer_ctxt) -> ~str {
+impl<T:InferStr> Bounds<T> : InferStr {
+    fn inf_str(cx: @InferCtxt) -> ~str {
         fmt!("{%s <: %s}",
-             self.lb.to_str(cx),
-             self.ub.to_str(cx))
+             self.lb.inf_str(cx),
+             self.ub.inf_str(cx))
     }
 }
 
-impl int_ty_set: ToStr {
-    fn to_str(_cx: infer_ctxt) -> ~str {
+impl<V:Vid ToStr, T:InferStr> VarValue<V, T> : InferStr {
+    fn inf_str(cx: @InferCtxt) -> ~str {
         match self {
-          int_ty_set(v) => uint::to_str(v, 10u)
+          Redirect(ref vid) => fmt!("Redirect(%s)", vid.to_str()),
+          Root(ref pt, rk) => fmt!("Root(%s, %s)", pt.inf_str(cx),
+                               uint::to_str(rk, 10u))
         }
     }
 }
 
-impl float_ty_set: ToStr {
-    fn to_str(_cx: infer_ctxt) -> ~str {
+impl IntVarValue : InferStr {
+    fn inf_str(_cx: @InferCtxt) -> ~str {
         match self {
-          float_ty_set(v) => uint::to_str(v, 10u)
+            IntType(t) => ast_util::int_ty_to_str(t),
+            UintType(t) => ast_util::uint_ty_to_str(t)
         }
     }
 }
 
-impl<V:Copy vid, T:Copy ToStr> var_value<V, T>: ToStr {
-    fn to_str(cx: infer_ctxt) -> ~str {
-        match self {
-          redirect(ref vid) => fmt!("redirect(%s)", (*vid).to_str()),
-          root(ref pt, rk) => fmt!("root(%s, %s)", (*pt).to_str(cx),
-                               uint::to_str(rk, 10u))
-        }
+impl ast::float_ty : InferStr {
+    fn inf_str(_cx: @InferCtxt) -> ~str {
+        ast_util::float_ty_to_str(self)
     }
 }
 
index 2ec356a6dc845ac2ce1744be09c05526a43faf31..77bd46eea2dfd29eba5b79d556e0fec9514243e7 100644 (file)
@@ -8,32 +8,47 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use middle::typeck::infer::combine::combine;
-use middle::typeck::infer::floating::*;
-use middle::typeck::infer::integral::*;
-use middle::typeck::infer::to_str::ToStr;
+use core::prelude::*;
 
+use middle::ty::Vid;
+use middle::ty;
+use middle::typeck::infer::{Bound, Bounds, cres, uok, ures};
+use middle::typeck::infer::combine::Combine;
+use middle::typeck::infer::InferCtxt;
+use middle::typeck::infer::to_str::InferStr;
+use util::common::{indent, indenter};
+
+use core::result;
 use std::smallintmap::SmallIntMap;
 
-enum var_value<V:Copy, T:Copy> {
-    redirect(V),
-    root(T, uint),
+enum VarValue<V, T> {
+    Redirect(V),
+    Root(T, uint),
 }
 
-struct vals_and_bindings<V:Copy, T:Copy> {
-    vals: SmallIntMap<var_value<V, T>>,
-    mut bindings: ~[(V, var_value<V, T>)],
+struct ValsAndBindings<V:Copy, T:Copy> {
+    vals: SmallIntMap<VarValue<V, T>>,
+    mut bindings: ~[(V, VarValue<V, T>)],
 }
 
-struct node<V:Copy, T:Copy> {
+struct Node<V:Copy, T:Copy> {
     root: V,
     possible_types: T,
     rank: uint,
 }
 
-impl infer_ctxt {
-    fn get<V:Copy vid Eq, T:Copy>(
-        vb: &vals_and_bindings<V, T>, vid: V) -> node<V, T> {
+impl @InferCtxt {
+    fn get<V:Copy Eq Vid, T:Copy>(
+        vb: &ValsAndBindings<V, T>,
+        vid: V)
+        -> Node<V, T>
+    {
+        /*!
+         *
+         * Find the root node for `vid`. This uses the standard
+         * union-find algorithm with path compression:
+         * http://en.wikipedia.org/wiki/Disjoint-set_data_structure
+         */
 
         let vid_u = vid.to_uint();
         match vb.vals.find(vid_u) {
@@ -42,431 +57,141 @@ fn get<V:Copy vid Eq, T:Copy>(
           }
           Some(ref var_val) => {
             match (*var_val) {
-              redirect(ref vid) => {
+              Redirect(ref vid) => {
                 let node = self.get(vb, (*vid));
                 if node.root.ne(vid) {
                     // Path compression
-                    vb.vals.insert((*vid).to_uint(), redirect(node.root));
+                    vb.vals.insert(vid.to_uint(), Redirect(node.root));
                 }
                 node
               }
-              root(ref pt, rk) => {
-                node {root: vid, possible_types: (*pt), rank: rk}
+              Root(ref pt, rk) => {
+                Node {root: vid, possible_types: *pt, rank: rk}
               }
             }
           }
         }
     }
 
-    fn set<V:Copy vid, T:Copy ToStr>(
-        vb: &vals_and_bindings<V, T>, vid: V,
-        +new_v: var_value<V, T>) {
+    fn set<V:Copy Vid ToStr, T:Copy InferStr>(
+        vb: &ValsAndBindings<V, T>,
+        vid: V,
+        +new_v: VarValue<V, T>)
+    {
+        /*!
+         *
+         * Sets the value for `vid` to `new_v`.  `vid` MUST be a root node!
+         */
 
         let old_v = vb.vals.get(vid.to_uint());
         vb.bindings.push((vid, old_v));
         vb.vals.insert(vid.to_uint(), new_v);
 
         debug!("Updating variable %s from %s to %s",
-               vid.to_str(), old_v.to_str(self), new_v.to_str(self));
-    }
-}
-
-// Combines the two bounds into a more general bound.
-fn merge_bnd<C: combine>(
-    self: &C, a: bound<ty::t>, b: bound<ty::t>,
-    merge_op: fn(ty::t,ty::t) -> cres<ty::t>) -> cres<bound<ty::t>> {
-
-    debug!("merge_bnd(%s,%s)",
-           a.to_str(self.infcx()),
-           b.to_str(self.infcx()));
-    let _r = indenter();
-
-    match (a, b) {
-      (None, None) => Ok(None),
-      (Some(_), None) => Ok(a),
-      (None, Some(_)) => Ok(b),
-      (Some(v_a), Some(v_b)) => {
-        do merge_op(v_a, v_b).chain |v| {
-            Ok(Some(v))
-        }
-      }
-    }
-}
-
-fn merge_bnds<C: combine>(
-    self: &C, a: bounds<ty::t>, b: bounds<ty::t>,
-    lub: fn(ty::t,ty::t) -> cres<ty::t>,
-    glb: fn(ty::t,ty::t) -> cres<ty::t>) -> cres<bounds<ty::t>> {
-
-    let _r = indenter();
-    do merge_bnd(self, a.ub, b.ub, glb).chain |ub| {
-        debug!("glb of ubs %s and %s is %s",
-               a.ub.to_str(self.infcx()),
-               b.ub.to_str(self.infcx()),
-               ub.to_str(self.infcx()));
-        do merge_bnd(self, a.lb, b.lb, lub).chain |lb| {
-            debug!("lub of lbs %s and %s is %s",
-                   a.lb.to_str(self.infcx()),
-                   b.lb.to_str(self.infcx()),
-                   lb.to_str(self.infcx()));
-            Ok({lb: lb, ub: ub})
-        }
-    }
-}
-
-// Updates the bounds for the variable `v_id` to be the intersection
-// of `a` and `b`.  That is, the new bounds for `v_id` will be
-// a bounds c such that:
-//    c.ub <: a.ub
-//    c.ub <: b.ub
-//    a.lb <: c.lb
-//    b.lb <: c.lb
-// If this cannot be achieved, the result is failure.
-
-fn set_var_to_merged_bounds<C: combine>(
-    self: &C,
-    v_id: ty::TyVid,
-    a: bounds<ty::t>,
-    b: bounds<ty::t>,
-    rank: uint) -> ures {
-
-    let vb = &self.infcx().ty_var_bindings;
-
-    // Think of the two diamonds, we want to find the
-    // intersection.  There are basically four possibilities (you
-    // can swap A/B in these pictures):
-    //
-    //       A         A
-    //      / \       / \
-    //     / B \     / B \
-    //    / / \ \   / / \ \
-    //   * *   * * * /   * *
-    //    \ \ / /   \   / /
-    //     \ B /   / \ / /
-    //      \ /   *   \ /
-    //       A     \ / A
-    //              B
-
-    debug!("merge(%s,%s,%s)",
-           v_id.to_str(),
-           a.to_str(self.infcx()),
-           b.to_str(self.infcx()));
-
-    // First, relate the lower/upper bounds of A and B.
-    // Note that these relations *must* hold for us to
-    // to be able to merge A and B at all, and relating
-    // them explicitly gives the type inferencer more
-    // information and helps to produce tighter bounds
-    // when necessary.
-    do indent {
-        do bnds(self, a.lb, b.ub).then {
-            do bnds(self, b.lb, a.ub).then {
-                do merge_bnd(self, a.ub, b.ub,
-                             |x, y| self.glb().tys(x, y)).chain |ub| {
-                    do merge_bnd(self, a.lb, b.lb,
-                                 |x, y| self.lub().tys(x, y)).chain |lb| {
-                        let bounds = {lb: lb, ub: ub};
-                        debug!("merge(%s): bounds=%s",
-                               v_id.to_str(),
-                               bounds.to_str(self.infcx()));
-
-                        // the new bounds must themselves
-                        // be relatable:
-                        do bnds(self, bounds.lb, bounds.ub).then {
-                            self.infcx().set(vb, v_id, root(bounds, rank));
-                            uok()
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-/// Ensure that variable A is a subtype of variable B.  This is a
-/// subtle and tricky process, as described in detail at the top
-/// of infer.rs
-fn var_sub_var<C: combine>(self: &C,
-                           a_id: ty::TyVid,
-                           b_id: ty::TyVid) -> ures {
-    let vb = &self.infcx().ty_var_bindings;
-
-    // Need to make sub_id a subtype of sup_id.
-    let nde_a = self.infcx().get(vb, a_id);
-    let nde_b = self.infcx().get(vb, b_id);
-    let a_id = nde_a.root;
-    let b_id = nde_b.root;
-    let a_bounds = nde_a.possible_types;
-    let b_bounds = nde_b.possible_types;
-
-    debug!("vars(%s=%s <: %s=%s)",
-           a_id.to_str(), a_bounds.to_str(self.infcx()),
-           b_id.to_str(), b_bounds.to_str(self.infcx()));
-
-    if a_id == b_id { return uok(); }
-
-    // If both A's UB and B's LB have already been bound to types,
-    // see if we can make those types subtypes.
-    match (a_bounds.ub, b_bounds.lb) {
-      (Some(a_ub), Some(b_lb)) => {
-        let r = self.infcx().try(|| self.sub().tys(a_ub, b_lb));
-        match r {
-          Ok(_ty) => return result::Ok(()),
-          Err(_) => { /*fallthrough */ }
-        }
-      }
-      _ => { /*fallthrough*/ }
-    }
-
-    // Otherwise, we need to merge A and B so as to guarantee that
-    // A remains a subtype of B.  Actually, there are other options,
-    // but that's the route we choose to take.
-
-    // Rank optimization
-
-    // Make the node with greater rank the parent of the node with
-    // smaller rank.
-    if nde_a.rank > nde_b.rank {
-        debug!("vars(): a has smaller rank");
-        // a has greater rank, so a should become b's parent,
-        // i.e., b should redirect to a.
-        self.infcx().set(vb, b_id, redirect(a_id));
-        set_var_to_merged_bounds(
-            self, a_id, a_bounds, b_bounds, nde_a.rank)
-    } else if nde_a.rank < nde_b.rank {
-        debug!("vars(): b has smaller rank");
-        // b has greater rank, so a should redirect to b.
-        self.infcx().set(vb, a_id, redirect(b_id));
-        set_var_to_merged_bounds(
-            self, b_id, a_bounds, b_bounds, nde_b.rank)
-    } else {
-        debug!("vars(): a and b have equal rank");
-        assert nde_a.rank == nde_b.rank;
-        // If equal, just redirect one to the other and increment
-        // the other's rank.  We choose arbitrarily to redirect b
-        // to a and increment a's rank.
-        self.infcx().set(vb, b_id, redirect(a_id));
-        set_var_to_merged_bounds(
-            self, a_id, a_bounds, b_bounds, nde_a.rank + 1u
-        )
-    }
-}
-
-/// make variable a subtype of T
-fn var_sub_t<C: combine>(self: &C, a_id: ty::TyVid, b: ty::t) -> ures {
-
-    let vb = &self.infcx().ty_var_bindings;
-    let nde_a = self.infcx().get(vb, a_id);
-    let a_id = nde_a.root;
-    let a_bounds = nde_a.possible_types;
-
-    debug!("var_sub_t(%s=%s <: %s)",
-           a_id.to_str(),
-           a_bounds.to_str(self.infcx()),
-           b.to_str(self.infcx()));
-    let b_bounds = {lb: None, ub: Some(b)};
-    set_var_to_merged_bounds(self, a_id, a_bounds, b_bounds, nde_a.rank)
-}
-
-/// make T a subtype of variable
-fn t_sub_var<C: combine>(self: &C, a: ty::t, b_id: ty::TyVid) -> ures {
-
-    let vb = &self.infcx().ty_var_bindings;
-    let a_bounds = {lb: Some(a), ub: None};
-    let nde_b = self.infcx().get(vb, b_id);
-    let b_id = nde_b.root;
-    let b_bounds = nde_b.possible_types;
-
-    debug!("t_sub_var(%s <: %s=%s)",
-           a.to_str(self.infcx()),
-           b_id.to_str(),
-           b_bounds.to_str(self.infcx()));
-    set_var_to_merged_bounds(self, b_id, a_bounds, b_bounds, nde_b.rank)
-}
-
-fn bnds<C: combine>(
-    self: &C, a: bound<ty::t>, b: bound<ty::t>) -> ures {
-
-    debug!("bnds(%s <: %s)", a.to_str(self.infcx()), b.to_str(self.infcx()));
-    do indent {
-        match (a, b) {
-          (None, None) |
-          (Some(_), None) |
-          (None, Some(_)) => {
-            uok()
-          }
-          (Some(t_a), Some(t_b)) => {
-            self.sub().tys(t_a, t_b).to_ures()
-          }
-        }
+               vid.to_str(), old_v.inf_str(self), new_v.inf_str(self));
     }
-}
-
-// ______________________________________________________________________
-// Integral variables
 
-impl infer_ctxt {
-    fn optimize_ranks<V:Copy vid Eq,T:Copy ToStr>(vb: &vals_and_bindings<V,T>,
-                                                  nde_a: node<V,T>,
-                                                  nde_b: node<V,T>,
-                                                  a_id: V,
-                                                  b_id: V,
-                                                  intersection: T) {
-        if nde_a.rank > nde_b.rank {
-            debug!("int_vars(): a has smaller rank");
+    fn unify<V:Copy Vid ToStr, T:Copy InferStr, R>(
+        vb: &ValsAndBindings<V, T>,
+        node_a: &Node<V, T>,
+        node_b: &Node<V, T>,
+        op: &fn(new_root: V, new_rank: uint) -> R
+    ) -> R {
+        // Rank optimization: if you don't know what it is, check
+        // out <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>
+
+        debug!("unify(node_a(id=%?, rank=%?), \
+                node_b(id=%?, rank=%?))",
+               node_a.root, node_a.rank,
+               node_b.root, node_b.rank);
+
+        if node_a.rank > node_b.rank {
             // a has greater rank, so a should become b's parent,
             // i.e., b should redirect to a.
-            self.set(vb, a_id, root(intersection, nde_a.rank));
-            self.set(vb, b_id, redirect(a_id));
-        } else if nde_a.rank < nde_b.rank {
-            debug!("int_vars(): b has smaller rank");
+            self.set(vb, node_b.root, Redirect(node_a.root));
+            op(node_a.root, node_a.rank)
+        } else if node_a.rank < node_b.rank {
             // b has greater rank, so a should redirect to b.
-            self.set(vb, b_id, root(intersection, nde_b.rank));
-            self.set(vb, a_id, redirect(b_id));
+            self.set(vb, node_a.root, Redirect(node_b.root));
+            op(node_b.root, node_b.rank)
         } else {
-            debug!("int_vars(): a and b have equal rank");
-            assert nde_a.rank == nde_b.rank;
-            // If equal, just redirect one to the other and increment
-            // the other's rank.  We choose arbitrarily to redirect b
-            // to a and increment a's rank.
-            self.set(vb, a_id, root(intersection, nde_a.rank + 1u));
-            self.set(vb, b_id, redirect(a_id));
-        };
-    }
-
-    fn int_vars(a_id: ty::IntVid, b_id: ty::IntVid) -> ures {
-        let vb = &self.int_var_bindings;
-
-        let nde_a = self.get(vb, a_id);
-        let nde_b = self.get(vb, b_id);
-        let a_id = nde_a.root;
-        let b_id = nde_b.root;
-        let a_pt = nde_a.possible_types;
-        let b_pt = nde_b.possible_types;
-
-        // If we're already dealing with the same two variables,
-        // there's nothing to do.
-        if a_id == b_id { return uok(); }
-
-        // Otherwise, take the intersection of the two sets of
-        // possible types.
-        let intersection = integral::intersection(a_pt, b_pt);
-        if *intersection == INT_TY_SET_EMPTY {
-            return Err(ty::terr_no_integral_type);
+            // If equal, redirect one to the other and increment the
+            // other's rank.
+            assert node_a.rank == node_b.rank;
+            self.set(vb, node_b.root, Redirect(node_a.root));
+            op(node_a.root, node_a.rank + 1)
         }
-
-        // Rank optimization
-        self.optimize_ranks(vb, nde_a, nde_b, a_id, b_id, intersection);
-
-        uok()
     }
 
-    fn int_var_sub_t(a_id: ty::IntVid, b: ty::t) -> ures {
-        assert ty::type_is_integral(b);
-
-        let vb = &self.int_var_bindings;
-        let nde_a = self.get(vb, a_id);
-        let a_id = nde_a.root;
-        let a_pt = nde_a.possible_types;
-
-        let intersection =
-            integral::intersection(a_pt,
-                         convert_integral_ty_to_int_ty_set(self.tcx, b));
-        if *intersection == INT_TY_SET_EMPTY {
-            return Err(ty::terr_no_integral_type);
-        }
-        self.set(vb, a_id, root(intersection, nde_a.rank));
-        uok()
-    }
-
-    fn t_sub_int_var(a: ty::t, b_id: ty::IntVid) -> ures {
-        assert ty::type_is_integral(a);
-        let vb = &self.int_var_bindings;
-
-        let nde_b = self.get(vb, b_id);
-        let b_id = nde_b.root;
-        let b_pt = nde_b.possible_types;
-
-        let intersection =
-            integral::intersection(b_pt,
-                         convert_integral_ty_to_int_ty_set(self.tcx, a));
-        if *intersection == INT_TY_SET_EMPTY {
-            return Err(ty::terr_no_integral_type);
-        }
-        self.set(vb, b_id, root(intersection, nde_b.rank));
-        uok()
-    }
-
-
 }
 
 // ______________________________________________________________________
-// Floating point variables
-
-impl infer_ctxt {
-    fn float_vars(a_id: ty::FloatVid, b_id: ty::FloatVid) -> ures {
-        let vb = &self.float_var_bindings;
-
-        let nde_a = self.get(vb, a_id);
-        let nde_b = self.get(vb, b_id);
-        let a_id = nde_a.root;
-        let b_id = nde_b.root;
-        let a_pt = nde_a.possible_types;
-        let b_pt = nde_b.possible_types;
+// Code to handle simple variables like ints, floats---anything that
+// doesn't have a subtyping relationship we need to worry about.
+
+impl @InferCtxt {
+    fn simple_vars<V:Copy Eq Vid ToStr, T:Copy Eq InferStr>(
+        vb: &ValsAndBindings<V, Option<T>>,
+        err: ty::type_err,
+        a_id: V,
+        b_id: V) -> ures
+    {
+        /*!
+         *
+         * Unifies two simple variables.  Because simple variables do
+         * not have any subtyping relationships, if both variables
+         * have already been associated with a value, then those two
+         * values must be the same. */
+
+        let node_a = self.get(vb, a_id);
+        let node_b = self.get(vb, b_id);
+        let a_id = node_a.root;
+        let b_id = node_b.root;
 
-        // If we're already dealing with the same two variables,
-        // there's nothing to do.
         if a_id == b_id { return uok(); }
 
-        // Otherwise, take the intersection of the two sets of
-        // possible types.
-        let intersection = floating::intersection(a_pt, b_pt);
-        if *intersection == FLOAT_TY_SET_EMPTY {
-            return Err(ty::terr_no_floating_point_type);
-        }
-
-        // Rank optimization
-        self.optimize_ranks(vb, nde_a, nde_b, a_id, b_id, intersection);
+        let combined = match (&node_a.possible_types, &node_b.possible_types)
+        {
+            (&None, &None) => None,
+            (&Some(ref v), &None) | (&None, &Some(ref v)) => Some(*v),
+            (&Some(ref v1), &Some(ref v2)) => {
+                if *v1 != *v2 { return Err(err); }
+                Some(*v1)
+            }
+        };
 
-        uok()
+        self.unify(vb, &node_a, &node_b, |new_root, new_rank| {
+            self.set(vb, new_root, Root(combined, new_rank));
+        });
+        return uok();
     }
 
-    fn float_var_sub_t(a_id: ty::FloatVid, b: ty::t) -> ures {
-        assert ty::type_is_fp(b);
-
-        let vb = &self.float_var_bindings;
-        let nde_a = self.get(vb, a_id);
-        let a_id = nde_a.root;
-        let a_pt = nde_a.possible_types;
-
-        let intersection =
-            floating::intersection(
-                a_pt,
-                convert_floating_point_ty_to_float_ty_set(self.tcx, b));
-        if *intersection == FLOAT_TY_SET_EMPTY {
-            return Err(ty::terr_no_floating_point_type);
+    fn simple_var_t<V:Copy Eq Vid ToStr, T:Copy Eq InferStr>(
+        vb: &ValsAndBindings<V, Option<T>>,
+        err: ty::type_err,
+        a_id: V,
+        b: T) -> ures
+    {
+        /*!
+         *
+         * Sets the value of the variable `a_id` to `b`.  Because
+         * simple variables do not have any subtyping relationships,
+         * if `a_id` already has a value, it must be the same as
+         * `b`. */
+
+        let node_a = self.get(vb, a_id);
+        let a_id = node_a.root;
+
+        if node_a.possible_types.is_none() {
+            self.set(vb, a_id, Root(Some(b), node_a.rank));
+            return uok();
         }
-        self.set(vb, a_id, root(intersection, nde_a.rank));
-        uok()
-    }
-
-    fn t_sub_float_var(a: ty::t, b_id: ty::FloatVid) -> ures {
-        assert ty::type_is_fp(a);
-        let vb = &self.float_var_bindings;
 
-        let nde_b = self.get(vb, b_id);
-        let b_id = nde_b.root;
-        let b_pt = nde_b.possible_types;
-
-        let intersection =
-            floating::intersection(
-                b_pt,
-                convert_floating_point_ty_to_float_ty_set(self.tcx, a));
-        if *intersection == FLOAT_TY_SET_EMPTY {
-            return Err(ty::terr_no_floating_point_type);
+        if node_a.possible_types == Some(b) {
+            return uok();
         }
-        self.set(vb, b_id, root(intersection, nde_b.rank));
-        uok()
+
+        return Err(err);
     }
 }
 
index 684ee4fa45422d822b133184f0986ba730934313..509fe96508b2c69e85937f758b3e35600ad7d1e7 100644 (file)
 
 #[legacy_exports];
 
+use core::prelude::*;
+
 use metadata::csearch;
 use middle::pat_util::{pat_id_map, PatIdMap};
+use middle::resolve;
 use middle::ty::{arg, field, node_type_table, mk_nil, ty_param_bounds_and_ty};
 use middle::ty::{ty_param_substs_and_ty, vstore_uniq};
 use middle::ty;
@@ -62,6 +65,8 @@
 
 use core::dvec::DVec;
 use core::result::Result;
+use core::result;
+use core::vec;
 use std::list::{List, Nil, Cons};
 use std::list;
 use std::map::HashMap;
 export collect;
 export coherence;
 export deriving;
+export crate_ctxt;
+export write_ty_to_tcx, write_substs_to_tcx;
+export no_params;
+export isr_alist;
+export require_same_types;
+export lookup_def_ccx, lookup_def_tcx;
 
 #[legacy_exports]
 #[path = "check/mod.rs"]
@@ -213,16 +224,17 @@ fn to_str(tcx: ty::ctxt) -> ~str {
 
 type vtable_map = HashMap<ast::node_id, vtable_res>;
 
-type crate_ctxt_ = {// A mapping from method call sites to traits that have
-                    // that method.
-                    trait_map: resolve::TraitMap,
-                    method_map: method_map,
-                    vtable_map: vtable_map,
-                    coherence_info: @coherence::CoherenceInfo,
-                    tcx: ty::ctxt};
+struct crate_ctxt__ {
+    // A mapping from method call sites to traits that have that method.
+    trait_map: resolve::TraitMap,
+    method_map: method_map,
+    vtable_map: vtable_map,
+    coherence_info: @coherence::CoherenceInfo,
+    tcx: ty::ctxt
+}
 
-enum crate_ctxt {
-    crate_ctxt_(crate_ctxt_)
+pub enum crate_ctxt {
+    crate_ctxt_(crate_ctxt__)
 }
 
 // Functions that write types into the node type table
@@ -259,7 +271,7 @@ fn no_params(t: ty::t) -> ty::ty_param_bounds_and_ty {
 
 fn require_same_types(
     tcx: ty::ctxt,
-    maybe_infcx: Option<infer::infer_ctxt>,
+    maybe_infcx: Option<@infer::InferCtxt>,
     t1_is_expected: bool,
     span: span,
     t1: ty::t,
@@ -343,7 +355,8 @@ fn check_main_fn_ty(ccx: @crate_ctxt,
             match tcx.items.find(main_id) {
                 Some(ast_map::node_item(it,_)) => {
                     match it.node {
-                        ast::item_fn(_,_,ps,_) if vec::is_not_empty(ps) => {
+                        ast::item_fn(_, _, ref ps, _)
+                        if vec::is_not_empty(*ps) => {
                             tcx.sess.span_err(
                                 main_span,
                                 ~"main function is not allowed \
@@ -389,12 +402,13 @@ fn check_crate(tcx: ty::ctxt,
                crate: @ast::crate)
     -> (method_map, vtable_map) {
 
-    let ccx = @crate_ctxt_({trait_map: trait_map,
-                            method_map: std::map::HashMap(),
-                            vtable_map: std::map::HashMap(),
-                            coherence_info: @coherence::CoherenceInfo(),
-                            tcx: tcx
-                           });
+    let ccx = @crate_ctxt_(crate_ctxt__ {
+        trait_map: trait_map,
+        method_map: map::HashMap(),
+        vtable_map: map::HashMap(),
+        coherence_info: @coherence::CoherenceInfo(),
+        tcx: tcx
+    });
     collect::collect_item_types(ccx, crate);
     coherence::check_coherence(ccx, crate);
 
index 5fba2b7e6fad69ad39ab2c4847cf540ab6b09e91..f1655f2a363b1a23d42ce940c426333fe0412aa7 100644 (file)
@@ -8,7 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use middle::ty;
+
 use core::result::Result;
+use core::result;
+use syntax::ast;
+use syntax::codemap::span;
 use syntax::parse::token::special_idents;
 
 trait region_scope {
index 9331693bf0a5f65d1a4ce7690bd2318efeca200b..56a228991939b60fdcb9599d4af038eb590350be 100644 (file)
 #[license = "MIT"];
 #[crate_type = "lib"];
 
-#[no_core];
-
 #[legacy_modes];
 #[legacy_exports];
 
-#[allow(vecs_implicitly_copyable)];
+#[allow(non_implicitly_copyable_typarams)];
 #[allow(non_camel_case_types)];
 #[allow(deprecated_mode)];
 #[warn(deprecated_pattern)];
 
+#[no_core];
+
 extern mod core(vers = "0.6");
+use core::*;
+
 extern mod std(vers = "0.6");
 extern mod syntax(vers = "0.6");
 
-use core::*;
-
 /*
 Alternate names for some modules.
 
@@ -77,7 +77,7 @@ mod middle {
         #[legacy_exports]
         mod base;
         #[legacy_exports]
-        mod alt;
+        mod _match;
         #[legacy_exports]
         mod uniq;
         #[legacy_exports]
@@ -109,7 +109,7 @@ mod middle {
     #[legacy_exports]
     mod check_loop;
     #[legacy_exports]
-    mod check_alt;
+    mod check_match;
     #[legacy_exports]
     mod check_const;
     #[legacy_exports]
@@ -162,6 +162,8 @@ mod back {
     #[legacy_exports]
     mod upcall;
     #[legacy_exports]
+    mod arm;
+    #[legacy_exports]
     mod x86;
     #[legacy_exports]
     mod x86_64;
@@ -262,7 +264,7 @@ Available lint options:
 fn describe_debug_flags() {
     io::println(fmt!("\nAvailable debug options:\n"));
     for session::debugging_opts_map().each |pair| {
-        let (name, desc, _) = *pair;
+        let (name, desc, _) = /*bad*/copy *pair;
         io::println(fmt!("    -Z %-20s -- %s", name, desc));
     }
 }
@@ -271,7 +273,7 @@ fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
     // Don't display log spew by default. Can override with RUST_LOG.
     logging::console_off();
 
-    let mut args = *args;
+    let mut args = /*bad*/copy *args;
     let binary = args.shift();
 
     if args.is_empty() { usage(binary); return; }
@@ -308,7 +310,7 @@ fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
     let input = match vec::len(matches.free) {
       0u => early_error(demitter, ~"no input filename given"),
       1u => {
-        let ifile = matches.free[0];
+        let ifile = /*bad*/copy matches.free[0];
         if ifile == ~"-" {
             let src = str::from_bytes(io::stdin().read_whole_stream());
             str_input(src)
@@ -319,7 +321,8 @@ fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
       _ => early_error(demitter, ~"multiple input filenames provided")
     };
 
-    let sopts = build_session_options(binary, matches, demitter);
+    // XXX: Bad copy.
+    let sopts = build_session_options(copy binary, matches, demitter);
     let sess = build_session(sopts, demitter);
     let odir = getopts::opt_maybe_str(matches, ~"out-dir");
     let odir = odir.map(|o| Path(*o));
index c1a88cae13cdec976ca51a329883e7cb60a5b58e..528b997c8e6c8e9b6044f0b79b5ba78f2104dae2 100644 (file)
@@ -8,11 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::map::HashMap;
+use core::prelude::*;
+
 use syntax::ast;
 use syntax::codemap::{span};
 use syntax::visit;
 use syntax::print;
+use syntax;
+
+use core::option;
+use core::str;
+use core::vec;
+use std::map::HashMap;
 
 fn indent<R>(op: fn() -> R) -> R {
     // Use in conjunction with the log post-processor like `src/etc/indenter`
@@ -62,8 +69,9 @@ fn loop_query(b: ast::blk, p: fn@(ast::expr_) -> bool) -> bool {
           _ => visit::visit_expr(e, flag, v)
         }
     };
-    let v = visit::mk_vt(@{visit_expr: visit_expr
-                           ,.. *visit::default_visitor()});
+    let v = visit::mk_vt(@visit::Visitor {
+        visit_expr: visit_expr,
+        .. *visit::default_visitor()});
     visit::visit_block(b, rs, v);
     return *rs;
 }
@@ -77,8 +85,9 @@ fn block_query(b: ast::blk, p: fn@(@ast::expr) -> bool) -> bool {
         *flag |= p(e);
         visit::visit_expr(e, flag, v)
     };
-    let v = visit::mk_vt(@{visit_expr: visit_expr
-                           ,.. *visit::default_visitor()});
+    let v = visit::mk_vt(@visit::Visitor{
+        visit_expr: visit_expr,
+        .. *visit::default_visitor()});
     visit::visit_block(b, rs, v);
     return *rs;
 }
@@ -96,7 +105,7 @@ fn is_main_name(path: syntax::ast_map::path) -> bool {
     )
 }
 
-fn pluralize(n: uint, s: ~str) -> ~str {
+fn pluralize(n: uint, +s: ~str) -> ~str {
     if n == 1 { s }
     else { str::concat([s, ~"s"]) }
 }
index 9e2f5a063ac0dfde8607325aae9fba8c48a3e3e2..3cd38d67a297dbeda417ffbbabcb6b353a7ff5c3 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::map::HashMap;
+use core::prelude::*;
+
 use middle::ty;
 use middle::ty::{arg, canon_mode};
 use middle::ty::{bound_copy, bound_const, bound_durable, bound_owned,
         bound_trait};
-use middle::ty::{bound_region, br_anon, br_named, br_self, br_cap_avoid};
+use middle::ty::{bound_region, br_anon, br_named, br_self, br_cap_avoid,
+                 br_fresh};
 use middle::ty::{ctxt, field, method};
 use middle::ty::{mt, t, param_bound};
 use middle::ty::{re_bound, re_free, re_scope, re_infer, re_static, Region};
 use middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param};
 use middle::ty::{ty_ptr, ty_rec, ty_rptr, ty_self, ty_tup};
 use middle::ty::{ty_type, ty_uniq, ty_uint, ty_infer};
-use middle::ty::{ty_unboxed_vec, vid};
+use middle::ty::{ty_unboxed_vec};
 use metadata::encoder;
 use syntax::codemap;
 use syntax::codemap::span;
 use syntax::print::pprust;
-use syntax::print::pprust::{path_to_str, proto_to_str,
-                            mode_to_str, purity_to_str,
-                            onceness_to_str};
+use syntax::print::pprust::{path_to_str, proto_to_str, mode_to_str};
 use syntax::{ast, ast_util};
 use syntax::ast_map;
 
+use core::str;
+use core::vec;
+use std::map::HashMap;
+
 fn note_and_explain_region(cx: ctxt,
                            prefix: ~str,
                            region: ty::Region,
@@ -66,16 +70,16 @@ fn explain_region_and_span(cx: ctxt, region: ty::Region)
       re_scope(node_id) => {
         match cx.items.find(node_id) {
           Some(ast_map::node_block(ref blk)) => {
-            explain_span(cx, ~"block", (*blk).span)
+            explain_span(cx, "block", (*blk).span)
           }
           Some(ast_map::node_expr(expr)) => {
             match expr.node {
-              ast::expr_call(*) => explain_span(cx, ~"call", expr.span),
+              ast::expr_call(*) => explain_span(cx, "call", expr.span),
               ast::expr_method_call(*) => {
-                explain_span(cx, ~"method call", expr.span)
+                explain_span(cx, "method call", expr.span)
               },
-              ast::expr_match(*) => explain_span(cx, ~"match", expr.span),
-              _ => explain_span(cx, ~"expression", expr.span)
+              ast::expr_match(*) => explain_span(cx, "match", expr.span),
+              _ => explain_span(cx, "expression", expr.span)
             }
           }
           Some(_) | None => {
@@ -90,13 +94,14 @@ fn explain_region_and_span(cx: ctxt, region: ty::Region)
         let prefix = match br {
           br_anon(idx) => fmt!("the anonymous lifetime #%u defined on",
                                idx + 1),
+          br_fresh(_) => fmt!("an anonymous lifetime defined on"),
           _ => fmt!("the lifetime %s as defined on",
                     bound_region_to_str(cx, br))
         };
 
         match cx.items.find(id) {
           Some(ast_map::node_block(ref blk)) => {
-            let (msg, opt_span) = explain_span(cx, ~"block", (*blk).span);
+            let (msg, opt_span) = explain_span(cx, "block", (*blk).span);
             (fmt!("%s %s", prefix, msg), opt_span)
           }
           Some(_) | None => {
@@ -115,7 +120,7 @@ fn explain_region_and_span(cx: ctxt, region: ty::Region)
       }
     };
 
-    fn explain_span(cx: ctxt, heading: ~str, span: span)
+    fn explain_span(cx: ctxt, heading: &str, span: span)
         -> (~str, Option<span>)
     {
         let lo = cx.sess.codemap.lookup_char_pos_adj(span.lo);
@@ -125,17 +130,18 @@ fn explain_span(cx: ctxt, heading: ~str, span: span)
 }
 
 fn bound_region_to_str(cx: ctxt, br: bound_region) -> ~str {
-    bound_region_to_str_adorned(cx, ~"&", br, ~"")
+    bound_region_to_str_adorned(cx, "&", br, "")
 }
 
-fn bound_region_to_str_adorned(cx: ctxt, prefix: ~str,
-                               br: bound_region, sep: ~str) -> ~str {
+fn bound_region_to_str_adorned(cx: ctxt, prefix: &str,
+                               br: bound_region, sep: &str) -> ~str {
     if cx.sess.verbose() { return fmt!("%s%?%s", prefix, br, sep); }
 
     match br {
       br_named(id)         => fmt!("%s%s%s", prefix, cx.sess.str_of(id), sep),
       br_self              => fmt!("%sself%s", prefix, sep),
-      br_anon(_)           => prefix,
+      br_anon(_)           => prefix.to_str(),
+      br_fresh(_)          => prefix.to_str(),
       br_cap_avoid(_, br)  => bound_region_to_str_adorned(cx, prefix,
                                                           *br, sep)
     }
@@ -154,7 +160,7 @@ fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> ~str {
                  cx.sess.codemap.span_to_str(expr.span))
           }
           ast::expr_match(*) => {
-            fmt!("<alt at %s>",
+            fmt!("<match at %s>",
                  cx.sess.codemap.span_to_str(expr.span))
           }
           ast::expr_assign_op(*) |
@@ -185,11 +191,11 @@ fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> ~str {
 // you should use `explain_region()` or, better yet,
 // `note_and_explain_region()`
 fn region_to_str(cx: ctxt, region: Region) -> ~str {
-    region_to_str_adorned(cx, ~"&", region, ~"")
+    region_to_str_adorned(cx, "&", region, "")
 }
 
-fn region_to_str_adorned(cx: ctxt, prefix: ~str,
-                         region: Region, sep: ~str) -> ~str {
+fn region_to_str_adorned(cx: ctxt, prefix: &str,
+                         region: Region, sep: &str) -> ~str {
     if cx.sess.verbose() {
         return fmt!("%s%?%s", prefix, region, sep);
     }
@@ -199,24 +205,24 @@ fn region_to_str_adorned(cx: ctxt, prefix: ~str,
     // to fit that into a short string.  Hence the recommendation to use
     // `explain_region()` or `note_and_explain_region()`.
     match region {
-        re_scope(_) => prefix,
+        re_scope(_) => prefix.to_str(),
         re_bound(br) => bound_region_to_str_adorned(cx, prefix, br, sep),
         re_free(_, br) => bound_region_to_str_adorned(cx, prefix, br, sep),
         re_infer(ReSkolemized(_, br)) => {
             bound_region_to_str_adorned(cx, prefix, br, sep)
         }
-        re_infer(ReVar(_)) => prefix,
+        re_infer(ReVar(_)) => prefix.to_str(),
         re_static => fmt!("%sstatic%s", prefix, sep)
     }
 }
 
 fn mt_to_str(cx: ctxt, m: mt) -> ~str {
     let mstr = match m.mutbl {
-      ast::m_mutbl => ~"mut ",
-      ast::m_imm => ~"",
-      ast::m_const => ~"const "
+      ast::m_mutbl => "mut ",
+      ast::m_imm => "",
+      ast::m_const => "const "
     };
-    return mstr + ty_to_str(cx, m.ty);
+    return fmt!("%s%s", mstr, ty_to_str(cx, m.ty));
 }
 
 fn vstore_to_str(cx: ctxt, vs: ty::vstore) -> ~str {
@@ -240,12 +246,14 @@ fn vstore_ty_to_str(cx: ctxt, ty: ~str, vs: ty::vstore) -> ~str {
     }
 }
 
-fn proto_ty_to_str(_cx: ctxt, proto: ast::Proto) -> ~str {
+fn proto_ty_to_str(_cx: ctxt, proto: ast::Proto,
+                   followed_by_word: bool) -> &static/str {
     match proto {
-        ast::ProtoBare => ~"",
-        ast::ProtoBox => ~"@",
-        ast::ProtoBorrowed => ~"&",
-        ast::ProtoUniq => ~"~",
+        ast::ProtoBare if followed_by_word => "extern ",
+        ast::ProtoBare => "extern",
+        ast::ProtoBox => "@",
+        ast::ProtoBorrowed => "&",
+        ast::ProtoUniq => "~",
     }
 }
 
@@ -255,15 +263,21 @@ fn expr_repr(cx: ctxt, expr: @ast::expr) -> ~str {
          pprust::expr_to_str(expr, cx.sess.intr()))
 }
 
-fn tys_to_str(cx: ctxt, ts: ~[t]) -> ~str {
+fn tys_to_str(cx: ctxt, ts: &[t]) -> ~str {
     let tstrs = ts.map(|t| ty_to_str(cx, *t));
-    fmt!("[%s]", str::connect(tstrs, ", "))
+    fmt!("(%s)", str::connect(tstrs, ", "))
 }
 
 fn bound_to_str(cx: ctxt, b: param_bound) -> ~str {
     ty::param_bound_to_str(cx, &b)
 }
 
+fn fn_sig_to_str(cx: ctxt, typ: &ty::FnSig) -> ~str {
+    fmt!("fn%s -> %s",
+         tys_to_str(cx, typ.inputs.map(|a| a.ty)),
+         ty_to_str(cx, typ.output))
+}
+
 fn ty_to_str(cx: ctxt, typ: t) -> ~str {
     fn fn_input_to_str(cx: ctxt, input: {mode: ast::mode, ty: t}) ->
        ~str {
@@ -275,11 +289,11 @@ fn fn_input_to_str(cx: ctxt, input: {mode: ast::mode, ty: t}) ->
                 m == ty::default_arg_mode_for_ty(cx, ty) {
                 ~""
             } else {
-                mode_to_str(ast::expl(m)) + ":"
+                mode_to_str(ast::expl(m)) + ~":"
             }
           }
         };
-        modestr + ty_to_str(cx, ty)
+        fmt!("%s%s", modestr, ty_to_str(cx, ty))
     }
     fn fn_to_str(cx: ctxt,
                  proto: ast::Proto,
@@ -287,22 +301,21 @@ fn fn_to_str(cx: ctxt,
                  purity: ast::purity,
                  onceness: ast::Onceness,
                  ident: Option<ast::ident>,
-                 inputs: ~[arg],
-                 output: t,
-                 cf: ast::ret_style) -> ~str {
+                 inputs: &[arg],
+                 output: t) -> ~str {
         let mut s;
 
         s = match purity {
             ast::impure_fn => ~"",
-            _ => purity_to_str(purity) + ~" "
+            _ => purity.to_str() + ~" "
         };
 
         s += match onceness {
             ast::Many => ~"",
-            ast::Once => onceness_to_str(onceness) + ~" "
+            ast::Once => onceness.to_str() + ~" "
         };
 
-        s += proto_ty_to_str(cx, proto);
+        s += proto_ty_to_str(cx, proto, true);
 
         match (proto, region) {
             (ast::ProtoBox, ty::re_static) |
@@ -327,9 +340,10 @@ fn fn_to_str(cx: ctxt,
         s += ~")";
         if ty::get(output).sty != ty_nil {
             s += ~" -> ";
-            match cf {
-              ast::noreturn => { s += ~"!"; }
-              ast::return_val => { s += ty_to_str(cx, output); }
+            if ty::type_is_bot(output) {
+                s += ~"!";
+            } else {
+                s += ty_to_str(cx, output);
             }
         }
         return s;
@@ -343,24 +357,23 @@ fn method_to_str(cx: ctxt, m: method) -> ~str {
             m.fty.meta.onceness,
             Some(m.ident),
             m.fty.sig.inputs,
-            m.fty.sig.output,
-            m.fty.meta.ret_style) + ~";";
+            m.fty.sig.output) + ~";";
     }
     fn field_to_str(cx: ctxt, f: field) -> ~str {
         return cx.sess.str_of(f.ident) + ~": " + mt_to_str(cx, f.mt);
     }
 
     // if there is an id, print that instead of the structural type:
-    for ty::type_def_id(typ).each |def_id| {
+    /*for ty::type_def_id(typ).each |def_id| {
         // note that this typedef cannot have type parameters
         return ast_map::path_to_str(ty::item_path(cx, *def_id),
                                     cx.sess.intr());
-    }
+    }*/
 
     // pretty print the structural type representation:
-    return match ty::get(typ).sty {
+    return match /*bad*/copy ty::get(typ).sty {
       ty_nil => ~"()",
-      ty_bot => ~"_|_",
+      ty_bot => ~"!",
       ty_bool => ~"bool",
       ty_int(ast::ty_i) => ~"int",
       ty_int(ast::ty_char) => ~"char",
@@ -393,8 +406,7 @@ fn field_to_str(cx: ctxt, f: field) -> ~str {
                   f.meta.onceness,
                   None,
                   f.sig.inputs,
-                  f.sig.output,
-                  f.meta.ret_style)
+                  f.sig.output)
       }
       ty_infer(infer_ty) => infer_ty.to_str(),
       ty_err => ~"[type error]",
@@ -405,12 +417,12 @@ fn field_to_str(cx: ctxt, f: field) -> ~str {
       ty_enum(did, ref substs) | ty_struct(did, ref substs) => {
         let path = ty::item_path(cx, did);
         let base = ast_map::path_to_str(path, cx.sess.intr());
-        parameterized(cx, base, (*substs).self_r, (*substs).tps)
+        parameterized(cx, base, substs.self_r, substs.tps)
       }
       ty_trait(did, ref substs, vs) => {
         let path = ty::item_path(cx, did);
         let base = ast_map::path_to_str(path, cx.sess.intr());
-        let result = parameterized(cx, base, (*substs).self_r, (*substs).tps);
+        let result = parameterized(cx, base, substs.self_r, substs.tps);
         vstore_ty_to_str(cx, result, vs)
       }
       ty_evec(mt, vs) => {
@@ -426,9 +438,9 @@ fn field_to_str(cx: ctxt, f: field) -> ~str {
 }
 
 fn parameterized(cx: ctxt,
-                 base: ~str,
+                 base: &str,
                  self_r: Option<ty::Region>,
-                 tps: ~[ty::t]) -> ~str {
+                 tps: &[ty::t]) -> ~str {
 
     let r_str = match self_r {
       None => ~"",
@@ -439,7 +451,7 @@ fn parameterized(cx: ctxt,
 
     if vec::len(tps) > 0u {
         let strs = vec::map(tps, |t| ty_to_str(cx, *t));
-        fmt!("%s%s<%s>", base, r_str, str::connect(strs, ~","))
+        fmt!("%s%s<%s>", base, r_str, str::connect(strs, ","))
     } else {
         fmt!("%s%s", base, r_str)
     }
index 14b7b52e4d360bd2fdff928f7b98ec484d7663a5..99cf301f18248d811d29d4e32662ee2f119927f6 100644 (file)
 non-sendableness.
 */
 
+use core::prelude::*;
+
+use parse;
+use util;
+
+use core::oldcomm;
+use core::vec;
 use rustc::back::link;
 use rustc::driver::driver;
 use rustc::driver::session::Session;
@@ -30,6 +37,7 @@
 use syntax::codemap;
 use syntax::diagnostic::handler;
 use syntax::diagnostic;
+use syntax;
 
 pub type Ctxt = {
     ast: @ast::crate,
index 1a46b924147eea66ba9a456aa1137ecc55508061..aa6e40ab1d1efc9f231c4df2784276e4ae140533 100644 (file)
 an AST's attributes.
 */
 
+use core::prelude::*;
+
+use core::str;
+use core::tuple;
+use core::vec;
 use syntax::ast;
 use syntax::attr;
-use core::tuple;
+use syntax::codemap;
+use syntax;
 
 pub type CrateAttrs = {
     name: Option<~str>
 
 #[cfg(test)]
 mod test {
-    #[legacy_exports];
+    use syntax::ast;
+    use syntax;
+
+    use core::option::None;
 
-    fn parse_attributes(+source: ~str) -> ~[ast::attribute] {
+    pub fn parse_attributes(+source: ~str) -> ~[ast::attribute] {
         use syntax::parse;
         use syntax::parse::parser;
         use syntax::parse::attr::parser_attr;
index 0180d18668daf86d8ffa587e1192072486cd2aaf..165b5e257b2287665d4c15dd8511f00c56df301b 100644 (file)
 of the natural-language documentation for a crate.
 */
 
+use core::prelude::*;
+
+use astsrv;
+use attr_parser;
 use doc::ItemUtils;
+use doc;
 use extract::to_str;
 use fold::Fold;
+use fold;
+use pass::Pass;
+
+use core::option;
+use core::vec;
 use syntax::ast;
 use syntax::ast_map;
 use std::map::HashMap;
+use std::par;
 
 pub fn mk_pass() -> Pass {
-    {
+    Pass {
         name: ~"attr",
         f: run
     }
 }
 
-fn run(
+pub fn run(
     srv: astsrv::Srv,
     +doc: doc::Doc
 ) -> doc::Doc {
@@ -61,7 +72,7 @@ fn fold_crate(
     {
         topmod: doc::ModDoc_({
             item: {
-                name: option::get_default(attrs.name, doc.topmod.name()),
+                name: option::get_or_default(attrs.name, doc.topmod.name()),
                 .. doc.topmod.item
             },
             .. *doc.topmod
@@ -301,8 +312,12 @@ fn f(a: bool) -> bool { }\
 
 #[cfg(test)]
 mod test {
-    #[legacy_exports];
-    fn mk_doc(source: ~str) -> doc::Doc {
+    use astsrv;
+    use attr_pass::run;
+    use doc;
+    use extract;
+
+    pub fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let doc = extract::from_srv(srv, ~"");
             run(srv, doc)
index ec600860690bf1f5e1b2b76a9acf4dac4a292c05..ebd5c047df372433a46f0af1f687fefd1796d777 100644 (file)
@@ -8,7 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use result::Result;
+use core::prelude::*;
+
+use core::cmp;
+use core::os;
+use core::result;
+use core::run;
+use core::vec;
+use core::result::Result;
 use std::getopts;
 use std::cell::Cell;
 
@@ -51,7 +58,7 @@ impl OutputStyle : cmp::Eq {
     pandoc_cmd: Option<~str>
 };
 
-impl Config: Clone {
+pub impl Config: Clone {
     fn clone(&self) -> Config { copy *self }
 }
 
@@ -100,7 +107,7 @@ pub fn default_config(input_crate: &Path) -> Config {
 type ProgramOutput = fn~((&str), (&[~str])) ->
     {status: int, out: ~str, err: ~str};
 
-fn mock_program_output(_prog: &str, _args: &[~str]) -> {
+pub fn mock_program_output(_prog: &str, _args: &[~str]) -> {
     status: int, out: ~str, err: ~str
 } {
     {
@@ -114,7 +121,7 @@ pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
     parse_config_(args, run::program_output)
 }
 
-fn parse_config_(
+pub fn parse_config_(
     args: &[~str],
     +program_output: ProgramOutput
 ) -> Result<Config, ~str> {
@@ -149,7 +156,7 @@ fn config_from_opts(
         let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
         let output_dir = output_dir.map(|s| Path(*s));
         result::Ok({
-            output_dir: output_dir.get_default(config.output_dir),
+            output_dir: output_dir.get_or_default(config.output_dir),
             .. config
         })
     };
@@ -283,8 +290,11 @@ fn should_error_with_no_pandoc() {
 
 #[cfg(test)]
 mod test {
-    #[legacy_exports];
-    fn parse_config(args: &[~str]) -> Result<Config, ~str> {
+    use config::{Config, mock_program_output, parse_config_};
+
+    use core::result::Result;
+
+    pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
         parse_config_(args, mock_program_output)
     }
 }
index d7b505955806d2fdf348e703b364246f96f7f54d..bb8f37dc7ade9a2fbccc895cd95cb3551b93728a 100644 (file)
@@ -21,6 +21,8 @@
  * tests on this file
  */
 
+use core::prelude::*;
+
 /// The base price of a muffin on a non-holiday
 const price_of_a_muffin: float = 70f;
 
index fa21366d917cc51b98a277f42a325c740c21a318..4074d9aa691167e3c3153c666ba7b4673556dedf 100644 (file)
 is interpreted as the brief description.
 */
 
+use core::prelude::*;
+
+use astsrv;
 use doc::ItemUtils;
+use doc;
 use fold::Fold;
+use fold;
+use pass::Pass;
+
+use core::str;
+use core::vec;
+use std::par;
 
 pub fn mk_pass() -> Pass {
-    {
+    Pass {
         name: ~"desc_to_brief",
         f: run
     }
 }
 
-fn run(
+pub fn run(
     _srv: astsrv::Srv,
     +doc: doc::Doc
 ) -> doc::Doc {
@@ -91,9 +101,14 @@ fn should_promote_impl_method_desc() {
 }
 
 #[cfg(test)]
-mod test {
-    #[legacy_exports];
-    fn mk_doc(source: ~str) -> doc::Doc {
+pub mod test {
+    use astsrv;
+    use attr_pass;
+    use desc_to_brief_pass::run;
+    use doc;
+    use extract;
+
+    pub fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let doc = extract::from_srv(srv, ~"");
             let doc = (attr_pass::mk_pass().f)(srv, doc);
index c7d52fb77d663b41de9064a787afdd8dabb4f588..18742720b90c985528af26b03224d621947b1ce5 100644 (file)
 
 //! The document model
 
+use core::prelude::*;
+
+use doc;
+use pass::Pass;
+
+use core::cmp;
+use core::option;
+use core::vec;
+
 pub type AstId = int;
 
 pub type Doc_ = {
index 9daf334758603c8115406dd78df774ef93768f1f..6e000444865f15aee8ba354123669296e3ad1667 100644 (file)
 
 //! Escapes text sequences
 
+use pass::Pass;
+use text_pass;
+
+use core::str;
+
 pub fn mk_pass() -> Pass {
     text_pass::mk_pass(~"escape", escape)
 }
index 717ae9d7fba8e4514a1fc6e3fb6f80d6cfefcb53..444949cfb7f0ccde1b1722e71a32138468f5e297 100644 (file)
 
 //! Converts the Rust AST to the rustdoc document model
 
-use syntax::ast;
+use core::prelude::*;
+
+use astsrv;
 use doc::ItemUtils;
-use task::local_data::local_data_get;
+use doc;
+
+use core::cast;
+use core::task::local_data::local_data_get;
+use core::vec;
+use syntax::ast;
+use syntax;
 
 /* can't import macros yet, so this is copied from token.rs. See its comment
  * there. */
@@ -338,6 +346,13 @@ fn should_extract_struct_fields() {
 mod test {
     #[legacy_exports];
 
+    use astsrv;
+    use doc;
+    use extract::{extract, from_srv};
+    use parse;
+
+    use core::vec;
+
     fn mk_doc(+source: ~str) -> doc::Doc {
         let ast = parse::from_str(source);
         extract(ast, ~"")
index ba626f80ddb8f5b19470226177576be47f76f57f..29c53e0af2555bcf8e6ecd8870cd8832b5115fcb 100644 (file)
@@ -8,6 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use astsrv;
+use doc;
+use extract;
+use parse;
+use pass::Pass;
+
+use core::vec;
+use std::par;
+
 pub struct Fold<T> {
     ctxt: T,
     fold_doc: FoldDoc<T>,
index b1cc778bd1bf3dd832a559d7a09d52c1db315224..1f4e1be62fc3be931c3dd7c9ad8cd5773ad46cf5 100644 (file)
 
 //! Build indexes as appropriate for the markdown pass
 
+use core::prelude::*;
+
+use astsrv;
+use config;
 use doc::ItemUtils;
+use doc;
 use fold::Fold;
+use fold;
+use markdown_pass;
+use markdown_writer;
+use pass::Pass;
+
+use core::str;
+use std::par;
 
 pub fn mk_pass(+config: config::Config) -> Pass {
-    {
+    Pass {
         name: ~"markdown_index",
         f: fn~(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
             run(srv, doc, config)
@@ -22,7 +34,7 @@ pub fn mk_pass(+config: config::Config) -> Pass {
     }
 }
 
-fn run(
+pub fn run(
     _srv: astsrv::Srv,
     +doc: doc::Doc,
     +config: config::Config
@@ -242,8 +254,19 @@ fn should_index_foreign_mod_contents() {
 
 #[cfg(test)]
 mod test {
-    #[legacy_exports];
-    fn mk_doc(output_style: config::OutputStyle, +source: ~str) -> doc::Doc {
+    use astsrv;
+    use attr_pass;
+    use config;
+    use desc_to_brief_pass;
+    use doc;
+    use extract;
+    use markdown_index_pass::run;
+    use path_pass;
+
+    use core::path::Path;
+
+    pub fn mk_doc(output_style: config::OutputStyle, +source: ~str)
+               -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let config = {
                 output_style: output_style,
index 3328cdd527a86d3422a65a430ee4bcef33151504..1ec30bc74ab66f59df569ccd663ca08dbf24a851 100644 (file)
 
 //! Generate markdown from a document tree
 
+use core::prelude::*;
+
+use astsrv;
+use attr_pass;
+use config;
+use desc_to_brief_pass;
 use doc::ItemUtils;
+use doc;
+use extract;
+use fold;
+use markdown_index_pass;
+use markdown_pass;
 use markdown_writer::Writer;
 use markdown_writer::WriterUtils;
 use markdown_writer::WriterFactory;
+use markdown_writer;
+use page_pass;
+use pass::Pass;
+use path_pass;
+use sectionalize_pass;
+use sort_pass;
+use trim_pass;
+use unindent_pass;
+
+use core::iter;
+use core::oldcomm;
+use core::str;
+use core::vec;
+use std::par;
+use syntax;
 
 pub fn mk_pass(+writer_factory: WriterFactory) -> Pass {
     let f = fn~(move writer_factory,
@@ -21,7 +47,7 @@ pub fn mk_pass(+writer_factory: WriterFactory) -> Pass {
         run(srv, doc, copy writer_factory)
     };
 
-    {
+    Pass {
         name: ~"markdown",
         f: move f
     }
@@ -88,7 +114,7 @@ fn d() { }"
     w: Writer
 };
 
-fn write_markdown(
+pub fn write_markdown(
     +doc: doc::Doc,
     +writer_factory: WriterFactory
 ) {
@@ -212,7 +238,7 @@ pub fn header_kind(+doc: doc::ItemTag) -> ~str {
         ~"Enum"
       }
       doc::TraitTag(_) => {
-        ~"Interface"
+        ~"Trait"
       }
       doc::ImplTag(_) => {
         ~"Implementation"
@@ -701,7 +727,7 @@ fn write_method(ctxt: &Ctxt, +doc: doc::MethodDoc) {
 #[test]
 fn should_write_trait_header() {
     let markdown = test::render(~"trait i { fn a(); }");
-    assert str::contains(markdown, ~"## Interface `i`");
+    assert str::contains(markdown, ~"## Trait `i`");
 }
 
 #[test]
@@ -807,6 +833,26 @@ fn should_write_struct_header() {
 #[cfg(test)]
 mod test {
     #[legacy_exports];
+
+    use astsrv;
+    use attr_pass;
+    use config;
+    use desc_to_brief_pass;
+    use doc;
+    use extract;
+    use markdown_index_pass;
+    use markdown_pass::{mk_pass, write_markdown};
+    use markdown_writer;
+    use path_pass;
+    use sectionalize_pass;
+    use trim_pass;
+    use tystr_pass;
+    use unindent_pass;
+
+    use core::oldcomm;
+    use core::path::Path;
+    use core::str;
+
     fn render(+source: ~str) -> ~str {
         let (srv, doc) = create_doc_srv(source);
         let markdown = write_markdown_str_srv(srv, doc);
index 9cf404e0533d5ba5546777d1899c24d18a9114b8..2a8a777ef6974b423fa7b01d5c18f47e3ef5d970 100644 (file)
@@ -8,9 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use config;
 use doc::ItemUtils;
-use io::ReaderUtil;
+use doc;
+use pass::Pass;
+
+use core::io::ReaderUtil;
+use core::io;
+use core::libc;
+use core::oldcomm;
+use core::os;
+use core::pipes;
+use core::result;
+use core::run;
+use core::str;
+use core::task;
 use std::future;
+use syntax;
 
 pub enum WriteInstr {
     Write(~str),
@@ -135,17 +151,19 @@ fn pandoc_writer(
 
 fn readclose(fd: libc::c_int) -> ~str {
     // Copied from run::program_output
-    let file = os::fdopen(fd);
-    let reader = io::FILE_reader(file, false);
-    let buf = io::with_bytes_writer(|writer| {
-        let mut bytes = [mut 0, ..4096];
-        while !reader.eof() {
-            let nread = reader.read(bytes, bytes.len());
-            writer.write(bytes.view(0, nread));
-        }
-    });
-    os::fclose(file);
-    str::from_bytes(buf)
+    unsafe {
+        let file = os::fdopen(fd);
+        let reader = io::FILE_reader(file, false);
+        let buf = io::with_bytes_writer(|writer| {
+            let mut bytes = [mut 0, ..4096];
+            while !reader.eof() {
+                let nread = reader.read(bytes, bytes.len());
+                writer.write(bytes.view(0, nread));
+            }
+        });
+        os::fclose(file);
+        str::from_bytes(buf)
+    }
 }
 
 fn generic_writer(+process: fn~(+markdown: ~str)) -> Writer {
@@ -254,6 +272,12 @@ fn should_name_mod_file_names_by_path() {
 #[cfg(test)]
 mod test {
     #[legacy_exports];
+
+    use astsrv;
+    use doc;
+    use extract;
+    use path_pass;
+
     fn mk_doc(+name: ~str, +source: ~str) -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let doc = extract::from_srv(srv, name);
index af8ac5f1427efcd9af54e583dce4a73c400dcecb..2629d45635e0ba65a9674d0f29052b5403a50af1 100644 (file)
 individual modules, pages for the crate, indexes, etc.
 */
 
+use core::prelude::*;
+
+use astsrv;
+use config;
 use doc::{ItemUtils, PageUtils};
+use doc;
 use fold::Fold;
-use syntax::ast;
+use fold;
+use pass::Pass;
+use sort_pass;
 use util::NominalOp;
+use util;
+
+use core::oldcomm;
+use core::option;
+use core::vec;
+use syntax::ast;
 
 pub fn mk_pass(output_style: config::OutputStyle) -> Pass {
-    {
+    Pass {
         name: ~"page",
         f: fn~(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
             run(srv, doc, output_style)
@@ -29,7 +42,7 @@ pub fn mk_pass(output_style: config::OutputStyle) -> Pass {
     }
 }
 
-fn run(
+pub fn run(
     _srv: astsrv::Srv,
     +doc: doc::Doc,
     output_style: config::OutputStyle
@@ -116,7 +129,7 @@ fn fold_mod(
 
 fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc {
     doc::ModDoc_({
-        items: do vec::filter(doc.items) |item| {
+        items: do doc.items.filtered |item| {
             match *item {
               doc::ModTag(_) => false,
               doc::NmodTag(_) => false,
@@ -172,8 +185,13 @@ fn should_remove_foreign_mods_from_containing_mods() {
 
 #[cfg(test)]
 mod test {
-    #[legacy_exports];
-    fn mk_doc_(
+    use astsrv;
+    use config;
+    use doc;
+    use extract;
+    use page_pass::run;
+
+    pub fn mk_doc_(
         output_style: config::OutputStyle,
         source: ~str
     ) -> doc::Doc {
@@ -183,7 +201,7 @@ fn mk_doc_(
         }
     }
 
-    fn mk_doc(source: ~str) -> doc::Doc {
+    pub fn mk_doc(source: ~str) -> doc::Doc {
         mk_doc_(config::DocPerMod, source)
     }
 }
index db97f34f20168d49ef8ab1ebc35e48c32747b028..48eb3d47a167ac33728c6e3927e035256da2d48f 100644 (file)
@@ -10,6 +10,8 @@
 
 //! AST-parsing helpers
 
+use core::prelude::*;
+
 use rustc::driver::driver::{file_input, str_input};
 use rustc::driver::driver;
 use rustc::driver::session;
index 0fbc61ad4544d285496f15ce7ec0e1bf7e31fee0..1e5d5542963af6ede30b6b19970ef138b531cc30 100644 (file)
@@ -8,11 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use astsrv;
+use doc;
+use extract;
+use time;
+
+use core::vec;
+
 /// A single operation on the document model
-pub type Pass = {
+pub struct Pass {
     name: ~str,
     f: fn~(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc
-};
+}
 
 pub fn run_passes(
     srv: astsrv::Srv,
@@ -73,11 +82,11 @@ fn pass2(
     let source = ~"";
     do astsrv::from_str(source) |srv| {
         let passes = ~[
-            {
+            Pass {
                 name: ~"",
                 f: pass1
             },
-            {
+            Pass {
                 name: ~"",
                 f: pass2
             }
index b17f4d67a5c328d01943a896896bfe800dad467f..48ed1878771261c18010a704b7ec0f8d5b81a5a8 100644 (file)
 
 //! Records the full path to items
 
+use core::prelude::*;
+
+use astsrv;
 use doc::ItemUtils;
+use doc;
+use extract;
 use fold::Fold;
+use fold;
+use pass::Pass;
+
 use syntax::ast;
 
 pub fn mk_pass() -> Pass {
-    {
+    Pass {
         name: ~"path",
         f: run
     }
index bfe6f8387041627c04b8d26e03b005ebcd5224c8..3a924e3bddf699c5b0294219ef337972a04c92ff 100644 (file)
 
 //! Prunes things with the #[doc(hidden)] attribute
 
+use astsrv;
+use attr_parser;
 use doc::ItemUtils;
+use doc;
 use fold::Fold;
+use fold;
+use pass::Pass;
+
+use core::vec;
 use std::map::HashMap;
 
 pub fn mk_pass() -> Pass {
-    {
+    Pass {
         name: ~"prune_hidden",
         f: run
     }
 }
 
-fn run(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
+pub fn run(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
     let fold = Fold {
         fold_mod: fold_mod,
         .. fold::default_any_fold(srv)
@@ -36,9 +43,9 @@ fn fold_mod(
     let doc = fold::default_any_fold_mod(fold, doc);
 
     doc::ModDoc_({
-        items: vec::filter(doc.items, |ItemTag| {
+        items: do doc.items.filtered |ItemTag| {
             !is_hidden(fold.ctxt, ItemTag.item())
-        }),
+        },
         .. *doc
     })
 }
@@ -63,9 +70,13 @@ fn should_prune_hidden_items() {
 }
 
 #[cfg(test)]
-mod test {
-    #[legacy_exports];
-    fn mk_doc(source: ~str) -> doc::Doc {
+pub mod test {
+    use astsrv;
+    use doc;
+    use extract;
+    use prune_hidden_pass::run;
+
+    pub fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let doc = extract::from_srv(srv, ~"");
             run(srv, doc)
index e3dc1553a6392fc37f065774faa5a95c2446ddbd..3b11437acebaf1967f06dfc456a1d306733ab74f 100644 (file)
 
 #[legacy_exports];
 
+use core::prelude::*;
+
+use astsrv;
+use doc;
 use fold::Fold;
+use fold;
+use pass::Pass;
+
+use core::util;
+use core::vec;
+use syntax::ast;
 
 export mk_pass;
+export run;
 
 fn mk_pass() -> Pass {
-    {
+    Pass {
         name: ~"prune_private",
         f: run
     }
 }
 
-fn run(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
+pub fn run(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
     let fold = Fold {
         fold_mod: fold_mod,
         .. fold::default_any_fold(srv)
@@ -38,9 +49,9 @@ fn fold_mod(
     let doc = fold::default_any_fold_mod(fold, doc);
 
     doc::ModDoc_({
-        items: do doc.items.filter |ItemTag| {
+        items: doc.items.filtered(|ItemTag| {
             is_visible(fold.ctxt, ItemTag.item())
-        },
+        }),
         .. *doc
     })
 }
@@ -56,7 +67,7 @@ fn is_visible(srv: astsrv::Srv, doc: doc::ItemDoc) -> bool {
             ast_map::node_item(item, _) => {
                 item.vis == ast::public
             }
-            _ => core::util::unreachable()
+            _ => util::unreachable()
         }
     }
 }
@@ -68,7 +79,12 @@ fn should_prune_items_without_pub_modifier() {
 }
 
 #[cfg(test)]
-mod test {
+pub mod test {
+    use astsrv;
+    use doc;
+    use extract;
+    use prune_private_pass::run;
+
     pub fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let doc = extract::from_srv(srv, ~"");
index 2c73d4c478b1208486a04ea528c87c230f804c9e..eeadd82371fd9d7a4f2079d1fb6e417fedf8c163 100644 (file)
 
 //! Breaks rustdocs into sections according to their headers
 
+use core::prelude::*;
+
+use astsrv;
+use attr_pass;
 use doc::ItemUtils;
+use doc;
+use extract;
 use fold::Fold;
+use fold;
+use pass::Pass;
+
+use core::str;
+use core::vec;
+use std::par;
 
 pub fn mk_pass() -> Pass {
-    {
+    Pass {
         name: ~"sectionalize",
         f: run
     }
 }
 
-fn run(_srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
+pub fn run(_srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
     let fold = Fold {
         fold_item: fold_item,
         fold_trait: fold_trait,
@@ -240,9 +252,14 @@ fn should_sectionalize_impl_methods() {
 }
 
 #[cfg(test)]
-mod test {
-    #[legacy_exports];
-    fn mk_doc(source: ~str) -> doc::Doc {
+pub mod test {
+    use astsrv;
+    use attr_pass;
+    use doc;
+    use extract;
+    use sectionalize_pass::run;
+
+    pub fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let doc = extract::from_srv(srv, ~"");
             let doc = (attr_pass::mk_pass().f)(srv, doc);
index 3ef4750b9ad849efbe3cba1c5f444190a12e50b6..9a777d79345f56883b7ede442bfdb106f1d8d7f8 100644 (file)
 
 //! Sorts items by name
 
+use astsrv;
 use doc::ItemUtils;
+use doc;
+use extract;
+use pass::Pass;
+use sort_pass;
 
 pub fn mk_pass() -> Pass {
     pure fn by_item_name(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool {
index 25fc11a4a2a0ea81801648678e3f1c1f8483bd09..332c2082e4ba97d35cda669e8e5904ab2b774652 100644 (file)
 
 //! Sorts items by type
 
+use core::prelude::*;
+
+use astsrv;
 use doc::ItemUtils;
+use doc;
+use extract;
+use pass::Pass;
+use sort_pass;
 
 pub fn mk_pass() -> Pass {
     pure fn by_score(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool {
index a4926e765a7736342d2a3bef7ee691239770d3a4..b3ecb8173fee795a7084cacfb6a17f93678e1191 100644 (file)
 
 //! A general sorting pass
 
+use core::prelude::*;
+
+use astsrv;
 use doc::ItemUtils;
+use doc;
+use extract;
 use fold::Fold;
-use std::sort;
+use fold;
+use pass::Pass;
 use util::NominalOp;
 
+use std::sort;
+
 pub type ItemLtEqOp = pure fn~(v1: &doc::ItemTag, v2:  &doc::ItemTag) -> bool;
 
 type ItemLtEq = NominalOp<ItemLtEqOp>;
 
 pub fn mk_pass(name: ~str, +lteq: ItemLtEqOp) -> Pass {
-    {
+    Pass {
         name: name,
         f: fn~(move lteq, srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
             run(srv, doc, NominalOp { op: copy lteq })
index 9a48822b45360d93bfaf8fa5613e408739e2c7f4..5627bfead9f451dc93c228528f720ca485bace91 100644 (file)
 
 //! Generic pass for performing an operation on all descriptions
 
+use core::prelude::*;
+
+use astsrv;
 use doc::ItemUtils;
+use doc;
 use fold::Fold;
+use fold;
+use pass::Pass;
 use util::NominalOp;
 
+use std::par;
+
 pub fn mk_pass(name: ~str, +op: fn~(~str) -> ~str) -> Pass {
-    {
+    Pass {
         name: name,
         f: fn~(move op, srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
             run(srv, doc, copy op)
@@ -283,8 +291,17 @@ fn should_execute_on_impl_method_section_bodies() {
 
 #[cfg(test)]
 mod test {
-    #[legacy_exports];
-    fn mk_doc(source: ~str) -> doc::Doc {
+    use astsrv;
+    use attr_pass;
+    use desc_to_brief_pass;
+    use doc;
+    use extract;
+    use sectionalize_pass;
+    use text_pass::mk_pass;
+
+    use core::str;
+
+    pub fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let doc = extract::from_srv(srv, ~"");
             let doc = (attr_pass::mk_pass().f)(srv, doc);
index e6696b74eaec30890a2f49fb7c1fda190e188459..4ac8b51a6bcf70ef8893099a970d6cc9de79a336 100644 (file)
 */
 
 use doc::ItemUtils;
+use doc;
+use pass::Pass;
+use text_pass;
+
+use core::option::Some;
+use core::str;
 
 pub fn mk_pass() -> Pass {
     text_pass::mk_pass(~"trim", |s| str::trim(s) )
@@ -31,8 +37,13 @@ mod m {
 
 #[cfg(test)]
 mod test {
-    #[legacy_exports];
-    fn mk_doc(source: ~str) -> doc::Doc {
+    use astsrv;
+    use attr_pass;
+    use doc;
+    use extract;
+    use trim_pass::mk_pass;
+
+    pub fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let doc = extract::from_srv(srv, ~"");
             let doc = (attr_pass::mk_pass().f)(srv, doc);
index 4609454315f2633bf940454e58241f393989998a..ae1b7577ad83bc64f8c28c839611ebfce3087679 100644 (file)
 
 //! Pulls type information out of the AST and attaches it to the document
 
+use core::prelude::*;
+
+use astsrv;
 use doc::ItemUtils;
+use doc;
+use extract::to_str;
+use extract;
 use fold::Fold;
+use fold;
+use pass::Pass;
+
+use core::vec;
+use std::map::HashMap;
+use std::par;
 use syntax::ast;
 use syntax::print::pprust;
 use syntax::ast_map;
-use std::map::HashMap;
-use extract::to_str;
 
 pub fn mk_pass() -> Pass {
-    {
+    Pass {
         name: ~"tystr",
         f: run
     }
 }
 
-fn run(
+pub fn run(
     srv: astsrv::Srv,
     +doc: doc::Doc
 ) -> doc::Doc {
@@ -398,9 +408,13 @@ fn should_not_serialize_struct_attrs() {
 }
 
 #[cfg(test)]
-mod test {
-    #[legacy_exports];
-    fn mk_doc(source: ~str) -> doc::Doc {
+pub mod test {
+    use astsrv;
+    use doc;
+    use extract;
+    use tystr_pass::run;
+
+    pub fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(source) |srv| {
             let doc = extract::from_srv(srv, ~"");
             run(srv, doc)
index a2a402385004a347cb826ca3f193136dfdb70de9..87c249a7a18fc5dae9c408df085eef1ca76d5462 100644 (file)
 middle of a line, and each of the following lines is indented.
 */
 
+use core::prelude::*;
+
+use pass::Pass;
+use text_pass;
+
+use core::str;
+use core::uint;
+use core::vec;
+use std::par;
+
 pub fn mk_pass() -> Pass {
     text_pass::mk_pass(~"unindent", unindent)
 }
index ebeb9346d3c499b496f6938903e600d2f0e695ac..48ed77099c435419705e1596702a396a02f18a44 100644 (file)
@@ -8,6 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use core::oldcomm;
+use core::task;
+
 // Just a named container for our op, so it can have impls
 pub struct NominalOp<T> {
     op: T
index 8afb8d3f85136a22c43bd84338a73b5961d9deca..828877fc4a401d63fa1182e9321cb127f47aac8a 100644 (file)
@@ -134,6 +134,7 @@ fn run(repl: Repl, input: ~str) -> Repl {
         crate_type: session::unknown_crate,
         binary: repl.binary,
         addl_lib_search_paths: repl.lib_search_paths.map(|p| Path(*p)),
+        jit: true,
         .. *session::basic_options()
     };
 
@@ -153,8 +154,12 @@ fn run(repl: Repl, input: ~str) -> Repl {
                                           repl.binary,
                                           wrapped);
 
-    debug!("parsing");
-    let mut crate = driver::parse_input(sess, cfg, wrapped);
+    let outputs = driver::build_output_filenames(wrapped, &None, &None, sess);
+    debug!("calling compile_upto");
+    let {crate: crate, tcx: _} = driver::compile_upto(sess, cfg, wrapped,
+                                                 driver::cu_everything,
+                                                 Some(outputs));
+
     let mut opt = None;
 
     for crate.node.module.items.each |item| {
@@ -177,114 +182,6 @@ fn run(repl: Repl, input: ~str) -> Repl {
         }
         _ => fail
     };
-
-    debug!("configuration");
-    crate = front::config::strip_unconfigured_items(crate);
-
-    debug!("maybe building test harness");
-    crate = front::test::modify_for_testing(sess, crate);
-
-    debug!("expansion");
-    crate = syntax::ext::expand::expand_crate(sess.parse_sess,
-                                              sess.opts.cfg,
-                                              crate);
-
-    debug!("intrinsic injection");
-    crate = front::intrinsic_inject::inject_intrinsic(sess, crate);
-
-    debug!("core injection");
-    crate = front::core_inject::maybe_inject_libcore_ref(sess, crate);
-
-    debug!("building lint settings table");
-    lint::build_settings_crate(sess, crate);
-
-    debug!("ast indexing");
-    let ast_map = syntax::ast_map::map_crate(sess.diagnostic(), *crate);
-
-    debug!("external crate/lib resolution");
-    creader::read_crates(sess.diagnostic(), *crate, sess.cstore,
-                         sess.filesearch,
-                         session::sess_os_to_meta_os(sess.targ_cfg.os),
-                         sess.opts.static, sess.parse_sess.interner);
-
-    debug!("language item collection");
-    let lang_items = middle::lang_items::collect_language_items(crate, sess);
-
-    debug!("resolution");
-    let {def_map: def_map,
-         exp_map2: exp_map2,
-         trait_map: trait_map} = middle::resolve::resolve_crate(sess,
-                                                                lang_items,
-                                                                crate);
-
-    debug!("freevar finding");
-    let freevars = freevars::annotate_freevars(def_map, crate);
-
-    debug!("region_resolution");
-    let region_map = middle::region::resolve_crate(sess, def_map, crate);
-
-    debug!("region paramaterization inference");
-    let rp_set = middle::region::determine_rp_in_crate(sess, ast_map,
-                                                       def_map, crate);
-
-    debug!("typechecking");
-    let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars,
-                            region_map, rp_set, move lang_items, crate);
-    let (method_map, vtable_map) = typeck::check_crate(ty_cx, trait_map,
-                                                       crate);
-
-    debug!("const marking");
-    middle::const_eval::process_crate(crate, def_map, ty_cx);
-
-    debug!("const checking");
-    middle::check_const::check_crate(sess, crate, ast_map, def_map,
-                                     method_map, ty_cx);
-
-    debug!("privacy checking");
-    middle::privacy::check_crate(ty_cx, &method_map, crate);
-
-    debug!("loop checking");
-    middle::check_loop::check_crate(ty_cx, crate);
-
-    debug!("mode computation");
-    middle::mode::compute_modes(ty_cx, method_map, crate);
-
-    debug!("alt checking");
-    middle::check_alt::check_crate(ty_cx, method_map, crate);
-
-    debug!("liveness checking");
-    let last_use_map = middle::liveness::check_crate(ty_cx,
-                                                     method_map, crate);
-
-    debug!("borrow checking");
-    let (root_map, mutbl_map) = middle::borrowck::check_crate(ty_cx,
-                                                              method_map,
-                                                              last_use_map,
-                                                              crate);
-
-    debug!("kind checking");
-    kind::check_crate(ty_cx, method_map, last_use_map, crate);
-
-    debug!("lint checking");
-    lint::check_crate(ty_cx, crate);
-
-    let maps = {mutbl_map: mutbl_map,
-                root_map: root_map,
-                last_use_map: last_use_map,
-                method_map: method_map,
-                vtable_map: vtable_map};
-
-    debug!("translation");
-    let path = ~path::GenericPath::from_str("<repl>");
-    let (llmod, _) = trans::base::trans_crate(sess, crate, ty_cx,
-                                              path,
-                                              exp_map2, maps);
-    let pm = llvm::LLVMCreatePassManager();
-
-    debug!("executing jit");
-    back::link::jit::exec(sess, pm, llmod, 0, false);
-    llvm::LLVMDisposePassManager(pm);
-
     debug!("recording input into repl history");
     record(repl, blk, sess.parse_sess.interner)
 }
@@ -380,7 +277,7 @@ fn run_cmd(repl: &mut Repl, _in: io::Reader, _out: io::Writer,
             io::println(
                 ~":{\\n ..lines.. \\n:}\\n - execute multiline command\n" +
                 ~":load <crate> ... - \
-                  loads given crates as dynamic libraries" +
+                  loads given crates as dynamic libraries\n" +
                 ~":clear - clear the screen\n" +
                 ~":exit - exit from the repl\n" +
                 ~":help - show this message");
index e2bbda46d7cf389e281ef7dbdbae5ff72bd6098e..3463b31c55c6d0c709189867bf8d79ec2f3e2af6 100644 (file)
  * between tasks.
  */
 
-use private::{SharedMutableState, shared_mutable_state,
-                clone_shared_mutable_state, unwrap_shared_mutable_state,
-                get_shared_mutable_state, get_shared_immutable_state};
-use sync::{Mutex,  mutex_with_condvars,
-              RWlock, rwlock_with_condvars};
-
+use sync;
+use sync::{Mutex, mutex_with_condvars, RWlock, rwlock_with_condvars};
+
+use core::cast;
+use core::pipes;
+use core::prelude::*;
+use core::private::{SharedMutableState, shared_mutable_state};
+use core::private::{clone_shared_mutable_state, unwrap_shared_mutable_state};
+use core::private::{get_shared_mutable_state, get_shared_immutable_state};
+use core::ptr;
+use core::task;
+use core::util;
 
 /// As sync::condvar, a mechanism for unlock-and-descheduling and signalling.
 pub struct Condvar { is_mutex: bool, failed: &mut bool, cond: &sync::Condvar }
@@ -464,7 +470,18 @@ fn read<U>(blk: fn(x: &T) -> U) -> U {
 #[cfg(test)]
 mod tests {
     #[legacy_exports];
-    use comm::*;
+
+    use core::prelude::*;
+
+    use arc::*;
+    use arc;
+
+    use core::oldcomm::*;
+    use core::option::{Some, None};
+    use core::option;
+    use core::pipes;
+    use core::task;
+    use core::vec;
 
     #[test]
     fn manually_share_arc() {
index 9054f9355ad87950414baed577a4b81a6b1be532..a669adc6dc8a4bb7b3abce7a34bc53ff22a93906 100644 (file)
 
 #[forbid(deprecated_mode)];
 
+use arena;
+use list;
 use list::{List, Cons, Nil};
-use cast::reinterpret_cast;
-use sys::TypeDesc;
-use libc::size_t;
+
+use core::at_vec;
+use core::cast::reinterpret_cast;
+use core::cast;
+use core::libc::size_t;
+use core::prelude::*;
+use core::ptr;
+use core::sys::TypeDesc;
+use core::sys;
+use core::uint;
+use core::vec;
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
@@ -47,7 +57,9 @@
 
 extern mod rustrt {
     #[rust_stack]
-    fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t);
+    unsafe fn rust_call_tydesc_glue(root: *u8,
+                                    tydesc: *TypeDesc,
+                                    field: size_t);
 }
 // This probably belongs somewhere else. Needs to be kept in sync with
 // changes to glue...
index 43f13b5b91f482690017edf2a2db9a680e94a272..db3991a1d3bedf1c4232ee4c65148c3a7c01fe20 100644 (file)
@@ -9,7 +9,11 @@
 // except according to those terms.
 
 #[forbid(deprecated_mode)];
-use io::Reader;
+
+use core::io::Reader;
+use core::iter;
+use core::str;
+use core::vec;
 
 pub trait ToBase64 {
     pure fn to_base64() -> ~str;
@@ -149,6 +153,9 @@ impl ~str: FromBase64 {
 #[cfg(test)]
 mod tests {
     #[legacy_exports];
+
+    use core::str;
+
     #[test]
     fn test_to_base64() {
         assert (~"").to_base64()       == ~"";
diff --git a/src/libstd/bigint.rs b/src/libstd/bigint.rs
new file mode 100644 (file)
index 0000000..303129c
--- /dev/null
@@ -0,0 +1,1590 @@
+/*!
+
+A Big integer (signed version: BigInt, unsigned version: BigUint).
+
+A BigUint is represented as an array of BigDigits.
+A BigInt is a combination of BigUint and Sign.
+*/
+
+use core::cmp::{Eq, Ord};
+use core::num::{Num, Zero, One};
+use core::*;
+
+/**
+A BigDigit is a BigUint's composing element.
+
+A BigDigit is half the size of machine word size.
+*/
+#[cfg(target_arch = "x86")]
+#[cfg(target_arch = "arm")]
+pub type BigDigit = u16;
+
+/**
+A BigDigit is a BigUint's composing element.
+
+A BigDigit is half the size of machine word size.
+*/
+#[cfg(target_arch = "x86_64")]
+pub type BigDigit = u32;
+
+pub mod BigDigit {
+    use bigint::BigDigit;
+
+    #[cfg(target_arch = "x86")]
+    #[cfg(target_arch = "arm")]
+    pub const bits: uint = 16;
+
+    #[cfg(target_arch = "x86_64")]
+    pub const bits: uint = 32;
+
+    pub const base: uint = 1 << bits;
+    priv const hi_mask: uint = (-1 as uint) << bits;
+    priv const lo_mask: uint = (-1 as uint) >> bits;
+
+    priv pure fn get_hi(n: uint) -> BigDigit { (n >> bits) as BigDigit }
+    priv pure fn get_lo(n: uint) -> BigDigit { (n & lo_mask) as BigDigit }
+
+    /// Split one machine sized unsigned integer into two BigDigits.
+    pub pure fn from_uint(n: uint) -> (BigDigit, BigDigit) {
+        (get_hi(n), get_lo(n))
+    }
+
+    /// Join two BigDigits into one machine sized unsigned integer
+    pub pure fn to_uint(hi: BigDigit, lo: BigDigit) -> uint {
+        (lo as uint) | ((hi as uint) << bits)
+    }
+}
+
+/**
+A big unsigned integer type.
+
+A BigUint-typed value BigUint { data: @[a, b, c] } represents a number
+(a + b * BigDigit::base + c * BigDigit::base^2).
+*/
+pub struct BigUint {
+    priv data: ~[BigDigit]
+}
+
+impl BigUint : Eq {
+    pure fn eq(&self, other: &BigUint) -> bool { self.cmp(other) == 0 }
+    pure fn ne(&self, other: &BigUint) -> bool { self.cmp(other) != 0 }
+}
+
+impl BigUint : Ord {
+    pure fn lt(&self, other: &BigUint) -> bool { self.cmp(other) <  0 }
+    pure fn le(&self, other: &BigUint) -> bool { self.cmp(other) <= 0 }
+    pure fn ge(&self, other: &BigUint) -> bool { self.cmp(other) >= 0 }
+    pure fn gt(&self, other: &BigUint) -> bool { self.cmp(other) >  0 }
+}
+
+impl BigUint : ToStr {
+    pure fn to_str() -> ~str { self.to_str_radix(10) }
+}
+
+impl BigUint : from_str::FromStr {
+    static pure fn from_str(s: &str) -> Option<BigUint> {
+        BigUint::from_str_radix(s, 10)
+    }
+}
+
+impl BigUint : Shl<uint, BigUint> {
+    pure fn shl(&self, rhs: &uint) -> BigUint {
+        let n_unit = *rhs / BigDigit::bits;
+        let n_bits = *rhs % BigDigit::bits;
+        return self.shl_unit(n_unit).shl_bits(n_bits);
+    }
+}
+
+impl BigUint : Shr<uint, BigUint> {
+    pure fn shr(&self, rhs: &uint) -> BigUint {
+        let n_unit = *rhs / BigDigit::bits;
+        let n_bits = *rhs % BigDigit::bits;
+        return self.shr_unit(n_unit).shr_bits(n_bits);
+    }
+}
+
+impl BigUint : Zero {
+    static pure fn zero() -> BigUint { BigUint::new(~[]) }
+}
+
+impl BigUint : One {
+    static pub pure fn one() -> BigUint { BigUint::new(~[1]) }
+}
+
+impl BigUint : Num {
+    pure fn add(&self, other: &BigUint) -> BigUint {
+        let new_len = uint::max(self.data.len(), other.data.len());
+
+        let mut carry = 0;
+        let sum = do vec::from_fn(new_len) |i| {
+            let ai = if i < self.data.len()  { self.data[i]  } else { 0 };
+            let bi = if i < other.data.len() { other.data[i] } else { 0 };
+            let (hi, lo) = BigDigit::from_uint(
+                (ai as uint) + (bi as uint) + (carry as uint)
+            );
+            carry = hi;
+            lo
+        };
+        if carry == 0 { return BigUint::new(sum) };
+        return BigUint::new(sum + [carry]);
+    }
+
+    pure fn sub(&self, other: &BigUint) -> BigUint {
+        let new_len = uint::max(self.data.len(), other.data.len());
+
+        let mut borrow = 0;
+        let diff = do vec::from_fn(new_len) |i| {
+            let ai = if i < self.data.len()  { self.data[i]  } else { 0 };
+            let bi = if i < other.data.len() { other.data[i] } else { 0 };
+            let (hi, lo) = BigDigit::from_uint(
+                (BigDigit::base) +
+                (ai as uint) - (bi as uint) - (borrow as uint)
+            );
+            /*
+            hi * (base) + lo == 1*(base) + ai - bi - borrow
+            => ai - bi - borrow < 0 <=> hi == 0
+            */
+            borrow = if hi == 0 { 1 } else { 0 };
+            lo
+        };
+
+        assert borrow == 0;     // <=> assert (self >= other);
+        return BigUint::new(diff);
+    }
+
+    pure fn mul(&self, other: &BigUint) -> BigUint {
+        if self.is_zero() || other.is_zero() { return Zero::zero(); }
+
+        let s_len = self.data.len(), o_len = other.data.len();
+        if s_len == 1 { return mul_digit(other, self.data[0]);  }
+        if o_len == 1 { return mul_digit(self,  other.data[0]); }
+
+        // Using Karatsuba multiplication
+        // (a1 * base + a0) * (b1 * base + b0)
+        // = a1*b1 * base^2 +
+        //   (a1*b1 + a0*b0 - (a1-b0)*(b1-a0)) * base +
+        //   a0*b0
+        let half_len = uint::max(s_len, o_len) / 2;
+        let (sHi, sLo) = cut_at(self,  half_len);
+        let (oHi, oLo) = cut_at(other, half_len);
+
+        let ll = sLo * oLo;
+        let hh = sHi * oHi;
+        let mm = {
+            let (s1, n1) = sub_sign(sHi, sLo);
+            let (s2, n2) = sub_sign(oHi, oLo);
+            if s1 * s2 < 0 {
+                hh + ll + (n1 * n2)
+            } else if s1 * s2 > 0 {
+                hh + ll - (n1 * n2)
+            } else {
+                hh + ll
+            }
+        };
+
+        return ll + mm.shl_unit(half_len) + hh.shl_unit(half_len * 2);
+
+        pure fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
+            if n == 0 { return Zero::zero(); }
+            if n == 1 { return copy *a; }
+
+            let mut carry = 0;
+            let prod = do vec::map(a.data) |ai| {
+                let (hi, lo) = BigDigit::from_uint(
+                    (*ai as uint) * (n as uint) + (carry as uint)
+                );
+                carry = hi;
+                lo
+            };
+            if carry == 0 { return BigUint::new(prod) };
+            return BigUint::new(prod + [carry]);
+        }
+
+        pure fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) {
+            let mid = uint::min(a.data.len(), n);
+            return (BigUint::from_slice(vec::view(a.data, mid, a.data.len())),
+                    BigUint::from_slice(vec::view(a.data, 0, mid)));
+        }
+
+        pure fn sub_sign(a: BigUint, b: BigUint) -> (int, BigUint) {
+            match a.cmp(&b) {
+                s if s < 0 => (s, b - a),
+                s if s > 0 => (s, a - b),
+                _          => (0, Zero::zero())
+            }
+        }
+    }
+
+    pure fn div(&self, other: &BigUint) -> BigUint {
+        let (d, _) = self.divmod(other);
+        return d;
+    }
+    pure fn modulo(&self, other: &BigUint) -> BigUint {
+        let (_, m) = self.divmod(other);
+        return m;
+    }
+
+    pure fn neg(&self) -> BigUint { fail }
+
+    pure fn to_int(&self) -> int {
+        uint::min(self.to_uint(), int::max_value as uint) as int
+    }
+
+    static pure fn from_int(n: int) -> BigUint {
+        if (n < 0) { Zero::zero() } else { BigUint::from_uint(n as uint) }
+    }
+}
+
+pub impl BigUint {
+    /// Creates and initializes an BigUint.
+    static pub pure fn new(v: ~[BigDigit]) -> BigUint {
+        // omit trailing zeros
+        let new_len = v.rposition(|n| *n != 0).map_default(0, |p| *p + 1);
+
+        if new_len == v.len() { return BigUint { data: v }; }
+        let mut v = v;
+        unsafe { v.truncate(new_len); }
+        return BigUint { data: v };
+    }
+
+    /// Creates and initializes an BigUint.
+    static pub pure fn from_uint(n: uint) -> BigUint {
+        match BigDigit::from_uint(n) {
+            (0,  0)  => Zero::zero(),
+            (0,  n0) => BigUint::new(~[n0]),
+            (n1, n0) => BigUint::new(~[n0, n1])
+        }
+    }
+
+    /// Creates and initializes an BigUint.
+    static pub pure fn from_slice(slice: &[BigDigit]) -> BigUint {
+        return BigUint::new(vec::from_slice(slice));
+    }
+
+    /// Creates and initializes an BigUint.
+    static pub pure fn from_str_radix(s: &str, radix: uint)
+        -> Option<BigUint> {
+        BigUint::parse_bytes(str::to_bytes(s), radix)
+    }
+
+    /// Creates and initializes an BigUint.
+    static pub pure fn parse_bytes(buf: &[u8], radix: uint)
+        -> Option<BigUint> {
+        let (base, unit_len) = get_radix_base(radix);
+        let base_num: BigUint = BigUint::from_uint(base);
+
+        let mut end             = buf.len();
+        let mut n: BigUint      = Zero::zero();
+        let mut power: BigUint  = One::one();
+        loop {
+            let start = uint::max(end, unit_len) - unit_len;
+            match uint::parse_bytes(vec::view(buf, start, end), radix) {
+                Some(d) => n += BigUint::from_uint(d) * power,
+                None    => return None
+            }
+            if end <= unit_len {
+                return Some(n);
+            }
+            end -= unit_len;
+            power *= base_num;
+        }
+    }
+
+    pure fn abs(&self) -> BigUint { copy *self }
+
+    /// Compare two BigUint value.
+    pure fn cmp(&self, other: &BigUint) -> int {
+        let s_len = self.data.len(), o_len = other.data.len();
+        if s_len < o_len { return -1; }
+        if s_len > o_len { return  1;  }
+
+        for vec::rev_eachi(self.data) |i, elm| {
+            match (*elm, other.data[i]) {
+                (l, r) if l < r => return -1,
+                (l, r) if l > r => return  1,
+                _               => loop
+            };
+        }
+        return 0;
+    }
+
+    pure fn divmod(&self, other: &BigUint) -> (BigUint, BigUint) {
+        if other.is_zero() { fail }
+        if self.is_zero() { return (Zero::zero(), Zero::zero()); }
+        if *other == One::one() { return (copy *self, Zero::zero()); }
+
+        match self.cmp(other) {
+            s if s < 0 => return (Zero::zero(), copy *self),
+            0          => return (One::one(), Zero::zero()),
+            _          => {} // Do nothing
+        }
+
+        let mut shift = 0;
+        let mut n = other.data.last();
+        while n < (1 << BigDigit::bits - 2) {
+            n <<= 1;
+            shift += 1;
+        }
+        assert shift < BigDigit::bits;
+        let (d, m) = divmod_inner(self << shift, other << shift);
+        return (d, m >> shift);
+
+        pure fn divmod_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
+            let mut r = a;
+            let mut d = Zero::zero::<BigUint>();
+            let mut n = 1;
+            while r >= b {
+                let mut (d0, d_unit, b_unit) = div_estimate(&r, &b, n);
+                let mut prod = b * d0;
+                while prod > r {
+                    d0   -= d_unit;
+                    prod -= b_unit;
+                }
+                if d0.is_zero() {
+                    n = 2;
+                    loop;
+                }
+                n = 1;
+                d += d0;
+                r -= prod;
+            }
+            return (d, r);
+        }
+
+        pure fn div_estimate(a: &BigUint, b: &BigUint, n: uint)
+            -> (BigUint, BigUint, BigUint) {
+            if a.data.len() < n {
+                return (Zero::zero(), Zero::zero(), copy *a);
+            }
+
+            let an = vec::view(a.data, a.data.len() - n, a.data.len());
+            let bn = b.data.last();
+            let mut d = ~[];
+            let mut carry = 0;
+            for vec::rev_each(an) |elt| {
+                let ai = BigDigit::to_uint(carry, *elt);
+                let di = ai / (bn as uint);
+                assert di < BigDigit::base;
+                carry = (ai % (bn as uint)) as BigDigit;
+                d = ~[di as BigDigit] + d;
+            }
+
+            let shift = (a.data.len() - an.len()) - (b.data.len() - 1);
+            if shift == 0 {
+                return (BigUint::new(d), One::one(), copy *b);
+            }
+            return (BigUint::from_slice(d).shl_unit(shift),
+                    One::one::<BigUint>().shl_unit(shift),
+                    b.shl_unit(shift));
+        }
+    }
+
+    pure fn quot(&self, other: &BigUint) -> BigUint {
+        let (q, _) = self.quotrem(other);
+        return q;
+    }
+    pure fn rem(&self, other: &BigUint) -> BigUint {
+        let (_, r) = self.quotrem(other);
+        return r;
+    }
+    pure fn quotrem(&self, other: &BigUint) -> (BigUint, BigUint) {
+        self.divmod(other)
+    }
+
+    pure fn is_zero(&self) -> bool { self.data.is_empty() }
+    pure fn is_not_zero(&self) -> bool { self.data.is_not_empty() }
+    pure fn is_positive(&self) -> bool { self.is_not_zero() }
+    pure fn is_negative(&self) -> bool { false }
+    pure fn is_nonpositive(&self) -> bool { self.is_zero() }
+    pure fn is_nonnegative(&self) -> bool { true }
+
+    pure fn to_uint(&self) -> uint {
+        match self.data.len() {
+            0 => 0,
+            1 => self.data[0] as uint,
+            2 => BigDigit::to_uint(self.data[1], self.data[0]),
+            _ => uint::max_value
+        }
+    }
+
+    pure fn to_str_radix(&self, radix: uint) -> ~str {
+        assert 1 < radix && radix <= 16;
+        let (base, max_len) = get_radix_base(radix);
+        if base == BigDigit::base {
+            return fill_concat(self.data, radix, max_len)
+        }
+        return fill_concat(convert_base(copy *self, base), radix, max_len);
+
+        pure fn convert_base(n: BigUint, base: uint) -> ~[BigDigit] {
+            let divider    = BigUint::from_uint(base);
+            let mut result = ~[];
+            let mut r      = n;
+            while r > divider {
+                let (d, r0) = r.divmod(&divider);
+                result += [r0.to_uint() as BigDigit];
+                r = d;
+            }
+            if r.is_not_zero() {
+                result += [r.to_uint() as BigDigit];
+            }
+            return result;
+        }
+
+        pure fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str {
+            if v.is_empty() { return ~"0" }
+            str::trim_left_chars(str::concat(vec::reversed(v).map(|n| {
+                let s = uint::to_str(*n as uint, radix);
+                str::from_chars(vec::from_elem(l - s.len(), '0')) + s
+            })), ['0'])
+        }
+    }
+
+    priv pure fn shl_unit(self, n_unit: uint) -> BigUint {
+        if n_unit == 0 || self.is_zero() { return self; }
+
+        return BigUint::new(vec::from_elem(n_unit, 0) + self.data);
+    }
+
+    priv pure fn shl_bits(self, n_bits: uint) -> BigUint {
+        if n_bits == 0 || self.is_zero() { return self; }
+
+        let mut carry = 0;
+        let shifted = do vec::map(self.data) |elem| {
+            let (hi, lo) = BigDigit::from_uint(
+                (*elem as uint) << n_bits | (carry as uint)
+            );
+            carry = hi;
+            lo
+        };
+        if carry == 0 { return BigUint::new(shifted); }
+        return BigUint::new(shifted + [carry]);
+    }
+
+    priv pure fn shr_unit(self, n_unit: uint) -> BigUint {
+        if n_unit == 0 { return self; }
+        if self.data.len() < n_unit { return Zero::zero(); }
+        return BigUint::from_slice(
+            vec::view(self.data, n_unit, self.data.len())
+        );
+    }
+
+    priv pure fn shr_bits(self, n_bits: uint) -> BigUint {
+        if n_bits == 0 || self.data.is_empty() { return self; }
+
+        let mut borrow = 0;
+        let mut shifted = ~[];
+        for vec::rev_each(self.data) |elem| {
+            shifted = ~[(*elem >> n_bits) | borrow] + shifted;
+            borrow = *elem << (uint::bits - n_bits);
+        }
+        return BigUint::new(shifted);
+    }
+}
+
+#[cfg(target_arch = "x86_64")]
+priv pure fn get_radix_base(radix: uint) -> (uint, uint) {
+    assert 1 < radix && radix <= 16;
+    match radix {
+        2  => (4294967296, 32),
+        3  => (3486784401, 20),
+        4  => (4294967296, 16),
+        5  => (1220703125, 13),
+        6  => (2176782336, 12),
+        7  => (1977326743, 11),
+        8  => (1073741824, 10),
+        9  => (3486784401, 10),
+        10 => (1000000000, 9),
+        11 => (2357947691, 9),
+        12 => (429981696,  8),
+        13 => (815730721,  8),
+        14 => (1475789056, 8),
+        15 => (2562890625, 8),
+        16 => (4294967296, 8),
+        _  => fail
+    }
+}
+
+#[cfg(target_arch = "arm")]
+#[cfg(target_arch = "x86")]
+priv pure fn get_radix_base(radix: uint) -> (uint, uint) {
+    assert 1 < radix && radix <= 16;
+    match radix {
+        2  => (65536, 16),
+        3  => (59049, 10),
+        4  => (65536, 8),
+        5  => (15625, 6),
+        6  => (46656, 6),
+        7  => (16807, 5),
+        8  => (32768, 5),
+        9  => (59049, 5),
+        10 => (10000, 4),
+        11 => (14641, 4),
+        12 => (20736, 4),
+        13 => (28561, 4),
+        14 => (38416, 4),
+        15 => (50625, 4),
+        16 => (65536, 4),
+        _  => fail
+    }
+}
+
+/// A Sign is a BigInt's composing element.
+pub enum Sign { Minus, Zero, Plus }
+
+impl Sign : Eq {
+    pure fn eq(&self, other: &Sign) -> bool { self.cmp(other) == 0 }
+    pure fn ne(&self, other: &Sign) -> bool { self.cmp(other) != 0 }
+}
+
+impl Sign : Ord {
+    pure fn lt(&self, other: &Sign) -> bool { self.cmp(other) <  0 }
+    pure fn le(&self, other: &Sign) -> bool { self.cmp(other) <= 0 }
+    pure fn ge(&self, other: &Sign) -> bool { self.cmp(other) >= 0 }
+    pure fn gt(&self, other: &Sign) -> bool { self.cmp(other) >  0 }
+}
+
+pub impl Sign {
+    /// Compare two Sign.
+    pure fn cmp(&self, other: &Sign) -> int {
+        match (*self, *other) {
+          (Minus, Minus) | (Zero,  Zero) | (Plus, Plus) =>  0,
+          (Minus, Zero)  | (Minus, Plus) | (Zero, Plus) => -1,
+          _                                             =>  1
+        }
+    }
+
+    /// Negate Sign value.
+    pure fn neg(&self) -> Sign {
+        match *self {
+          Minus => Plus,
+          Zero  => Zero,
+          Plus  => Minus
+        }
+    }
+}
+
+/// A big signed integer type.
+pub struct BigInt {
+    priv sign: Sign,
+    priv data: BigUint
+}
+
+impl BigInt : Eq {
+    pure fn eq(&self, other: &BigInt) -> bool { self.cmp(other) == 0 }
+    pure fn ne(&self, other: &BigInt) -> bool { self.cmp(other) != 0 }
+}
+
+impl BigInt : Ord {
+    pure fn lt(&self, other: &BigInt) -> bool { self.cmp(other) <  0 }
+    pure fn le(&self, other: &BigInt) -> bool { self.cmp(other) <= 0 }
+    pure fn ge(&self, other: &BigInt) -> bool { self.cmp(other) >= 0 }
+    pure fn gt(&self, other: &BigInt) -> bool { self.cmp(other) >  0 }
+}
+
+impl BigInt : ToStr {
+    pure fn to_str() -> ~str { self.to_str_radix(10) }
+}
+
+impl BigInt : from_str::FromStr {
+    static pure fn from_str(s: &str) -> Option<BigInt> {
+        BigInt::from_str_radix(s, 10)
+    }
+}
+
+impl BigInt : Shl<uint, BigInt> {
+    pure fn shl(&self, rhs: &uint) -> BigInt {
+        BigInt::from_biguint(self.sign, self.data << *rhs)
+    }
+}
+
+impl BigInt : Shr<uint, BigInt> {
+    pure fn shr(&self, rhs: &uint) -> BigInt {
+        BigInt::from_biguint(self.sign, self.data >> *rhs)
+    }
+}
+
+impl BigInt : Zero {
+    static pub pure fn zero() -> BigInt {
+        BigInt::from_biguint(Zero, Zero::zero())
+    }
+}
+
+impl BigInt : One {
+    static pub pure fn one() -> BigInt {
+        BigInt::from_biguint(Plus, One::one())
+    }
+}
+
+impl BigInt : Num {
+    pure fn add(&self, other: &BigInt) -> BigInt {
+        match (self.sign, other.sign) {
+            (Zero, _)      => copy *other,
+            (_,    Zero)   => copy *self,
+            (Plus, Plus)   => BigInt::from_biguint(Plus,
+                                                   self.data + other.data),
+            (Plus, Minus)  => self - (-*other),
+            (Minus, Plus)  => other - (-*self),
+            (Minus, Minus) => -((-self) + (-*other))
+        }
+    }
+    pure fn sub(&self, other: &BigInt) -> BigInt {
+        match (self.sign, other.sign) {
+            (Zero, _)    => -other,
+            (_,    Zero) => copy *self,
+            (Plus, Plus) => match self.data.cmp(&other.data) {
+                s if s < 0 =>
+                    BigInt::from_biguint(Minus, other.data - self.data),
+                s if s > 0 =>
+                    BigInt::from_biguint(Plus, self.data - other.data),
+                _ =>
+                    Zero::zero()
+            },
+            (Plus, Minus) => self + (-*other),
+            (Minus, Plus) => -((-self) + *other),
+            (Minus, Minus) => (-other) - (-*self)
+        }
+    }
+    pure fn mul(&self, other: &BigInt) -> BigInt {
+        match (self.sign, other.sign) {
+            (Zero, _)     | (_,     Zero)  => Zero::zero(),
+            (Plus, Plus)  | (Minus, Minus) => {
+                BigInt::from_biguint(Plus, self.data * other.data)
+            },
+            (Plus, Minus) | (Minus, Plus) => {
+                BigInt::from_biguint(Minus, self.data * other.data)
+            }
+        }
+    }
+    pure fn div(&self, other: &BigInt) -> BigInt {
+        let (d, _) = self.divmod(other);
+        return d;
+    }
+    pure fn modulo(&self, other: &BigInt) -> BigInt {
+        let (_, m) = self.divmod(other);
+        return m;
+    }
+    pure fn neg(&self) -> BigInt {
+        BigInt::from_biguint(self.sign.neg(), copy self.data)
+    }
+
+    pure fn to_int(&self) -> int {
+        match self.sign {
+            Plus  => uint::min(self.to_uint(), int::max_value as uint) as int,
+            Zero  => 0,
+            Minus => uint::min((-self).to_uint(),
+                               (int::max_value as uint) + 1) as int
+        }
+    }
+
+    static pure fn from_int(n: int) -> BigInt {
+        if n > 0 {
+           return BigInt::from_biguint(Plus,  BigUint::from_uint(n as uint));
+        }
+        if n < 0 {
+            return BigInt::from_biguint(
+                Minus, BigUint::from_uint(uint::max_value - (n as uint) + 1)
+            );
+        }
+        return Zero::zero();
+    }
+}
+
+pub impl BigInt {
+    /// Creates and initializes an BigInt.
+    static pub pure fn new(sign: Sign, v: ~[BigDigit]) -> BigInt {
+        BigInt::from_biguint(sign, BigUint::new(v))
+    }
+
+    /// Creates and initializes an BigInt.
+    static pub pure fn from_biguint(sign: Sign, data: BigUint) -> BigInt {
+        if sign == Zero || data.is_zero() {
+            return BigInt { sign: Zero, data: Zero::zero() };
+        }
+        return BigInt { sign: sign, data: data };
+    }
+
+    /// Creates and initializes an BigInt.
+    static pub pure fn from_uint(n: uint) -> BigInt {
+        if n == 0 { return Zero::zero(); }
+        return BigInt::from_biguint(Plus, BigUint::from_uint(n));
+    }
+
+    /// Creates and initializes an BigInt.
+    static pub pure fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt {
+        BigInt::from_biguint(sign, BigUint::from_slice(slice))
+    }
+
+    /// Creates and initializes an BigInt.
+    static pub pure fn from_str_radix(s: &str, radix: uint)
+        -> Option<BigInt> {
+        BigInt::parse_bytes(str::to_bytes(s), radix)
+    }
+
+    /// Creates and initializes an BigInt.
+    static pub pure fn parse_bytes(buf: &[u8], radix: uint)
+        -> Option<BigInt> {
+        if buf.is_empty() { return None; }
+        let mut sign  = Plus;
+        let mut start = 0;
+        if buf[0] == ('-' as u8) {
+            sign  = Minus;
+            start = 1;
+        }
+        return BigUint::parse_bytes(vec::view(buf, start, buf.len()), radix)
+            .map(|bu| BigInt::from_biguint(sign, *bu));
+    }
+
+    pure fn abs(&self) -> BigInt {
+        BigInt::from_biguint(Plus, copy self.data)
+    }
+
+    pure fn cmp(&self, other: &BigInt) -> int {
+        let ss = self.sign, os = other.sign;
+        if ss < os { return -1; }
+        if ss > os { return  1; }
+
+        assert ss == os;
+        match ss {
+            Zero  => 0,
+            Plus  => self.data.cmp(&other.data),
+            Minus => self.data.cmp(&other.data).neg(),
+        }
+    }
+
+    pure fn divmod(&self, other: &BigInt) -> (BigInt, BigInt) {
+        // m.sign == other.sign
+        let (d_ui, m_ui) = self.data.divmod(&other.data);
+        let d = BigInt::from_biguint(Plus, d_ui),
+            m = BigInt::from_biguint(Plus, m_ui);
+        match (self.sign, other.sign) {
+            (_,    Zero)   => fail,
+            (Plus, Plus)  | (Zero, Plus)  => (d, m),
+            (Plus, Minus) | (Zero, Minus) => if m.is_zero() {
+                (-d, Zero::zero())
+            } else {
+                (-d - One::one(), m + *other)
+            },
+            (Minus, Plus) => if m.is_zero() {
+                (-d, Zero::zero())
+            } else {
+                (-d - One::one(), other - m)
+            },
+            (Minus, Minus) => (d, -m)
+        }
+    }
+
+    pure fn quot(&self, other: &BigInt) -> BigInt {
+        let (q, _) = self.quotrem(other);
+        return q;
+    }
+    pure fn rem(&self, other: &BigInt) -> BigInt {
+        let (_, r) = self.quotrem(other);
+        return r;
+    }
+
+    pure fn quotrem(&self, other: &BigInt) -> (BigInt, BigInt) {
+        // r.sign == self.sign
+        let (q_ui, r_ui) = self.data.quotrem(&other.data);
+        let q = BigInt::from_biguint(Plus, q_ui);
+        let r = BigInt::from_biguint(Plus, r_ui);
+        match (self.sign, other.sign) {
+            (_,    Zero)   => fail,
+            (Plus, Plus)  | (Zero, Plus)  => ( q,  r),
+            (Plus, Minus) | (Zero, Minus) => (-q,  r),
+            (Minus, Plus)                 => (-q, -r),
+            (Minus, Minus)                => ( q, -r)
+        }
+    }
+
+    pure fn is_zero(&self) -> bool { self.sign == Zero }
+    pure fn is_not_zero(&self) -> bool { self.sign != Zero }
+    pure fn is_positive(&self) -> bool { self.sign == Plus }
+    pure fn is_negative(&self) -> bool { self.sign == Minus }
+    pure fn is_nonpositive(&self) -> bool { self.sign != Plus }
+    pure fn is_nonnegative(&self) -> bool { self.sign != Minus }
+
+    pure fn to_uint(&self) -> uint {
+        match self.sign {
+            Plus  => self.data.to_uint(),
+            Zero  => 0,
+            Minus => 0
+        }
+    }
+
+    pure fn to_str_radix(&self, radix: uint) -> ~str {
+        match self.sign {
+            Plus  => self.data.to_str_radix(radix),
+            Zero  => ~"0",
+            Minus => ~"-" + self.data.to_str_radix(radix)
+        }
+    }
+}
+
+#[cfg(test)]
+mod biguint_tests {
+
+    use core::*;
+    use core::num::{Num, Zero, One};
+    use super::{BigInt, BigUint, BigDigit};
+
+    #[test]
+    fn test_from_slice() {
+        fn check(slice: &[BigDigit], data: &[BigDigit]) {
+            assert data == BigUint::from_slice(slice).data;
+        }
+        check(~[1], ~[1]);
+        check(~[0, 0, 0], ~[]);
+        check(~[1, 2, 0, 0], ~[1, 2]);
+        check(~[0, 0, 1, 2], ~[0, 0, 1, 2]);
+        check(~[0, 0, 1, 2, 0, 0], ~[0, 0, 1, 2]);
+        check(~[-1], ~[-1]);
+    }
+
+    #[test]
+    fn test_cmp() {
+        let data = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1]  ]
+            .map(|v| BigUint::from_slice(*v));
+        for data.eachi |i, ni| {
+            for vec::view(data, i, data.len()).eachi |j0, nj| {
+                let j = j0 + i;
+                if i == j {
+                    assert ni.cmp(nj) == 0;
+                    assert nj.cmp(ni) == 0;
+                    assert ni == nj;
+                    assert !(ni != nj);
+                    assert ni <= nj;
+                    assert ni >= nj;
+                    assert !(ni < nj);
+                    assert !(ni > nj);
+                } else {
+                    assert ni.cmp(nj) < 0;
+                    assert nj.cmp(ni) > 0;
+
+                    assert !(ni == nj);
+                    assert ni != nj;
+
+                    assert ni <= nj;
+                    assert !(ni >= nj);
+                    assert ni < nj;
+                    assert !(ni > nj);
+
+                    assert !(nj <= ni);
+                    assert nj >= ni;
+                    assert !(nj < ni);
+                    assert nj > ni;
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn test_shl() {
+        fn check(v: ~[BigDigit], shift: uint, ans: ~[BigDigit]) {
+            assert BigUint::new(v) << shift == BigUint::new(ans);
+        }
+
+        check(~[], 3, ~[]);
+        check(~[1, 1, 1], 3, ~[1 << 3, 1 << 3, 1 << 3]);
+        check(~[1 << (BigDigit::bits - 2)], 2, ~[0, 1]);
+        check(~[1 << (BigDigit::bits - 2)], 3, ~[0, 2]);
+        check(~[1 << (BigDigit::bits - 2)], 3 + BigDigit::bits, ~[0, 0, 2]);
+
+        test_shl_bits();
+
+        #[cfg(target_arch = "x86_64")]
+        fn test_shl_bits() {
+            check(~[0x7654_3210, 0xfedc_ba98,
+                    0x7654_3210, 0xfedc_ba98], 4,
+                  ~[0x6543_2100, 0xedcb_a987,
+                    0x6543_210f, 0xedcb_a987, 0xf]);
+            check(~[0x2222_1111, 0x4444_3333,
+                    0x6666_5555, 0x8888_7777], 16,
+                  ~[0x1111_0000, 0x3333_2222,
+                    0x5555_4444, 0x7777_6666, 0x8888]);
+        }
+
+        #[cfg(target_arch = "arm")]
+        #[cfg(target_arch = "x86")]
+        fn test_shl_bits() {
+            check(~[0x3210, 0x7654, 0xba98, 0xfedc,
+                    0x3210, 0x7654, 0xba98, 0xfedc], 4,
+                  ~[0x2100, 0x6543, 0xa987, 0xedcb,
+                    0x210f, 0x6543, 0xa987, 0xedcb, 0xf]);
+            check(~[0x1111, 0x2222, 0x3333, 0x4444,
+                    0x5555, 0x6666, 0x7777, 0x8888], 16,
+                  ~[0x0000, 0x1111, 0x2222, 0x3333,
+                    0x4444, 0x5555, 0x6666, 0x7777, 0x8888]);
+        }
+
+    }
+
+    #[test]
+    #[ignore(cfg(target_arch = "x86"))]
+    #[ignore(cfg(target_arch = "arm"))]
+    fn test_shr() {
+        fn check(v: ~[BigDigit], shift: uint, ans: ~[BigDigit]) {
+            assert BigUint::new(v) >> shift == BigUint::new(ans);
+        }
+
+        check(~[], 3, ~[]);
+        check(~[1, 1, 1], 3,
+              ~[1 << (BigDigit::bits - 3), 1 << (BigDigit::bits - 3)]);
+        check(~[1 << 2], 2, ~[1]);
+        check(~[1, 2], 3, ~[1 << (BigDigit::bits - 2)]);
+        check(~[1, 1, 2], 3 + BigDigit::bits, ~[1 << (BigDigit::bits - 2)]);
+        test_shr_bits();
+
+        #[cfg(target_arch = "x86_64")]
+        fn test_shr_bits() {
+            check(~[0x6543_2100, 0xedcb_a987,
+                    0x6543_210f, 0xedcb_a987, 0xf], 4,
+                  ~[0x7654_3210, 0xfedc_ba98,
+                    0x7654_3210, 0xfedc_ba98]);
+            check(~[0x1111_0000, 0x3333_2222,
+                    0x5555_4444, 0x7777_6666, 0x8888], 16,
+                  ~[0x2222_1111, 0x4444_3333,
+                    0x6666_5555, 0x8888_7777]);
+        }
+
+        #[cfg(target_arch = "arm")]
+        #[cfg(target_arch = "x86")]
+        fn test_shr_bits() {
+            check(~[0x2100, 0x6543, 0xa987, 0xedcb,
+                    0x210f, 0x6543, 0xa987, 0xedcb, 0xf], 4,
+                  ~[0x3210, 0x7654, 0xba98, 0xfedc,
+                    0x3210, 0x7654, 0xba98, 0xfedc]);
+            check(~[0x0000, 0x1111, 0x2222, 0x3333,
+                    0x4444, 0x5555, 0x6666, 0x7777, 0x8888], 16,
+                  ~[0x1111, 0x2222, 0x3333, 0x4444,
+                    0x5555, 0x6666, 0x7777, 0x8888]);
+        }
+    }
+
+    #[test]
+    fn test_convert_int() {
+        fn check(v: ~[BigDigit], i: int) {
+            let b = BigUint::new(v);
+            assert b == Num::from_int(i);
+            assert b.to_int() == i;
+        }
+
+        check(~[], 0);
+        check(~[1], 1);
+        check(~[-1], (uint::max_value >> BigDigit::bits) as int);
+        check(~[ 0,  1], ((uint::max_value >> BigDigit::bits) + 1) as int);
+        check(~[-1, -1 >> 1], int::max_value);
+
+        assert BigUint::new(~[0, -1]).to_int() == int::max_value;
+        assert BigUint::new(~[0, 0, 1]).to_int() == int::max_value;
+        assert BigUint::new(~[0, 0, -1]).to_int() == int::max_value;
+    }
+
+    #[test]
+    fn test_convert_uint() {
+        fn check(v: ~[BigDigit], u: uint) {
+            let b = BigUint::new(v);
+            assert b == BigUint::from_uint(u);
+            assert b.to_uint() == u;
+        }
+
+        check(~[], 0);
+        check(~[ 1], 1);
+        check(~[-1], uint::max_value >> BigDigit::bits);
+        check(~[ 0,  1], (uint::max_value >> BigDigit::bits) + 1);
+        check(~[ 0, -1], uint::max_value << BigDigit::bits);
+        check(~[-1, -1], uint::max_value);
+
+        assert BigUint::new(~[0, 0, 1]).to_uint()  == uint::max_value;
+        assert BigUint::new(~[0, 0, -1]).to_uint() == uint::max_value;
+    }
+
+    const sum_triples: &[(&[BigDigit], &[BigDigit], &[BigDigit])] = &[
+        (&[],          &[],       &[]),
+        (&[],          &[ 1],     &[ 1]),
+        (&[ 1],        &[ 1],     &[ 2]),
+        (&[ 1],        &[ 1,  1], &[ 2,  1]),
+        (&[ 1],        &[-1],     &[ 0,  1]),
+        (&[ 1],        &[-1, -1], &[ 0,  0, 1]),
+        (&[-1, -1],    &[-1, -1], &[-2, -1, 1]),
+        (&[ 1,  1, 1], &[-1, -1], &[ 0,  1, 2]),
+        (&[ 2,  2, 1], &[-1, -2], &[ 1,  1, 2])
+    ];
+
+    #[test]
+    fn test_add() {
+        for sum_triples.each |elm| {
+            let (aVec, bVec, cVec) = *elm;
+            let a = BigUint::from_slice(aVec);
+            let b = BigUint::from_slice(bVec);
+            let c = BigUint::from_slice(cVec);
+
+            assert a + b == c;
+            assert b + a == c;
+        }
+    }
+
+    #[test]
+    fn test_sub() {
+        for sum_triples.each |elm| {
+            let (aVec, bVec, cVec) = *elm;
+            let a = BigUint::from_slice(aVec);
+            let b = BigUint::from_slice(bVec);
+            let c = BigUint::from_slice(cVec);
+
+            assert c - a == b;
+            assert c - b == a;
+        }
+    }
+
+    const mul_triples: &[(&[BigDigit], &[BigDigit], &[BigDigit])] = &[
+        (&[],               &[],               &[]),
+        (&[],               &[ 1],             &[]),
+        (&[ 2],             &[],               &[]),
+        (&[ 1],             &[ 1],             &[1]),
+        (&[ 2],             &[ 3],             &[ 6]),
+        (&[ 1],             &[ 1,  1,  1],     &[1, 1,  1]),
+        (&[ 1,  2,  3],     &[ 3],             &[ 3,  6,  9]),
+        (&[ 1,  1,  1],     &[-1],             &[-1, -1, -1]),
+        (&[ 1,  2,  3],     &[-1],             &[-1, -2, -2, 2]),
+        (&[ 1,  2,  3,  4], &[-1],             &[-1, -2, -2, -2, 3]),
+        (&[-1],             &[-1],             &[ 1, -2]),
+        (&[-1, -1],         &[-1],             &[ 1, -1, -2]),
+        (&[-1, -1, -1],     &[-1],             &[ 1, -1, -1, -2]),
+        (&[-1, -1, -1, -1], &[-1],             &[ 1, -1, -1, -1, -2]),
+        (&[-1/2 + 1],       &[ 2],             &[ 0,  1]),
+        (&[0, -1/2 + 1],    &[ 2],             &[ 0,  0,  1]),
+        (&[ 1,  2],         &[ 1,  2,  3],     &[1, 4,  7,  6]),
+        (&[-1, -1],         &[-1, -1, -1],     &[1, 0, -1, -2, -1]),
+        (&[-1, -1, -1],     &[-1, -1, -1, -1], &[1, 0,  0, -1, -2, -1, -1]),
+        (&[ 0,  0,  1],     &[ 1,  2,  3],     &[0, 0,  1,  2,  3]),
+        (&[ 0,  0,  1],     &[ 0,  0,  0,  1], &[0, 0,  0,  0,  0,  1])
+    ];
+
+    const divmod_quadruples: &[(&[BigDigit], &[BigDigit],
+                                &[BigDigit], &[BigDigit])]
+        = &[
+            (&[ 1],        &[ 2], &[],               &[1]),
+            (&[ 1,  1],    &[ 2], &[-1/2+1],         &[1]),
+            (&[ 1,  1, 1], &[ 2], &[-1/2+1, -1/2+1], &[1]),
+            (&[ 0,  1],    &[-1], &[1],              &[1]),
+            (&[-1, -1],    &[-2], &[2, 1],           &[3])
+        ];
+
+    #[test]
+    fn test_mul() {
+        for mul_triples.each |elm| {
+            let (aVec, bVec, cVec) = *elm;
+            let a = BigUint::from_slice(aVec);
+            let b = BigUint::from_slice(bVec);
+            let c = BigUint::from_slice(cVec);
+
+            assert a * b == c;
+            assert b * a == c;
+        }
+
+        for divmod_quadruples.each |elm| {
+            let (aVec, bVec, cVec, dVec) = *elm;
+            let a = BigUint::from_slice(aVec);
+            let b = BigUint::from_slice(bVec);
+            let c = BigUint::from_slice(cVec);
+            let d = BigUint::from_slice(dVec);
+
+            assert a == b * c + d;
+            assert a == c * b + d;
+        }
+    }
+
+    #[test]
+    fn test_divmod() {
+        for mul_triples.each |elm| {
+            let (aVec, bVec, cVec) = *elm;
+            let a = BigUint::from_slice(aVec);
+            let b = BigUint::from_slice(bVec);
+            let c = BigUint::from_slice(cVec);
+
+            if a.is_not_zero() {
+                assert c.divmod(&a) == (b, Zero::zero());
+            }
+            if b.is_not_zero() {
+                assert c.divmod(&b) == (a, Zero::zero());
+            }
+        }
+
+        for divmod_quadruples.each |elm| {
+            let (aVec, bVec, cVec, dVec) = *elm;
+            let a = BigUint::from_slice(aVec);
+            let b = BigUint::from_slice(bVec);
+            let c = BigUint::from_slice(cVec);
+            let d = BigUint::from_slice(dVec);
+
+            if b.is_not_zero() { assert a.divmod(&b) == (c, d); }
+        }
+    }
+
+    fn to_str_pairs() -> ~[ (BigUint, ~[(uint, ~str)]) ] {
+        let bits = BigDigit::bits;
+        ~[( Zero::zero(), ~[
+            (2, ~"0"), (3, ~"0")
+        ]), ( BigUint::from_slice([ 0xff ]), ~[
+            (2,  ~"11111111"),
+            (3,  ~"100110"),
+            (4,  ~"3333"),
+            (5,  ~"2010"),
+            (6,  ~"1103"),
+            (7,  ~"513"),
+            (8,  ~"377"),
+            (9,  ~"313"),
+            (10, ~"255"),
+            (11, ~"212"),
+            (12, ~"193"),
+            (13, ~"168"),
+            (14, ~"143"),
+            (15, ~"120"),
+            (16, ~"ff")
+        ]), ( BigUint::from_slice([ 0xfff ]), ~[
+            (2,  ~"111111111111"),
+            (4,  ~"333333"),
+            (16, ~"fff")
+        ]), ( BigUint::from_slice([ 1, 2 ]), ~[
+            (2,
+             ~"10" +
+             str::from_chars(vec::from_elem(bits - 1, '0')) + "1"),
+            (4,
+             ~"2" +
+             str::from_chars(vec::from_elem(bits / 2 - 1, '0')) + "1"),
+            (10, match bits {
+                32 => ~"8589934593", 16 => ~"131073", _ => fail
+            }),
+            (16,
+             ~"2" +
+             str::from_chars(vec::from_elem(bits / 4 - 1, '0')) + "1")
+        ]), ( BigUint::from_slice([ 1, 2, 3 ]), ~[
+            (2,
+             ~"11" +
+             str::from_chars(vec::from_elem(bits - 2, '0')) + "10" +
+             str::from_chars(vec::from_elem(bits - 1, '0')) + "1"),
+            (4,
+             ~"3" +
+             str::from_chars(vec::from_elem(bits / 2 - 1, '0')) + "2" +
+             str::from_chars(vec::from_elem(bits / 2 - 1, '0')) + "1"),
+            (10, match bits {
+                32 => ~"55340232229718589441",
+                16 => ~"12885032961",
+                _ => fail
+            }),
+            (16, ~"3" +
+             str::from_chars(vec::from_elem(bits / 4 - 1, '0')) + "2" +
+             str::from_chars(vec::from_elem(bits / 4 - 1, '0')) + "1")
+        ]) ]
+    }
+
+    #[test]
+    fn test_to_str_radix() {
+        for to_str_pairs().each |num_pair| {
+            let &(n, rs) = num_pair;
+            for rs.each |str_pair| {
+                let &(radix, str) = str_pair;
+                assert n.to_str_radix(radix) == str;
+            }
+        }
+    }
+
+    #[test]
+    fn test_from_str_radix() {
+        for to_str_pairs().each |num_pair| {
+            let &(n, rs) = num_pair;
+            for rs.each |str_pair| {
+                let &(radix, str) = str_pair;
+                assert Some(n) == BigUint::from_str_radix(str, radix);
+            }
+        }
+
+        assert BigUint::from_str_radix(~"Z", 10) == None;
+        assert BigUint::from_str_radix(~"_", 2) == None;
+        assert BigUint::from_str_radix(~"-1", 10) == None;
+    }
+
+    #[test]
+    fn test_factor() {
+        fn factor(n: uint) -> BigUint {
+            let mut f= One::one::<BigUint>();
+            for uint::range(2, n + 1) |i| {
+                f *= BigUint::from_uint(i);
+            }
+            return f;
+        }
+
+        fn check(n: uint, s: &str) {
+            let n = factor(n);
+            let ans = match BigUint::from_str_radix(s, 10) {
+                Some(x) => x, None => fail
+            };
+            assert n == ans;
+        }
+
+        check(3, "6");
+        check(10, "3628800");
+        check(20, "2432902008176640000");
+        check(30, "265252859812191058636308480000000");
+    }
+}
+
+#[cfg(test)]
+mod bigint_tests {
+    use super::{BigInt, BigUint, BigDigit, Sign, Minus, Zero, Plus};
+
+    use core::*;
+    use core::num::{Num, Zero, One};
+
+    #[test]
+    fn test_from_biguint() {
+        fn check(inp_s: Sign, inp_n: uint, ans_s: Sign, ans_n: uint) {
+            let inp = BigInt::from_biguint(inp_s, BigUint::from_uint(inp_n));
+            let ans = BigInt { sign: ans_s, data: BigUint::from_uint(ans_n)};
+            assert inp == ans;
+        }
+        check(Plus, 1, Plus, 1);
+        check(Plus, 0, Zero, 0);
+        check(Minus, 1, Minus, 1);
+        check(Zero, 1, Zero, 0);
+    }
+
+    #[test]
+    fn test_cmp() {
+        let vs = [ &[2], &[1, 1], &[2, 1], &[1, 1, 1] ];
+        let mut nums = vec::reversed(vs)
+            .map(|s| BigInt::from_slice(Minus, *s));
+        nums.push(Zero::zero());
+        nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s)));
+
+        for nums.eachi |i, ni| {
+            for vec::view(nums, i, nums.len()).eachi |j0, nj| {
+                let j = i + j0;
+                if i == j {
+                    assert ni.cmp(nj) == 0;
+                    assert nj.cmp(ni) == 0;
+                    assert ni == nj;
+                    assert !(ni != nj);
+                    assert ni <= nj;
+                    assert ni >= nj;
+                    assert !(ni < nj);
+                    assert !(ni > nj);
+                } else {
+                    assert ni.cmp(nj) < 0;
+                    assert nj.cmp(ni) > 0;
+
+                    assert !(ni == nj);
+                    assert ni != nj;
+
+                    assert ni <= nj;
+                    assert !(ni >= nj);
+                    assert ni < nj;
+                    assert !(ni > nj);
+
+                    assert !(nj <= ni);
+                    assert nj >= ni;
+                    assert !(nj < ni);
+                    assert nj > ni;
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn test_convert_int() {
+        fn check(b: BigInt, i: int) {
+            assert b == Num::from_int(i);
+            assert b.to_int() == i;
+        }
+
+        check(Zero::zero(), 0);
+        check(One::one(), 1);
+        check(BigInt::from_biguint(
+            Plus, BigUint::from_uint(int::max_value as uint)
+        ), int::max_value);
+
+        assert BigInt::from_biguint(
+            Plus, BigUint::from_uint(int::max_value as uint + 1)
+        ).to_int() == int::max_value;
+        assert BigInt::from_biguint(
+            Plus, BigUint::new(~[1, 2, 3])
+        ).to_int() == int::max_value;
+
+        check(BigInt::from_biguint(
+            Minus, BigUint::from_uint(-int::min_value as uint)
+        ), int::min_value);
+        assert BigInt::from_biguint(
+            Minus, BigUint::from_uint(-int::min_value as uint + 1)
+        ).to_int() == int::min_value;
+        assert BigInt::from_biguint(
+            Minus, BigUint::new(~[1, 2, 3])
+        ).to_int() == int::min_value;
+    }
+
+    #[test]
+    fn test_convert_uint() {
+        fn check(b: BigInt, u: uint) {
+            assert b == BigInt::from_uint(u);
+            assert b.to_uint() == u;
+        }
+
+        check(Zero::zero(), 0);
+        check(One::one(), 1);
+
+        check(
+            BigInt::from_biguint(Plus, BigUint::from_uint(uint::max_value)),
+            uint::max_value);
+        assert BigInt::from_biguint(
+            Plus, BigUint::new(~[1, 2, 3])
+        ).to_uint() == uint::max_value;
+
+        assert BigInt::from_biguint(
+            Minus, BigUint::from_uint(uint::max_value)
+        ).to_uint() == 0;
+        assert BigInt::from_biguint(
+            Minus, BigUint::new(~[1, 2, 3])
+        ).to_uint() == 0;
+    }
+
+    const sum_triples: &[(&[BigDigit], &[BigDigit], &[BigDigit])] = &[
+        (&[],          &[],       &[]),
+        (&[],          &[ 1],     &[ 1]),
+        (&[ 1],        &[ 1],     &[ 2]),
+        (&[ 1],        &[ 1,  1], &[ 2,  1]),
+        (&[ 1],        &[-1],     &[ 0,  1]),
+        (&[ 1],        &[-1, -1], &[ 0,  0, 1]),
+        (&[-1, -1],    &[-1, -1], &[-2, -1, 1]),
+        (&[ 1,  1, 1], &[-1, -1], &[ 0,  1, 2]),
+        (&[ 2,  2, 1], &[-1, -2], &[ 1,  1, 2])
+    ];
+
+    #[test]
+    fn test_add() {
+        for sum_triples.each |elm| {
+            let (aVec, bVec, cVec) = *elm;
+            let a = BigInt::from_slice(Plus, aVec);
+            let b = BigInt::from_slice(Plus, bVec);
+            let c = BigInt::from_slice(Plus, cVec);
+
+            assert a + b == c;
+            assert b + a == c;
+            assert c + (-a) == b;
+            assert c + (-b) == a;
+            assert a + (-c) == (-b);
+            assert b + (-c) == (-a);
+            assert (-a) + (-b) == (-c);
+            assert a + (-a) == Zero::zero();
+        }
+    }
+
+    #[test]
+    fn test_sub() {
+        for sum_triples.each |elm| {
+            let (aVec, bVec, cVec) = *elm;
+            let a = BigInt::from_slice(Plus, aVec);
+            let b = BigInt::from_slice(Plus, bVec);
+            let c = BigInt::from_slice(Plus, cVec);
+
+            assert c - a == b;
+            assert c - b == a;
+            assert (-b) - a == (-c);
+            assert (-a) - b == (-c);
+            assert b - (-a) == c;
+            assert a - (-b) == c;
+            assert (-c) - (-a) == (-b);
+            assert a - a == Zero::zero();
+        }
+    }
+
+    const mul_triples: &[(&[BigDigit], &[BigDigit], &[BigDigit])] = &[
+        (&[],               &[],               &[]),
+        (&[],               &[ 1],             &[]),
+        (&[ 2],             &[],               &[]),
+        (&[ 1],             &[ 1],             &[1]),
+        (&[ 2],             &[ 3],             &[ 6]),
+        (&[ 1],             &[ 1,  1,  1],     &[1, 1,  1]),
+        (&[ 1,  2,  3],     &[ 3],             &[ 3,  6,  9]),
+        (&[ 1,  1,  1],     &[-1],             &[-1, -1, -1]),
+        (&[ 1,  2,  3],     &[-1],             &[-1, -2, -2, 2]),
+        (&[ 1,  2,  3,  4], &[-1],             &[-1, -2, -2, -2, 3]),
+        (&[-1],             &[-1],             &[ 1, -2]),
+        (&[-1, -1],         &[-1],             &[ 1, -1, -2]),
+        (&[-1, -1, -1],     &[-1],             &[ 1, -1, -1, -2]),
+        (&[-1, -1, -1, -1], &[-1],             &[ 1, -1, -1, -1, -2]),
+        (&[-1/2 + 1],       &[ 2],             &[ 0,  1]),
+        (&[0, -1/2 + 1],    &[ 2],             &[ 0,  0,  1]),
+        (&[ 1,  2],         &[ 1,  2,  3],     &[1, 4,  7,  6]),
+        (&[-1, -1],         &[-1, -1, -1],     &[1, 0, -1, -2, -1]),
+        (&[-1, -1, -1],     &[-1, -1, -1, -1], &[1, 0,  0, -1, -2, -1, -1]),
+        (&[ 0,  0,  1],     &[ 1,  2,  3],     &[0, 0,  1,  2,  3]),
+        (&[ 0,  0,  1],     &[ 0,  0,  0,  1], &[0, 0,  0,  0,  0,  1])
+    ];
+
+    const divmod_quadruples: &[(&[BigDigit], &[BigDigit],
+                                &[BigDigit], &[BigDigit])]
+        = &[
+            (&[ 1],        &[ 2], &[],               &[1]),
+            (&[ 1,  1],    &[ 2], &[-1/2+1],         &[1]),
+            (&[ 1,  1, 1], &[ 2], &[-1/2+1, -1/2+1], &[1]),
+            (&[ 0,  1],    &[-1], &[1],              &[1]),
+            (&[-1, -1],    &[-2], &[2, 1],           &[3])
+        ];
+
+    #[test]
+    fn test_mul() {
+        for mul_triples.each |elm| {
+            let (aVec, bVec, cVec) = *elm;
+            let a = BigInt::from_slice(Plus, aVec);
+            let b = BigInt::from_slice(Plus, bVec);
+            let c = BigInt::from_slice(Plus, cVec);
+
+            assert a * b == c;
+            assert b * a == c;
+
+            assert (-a) * b == -c;
+            assert (-b) * a == -c;
+        }
+
+        for divmod_quadruples.each |elm| {
+            let (aVec, bVec, cVec, dVec) = *elm;
+            let a = BigInt::from_slice(Plus, aVec);
+            let b = BigInt::from_slice(Plus, bVec);
+            let c = BigInt::from_slice(Plus, cVec);
+            let d = BigInt::from_slice(Plus, dVec);
+
+            assert a == b * c + d;
+            assert a == c * b + d;
+        }
+    }
+
+    #[test]
+    fn test_divmod() {
+        fn check_sub(a: &BigInt, b: &BigInt, ans_d: &BigInt, ans_m: &BigInt) {
+            let (d, m) = a.divmod(b);
+            if m.is_not_zero() {
+                assert m.sign == b.sign;
+            }
+            assert m.abs() <= b.abs();
+            assert *a == b * d + m;
+            assert d == *ans_d;
+            assert m == *ans_m;
+        }
+
+        fn check(a: &BigInt, b: &BigInt, d: &BigInt, m: &BigInt) {
+            if m.is_zero() {
+                check_sub(a, b, d, m);
+                check_sub(a, &b.neg(), &d.neg(), m);
+                check_sub(&a.neg(), b, &d.neg(), m);
+                check_sub(&a.neg(), &b.neg(), d, m);
+            } else {
+                check_sub(a, b, d, m);
+                check_sub(a, &b.neg(), &(d.neg() - One::one()), &(m - *b));
+                check_sub(&a.neg(), b, &(d.neg() - One::one()), &(b - *m));
+                check_sub(&a.neg(), &b.neg(), d, &m.neg());
+            }
+        }
+
+        for mul_triples.each |elm| {
+            let (aVec, bVec, cVec) = *elm;
+            let a = BigInt::from_slice(Plus, aVec);
+            let b = BigInt::from_slice(Plus, bVec);
+            let c = BigInt::from_slice(Plus, cVec);
+
+            if a.is_not_zero() { check(&c, &a, &b, &Zero::zero()); }
+            if b.is_not_zero() { check(&c, &b, &a, &Zero::zero()); }
+        }
+
+        for divmod_quadruples.each |elm| {
+            let (aVec, bVec, cVec, dVec) = *elm;
+            let a = BigInt::from_slice(Plus, aVec);
+            let b = BigInt::from_slice(Plus, bVec);
+            let c = BigInt::from_slice(Plus, cVec);
+            let d = BigInt::from_slice(Plus, dVec);
+
+            if b.is_not_zero() {
+                check(&a, &b, &c, &d);
+            }
+        }
+    }
+
+
+    #[test]
+    fn test_quotrem() {
+        fn check_sub(a: &BigInt, b: &BigInt, ans_q: &BigInt, ans_r: &BigInt) {
+            let (q, r) = a.quotrem(b);
+            if r.is_not_zero() {
+                assert r.sign == a.sign;
+            }
+            assert r.abs() <= b.abs();
+            assert *a == b * q + r;
+            assert q == *ans_q;
+            assert r == *ans_r;
+        }
+
+        fn check(a: &BigInt, b: &BigInt, q: &BigInt, r: &BigInt) {
+            check_sub(a, b, q, r);
+            check_sub(a, &b.neg(), &q.neg(), r);
+            check_sub(&a.neg(), b, &q.neg(), &r.neg());
+            check_sub(&a.neg(), &b.neg(), q, &r.neg());
+        }
+        for mul_triples.each |elm| {
+            let (aVec, bVec, cVec) = *elm;
+            let a = BigInt::from_slice(Plus, aVec);
+            let b = BigInt::from_slice(Plus, bVec);
+            let c = BigInt::from_slice(Plus, cVec);
+
+            if a.is_not_zero() { check(&c, &a, &b, &Zero::zero()); }
+            if b.is_not_zero() { check(&c, &b, &a, &Zero::zero()); }
+        }
+
+        for divmod_quadruples.each |elm| {
+            let (aVec, bVec, cVec, dVec) = *elm;
+            let a = BigInt::from_slice(Plus, aVec);
+            let b = BigInt::from_slice(Plus, bVec);
+            let c = BigInt::from_slice(Plus, cVec);
+            let d = BigInt::from_slice(Plus, dVec);
+
+            if b.is_not_zero() {
+                check(&a, &b, &c, &d);
+            }
+        }
+    }
+
+    #[test]
+    fn test_to_str_radix() {
+        fn check(n: int, ans: &str) {
+            assert ans == Num::from_int::<BigInt>(n).to_str_radix(10);
+        }
+        check(10, "10");
+        check(1, "1");
+        check(0, "0");
+        check(-1, "-1");
+        check(-10, "-10");
+    }
+
+
+    #[test]
+    fn test_from_str_radix() {
+        fn check(s: &str, ans: Option<int>) {
+            let ans = ans.map(|&n| Num::from_int(n));
+            assert BigInt::from_str_radix(s, 10) == ans;
+        }
+        check("10", Some(10));
+        check("1", Some(1));
+        check("0", Some(0));
+        check("-1", Some(-1));
+        check("-10", Some(-10));
+        check("Z", None);
+        check("_", None);
+    }
+
+    #[test]
+    fn test_neg() {
+        assert -BigInt::new(Plus,  ~[1, 1, 1]) ==
+            BigInt::new(Minus, ~[1, 1, 1]);
+        assert -BigInt::new(Minus, ~[1, 1, 1]) ==
+            BigInt::new(Plus,  ~[1, 1, 1]);
+        assert -Zero::zero::<BigInt>() == Zero::zero::<BigInt>();
+    }
+}
+
index 5b9dc6cf3a895ad5925ecfea5b8949860c8f86ed..834edc3f464e2b453354dce1e94487cc4b5bfe99 100644 (file)
 
 #[forbid(deprecated_mode)];
 
-use vec::{to_mut, from_elem};
+use core::ops;
+use core::prelude::*;
+use core::uint;
+use core::vec::{to_mut, from_elem};
+use core::vec;
 
 struct SmallBitv {
     /// only the lowest nbits of this value are used. the rest is undefined.
@@ -574,6 +578,15 @@ impl Bitv: ops::Index<uint,bool> {
 #[cfg(test)]
 mod tests {
     #[legacy_exports];
+
+    use core::prelude::*;
+
+    use bitv::*;
+    use bitv;
+
+    use core::uint;
+    use core::vec;
+
     #[test]
     fn test_to_str() {
         let zerolen = Bitv(0u, false);
index cc8cadb709d940400e55dd9a42f9d0eca3c0471b..359d3039229e606b5e1bbee7c2348e0c12770183 100644 (file)
  */
 #[forbid(deprecated_mode)];
 
+use core::libc;
+use core::oldcomm;
+use core::option;
+use core::prelude::*;
+use core::ptr;
+use core::task;
+
 /**
  * The type representing a foreign chunk of memory
  *
@@ -146,15 +153,22 @@ pub unsafe fn ptr<T>(t: CVec<T>) -> *mut T {
 
 #[cfg(test)]
 mod tests {
-    use libc::*;
+    use core::prelude::*;
+
+    use c_vec::*;
+
+    use core::libc::*;
+    use core::libc;
 
     fn malloc(n: size_t) -> CVec<u8> {
-        let mem = libc::malloc(n);
+        unsafe {
+            let mem = libc::malloc(n);
 
-        assert mem as int != 0;
+            assert mem as int != 0;
 
-        return unsafe { c_vec_with_dtor(mem as *mut u8, n as uint,
-                                     ||free(mem)) };
+            return unsafe { c_vec_with_dtor(mem as *mut u8, n as uint,
+                                         || unsafe { free(mem) }) };
+        }
     }
 
     #[test]
index b972ef953e4f80498059381697379658a0d82de3..d4077e94617a20a1209711af6f5d32ca77cf006d 100644 (file)
@@ -9,6 +9,10 @@
 // except according to those terms.
 
 #[forbid(deprecated_mode)];
+
+use core::option;
+use core::prelude::*;
+
 /// A dynamic, mutable location.
 ///
 /// Similar to a mutable option type, but friendlier.
index 28ee8c81e73d0bf98e88a5132a26f9ab010d1092..7c126c7338b71267bd26e933c813239c9662407e 100644 (file)
 #[forbid(deprecated_mode)];
 /// Additional general-purpose comparison functionality.
 
+use core::f32;
+use core::f64;
+use core::float;
+
 const fuzzy_epsilon: float = 1.0e-6;
 
 pub trait FuzzyEq {
index 1055f3ea7df7287e3f9c95ee00d59d326ba0d050..3118a0c1ba54573e38893c5a52bd1bafb0881bad 100644 (file)
 // NB: transitionary, de-mode-ing.
 #[forbid(deprecated_mode)];
 
-use pipes::{GenericChan, GenericSmartChan, GenericPort,
-            Chan, Port, Selectable, Peekable};
+use core::pipes::{GenericChan, GenericSmartChan, GenericPort};
+use core::pipes::{Chan, Port, Selectable, Peekable};
+use core::pipes;
+use core::prelude::*;
 
 /// An extension of `pipes::stream` that allows both sending and receiving.
 pub struct DuplexStream<T: Owned, U: Owned> {
@@ -79,6 +81,8 @@ pub fn DuplexStream<T: Owned, U: Owned>()
 #[cfg(test)]
 mod test {
     #[legacy_exports];
+    use comm::DuplexStream;
+
     #[test]
     fn DuplexStream1() {
         let (left, right) = DuplexStream();
index 75e25f75c6c219af5ee4689a3123b165a47ae2b2..9a910a2256cc6503f3ae733483aedec3fff96a9a 100644 (file)
 #[forbid(deprecated_mode)];
 //! Unsafe debugging functions for inspecting values.
 
-use cast::reinterpret_cast;
-
+use core::cast::reinterpret_cast;
+use core::ptr;
+use core::sys;
 
 #[abi = "cdecl"]
 extern mod rustrt {
     #[legacy_exports];
-    fn debug_tydesc(td: *sys::TypeDesc);
-    fn debug_opaque(td: *sys::TypeDesc, x: *());
-    fn debug_box(td: *sys::TypeDesc, x: *());
-    fn debug_tag(td: *sys::TypeDesc, x: *());
-    fn debug_fn(td: *sys::TypeDesc, x: *());
-    fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *();
-    fn rust_dbg_breakpoint();
+    unsafe fn debug_tydesc(td: *sys::TypeDesc);
+    unsafe fn debug_opaque(td: *sys::TypeDesc, x: *());
+    unsafe fn debug_box(td: *sys::TypeDesc, x: *());
+    unsafe fn debug_tag(td: *sys::TypeDesc, x: *());
+    unsafe fn debug_fn(td: *sys::TypeDesc, x: *());
+    unsafe fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *();
+    unsafe fn rust_dbg_breakpoint();
 }
 
 pub fn debug_tydesc<T>() {
-    rustrt::debug_tydesc(sys::get_type_desc::<T>());
+    unsafe {
+        rustrt::debug_tydesc(sys::get_type_desc::<T>());
+    }
 }
 
 pub fn debug_opaque<T>(x: T) {
-    rustrt::debug_opaque(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
+    unsafe {
+        rustrt::debug_opaque(sys::get_type_desc::<T>(),
+                             ptr::addr_of(&x) as *());
+    }
 }
 
 pub fn debug_box<T>(x: @T) {
-    rustrt::debug_box(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
+    unsafe {
+        rustrt::debug_box(sys::get_type_desc::<T>(),
+                          ptr::addr_of(&x) as *());
+    }
 }
 
 pub fn debug_tag<T>(x: T) {
-    rustrt::debug_tag(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
+    unsafe {
+        rustrt::debug_tag(sys::get_type_desc::<T>(),
+                          ptr::addr_of(&x) as *());
+    }
 }
 
 pub fn debug_fn<T>(x: T) {
-    rustrt::debug_fn(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
+    unsafe {
+        rustrt::debug_fn(sys::get_type_desc::<T>(),
+                         ptr::addr_of(&x) as *());
+    }
 }
 
 pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
@@ -54,7 +69,9 @@ pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
 
 /// Triggers a debugger breakpoint
 pub fn breakpoint() {
-    rustrt::rust_dbg_breakpoint();
+    unsafe {
+        rustrt::rust_dbg_breakpoint();
+    }
 }
 
 #[test]
index 687eff887c8b2774d560dd83e8a9fc62e96efe10..71d8743a3615402a4f5f118c107f0e2f2e083c00 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(non_camel_case_types)];
 
-use option::{Some, None};
-use dvec::DVec;
-use core::cmp::{Eq};
+use core::cmp::Eq;
+use core::dvec::DVec;
+use core::dvec;
+use core::prelude::*;
+use core::uint;
+use core::vec;
 
 pub trait Deque<T> {
     fn size() -> uint;
@@ -129,6 +132,11 @@ fn get(i: int) -> T {
 
 #[cfg(test)]
 mod tests {
+    use core::prelude::*;
+
+    use deque::*;
+    use deque;
+
     #[test]
     fn test_simple() {
         let d: deque::Deque<int> = deque::create::<int>();
index f782b6ff6a7bd370fd88fb731305a73879c3aee4..dc379cec21b59f5ed977b470e73a025522274136 100644 (file)
@@ -9,8 +9,15 @@
 // except according to those terms.
 
 #[forbid(deprecated_mode)];
+
 use serialize;
 
+use core::io;
+use core::ops;
+use core::prelude::*;
+use core::str;
+use core::vec;
+
 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
 // cursor model. See the specification here:
 //     http://www.matroska.org/technical/specs/rfc/index.html
@@ -27,18 +34,18 @@ struct EbmlState {
     data_pos: uint,
 }
 
-struct Doc {
+pub struct Doc {
     data: @~[u8],
     start: uint,
     end: uint,
 }
 
-struct TaggedDoc {
+pub struct TaggedDoc {
     tag: uint,
     doc: Doc,
 }
 
-enum EbmlEncoderTag {
+pub enum EbmlEncoderTag {
     EsUint, EsU64, EsU32, EsU16, EsU8,
     EsInt, EsI64, EsI32, EsI16, EsI8,
     EsBool,
@@ -54,6 +61,18 @@ enum EbmlEncoderTag {
 // --------------------------------------
 
 pub mod reader {
+    use ebml::{Doc, EbmlEncoderTag, EsBool, EsEnum, EsEnumBody, EsEnumVid};
+    use ebml::{EsF32, EsF64, EsFloat, EsI16, EsI32, EsI64, EsI8, EsInt};
+    use ebml::{EsLabel, EsOpaque, EsStr, EsU16, EsU32, EsU64, EsU8, EsUint};
+    use ebml::{EsVec, EsVecElt, EsVecLen, TaggedDoc};
+    use serialize;
+
+    use core::int;
+    use core::io;
+    use core::ops;
+    use core::prelude::*;
+    use core::str;
+    use core::vec;
 
     // ebml reading
 
@@ -271,7 +290,7 @@ fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
         fn read_u8 (&self) -> u8  { doc_as_u8 (self.next_doc(EsU8 )) }
         fn read_uint(&self) -> uint {
             let v = doc_as_u64(self.next_doc(EsUint));
-            if v > (core::uint::max_value as u64) {
+            if v > (::core::uint::max_value as u64) {
                 fail fmt!("uint %? too large for this architecture", v);
             }
             v as uint
@@ -385,6 +404,14 @@ fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
 }
 
 pub mod writer {
+    use ebml::{Doc, EbmlEncoderTag, EsBool, EsEnum, EsEnumBody, EsEnumVid};
+    use ebml::{EsF32, EsF64, EsFloat, EsI16, EsI32, EsI64, EsI8, EsInt};
+    use ebml::{EsLabel, EsOpaque, EsStr, EsU16, EsU32, EsU64, EsU8, EsUint};
+    use ebml::{EsVec, EsVecElt, EsVecLen, TaggedDoc};
+
+    use core::io;
+    use core::str;
+    use core::vec;
 
     // ebml writing
     pub struct Encoder {
@@ -546,7 +573,7 @@ fn emit_opaque(&self, f: fn()) {
         }
     }
 
-    impl Encoder: serialize::Encoder {
+    impl Encoder: ::serialize::Encoder {
         fn emit_nil(&self) {}
 
         fn emit_uint(&self, v: uint) {
@@ -647,6 +674,13 @@ fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
 
 #[cfg(test)]
 mod tests {
+    use ebml::reader;
+    use ebml::writer;
+    use serialize;
+
+    use core::io;
+    use core::option::{None, Option, Some};
+
     #[test]
     fn test_option_int() {
         fn test_v(v: Option<int>) {
index 1617641afe36625e0586d6eebefea5924d7f10b0..0607055db5c03ce36e4c58f194e5c184f6decfbf 100644 (file)
 */
 
 // The basic send/recv interface FlatChan and PortChan will implement
+use core::io;
 use core::pipes::GenericChan;
 use core::pipes::GenericPort;
-
+use core::pipes;
+use core::prelude::*;
 use core::sys::size_of;
+use core::uint;
+use core::vec;
 
 /**
 A FlatPort, consisting of a `BytePort` that recieves byte vectors,
@@ -69,18 +73,20 @@ pub struct FlatChan<T, F: Flattener<T>, C: ByteChan> {
 Constructors for flat pipes that using serialization-based flattening.
 */
 pub mod serial {
-
     pub use DefaultEncoder = ebml::writer::Encoder;
     pub use DefaultDecoder = ebml::reader::Decoder;
 
-    use core::io::{Reader, Writer};
-    use core::pipes::{Port, Chan};
     use serialize::{Decodable, Encodable};
     use flatpipes::flatteners::{DeserializingUnflattener,
                                 SerializingFlattener};
     use flatpipes::flatteners::{deserialize_buffer, serialize_value};
     use flatpipes::bytepipes::{ReaderBytePort, WriterByteChan};
     use flatpipes::bytepipes::{PipeBytePort, PipeByteChan};
+    use flatpipes::{FlatPort, FlatChan};
+
+    use core::io::{Reader, Writer};
+    use core::pipes::{Port, Chan};
+    use core::pipes;
 
     pub type ReaderPort<T, R> = FlatPort<
         T, DeserializingUnflattener<DefaultDecoder, T>,
@@ -141,7 +147,6 @@ pub fn pipe_stream<T: Encodable<DefaultEncoder>
         let (port, chan) = pipes::stream();
         return (pipe_port(move port), pipe_chan(move chan));
     }
-
 }
 
 // FIXME #4074 this doesn't correctly enforce POD bounds
@@ -156,12 +161,15 @@ pub fn pipe_stream<T: Encodable<DefaultEncoder>
 
 */
 pub mod pod {
-
-    use core::io::{Reader, Writer};
-    use core::pipes::{Port, Chan};
     use flatpipes::flatteners::{PodUnflattener, PodFlattener};
     use flatpipes::bytepipes::{ReaderBytePort, WriterByteChan};
     use flatpipes::bytepipes::{PipeBytePort, PipeByteChan};
+    use flatpipes::{FlatPort, FlatChan};
+
+    use core::io::{Reader, Writer};
+    use core::pipes::{Port, Chan};
+    use core::pipes;
+    use core::prelude::*;
 
     pub type ReaderPort<T: Copy Owned, R> =
         FlatPort<T, PodUnflattener<T>, ReaderBytePort<R>>;
@@ -242,7 +250,7 @@ pub trait ByteChan {
 
 const CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD];
 
-impl<T, U: Unflattener<T>, P: BytePort> FlatPort<T, U, P>: GenericPort<T> {
+pub impl<T,U:Unflattener<T>,P:BytePort> FlatPort<T, U, P>: GenericPort<T> {
     fn recv() -> T {
         match self.try_recv() {
             Some(move val) => move val,
@@ -287,7 +295,7 @@ fn try_recv() -> Option<T> {
     }
 }
 
-impl<T, F: Flattener<T>, C: ByteChan> FlatChan<T, F, C>: GenericChan<T> {
+impl<T,F:Flattener<T>,C:ByteChan> FlatChan<T, F, C>: GenericChan<T> {
     fn send(val: T) {
         self.byte_chan.send(CONTINUE.to_vec());
         let bytes = self.flattener.flatten(move val);
@@ -299,7 +307,7 @@ fn send(val: T) {
     }
 }
 
-impl<T, U: Unflattener<T>, P: BytePort> FlatPort<T, U, P> {
+pub impl<T,U:Unflattener<T>,P:BytePort> FlatPort<T, U, P> {
     static fn new(u: U, p: P) -> FlatPort<T, U, P> {
         FlatPort {
             unflattener: move u,
@@ -308,7 +316,7 @@ impl<T, U: Unflattener<T>, P: BytePort> FlatPort<T, U, P> {
     }
 }
 
-impl<T, F: Flattener<T>, C: ByteChan> FlatChan<T, F, C> {
+pub impl<T,F:Flattener<T>,C:ByteChan> FlatChan<T, F, C> {
     static fn new(f: F, c: C) -> FlatChan<T, F, C> {
         FlatChan {
             flattener: move f,
@@ -319,16 +327,21 @@ impl<T, F: Flattener<T>, C: ByteChan> FlatChan<T, F, C> {
 
 
 pub mod flatteners {
+    use ebml;
+    use flatpipes::{ByteChan, BytePort, Flattener, Unflattener};
+    use io_util::BufReader;
+    use json;
+    use serialize::{Encoder, Decoder, Encodable, Decodable};
 
+    use core::cast;
+    use core::io::{Writer, Reader, BytesWriter, ReaderUtil};
+    use core::prelude::*;
+    use core::ptr;
     use core::sys::size_of;
+    use core::vec;
 
-    use serialize::{Encoder, Decoder,
-                        Encodable, Decodable};
 
-    use core::io::{Writer, Reader, BytesWriter, ReaderUtil};
-    use flatpipes::util::BufReader;
-
-    // XXX: Is copy/send equivalent to pod?
+    // FIXME #4074: Copy + Owned != POD
     pub struct PodUnflattener<T: Copy Owned> {
         bogus: ()
     }
@@ -488,9 +501,12 @@ impl ebml::writer::Encoder: FromWriter {
 }
 
 pub mod bytepipes {
+    use flatpipes::{ByteChan, BytePort};
 
     use core::io::{Writer, Reader, ReaderUtil};
     use core::pipes::{Port, Chan};
+    use core::pipes;
+    use core::prelude::*;
 
     pub struct ReaderBytePort<R: Reader> {
         reader: R
@@ -556,12 +572,12 @@ pub struct PipeByteChan {
     pub impl PipeBytePort: BytePort {
         fn try_recv(&self, count: uint) -> Option<~[u8]> {
             if self.buf.len() >= count {
-                let mut bytes = core::util::replace(&mut self.buf, ~[]);
+                let mut bytes = ::core::util::replace(&mut self.buf, ~[]);
                 self.buf = bytes.slice(count, bytes.len());
                 bytes.truncate(count);
                 return Some(bytes);
             } else if self.buf.len() > 0 {
-                let mut bytes = core::util::replace(&mut self.buf, ~[]);
+                let mut bytes = ::core::util::replace(&mut self.buf, ~[]);
                 assert count > bytes.len();
                 match self.try_recv(count - bytes.len()) {
                     Some(move rest) => {
@@ -580,7 +596,7 @@ fn try_recv(&self, count: uint) -> Option<~[u8]> {
                     None => return None
                 }
             } else {
-                core::util::unreachable()
+                ::core::util::unreachable()
             }
         }
     }
@@ -610,78 +626,30 @@ pub impl PipeByteChan {
 
 }
 
-// XXX: This belongs elsewhere
-mod util {
-
-    use io::{Reader, BytesReader};
-
-    pub struct BufReader {
-        buf: ~[u8],
-        mut pos: uint
-    }
-
-    pub impl BufReader {
-        static pub fn new(v: ~[u8]) -> BufReader {
-            BufReader {
-                buf: move v,
-                pos: 0
-            }
-        }
-
-        priv fn as_bytes_reader<A>(f: &fn(&BytesReader) -> A) -> A {
-            // Recreating the BytesReader state every call since
-            // I can't get the borrowing to work correctly
-            let bytes_reader = BytesReader {
-                bytes: core::util::id::<&[u8]>(self.buf),
-                pos: self.pos
-            };
-
-            let res = f(&bytes_reader);
-
-            // XXX: This isn't correct if f fails
-            self.pos = bytes_reader.pos;
-
-            return move res;
-        }
-    }
-
-    impl BufReader: Reader {
-        fn read(&self, bytes: &[mut u8], len: uint) -> uint {
-            self.as_bytes_reader(|r| r.read(bytes, len) )
-        }
-        fn read_byte(&self) -> int {
-            self.as_bytes_reader(|r| r.read_byte() )
-        }
-        fn eof(&self) -> bool {
-            self.as_bytes_reader(|r| r.eof() )
-        }
-        fn seek(&self, offset: int, whence: io::SeekStyle) {
-            self.as_bytes_reader(|r| r.seek(offset, whence) )
-        }
-        fn tell(&self) -> uint {
-            self.as_bytes_reader(|r| r.tell() )
-        }
-    }
-
-}
-
 #[cfg(test)]
 mod test {
+    use core::prelude::*;
 
-    // XXX: json::Decoder doesn't work because of problems related to
-    // its interior pointers
-    //use DefaultEncoder = json::Encoder;
-    //use DefaultDecoder = json::Decoder;
-    use DefaultEncoder = ebml::writer::Encoder;
-    use DefaultDecoder = ebml::reader::Decoder;
+    use DefaultEncoder = json::Encoder;
+    use DefaultDecoder = json::Decoder;
 
     use flatpipes::flatteners::*;
     use flatpipes::bytepipes::*;
+    use flatpipes::pod;
+    use flatpipes::serial;
+    use io_util::BufReader;
+    use flatpipes::{BytePort, FlatChan, FlatPort};
+    use net::ip;
+    use net::tcp::TcpSocketBuf;
 
     use core::dvec::DVec;
-    use io::BytesReader;
-    use util::BufReader;
-    use net::tcp::TcpSocketBuf;
+    use core::int;
+    use core::io::BytesReader;
+    use core::io;
+    use core::prelude::*;
+    use core::result;
+    use core::sys;
+    use core::task;
 
     #[test]
     fn test_serializing_memory_stream() {
@@ -760,7 +728,7 @@ fn test_pod_pipes() {
         }
     }
 
-    // XXX: Networking doesn't work on x86
+    // FIXME #2064: Networking doesn't work on x86
     #[test]
     #[cfg(target_arch = "x86_64")]
     fn test_pod_tcp_stream() {
@@ -803,6 +771,7 @@ fn test_some_tcp_stream<U: Unflattener<int>, F: Flattener<int>>(
         use net::ip;
         use cell::Cell;
         use net::tcp::TcpSocket;
+        use uv;
 
         // Indicate to the client task that the server is listening
         let (begin_connect_port, begin_connect_chan) = pipes::stream();
@@ -901,6 +870,18 @@ fn test_some_tcp_stream<U: Unflattener<int>, F: Flattener<int>>(
     // Tests that the different backends behave the same when the
     // binary streaming protocol is broken
     mod broken_protocol {
+        use core::prelude::*;
+
+        use flatpipes::{BytePort, FlatPort};
+        use flatpipes::flatteners::PodUnflattener;
+        use flatpipes::pod;
+        use io_util::BufReader;
+
+        use core::io;
+        use core::pipes;
+        use core::sys;
+        use core::task;
+
         type PortLoader<P: BytePort> =
             ~fn(~[u8]) -> FlatPort<int, PodUnflattener<int>, P>;
 
index 1eccb5a8d92daf1191bfd6c67243572e7f8d5b50..e0d4b95a7e425e867df4351a0c121cc917f098e8 100644 (file)
@@ -22,8 +22,8 @@
  */
 
 use core::cmp::{Eq, Ord};
-use option::{Some, None};
-use option = option;
+use core::option::{Some, None};
+use core::prelude::*;
 
 pub type Treemap<K, V> = @TreeNode<K, V>;
 
index 2a72c2f696a54c4c42561d76196822b6e35b5a02..7d61326c02fa4931ec5c31318e0e60ffe806cf82 100644 (file)
  * ~~~
  */
 
-use either::Either;
-use pipes::{recv, oneshot, ChanOne, PortOne, send_one, recv_one};
-use cast::copy_lifetime;
+use core::cast::copy_lifetime;
+use core::cast;
+use core::either::Either;
+use core::option;
+use core::pipes::{recv, oneshot, ChanOne, PortOne, send_one, recv_one};
+use core::prelude::*;
+use core::task;
 
 #[doc = "The future type"]
 pub struct Future<A> {
-    /*priv*/ mut state: FutureState<A>,
+    priv mut state: FutureState<A>,
 }
 
 // FIXME(#2829) -- futures should not be copyable, because they close
@@ -142,6 +146,13 @@ pub fn spawn<A:Owned>(blk: fn~() -> A) -> Future<A> {
 
 #[allow(non_implicitly_copyable_typarams)]
 pub mod test {
+    use core::prelude::*;
+
+    use future::*;
+
+    use core::pipes::oneshot;
+    use core::task;
+
     #[test]
     pub fn test_from_value() {
         let f = from_value(~"snail");
index 38540524daca3974847fab55c95eb42bb61695f8..93eb2095c5eafb73ff01970a63cc92045bb5694b 100644 (file)
 #[forbid(deprecated_mode)];
 
 use core::cmp::Eq;
+use core::prelude::*;
 use core::result::{Err, Ok};
+use core::result;
 use core::option;
 use core::option::{Some, None};
+use core::str;
+use core::vec;
 
 #[deriving_eq]
-enum Name {
+pub enum Name {
     Long(~str),
     Short(char),
 }
 
 #[deriving_eq]
-enum HasArg { Yes, No, Maybe, }
+pub enum HasArg { Yes, No, Maybe, }
 
 #[deriving_eq]
-enum Occur { Req, Optional, Multi, }
+pub enum Occur { Req, Optional, Multi, }
 
 /// A description of a possible option
 #[deriving_eq]
@@ -450,6 +454,12 @@ enum FailType {
  *  groups of short and long option names, together.
  */
 pub mod groups {
+    use getopts::{HasArg, Long, Maybe, Multi, No, Occur, Opt, Optional, Req};
+    use getopts::{Result, Short, Yes};
+
+    use core::prelude::*;
+    use core::str;
+    use core::vec;
 
     /** one group of options, e.g., both -h and --help, along with
      * their shared description and properties
@@ -562,7 +572,7 @@ pub fn long_to_short(lopt: &OptGroup) -> ~[Opt] {
     /*
      * Parse command line args with the provided long format options
      */
-    pub fn getopts(args: &[~str], opts: &[OptGroup]) -> Result {
+    pub fn getopts(args: &[~str], opts: &[OptGroup]) -> ::getopts::Result {
         ::getopts::getopts(args, vec::flat_map(opts, long_to_short))
     }
 
@@ -626,9 +636,14 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
 #[cfg(test)]
 mod tests {
     #[legacy_exports];
+    use core::prelude::*;
+
     use opt = getopts;
-    use result::{Err, Ok};
     use getopts::groups::OptGroup;
+    use getopts::*;
+
+    use core::result::{Err, Ok};
+    use core::result;
 
     fn check_fail_type(f: Fail_, ft: FailType) {
         match f {
diff --git a/src/libstd/io_util.rs b/src/libstd/io_util.rs
new file mode 100644 (file)
index 0000000..fb410c1
--- /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 core::io::{Reader, BytesReader};
+use core::io;
+use core::prelude::*;
+
+pub struct BufReader {
+    buf: ~[u8],
+    mut pos: uint
+}
+
+pub impl BufReader {
+    static pub fn new(v: ~[u8]) -> BufReader {
+        BufReader {
+            buf: move v,
+            pos: 0
+        }
+    }
+
+    priv fn as_bytes_reader<A>(f: &fn(&BytesReader) -> A) -> A {
+        // Recreating the BytesReader state every call since
+        // I can't get the borrowing to work correctly
+        let bytes_reader = BytesReader {
+            bytes: ::core::util::id::<&[u8]>(self.buf),
+            pos: self.pos
+        };
+
+        let res = f(&bytes_reader);
+
+        // FIXME #4429: This isn't correct if f fails
+        self.pos = bytes_reader.pos;
+
+        return move res;
+    }
+}
+
+impl BufReader: Reader {
+    fn read(&self, bytes: &[mut u8], len: uint) -> uint {
+        self.as_bytes_reader(|r| r.read(bytes, len) )
+    }
+    fn read_byte(&self) -> int {
+        self.as_bytes_reader(|r| r.read_byte() )
+    }
+    fn eof(&self) -> bool {
+        self.as_bytes_reader(|r| r.eof() )
+    }
+    fn seek(&self, offset: int, whence: io::SeekStyle) {
+        self.as_bytes_reader(|r| r.seek(offset, whence) )
+    }
+    fn tell(&self) -> uint {
+        self.as_bytes_reader(|r| r.tell() )
+    }
+}
index 1d46a54518589397fe1f1c91376a4e44a493f86e..0dea73981db56e5ae994bf27cc12c230c131c415 100644 (file)
 
 //! json serialization
 
-use core::cmp::{Eq, Ord};
-use io::{WriterUtil, ReaderUtil};
-use send_map::linear;
+use serialize;
 use sort::Sort;
 
+use core::char;
+use core::cmp::{Eq, Ord};
+use core::float;
+use core::io::{WriterUtil, ReaderUtil};
+use core::io;
+use core::prelude::*;
+use core::send_map::linear;
+use core::str;
+use core::to_str;
+use core::vec;
+
 /// Represents a json value
 pub enum Json {
     Number(float),
@@ -917,22 +926,20 @@ fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
 
 impl Json : Eq {
     pure fn eq(&self, other: &Json) -> bool {
-        // XXX: This is ugly because matching on references is broken, and
-        // we can't match on dereferenced tuples without a copy.
-        match (*self) {
-            Number(f0) =>
-                match *other { Number(f1) => f0 == f1, _ => false },
-            String(ref s0) =>
-                match *other { String(ref s1) => s0 == s1, _ => false },
-            Boolean(b0) =>
-                match *other { Boolean(b1) => b0 == b1, _ => false },
-            Null =>
-                match *other { Null => true, _ => false },
-            List(ref v0) =>
-                match *other { List(ref v1) => v0 == v1, _ => false },
-            Object(ref d0) => {
-                match *other {
-                    Object(ref d1) => {
+        match (self) {
+            &Number(f0) =>
+                match other { &Number(f1) => f0 == f1, _ => false },
+            &String(ref s0) =>
+                match other { &String(ref s1) => s0 == s1, _ => false },
+            &Boolean(b0) =>
+                match other { &Boolean(b1) => b0 == b1, _ => false },
+            &Null =>
+                match other { &Null => true, _ => false },
+            &List(ref v0) =>
+                match other { &List(ref v1) => v0 == v1, _ => false },
+            &Object(ref d0) => {
+                match other {
+                    &Object(ref d1) => {
                         if d0.len() == d1.len() {
                             let mut equal = true;
                             for d0.each |k, v0| {
@@ -951,7 +958,7 @@ impl Json : Eq {
             }
         }
     }
-    pure fn ne(&self, other: &Json) -> bool { !(*self).eq(other) }
+    pure fn ne(&self, other: &Json) -> bool { !self.eq(other) }
 }
 
 /// Test if two json values are less than one another
@@ -998,7 +1005,7 @@ impl Json : Ord {
                             let mut d0_flat = ~[];
                             let mut d1_flat = ~[];
 
-                            // XXX: this is horribly inefficient...
+                            // FIXME #4430: this is horribly inefficient...
                             for d0.each |k, v| {
                                  d0_flat.push((@copy *k, @copy *v));
                             }
@@ -1185,6 +1192,13 @@ impl Error: to_str::ToStr {
 
 #[cfg(test)]
 mod tests {
+    use core::prelude::*;
+
+    use json::*;
+
+    use core::result;
+    use core::send_map::linear;
+
     fn mk_object(items: &[(~str, Json)]) -> Json {
         let mut d = ~linear::LinearMap();
 
index e41aab8ec1ffb5d4a5e5e920b9cf255a6dc1a6e8..2d9c96b28a983de1f377a0b799102cfad9ce8ea3 100644 (file)
@@ -13,8 +13,9 @@
 
 use core::cmp::Eq;
 use core::option;
-use option::*;
-use option::{Some, None};
+use core::option::*;
+use core::prelude::*;
+use core::vec;
 
 #[deriving_eq]
 pub enum List<T> {
@@ -162,6 +163,11 @@ pub fn has<T: Copy Eq>(ls: @List<T>, elt: T) -> bool {
 mod tests {
     #[legacy_exports];
 
+    use list::*;
+    use list;
+
+    use core::option;
+
     #[test]
     fn test_is_empty() {
         let empty : @list::List<int> = from_vec(~[]);
index 39124dfbfbae21c2ca46a75055eeaa9e55897921..d76fd85c5878c7093fd1dd65a946456ea0885d24 100644 (file)
 //! A map type
 #[forbid(deprecated_mode)];
 
-use io::WriterUtil;
-use to_str::ToStr;
-use mutable::Mut;
-use send_map::linear::LinearMap;
-
 use core::cmp::Eq;
-use hash::Hash;
-use to_bytes::IterBytes;
+use core::hash::Hash;
+use core::io::WriterUtil;
+use core::io;
+use core::ops;
+use core::to_str::ToStr;
+use core::mutable::Mut;
+use core::prelude::*;
+use core::send_map::linear::LinearMap;
+use core::to_bytes::IterBytes;
+use core::uint;
+use core::vec;
 
 /// A convenience type to treat a hashmap as a set
 pub type Set<K:Eq IterBytes Hash> = HashMap<K, ()>;
@@ -51,7 +55,7 @@ pub trait Map<K:Eq IterBytes Hash Copy, V: Copy> {
      * Add a value to the map.
      *
      * If the map contains a value for the key, use the function to
-     * set a new value.  (Like `insert_or_update_with_key`, but with a
+     * set a new value.  (Like `update_with_key`, but with a
      * function of only values.)
      */
     fn update(key: K, newval: V, ff: fn(V, V) -> V) -> bool;
@@ -103,7 +107,7 @@ pub trait Map<K:Eq IterBytes Hash Copy, V: Copy> {
     pure fn each_value_ref(fn(value: &V) -> bool);
 }
 
-mod util {
+pub mod util {
     pub type Rational = {num: int, den: int}; // : int::positive(*.den);
 
     pub pure fn rational_leq(x: Rational, y: Rational) -> bool {
@@ -117,6 +121,14 @@ mod util {
 // FIXME (#2344): package this up and export it as a datatype usable for
 // external code that doesn't want to pay the cost of a box.
 pub mod chained {
+    use map::{Map, util};
+
+    use core::io;
+    use core::ops;
+    use core::option;
+    use core::prelude::*;
+    use core::uint;
+    use core::vec;
 
     const initial_capacity: uint = 32u; // 2^5
 
@@ -486,7 +498,7 @@ pub fn hash_from_vec<K: Eq IterBytes Hash Const Copy, V: Copy>(
     map
 }
 
-// XXX Transitional
+// FIXME #4431: Transitional
 impl<K: Eq IterBytes Hash Copy, V: Copy> @Mut<LinearMap<K, V>>:
     Map<K, V> {
     pure fn size() -> uint {
@@ -603,6 +615,11 @@ fn clear() {
 
 #[cfg(test)]
 mod tests {
+    use map;
+
+    use core::option::None;
+    use core::option;
+    use core::uint;
 
     #[test]
     fn test_simple() {
index 8e58a010f469e9806eeae36f6b68c002b8aa997b..d10533008d965d9018f82cad9c34be5dabb6f518 100644 (file)
 
 #[forbid(deprecated_mode)];
 
+use core::str;
+use core::uint;
+use core::vec;
+
 pub pure fn md4(msg: &[u8]) -> {a: u32, b: u32, c: u32, d: u32} {
     // subtle: if orig_len is merely uint, then the code below
     // which performs shifts by 32 bits or more has undefined
index 230fb4b616d002815b0b1ae5de6730ca0596a160..ca1cc1235961abd4b79a1350b1c314d9f44df176 100644 (file)
@@ -8,7 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Top-level module for network-related functionality
+/*!
+Top-level module for network-related functionality.
+
+Basically, including this module gives you:
+
+* `net_tcp`
+* `net_ip`
+* `net_url`
+
+See each of those three modules for documentation on what they do.
+*/
 
 pub use tcp = net_tcp;
 pub use ip = net_ip;
index 1eb970526c36bca3a6c2460159de12b2013bf087..fad583a668b3b930d8fbd6dc4f07b18f9f2708ca 100644 (file)
 //! Types/fns concerning Internet Protocol (IP), versions 4 & 6
 #[forbid(deprecated_mode)];
 
+use core::libc;
+use core::oldcomm;
+use core::prelude::*;
+use core::ptr;
+use core::result;
+use core::str;
+use core::uint;
+use core::vec;
+
 use iotask = uv::iotask::IoTask;
 use interact = uv::iotask::interact;
 
@@ -39,7 +48,7 @@ pub enum IpAddr {
 }
 
 /// Human-friendly feedback on why a parse_addr attempt failed
-type ParseAddrErr = {
+pub type ParseAddrErr = {
     err_msg: ~str
 };
 
@@ -139,6 +148,18 @@ pub fn get_addr(node: &str, iotask: iotask)
 }
 
 pub mod v4 {
+    use net::ip::{IpAddr, Ipv4, Ipv6, ParseAddrErr};
+    use uv::ll;
+    use uv_ip4_addr = uv::ll::ip4_addr;
+    use uv_ip4_name = uv::ll::ip4_name;
+
+    use core::prelude::*;
+    use core::ptr;
+    use core::result;
+    use core::str;
+    use core::uint;
+    use core::vec;
+
     /**
      * Convert a str to `ip_addr`
      *
@@ -225,6 +246,14 @@ pub fn try_parse_addr(ip: &str) -> result::Result<IpAddr,ParseAddrErr> {
     }
 }
 pub mod v6 {
+    use net::ip::{IpAddr, Ipv6, ParseAddrErr};
+    use uv_ip6_addr = uv::ll::ip6_addr;
+    use uv_ip6_name = uv::ll::ip6_name;
+
+    use core::prelude::*;
+    use core::result;
+    use core::str;
+
     /**
      * Convert a str to `ip_addr`
      *
@@ -331,6 +360,16 @@ pub fn try_parse_addr(ip: &str) -> result::Result<IpAddr,ParseAddrErr> {
 
 #[cfg(test)]
 mod test {
+    use core::prelude::*;
+
+    use net_ip::*;
+    use net_ip::v4;
+    use net_ip::v6;
+    use uv;
+
+    use core::result;
+    use core::vec;
+
     #[test]
     fn test_ip_ipv4_parse_and_format_ip() {
         let localhost_str = ~"127.0.0.1";
index c888b457356b65f97e8501caf817106c928f0dd4..847962c1773a9a72457b0196eb26a93bd91b1a01 100644 (file)
@@ -9,22 +9,34 @@
 // except according to those terms.
 
 //! High-level interface to libuv's TCP functionality
-// XXX Need FFI fixes
+// FIXME #4425: Need FFI fixes
 #[allow(deprecated_mode)];
 
+use future;
+use future_spawn = future::spawn;
 use ip = net_ip;
+use uv;
 use uv::iotask;
 use uv::iotask::IoTask;
-use future_spawn = future::spawn;
-use result::{Result};
-use libc::size_t;
-use io::{Reader, ReaderUtil, Writer};
+
+use core::io::{Reader, ReaderUtil, Writer};
+use core::io;
+use core::libc::size_t;
+use core::libc;
+use core::oldcomm;
+use core::prelude::*;
+use core::ptr;
+use core::result::{Result};
+use core::result;
+use core::uint;
+use core::vec;
 
 #[nolink]
 extern mod rustrt {
-    fn rust_uv_current_kernel_malloc(size: libc::c_uint) -> *libc::c_void;
-    fn rust_uv_current_kernel_free(mem: *libc::c_void);
-    fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_current_kernel_malloc(size: libc::c_uint)
+                                         -> *libc::c_void;
+    unsafe fn rust_uv_current_kernel_free(mem: *libc::c_void);
+    unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
 }
 
 /**
@@ -76,7 +88,7 @@ pub fn TcpSocketBuf(data: @TcpBufferedSocketData) -> TcpSocketBuf {
     err_msg: ~str
 };
 /// Details returned as part of a `result::err` result from `tcp::listen`
-enum TcpListenErrData {
+pub enum TcpListenErrData {
     /**
      * Some unplanned-for error. The first and second fields correspond
      * to libuv's `err_name` and `err_msg` fields, respectively.
@@ -364,7 +376,7 @@ pub fn read_stop(sock: &TcpSocket,
  * * `timeout_msecs` - a `uint` value, in msecs, to wait before dropping the
  * read attempt. Pass `0u` to wait indefinitely
  */
-fn read(sock: &TcpSocket, timeout_msecs: uint)
+pub fn read(sock: &TcpSocket, timeout_msecs: uint)
     -> result::Result<~[u8],TcpErrData> {
     let socket_data = ptr::addr_of(&(*(sock.socket_data)));
     read_common_impl(socket_data, timeout_msecs)
@@ -815,7 +827,7 @@ fn read(&self, buf: &[mut u8], len: uint) -> uint {
         let mut data = ~[];
         self.data.buf <-> data;
 
-        vec::bytes::memcpy(buf, vec::view(data, 0, data.len()), count);
+        vec::bytes::copy_memory(buf, vec::view(data, 0, data.len()), count);
 
         self.data.buf.push_all(vec::view(data, count, data.len()));
 
@@ -901,6 +913,8 @@ fn tear_down_socket_data(socket_data: @TcpSocketData) unsafe {
 // shared implementation for tcp::read
 fn read_common_impl(socket_data: *TcpSocketData, timeout_msecs: uint)
     -> result::Result<~[u8],TcpErrData> unsafe {
+    use timer;
+
     log(debug, ~"starting tcp::read");
     let iotask = (*socket_data).iotask;
     let rs_result = read_start_common_impl(socket_data);
@@ -1257,16 +1271,35 @@ enum ConnAttempt {
 };
 
 //#[cfg(test)]
-mod test {
+pub mod test {
+    use net::ip;
+    use net::tcp::{GenericListenErr, TcpConnectErrData, TcpListenErrData};
+    use net::tcp::{connect, accept, read, listen, TcpSocket, socket_buf};
+    use net;
+    use uv::iotask::IoTask;
+    use uv;
+
+    use core::io;
+    use core::oldcomm;
+    use core::prelude::*;
+    use core::result;
+    use core::str;
+    use core::task;
+    use core::vec;
+
     // FIXME don't run on fbsd or linux 32 bit (#2064)
     #[cfg(target_os="win32")]
     #[cfg(target_os="darwin")]
     #[cfg(target_os="linux")]
-    mod tcp_ipv4_server_and_client_test {
+    #[cfg(target_os="android")]
+    pub mod tcp_ipv4_server_and_client_test {
         #[cfg(target_arch="x86_64")]
-        mod impl64 {
+        pub mod impl64 {
+            use net::tcp::test::*;
+
             #[test]
             fn test_gl_tcp_server_and_client_ipv4() unsafe {
+                use net::tcp::test::tcp_ipv4_server_and_client_test::*;
                 impl_gl_tcp_ipv4_server_and_client();
             }
             #[test]
@@ -1285,7 +1318,9 @@ fn test_gl_tcp_server_address_in_use() unsafe {
             fn test_gl_tcp_server_access_denied() unsafe {
                 impl_gl_tcp_ipv4_server_access_denied();
             }
+            // Strange failure on Windows. --pcwalton
             #[test]
+            #[ignore(cfg(target_os = "win32"))]
             fn test_gl_tcp_ipv4_server_client_reader_writer() {
                 impl_gl_tcp_ipv4_server_client_reader_writer();
             }
@@ -1295,7 +1330,10 @@ fn test_tcp_socket_impl_reader_handles_eof() {
             }
         }
         #[cfg(target_arch="x86")]
-        mod impl32 {
+        #[cfg(target_arch="arm")]
+        pub mod impl32 {
+            use net::tcp::test::*;
+
             #[test]
             #[ignore(cfg(target_os = "linux"))]
             fn test_gl_tcp_server_and_client_ipv4() unsafe {
@@ -1324,12 +1362,13 @@ fn test_gl_tcp_server_access_denied() unsafe {
             }
             #[test]
             #[ignore(cfg(target_os = "linux"))]
+            #[ignore(cfg(target_os = "win32"))]
             fn test_gl_tcp_ipv4_server_client_reader_writer() {
                 impl_gl_tcp_ipv4_server_client_reader_writer();
             }
         }
     }
-    fn impl_gl_tcp_ipv4_server_and_client() {
+    pub fn impl_gl_tcp_ipv4_server_and_client() {
         let hl_loop = uv::global_loop::get();
         let server_ip = ~"127.0.0.1";
         let server_port = 8888u;
@@ -1375,7 +1414,7 @@ fn impl_gl_tcp_ipv4_server_and_client() {
         assert str::contains(actual_req, expected_req);
         assert str::contains(actual_resp, expected_resp);
     }
-    fn impl_gl_tcp_ipv4_get_peer_addr() {
+    pub fn impl_gl_tcp_ipv4_get_peer_addr() {
         let hl_loop = uv::global_loop::get();
         let server_ip = ~"127.0.0.1";
         let server_port = 8887u;
@@ -1422,7 +1461,7 @@ fn impl_gl_tcp_ipv4_get_peer_addr() {
             client_ch.send(str::from_bytes(read_result.get()));
         };
     }
-    fn impl_gl_tcp_ipv4_client_error_connection_refused() {
+    pub fn impl_gl_tcp_ipv4_client_error_connection_refused() {
         let hl_loop = uv::global_loop::get();
         let server_ip = ~"127.0.0.1";
         let server_port = 8889u;
@@ -1442,7 +1481,7 @@ fn impl_gl_tcp_ipv4_client_error_connection_refused() {
           _ => fail ~"unknown error.. expected connection_refused"
         }
     }
-    fn impl_gl_tcp_ipv4_server_address_in_use() {
+    pub fn impl_gl_tcp_ipv4_server_address_in_use() {
         let hl_loop = uv::global_loop::get();
         let server_ip = ~"127.0.0.1";
         let server_port = 8890u;
@@ -1493,7 +1532,7 @@ fn impl_gl_tcp_ipv4_server_address_in_use() {
           }
         }
     }
-    fn impl_gl_tcp_ipv4_server_access_denied() {
+    pub fn impl_gl_tcp_ipv4_server_access_denied() {
         let hl_loop = uv::global_loop::get();
         let server_ip = ~"127.0.0.1";
         let server_port = 80u;
@@ -1512,9 +1551,7 @@ fn impl_gl_tcp_ipv4_server_access_denied() {
           }
         }
     }
-    fn impl_gl_tcp_ipv4_server_client_reader_writer() {
-        /*
-         XXX: Causes an ICE.
+    pub fn impl_gl_tcp_ipv4_server_client_reader_writer() {
 
         let iotask = uv::global_loop::get();
         let server_ip = ~"127.0.0.1";
@@ -1522,14 +1559,14 @@ fn impl_gl_tcp_ipv4_server_client_reader_writer() {
         let expected_req = ~"ping";
         let expected_resp = ~"pong";
 
-        let server_result_po = core::comm::port::<~str>();
-        let server_result_ch = core::comm::chan(server_result_po);
+        let server_result_po = oldcomm::Port::<~str>();
+        let server_result_ch = oldcomm::Chan(&server_result_po);
 
-        let cont_po = core::comm::port::<()>();
-        let cont_ch = core::comm::chan(cont_po);
+        let cont_po = oldcomm::Port::<()>();
+        let cont_ch = oldcomm::Chan(&cont_po);
         // server
         do task::spawn_sched(task::ManualThreads(1u)) {
-            let actual_req = do comm::listen |server_ch| {
+            let actual_req = do oldcomm::listen |server_ch| {
                 run_tcp_test_server(
                     server_ip,
                     server_port,
@@ -1540,33 +1577,33 @@ fn impl_gl_tcp_ipv4_server_client_reader_writer() {
             };
             server_result_ch.send(actual_req);
         };
-        core::comm::recv(cont_po);
+        oldcomm::recv(cont_po);
         // client
         let server_addr = ip::v4::parse_addr(server_ip);
         let conn_result = connect(server_addr, server_port, iotask);
-        if result::is_err(conn_result) {
+        if result::is_err(&conn_result) {
             assert false;
         }
         let sock_buf = @socket_buf(result::unwrap(conn_result));
         buf_write(sock_buf, expected_req);
 
         // so contrived!
-        let actual_resp = do str::as_bytes(expected_resp) |resp_buf| {
-            buf_read(sock_buf, vec::len(resp_buf))
+        let actual_resp = do str::as_bytes(&expected_resp) |resp_buf| {
+            buf_read(sock_buf, resp_buf.len())
         };
 
-        let actual_req = core::comm::recv(server_result_po);
+        let actual_req = oldcomm::recv(server_result_po);
         log(debug, fmt!("REQ: expected: '%s' actual: '%s'",
                        expected_req, actual_req));
         log(debug, fmt!("RESP: expected: '%s' actual: '%s'",
                        expected_resp, actual_resp));
         assert str::contains(actual_req, expected_req);
         assert str::contains(actual_resp, expected_resp);
-        */
     }
 
-    fn impl_tcp_socket_impl_reader_handles_eof() {
-        use io::{Reader,ReaderUtil};
+    pub fn impl_tcp_socket_impl_reader_handles_eof() {
+        use core::io::{Reader,ReaderUtil};
+
         let hl_loop = uv::global_loop::get();
         let server_ip = ~"127.0.0.1";
         let server_port = 10041u;
index a6ba728ccbb07670d1edb337b0b71a6a0e2898f4..1992e38e7fac3965fb42fe272bf967e26a8ec088 100644 (file)
 //! Types/fns concerning URLs (see RFC 3986)
 #[forbid(deprecated_mode)];
 
-use io::ReaderUtil;
-use send_map::linear::LinearMap;
+use map;
+use map::HashMap;
+
+use core::cmp::Eq;
+use core::dvec::DVec;
+use core::from_str::FromStr;
+use core::io::{Reader, ReaderUtil};
+use core::io;
+use core::prelude::*;
+use core::send_map::linear::LinearMap;
+use core::send_map;
+use core::str;
+use core::to_bytes::IterBytes;
+use core::to_bytes;
+use core::to_str::ToStr;
+use core::to_str;
+use core::uint;
+use core::util;
+use core::vec;
 
 #[deriving_eq]
 struct Url {
@@ -654,7 +671,7 @@ enum State {
     Ok(Url::new(scheme, userinfo, host, port, path, query, fragment))
 }
 
-impl Url: from_str::FromStr {
+impl Url: FromStr {
     static pure fn from_str(s: &str) -> Option<Url> {
         match from_str(s) {
             Ok(move url) => Some(url),
@@ -719,6 +736,15 @@ impl Url: to_bytes::IterBytes {
 #[cfg(test)]
 mod tests {
     #[legacy_exports];
+
+    use core::prelude::*;
+
+    use net_url::*;
+    use net_url::UserInfo;
+
+    use core::result;
+    use core::str;
+
     #[test]
     fn test_split_char_first() {
         let (u,v) = split_char_first(~"hello, sweet world", ',');
@@ -1051,6 +1077,9 @@ fn test_encode_form_urlencoded() {
 
     #[test]
     fn test_decode_form_urlencoded() {
+        // FIXME #4449: Commented out because this causes an ICE, but only
+        // on FreeBSD
+        /*
         assert decode_form_urlencoded(~[]).len() == 0;
 
         let s = str::to_bytes("a=1&foo+bar=abc&foo+bar=12+%3D+34");
@@ -1058,5 +1087,6 @@ fn test_decode_form_urlencoded() {
         assert form.len() == 2;
         assert form.get_ref(&~"a") == &~[~"1"];
         assert form.get_ref(&~"foo bar") == &~[~"abc", ~"12 = 34"];
+        */
     }
 }
index 10cbcaa0c3b3a07af3c1da523eeba9b5145bc46f..04d88af1100f5d526cdcad556276580a7d18088b 100644 (file)
 
 #[forbid(deprecated_mode)];
 
+use core::cast;
+use core::prelude::*;
+use core::ptr;
+use core::sys;
+use core::uint;
+use core::vec;
+
 use future_spawn = future::spawn;
 
 
index 5e477042b6be25b88d1dfb907a21e39455f791fe..d07c29d624ce54c131c0ce35f10010925bf636df 100644 (file)
 
 #[forbid(deprecated_mode)];
 
-use io::Writer;
-use io::WriterUtil;
 use serialize;
 
-pub struct Encoder {
+use core::io::Writer;
+use core::io::WriterUtil;
+use core::io;
+
+pub struct Serializer {
     wr: io::Writer,
 }
 
-pub fn Encoder(wr: io::Writer) -> Encoder {
-    Encoder { wr: wr }
+pub fn Serializer(wr: io::Writer) -> Serializer {
+    Serializer { wr: wr }
 }
 
-pub impl Encoder: serialize::Encoder {
+pub impl Serializer: serialize::Encoder {
     fn emit_nil(&self) {
         self.wr.write_str(~"()")
     }
index 642b27fa46543901e6c199d545dd54fd659d6a50..4d341d737f60279e686111439c2476ba4e9680a1 100644 (file)
@@ -2,7 +2,9 @@
 //! A priority queue implemented with a binary heap
 
 use core::cmp::Ord;
-use ptr::addr_of;
+use core::prelude::*;
+use core::ptr::addr_of;
+use core::vec;
 
 #[abi = "rust-intrinsic"]
 extern "C" mod rusti {
index b8cd1dc3ca2e9c5c0a594094e53d142811dee22a..70c7161b4cfaa4d99dc19e99fe71b3e81b96ed5b 100644 (file)
 // FIXME #3921. This is unsafe because linenoise uses global mutable
 // state without mutexes.
 
-use libc::{c_char, c_int};
+use core::libc::{c_char, c_int};
+use core::prelude::*;
+use core::str;
+use core::task;
 
 extern mod rustrt {
     #[legacy_exports];
-    fn linenoise(prompt: *c_char) -> *c_char;
-    fn linenoiseHistoryAdd(line: *c_char) -> c_int;
-    fn linenoiseHistorySetMaxLen(len: c_int) -> c_int;
-    fn linenoiseHistorySave(file: *c_char) -> c_int;
-    fn linenoiseHistoryLoad(file: *c_char) -> c_int;
-    fn linenoiseSetCompletionCallback(callback: *u8);
-    fn linenoiseAddCompletion(completions: *(), line: *c_char);
+    unsafe fn linenoise(prompt: *c_char) -> *c_char;
+    unsafe fn linenoiseHistoryAdd(line: *c_char) -> c_int;
+    unsafe fn linenoiseHistorySetMaxLen(len: c_int) -> c_int;
+    unsafe fn linenoiseHistorySave(file: *c_char) -> c_int;
+    unsafe fn linenoiseHistoryLoad(file: *c_char) -> c_int;
+    unsafe fn linenoiseSetCompletionCallback(callback: *u8);
+    unsafe fn linenoiseAddCompletion(completions: *(), line: *c_char);
 }
 
 /// Add a line to history
@@ -79,4 +82,4 @@ pub unsafe fn complete(cb: CompletionCb) unsafe {
     }
 
     rustrt::linenoiseSetCompletionCallback(callback);
-}
\ No newline at end of file
+}
index aa78d22e4c8ddaaf816c5605143edd35391a404a..153f39568845a143068b65bac1d02d0fcc6bfb6f 100644 (file)
 
 #[forbid(deprecated_mode)];
 
+use core::cast;
+use core::char;
+use core::option;
+use core::prelude::*;
+use core::str;
+use core::uint;
+use core::vec;
+
 /// The type of ropes.
 pub type Rope = node::Root;
 
@@ -441,6 +449,10 @@ pub fn loop_leaves(rope: Rope, it: fn(node::Leaf) -> bool) -> bool{
 
 pub mod iterator {
     pub mod leaf {
+        use rope::{Rope, node};
+
+        use core::prelude::*;
+
         pub fn start(rope: Rope) -> node::leaf_iterator::T {
             match (rope) {
               node::Empty      => return node::leaf_iterator::empty(),
@@ -452,6 +464,10 @@ pub fn next(it: &node::leaf_iterator::T) -> Option<node::Leaf> {
         }
     }
     pub mod char {
+        use rope::{Rope, node};
+
+        use core::prelude::*;
+
         pub fn start(rope: Rope) -> node::char_iterator::T {
             match (rope) {
               node::Empty      => return node::char_iterator::empty(),
@@ -543,7 +559,16 @@ pub fn char_at(rope: Rope, pos: uint) -> char {
 /*
  Section: Implementation
 */
-mod node {
+pub mod node {
+    use rope::node;
+
+    use core::cast;
+    use core::char;
+    use core::option;
+    use core::prelude::*;
+    use core::str;
+    use core::uint;
+    use core::vec;
 
     /// Implementation of type `rope`
     pub enum Root {
@@ -1116,6 +1141,12 @@ pub fn loop_leaves(node: @Node, it: fn(Leaf) -> bool) -> bool{
     }
 
     pub mod leaf_iterator {
+        use rope::node::{Concat, Leaf, Node, height};
+
+        use core::option;
+        use core::prelude::*;
+        use core::vec;
+
         pub type T = {
             stack:            ~[mut @Node],
             mut stackpos: int
@@ -1153,6 +1184,13 @@ pub fn next(it: &T) -> Option<Leaf> {
     }
 
     pub mod char_iterator {
+        use rope::node::{Leaf, Node};
+        use rope::node::leaf_iterator;
+
+        use core::option;
+        use core::prelude::*;
+        use core::str;
+
         pub type T = {
             leaf_iterator: leaf_iterator::T,
             mut leaf:  Option<Leaf>,
@@ -1232,6 +1270,12 @@ pub fn get_next_char_in_leaf(it: &T) -> Option<char> {
 
 #[cfg(test)]
 mod tests {
+    use rope::*;
+
+    use core::option;
+    use core::str;
+    use core::uint;
+    use core::vec;
 
     //Utility function, used for sanity check
     fn rope_to_string(r: Rope) -> ~str {
index a08d8defd5ce622a171a0fe9f8166ad9dc77c358..708df015dae49969138bf48d117389f8abdd2186 100644 (file)
 #[forbid(deprecated_mode)];
 #[forbid(non_camel_case_types)];
 
+use core::at_vec;
+use core::prelude::*;
+use core::vec;
+
 pub trait Encoder {
     // Primitive types:
     fn emit_nil(&self);
index 1a005bdc03f9aea48d321668f65021add98c6489..2fb12460498beb9e5486c1c080e715b18147f13e 100644 (file)
 
 #[forbid(deprecated_mode)];
 
+use core::str;
+use core::uint;
+use core::vec;
+
 /*
  * A SHA-1 implementation derived from Paul E. Jones's reference
  * implementation, which is written for clarity, not speed. At some
@@ -33,9 +37,9 @@
 /// The SHA-1 interface
 trait Sha1 {
     /// Provide message input as bytes
-    fn input((&[u8]));
+    fn input(&[const u8]);
     /// Provide message input as string
-    fn input_str((&str));
+    fn input_str(&str);
     /**
      * Read the digest as a vector of 20 bytes. After calling this no further
      * input may be provided until reset is called.
@@ -71,9 +75,9 @@ pub fn sha1() -> Sha1 {
          mut computed: bool,
          work_buf: @~[mut u32]};
 
-    fn add_input(st: &Sha1State, msg: &[u8]) {
+    fn add_input(st: &Sha1State, msg: &[const u8]) {
         assert (!st.computed);
-        for vec::each(msg) |element| {
+        for vec::each_const(msg) |element| {
             st.msg_block[st.msg_block_idx] = *element;
             st.msg_block_idx += 1u;
             st.len_low += 8u32;
@@ -239,7 +243,7 @@ fn reset() {
             self.h[4] = 0xC3D2E1F0u32;
             self.computed = false;
         }
-        fn input(msg: &[u8]) { add_input(&self, msg); }
+        fn input(msg: &[const u8]) { add_input(&self, msg); }
         fn input_str(msg: &str) {
             let bs = str::to_bytes(msg);
             add_input(&self, bs);
@@ -272,6 +276,11 @@ fn result_str() -> ~str {
 mod tests {
     #[legacy_exports];
 
+    use sha1;
+
+    use core::str;
+    use core::vec;
+
     #[test]
     fn test() unsafe {
         type Test = {input: ~str, output: ~[u8]};
index b16cf99cb4eff53691bb75ca683d58751da9c5bb..dbcb0c6aeec6ea20438bf2bd361a720d1a62672c 100644 (file)
  */
 #[forbid(deprecated_mode)];
 
-use core::option;
-use core::option::{Some, None};
-use dvec::DVec;
+use map;
 use map::Map;
 
+use core::dvec::DVec;
+use core::ops;
+use core::option::{Some, None};
+use core::option;
+use core::prelude::*;
+
 // FIXME (#2347): Should not be @; there's a bug somewhere in rustc that
 // requires this to be.
 type SmallIntMap_<T: Copy> = {v: DVec<Option<T>>};
@@ -165,6 +169,10 @@ pub fn as_map<V: Copy>(s: SmallIntMap<V>) -> map::Map<uint, V> {
 
 #[cfg(test)]
 mod tests {
+    use smallintmap::{mk, SmallIntMap};
+
+    use core::option::None;
+    use core::option;
 
     #[test]
     fn test_insert_with_key() {
index 316e23ef7ac225a5ac76124de6b06fd7885008b4..d83568ddd94756fb96b1aefd75b2cfb9d53a4792 100644 (file)
 //! Sorting methods
 #[forbid(deprecated_mode)];
 
-use vec::{len, push};
 use core::cmp::{Eq, Ord};
-use dvec::DVec;
+use core::dvec::DVec;
+use core::prelude::*;
+use core::util;
+use core::vec::{len, push};
+use core::vec;
 
 type Le<T> = pure fn(v1: &T, v2: &T) -> bool;
 
@@ -712,6 +715,13 @@ fn copy_vec<T: Copy>(dest: &[mut T], s1: uint,
 #[cfg(test)]
 mod test_qsort3 {
     #[legacy_exports];
+
+    use core::prelude::*;
+
+    use sort::*;
+
+    use core::vec;
+
     fn check_sort(v1: &[mut int], v2: &[mut int]) {
         let len = vec::len::<int>(v1);
         quick_sort3::<int>(v1);
@@ -752,6 +762,14 @@ fn test() {
 #[cfg(test)]
 mod test_qsort {
     #[legacy_exports];
+
+    use core::prelude::*;
+
+    use sort::*;
+
+    use core::int;
+    use core::vec;
+
     fn check_sort(v1: &[mut int], v2: &[mut int]) {
         let len = vec::len::<int>(v1);
         pure fn leual(a: &int, b: &int) -> bool { *a <= *b }
@@ -813,6 +831,12 @@ fn test_simple() {
 mod tests {
     #[legacy_exports];
 
+    use core::prelude::*;
+
+    use sort::*;
+
+    use core::vec;
+
     fn check_sort(v1: &[int], v2: &[int]) {
         let len = vec::len::<int>(v1);
         pub pure fn le(a: &int, b: &int) -> bool { *a <= *b }
@@ -876,6 +900,13 @@ fn test_merge_sort_stability()
 
 #[cfg(test)]
 mod test_tim_sort {
+    use core::prelude::*;
+
+    use sort::tim_sort;
+
+    use core::rand;
+    use core::vec;
+
     struct CVal {
         val: float,
     }
@@ -966,6 +997,14 @@ fn test_bad_Ord_impl() {
 
 #[cfg(test)]
 mod big_tests {
+    use core::prelude::*;
+
+    use sort::*;
+
+    use core::rand;
+    use core::task;
+    use core::uint;
+    use core::vec;
 
     #[test]
     fn test_unique() {
index f3781c386761053278af07b2c880c5edb155dd67..eea9bd0a40f7a1e6815b223f9506a58a0c0fda15 100644 (file)
@@ -26,8 +26,6 @@ not required in or otherwise suitable for the core library.
 #[license = "MIT"];
 #[crate_type = "lib"];
 
-#[no_core];
-
 #[allow(vecs_implicitly_copyable)];
 #[deny(non_camel_case_types)];
 // XXX this is set to allow because there are two methods in encoding
@@ -35,6 +33,8 @@ not required in or otherwise suitable for the core library.
 #[allow(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
+#[no_core];
+
 extern mod core(vers = "0.6");
 use core::*;
 
@@ -57,6 +57,7 @@ pub mod uv_global_loop;
 pub mod c_vec;
 pub mod timer;
 pub mod cell;
+pub mod io_util;
 
 // Concurrency
 
@@ -98,6 +99,7 @@ pub mod cmp;
 pub mod base64;
 pub mod rl;
 pub mod workcache;
+pub mod bigint;
 
 #[cfg(unicode)]
 mod unicode;
index e1b029c5396f4bb4dd495b8811f2aa1d00941846..58bdf8cfa74d8d04c5ffa0ee7c34b43be86e8808 100644 (file)
  * in std.
  */
 
-use private::{Exclusive, exclusive};
+use core::option;
+use core::pipes;
+use core::prelude::*;
+use core::private::{Exclusive, exclusive};
+use core::ptr;
+use core::task;
+use core::util;
+use core::vec;
 
 /****************************************************************************
  * Internals
@@ -353,7 +360,7 @@ fn access_cond<U>(blk: fn(c: &Condvar) -> U) -> U {
 struct Semaphore { priv sem: Sem<()> }
 
 /// Create a new semaphore with the specified count.
-fn semaphore(count: int) -> Semaphore {
+pub fn semaphore(count: int) -> Semaphore {
     Semaphore { sem: new_sem(count, ()) }
 }
 
@@ -442,9 +449,9 @@ struct RWlockInner {
  * unwinds.
  */
 struct RWlock {
-    /* priv */ order_lock:  Semaphore,
-    /* priv */ access_lock: Sem<~[mut Waitqueue]>,
-    /* priv */ state:       Exclusive<RWlockInner>
+    priv order_lock:  Semaphore,
+    priv access_lock: Sem<~[mut Waitqueue]>,
+    priv state:       Exclusive<RWlockInner>
 }
 
 /// Create a new rwlock, with one associated condvar.
@@ -676,7 +683,7 @@ fn RWlockReleaseDowngrade(lock: &r/RWlock) -> RWlockReleaseDowngrade/&r {
 }
 
 /// The "write permission" token used for rwlock.write_downgrade().
-pub struct RWlockWriteMode { /* priv */ lock: &RWlock }
+pub struct RWlockWriteMode { priv lock: &RWlock }
 impl RWlockWriteMode : Drop { fn finalize(&self) {} }
 /// The "read permission" token used for rwlock.write_downgrade().
 pub struct RWlockReadMode  { priv lock: &RWlock }
@@ -702,6 +709,19 @@ fn read<U>(blk: fn() -> U) -> U { blk() }
 #[cfg(test)]
 mod tests {
     #[legacy_exports];
+
+    use core::prelude::*;
+
+    use sync::*;
+
+    use core::cast;
+    use core::option;
+    use core::pipes;
+    use core::ptr;
+    use core::result;
+    use core::task;
+    use core::vec;
+
     /************************************************************************
      * Semaphore tests
      ************************************************************************/
index a87576789af55d66c99745ac45073b9e59d42bf6..5ed2195d2d2ad88d5fde1d837f8681df740e4059 100644 (file)
 /// A task pool abstraction. Useful for achieving predictable CPU
 /// parallelism.
 
-use pipes::{Chan, Port};
-use task::{SchedMode, SingleThreaded};
+use core::io;
+use core::pipes::{Chan, Port};
+use core::pipes;
+use core::prelude::*;
+use core::task::{SchedMode, SingleThreaded};
+use core::task;
+use core::vec;
 
 enum Msg<T> {
     Execute(~fn(&T)),
index 25ea4ad7bb5cfd7ce407c41aace5372c9c40846e..bbe1e5c7ccd9a625d869602d3e6afe7cbfeb747a 100644 (file)
 
 #[forbid(deprecated_mode)];
 
-use core::option;
-use option::{None, Some};
+use core::os;
+use core::prelude::*;
+use core::rand;
+use core::str;
 
 pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
     let r = rand::Rng();
index 5ec0f934440551321ea9f268ce72537df446ba49..ae5949e6f183d42ad2cfcc58a8406d7627144e7e 100644 (file)
 //! Simple ANSI color library
 #[forbid(deprecated_mode)];
 
-use core::Option;
+use core::i32;
+use core::io;
+use core::option;
+use core::os;
+use core::str;
+use core::vec;
 
 // FIXME (#2807): Windows support.
 
index d365077d0639d40a638d5e07efa7dfca7693ac8a..95523c1e5789f7d9c516d2db4ed3887bd9765d67 100644 (file)
 
 #[forbid(deprecated_mode)];
 
+use getopts;
+use sort;
+use term;
+
 use core::cmp::Eq;
-use either::Either;
-use result::{Ok, Err};
-use io::WriterUtil;
-use libc::size_t;
-use task::TaskBuilder;
+use core::either::Either;
+use core::either;
+use core::io::WriterUtil;
+use core::io;
+use core::libc::size_t;
+use core::oldcomm;
+use core::option;
+use core::prelude::*;
+use core::result;
+use core::str;
+use core::task::TaskBuilder;
+use core::task;
+use core::vec;
 
 #[abi = "cdecl"]
 extern mod rustrt {
     #[legacy_exports];
-    fn rust_sched_threads() -> libc::size_t;
+    unsafe fn rust_sched_threads() -> size_t;
 }
 
 // The name of a test. By convention this follows the rules for rust
 
 // The definition of a single test. A test runner will run a list of
 // these.
-pub type TestDesc = {
+pub struct TestDesc {
     name: TestName,
     testfn: TestFn,
     ignore: bool,
     should_fail: bool
-};
+}
 
 // The default console test runner. It accepts the command line
 // arguments and a vector of test_descs (generated at compile time).
@@ -68,7 +80,7 @@ pub fn test_main(args: &[~str], tests: &[TestDesc]) {
 type OptRes = Either<TestOpts, ~str>;
 
 // Parses command line arguments into test options
-fn parse_opts(args: &[~str]) -> OptRes {
+pub fn parse_opts(args: &[~str]) -> OptRes {
     let args_ = vec::tail(args);
     let opts = ~[getopts::optflag(~"ignored"), getopts::optopt(~"logfile")];
     let matches =
@@ -230,14 +242,14 @@ fn print_failures(st: ConsoleTestState) {
 #[test]
 fn should_sort_failures_before_printing_them() {
     let s = do io::with_str_writer |wr| {
-        let test_a = {
+        let test_a = TestDesc {
             name: ~"a",
             testfn: fn~() { },
             ignore: false,
             should_fail: false
         };
 
-        let test_b = {
+        let test_b = TestDesc {
             name: ~"b",
             testfn: fn~() { },
             ignore: false,
@@ -272,9 +284,9 @@ enum TestEvent {
 
 type MonitorMsg = (TestDesc, TestResult);
 
-fn run_tests(opts: &TestOpts, tests: &[TestDesc],
+fn run_tests(opts: &TestOpts,
+             tests: &[TestDesc],
              callback: fn@(e: TestEvent)) {
-
     let mut filtered_tests = filter_tests(opts, tests);
     callback(TeFiltered(copy filtered_tests));
 
@@ -323,14 +335,17 @@ fn run_tests(opts: &TestOpts, tests: &[TestDesc],
 const sched_overcommit : uint = 4u;
 
 fn get_concurrency() -> uint {
-    let threads = rustrt::rust_sched_threads() as uint;
-    if threads == 1u { 1u }
-    else { threads * sched_overcommit }
+    unsafe {
+        let threads = rustrt::rust_sched_threads() as uint;
+        if threads == 1u { 1u }
+        else { threads * sched_overcommit }
+    }
 }
 
 #[allow(non_implicitly_copyable_typarams)]
-fn filter_tests(opts: &TestOpts,
-                tests: &[TestDesc]) -> ~[TestDesc] {
+pub fn filter_tests(opts: &TestOpts,
+                    tests: &[TestDesc])
+                 -> ~[TestDesc] {
     let mut filtered = vec::slice(tests, 0, tests.len());
 
     // Remove tests that don't match the test filter
@@ -359,10 +374,11 @@ fn filter_fn(test: &TestDesc, filter_str: &str) ->
     } else {
         fn filter(test: &TestDesc) -> Option<TestDesc> {
             if test.ignore {
-                return option::Some({name: test.name,
-                                  testfn: copy test.testfn,
-                                  ignore: false,
-                                  should_fail: test.should_fail});
+                return option::Some(TestDesc {
+                    name: test.name,
+                    testfn: copy test.testfn,
+                    ignore: false,
+                    should_fail: test.should_fail});
             } else { return option::None; }
         };
 
@@ -382,7 +398,7 @@ fn filter(test: &TestDesc) -> Option<TestDesc> {
 
 type TestFuture = {test: TestDesc, wait: fn@() -> TestResult};
 
-fn run_test(test: TestDesc, monitor_ch: oldcomm::Chan<MonitorMsg>) {
+pub fn run_test(test: TestDesc, monitor_ch: oldcomm::Chan<MonitorMsg>) {
     if test.ignore {
         oldcomm::send(monitor_ch, (copy test, TrIgnored));
         return;
@@ -414,10 +430,18 @@ fn calc_result(test: &TestDesc, task_succeeded: bool) -> TestResult {
 mod tests {
     #[legacy_exports];
 
+    use test::{TrFailed, TrIgnored, TrOk, filter_tests, parse_opts, TestDesc};
+    use test::{run_test};
+
+    use core::either;
+    use core::oldcomm;
+    use core::option;
+    use core::vec;
+
     #[test]
     fn do_not_run_ignored_tests() {
         fn f() { fail; }
-        let desc = {
+        let desc = TestDesc {
             name: ~"whatever",
             testfn: f,
             ignore: true,
@@ -433,7 +457,7 @@ fn do_not_run_ignored_tests() {
     #[test]
     fn ignored_tests_result_in_ignored() {
         fn f() { }
-        let desc = {
+        let desc = TestDesc {
             name: ~"whatever",
             testfn: f,
             ignore: true,
@@ -450,7 +474,7 @@ fn f() { }
     #[ignore(cfg(windows))]
     fn test_should_fail() {
         fn f() { fail; }
-        let desc = {
+        let desc = TestDesc {
             name: ~"whatever",
             testfn: f,
             ignore: false,
@@ -466,7 +490,7 @@ fn test_should_fail() {
     #[test]
     fn test_should_fail_but_succeeds() {
         fn f() { }
-        let desc = {
+        let desc = TestDesc {
             name: ~"whatever",
             testfn: f,
             ignore: false,
@@ -507,10 +531,10 @@ fn filter_for_ignored_option() {
         let opts = {filter: option::None, run_ignored: true,
             logfile: option::None};
         let tests =
-            ~[{name: ~"1", testfn: fn~() { },
-               ignore: true, should_fail: false},
-             {name: ~"2", testfn: fn~() { },
-              ignore: false, should_fail: false}];
+            ~[TestDesc {name: ~"1", testfn: fn~() { },
+                        ignore: true, should_fail: false},
+              TestDesc {name: ~"2", testfn: fn~() { },
+                        ignore: false, should_fail: false}];
         let filtered = filter_tests(&opts, tests);
 
         assert (vec::len(filtered) == 1u);
@@ -535,8 +559,9 @@ fn sort_tests() {
             let testfn = fn~() { };
             let mut tests = ~[];
             for vec::each(names) |name| {
-                let test = {name: *name, testfn: copy testfn, ignore: false,
-                            should_fail: false};
+                let test = TestDesc {
+                    name: *name, testfn: copy testfn, ignore: false,
+                    should_fail: false};
                 tests.push(move test);
             }
             move tests
index 1058910c35a6485294f2c401f6f933b3b0436058..8cc6d0245a1e31aebb7ca4ba22512f69fe0e436e 100644 (file)
 #[forbid(deprecated_mode)];
 
 use core::cmp::Eq;
-use libc::{c_char, c_int, c_long, size_t, time_t};
-use io::{Reader, ReaderUtil};
-use result::{Result, Ok, Err};
+use core::int;
+use core::libc::{c_char, c_int, c_long, size_t, time_t};
+use core::i32;
+use core::io::{Reader, ReaderUtil};
+use core::io;
+use core::prelude::*;
+use core::result::{Result, Ok, Err};
+use core::str;
 
 #[abi = "cdecl"]
 extern mod rustrt {
     #[legacy_exports]
-    fn get_time(sec: &mut i64, nsec: &mut i32);
+    unsafe fn get_time(sec: &mut i64, nsec: &mut i32);
 
-    fn precise_time_ns(ns: &mut u64);
+    unsafe fn precise_time_ns(ns: &mut u64);
 
-    fn rust_tzset();
+    unsafe fn rust_tzset();
     // FIXME: The i64 values can be passed by-val when #2064 is fixed.
-    fn rust_gmtime(&&sec: i64, &&nsec: i32, &&result: Tm);
-    fn rust_localtime(&&sec: i64, &&nsec: i32, &&result: Tm);
-    fn rust_timegm(&&tm: Tm, sec: &mut i64);
-    fn rust_mktime(&&tm: Tm, sec: &mut i64);
+    unsafe fn rust_gmtime(&&sec: i64, &&nsec: i32, &&result: Tm);
+    unsafe fn rust_localtime(&&sec: i64, &&nsec: i32, &&result: Tm);
+    unsafe fn rust_timegm(&&tm: Tm, sec: &mut i64);
+    unsafe fn rust_mktime(&&tm: Tm, sec: &mut i64);
 }
 
 /// A record specifying a time value in seconds and nanoseconds.
@@ -53,10 +58,12 @@ impl Timespec : Eq {
  * nanoseconds since 1970-01-01T00:00:00Z.
  */
 pub fn get_time() -> Timespec {
-    let mut sec = 0i64;
-    let mut nsec = 0i32;
-    rustrt::get_time(&mut sec, &mut nsec);
-    return Timespec::new(sec, nsec);
+    unsafe {
+        let mut sec = 0i64;
+        let mut nsec = 0i32;
+        rustrt::get_time(&mut sec, &mut nsec);
+        return Timespec::new(sec, nsec);
+    }
 }
 
 
@@ -65,9 +72,11 @@ pub fn get_time() -> Timespec {
  * in nanoseconds since an unspecified epoch.
  */
 pub fn precise_time_ns() -> u64 {
-    let mut ns = 0u64;
-    rustrt::precise_time_ns(&mut ns);
-    ns
+    unsafe {
+        let mut ns = 0u64;
+        rustrt::precise_time_ns(&mut ns);
+        ns
+    }
 }
 
 
@@ -80,7 +89,9 @@ pub fn precise_time_s() -> float {
 }
 
 pub fn tzset() {
-    rustrt::rust_tzset();
+    unsafe {
+        rustrt::rust_tzset();
+    }
 }
 
 #[auto_encode]
@@ -137,10 +148,12 @@ impl Tm : Eq {
 
 /// Returns the specified time in UTC
 pub fn at_utc(clock: Timespec) -> Tm {
-    let mut Timespec { sec, nsec } = clock;
-    let mut tm = empty_tm();
-    rustrt::rust_gmtime(sec, nsec, tm);
-    move tm
+    unsafe {
+        let mut Timespec { sec, nsec } = clock;
+        let mut tm = empty_tm();
+        rustrt::rust_gmtime(sec, nsec, tm);
+        move tm
+    }
 }
 
 /// Returns the current time in UTC
@@ -150,10 +163,12 @@ pub fn now_utc() -> Tm {
 
 /// Returns the specified time in the local timezone
 pub fn at(clock: Timespec) -> Tm {
-    let mut Timespec { sec, nsec } = clock;
-    let mut tm = empty_tm();
-    rustrt::rust_localtime(sec, nsec, tm);
-    move tm
+    unsafe {
+        let mut Timespec { sec, nsec } = clock;
+        let mut tm = empty_tm();
+        rustrt::rust_localtime(sec, nsec, tm);
+        move tm
+    }
 }
 
 /// Returns the current time in the local timezone
@@ -178,13 +193,15 @@ pub fn now() -> Tm {
 impl Tm {
     /// Convert time to the seconds from January 1, 1970
     fn to_timespec() -> Timespec {
-        let mut sec = 0i64;
-        if self.tm_gmtoff == 0_i32 {
-            rustrt::rust_timegm(self, &mut sec);
-        } else {
-            rustrt::rust_mktime(self, &mut sec);
+        unsafe {
+            let mut sec = 0i64;
+            if self.tm_gmtoff == 0_i32 {
+                rustrt::rust_timegm(self, &mut sec);
+            } else {
+                rustrt::rust_mktime(self, &mut sec);
+            }
+            Timespec::new(sec, self.tm_nsec)
         }
-        Timespec::new(sec, self.tm_nsec)
     }
 
     /// Convert time to the local timezone
@@ -853,6 +870,16 @@ fn parse_type(ch: char, tm: &Tm) -> ~str {
 mod tests {
     #[legacy_exports];
 
+    use time::*;
+
+    use core::float;
+    use core::os;
+    use core::result;
+    use core::str;
+    use core::u64;
+    use core::uint;
+    use core::vec;
+
     #[test]
     fn test_get_time() {
         const some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z
@@ -900,7 +927,7 @@ fn test_at_utc() {
         os::setenv(~"TZ", ~"America/Los_Angeles");
         tzset();
 
-        let time = Timespec::new(1234567890, 54321);
+        let time = ::time::Timespec::new(1234567890, 54321);
         let utc = at_utc(time);
 
         assert utc.tm_sec == 30_i32;
@@ -922,7 +949,7 @@ fn test_at() {
         os::setenv(~"TZ", ~"America/Los_Angeles");
         tzset();
 
-        let time = Timespec::new(1234567890, 54321);
+        let time = ::time::Timespec::new(1234567890, 54321);
         let local = at(time);
 
         error!("time_at: %?", local);
@@ -951,7 +978,7 @@ fn test_to_timespec() {
         os::setenv(~"TZ", ~"America/Los_Angeles");
         tzset();
 
-        let time = Timespec::new(1234567890, 54321);
+        let time = ::time::Timespec::new(1234567890, 54321);
         let utc = at_utc(time);
 
         assert utc.to_timespec() == time;
@@ -963,7 +990,7 @@ fn test_conversions() {
         os::setenv(~"TZ", ~"America/Los_Angeles");
         tzset();
 
-        let time = Timespec::new(1234567890, 54321);
+        let time = ::time::Timespec::new(1234567890, 54321);
         let utc = at_utc(time);
         let local = at(time);
 
@@ -1136,7 +1163,7 @@ fn test_ctime() {
         os::setenv(~"TZ", ~"America/Los_Angeles");
         tzset();
 
-        let time = Timespec::new(1234567890, 54321);
+        let time = ::time::Timespec::new(1234567890, 54321);
         let utc   = at_utc(time);
         let local = at(time);
 
@@ -1152,7 +1179,7 @@ fn test_strftime() {
         os::setenv(~"TZ", ~"America/Los_Angeles");
         tzset();
 
-        let time = Timespec::new(1234567890, 54321);
+        let time = ::time::Timespec::new(1234567890, 54321);
         let utc = at_utc(time);
         let local = at(time);
 
index c3a2a11e1f840df1e7549da56679f8560e99cc92..18c623c2bd8ce8f24038e504238e621d767315ae 100644 (file)
 
 #[forbid(deprecated_mode)];
 
+use uv;
 use uv::iotask;
 use uv::iotask::IoTask;
 
+use core::either;
+use core::libc;
+use core::oldcomm;
+use core::prelude::*;
+use core::ptr;
+use core;
+
 /**
  * Wait for timeout period then send provided value over a channel
  *
@@ -32,7 +40,9 @@
  * * val - a value of type T to send over the provided `ch`
  */
 pub fn delayed_send<T: Owned>(iotask: IoTask,
-                                  msecs: uint, ch: oldcomm::Chan<T>, val: T) {
+                              msecs: uint,
+                              ch: oldcomm::Chan<T>,
+                              val: T) {
         unsafe {
             let timer_done_po = oldcomm::Port::<()>();
             let timer_done_ch = oldcomm::Chan(&timer_done_po);
@@ -108,8 +118,9 @@ pub fn sleep(iotask: IoTask, msecs: uint) {
  * be a `some(T)`. If not, then `none` will be returned.
  */
 pub fn recv_timeout<T: Copy Owned>(iotask: IoTask,
-                              msecs: uint,
-                              wait_po: oldcomm::Port<T>) -> Option<T> {
+                                   msecs: uint,
+                                   wait_po: oldcomm::Port<T>)
+                                -> Option<T> {
     let timeout_po = oldcomm::Port::<()>();
     let timeout_ch = oldcomm::Chan(&timeout_po);
     delayed_send(iotask, msecs, timeout_ch, ());
@@ -153,6 +164,17 @@ pub fn recv_timeout<T: Copy Owned>(iotask: IoTask,
 #[cfg(test)]
 mod test {
     #[legacy_exports];
+
+    use core::prelude::*;
+
+    use timer::*;
+    use uv;
+
+    use core::iter;
+    use core::oldcomm;
+    use core::rand;
+    use core::task;
+
     #[test]
     fn test_gl_timer_simple_sleep_test() {
         let hl_loop = uv::global_loop::get();
index e1874bd0bfd4931ae73883530ae1b087fda8993f..af3ab4b88eb68b29868fa405e41170ab1649947b 100644 (file)
@@ -18,8 +18,8 @@
 #[forbid(deprecated_mode)];
 
 use core::cmp::{Eq, Ord};
-use core::option::{Some, None};
-use Option = core::Option;
+use core::option::{Option, Some, None};
+use core::prelude::*;
 
 pub type TreeMap<K: Copy Eq Ord, V: Copy> = @mut TreeEdge<K, V>;
 
@@ -107,6 +107,11 @@ pub fn equals<K: Copy Eq Ord, V: Copy Eq>(t1: &const TreeEdge<K, V>,
 mod tests {
     #[legacy_exports];
 
+    use treemap::*;
+
+    use core::option::{None, Option, Some};
+    use core::str;
+
     #[test]
     fn init_treemap() { let _m = TreeMap::<int, int>(); }
 
index 732b20ec8f20c61cbac61af22c58e79d05e3d127..baf3610591a71bb53c5a244a5cf0ba37fca840e9 100644 (file)
@@ -160,13 +160,13 @@ pub mod icu {
     #[link_name = "icuuc"]
     #[abi = "cdecl"]
     pub extern mod libicu {
-        pure fn u_hasBinaryProperty(c: UChar32, which: UProperty) -> UBool;
-        pure fn u_isdigit(c: UChar32) -> UBool;
-        pure fn u_islower(c: UChar32) -> UBool;
-        pure fn u_isspace(c: UChar32) -> UBool;
-        pure fn u_isupper(c: UChar32) -> UBool;
-        pure fn u_tolower(c: UChar32) -> UChar32;
-        pure fn u_toupper(c: UChar32) -> UChar32;
+        unsafe fn u_hasBinaryProperty(c: UChar32, which: UProperty) -> UBool;
+        unsafe fn u_isdigit(c: UChar32) -> UBool;
+        unsafe fn u_islower(c: UChar32) -> UBool;
+        unsafe fn u_isspace(c: UChar32) -> UBool;
+        unsafe fn u_isupper(c: UChar32) -> UBool;
+        unsafe fn u_tolower(c: UChar32) -> UChar32;
+        unsafe fn u_toupper(c: UChar32) -> UChar32;
     }
 }
 
index 2efbfae3da4e26ee5d8f697de0a299c5b7641747..276cb9cab6431ddc4cee3ad1596226318c0f6091 100644 (file)
 use iotask = uv_iotask;
 use get_gl = get;
 use uv_iotask::{IoTask, spawn_iotask};
-use private::{chan_from_global_ptr, weaken_task};
+
+use core::either::{Left, Right};
+use core::libc;
 use core::oldcomm::{Port, Chan, select2, listen};
-use task::TaskBuilder;
-use either::{Left, Right};
+use core::private::{chan_from_global_ptr, weaken_task};
+use core::str;
+use core::task::TaskBuilder;
+use core::task;
+use core::vec;
 
 extern mod rustrt {
-    fn rust_uv_get_kernel_global_chan_ptr() -> *libc::uintptr_t;
+    unsafe fn rust_uv_get_kernel_global_chan_ptr() -> *libc::uintptr_t;
 }
 
 /**
@@ -118,6 +123,18 @@ fn spawn_loop() -> IoTask {
 
 #[cfg(test)]
 mod test {
+    use core::prelude::*;
+
+    use uv::iotask;
+    use uv::ll;
+    use uv_global_loop::*;
+
+    use core::iter;
+    use core::libc;
+    use core::oldcomm;
+    use core::ptr;
+    use core::task;
+
     extern fn simple_timer_close_cb(timer_ptr: *ll::uv_timer_t) unsafe {
         let exit_ch_ptr = ll::get_data_for_uv_handle(
             timer_ptr as *libc::c_void) as *oldcomm::Chan<bool>;
index d778606075d1a122dd6cf1b02575829414cf0e31..409d73c2539bbbbc2349717cd8a75302e6fbc17e 100644 (file)
  */
 #[forbid(deprecated_mode)];
 
-use libc::c_void;
-use ptr::addr_of;
-use core::oldcomm::{Port, Chan, listen};
-use task::TaskBuilder;
 use ll = uv_ll;
 
+use core::libc::c_void;
+use core::libc;
+use core::oldcomm::{Port, Chan, listen};
+use core::prelude::*;
+use core::ptr::addr_of;
+use core::task::TaskBuilder;
+use core::task;
+
 /// Used to abstract-away direct interaction with a libuv loop.
 pub enum IoTask {
     IoTask_({
@@ -173,6 +177,17 @@ fn begin_teardown(data: *IoTaskLoopData) unsafe {
 
 #[cfg(test)]
 mod test {
+    use core::prelude::*;
+
+    use uv::ll;
+    use uv_iotask::*;
+
+    use core::iter;
+    use core::libc;
+    use core::oldcomm;
+    use core::ptr;
+    use core::task;
+
     extern fn async_close_cb(handle: *ll::uv_async_t) unsafe {
         log(debug, fmt!("async_close_cb handle %?", handle));
         let exit_ch = (*(ll::get_data_for_uv_handle(handle)
index 65333b41864e52813d01913622b18bfbeef24226..eee3d60a66d6cf6664f30071bdc20d97d36fde07 100644 (file)
 
 #[allow(non_camel_case_types)]; // C types
 
-use libc::size_t;
-use ptr::to_unsafe_ptr;
+use core::libc::size_t;
+use core::libc;
+use core::prelude::*;
+use core::ptr::to_unsafe_ptr;
+use core::ptr;
+use core::str;
+use core::vec;
 
 // libuv struct mappings
 pub type uv_ip4_addr = {
@@ -104,6 +109,7 @@ pub enum uv_handle_type {
     a29: *u8
 };
 #[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
 pub type uv_tcp_t_32bit_unix_riders = {
     a29: *u8, a30: *u8, a31: *u8,
     a32: *u8, a33: *u8, a34: *u8,
@@ -160,6 +166,7 @@ pub enum uv_handle_type {
     a13: *u8
 };
 #[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
 pub type uv_write_t_32bit_unix_riders = {
     a13: *u8, a14: *u8
 };
@@ -187,6 +194,7 @@ pub enum uv_handle_type {
     a10: *u8
 };
 #[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
 pub type uv_async_t_32bit_unix_riders = {
     a10: *u8, a11: *u8, a12: *u8, a13: *u8
 };
@@ -215,6 +223,7 @@ pub enum uv_handle_type {
     a10: *u8, a11: *u8
 };
 #[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
 pub type uv_timer_t_32bit_unix_riders = {
     a10: *u8, a11: *u8, a12: *u8, a13: *u8,
     a14: *u8, a15: *u8, a16: *u8
@@ -244,6 +253,7 @@ pub enum uv_handle_type {
     a2: *u8, a3: *u8
 };
 #[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
 pub type sockaddr_in6 = {
     a0: *u8, a1: *u8,
     a2: *u8, a3: *u8,
@@ -262,6 +272,7 @@ pub mod addr_in_impl {
         a2: *u8, a3: *u8
     };
     #[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
     pub type addr_in = {
         a0: *u8, a1: *u8,
         a2: *u8, a3: *u8,
@@ -280,6 +291,7 @@ pub mod addr_in_impl {
 // unix size: 48, 32bit: 32
 pub type addrinfo = addrinfo_impl::addrinfo;
 #[cfg(target_os="linux")]
+#[cfg(target_os="android")]
 pub mod addrinfo_impl {
     #[cfg(target_arch="x86_64")]
     pub type addrinfo = {
@@ -287,6 +299,7 @@ pub mod addrinfo_impl {
         a04: *u8, a05: *u8
     };
     #[cfg(target_arch="x86")]
+    #[cfg(target_arch="arm")]
     pub type addrinfo = {
         a00: *u8, a01: *u8, a02: *u8, a03: *u8,
         a04: *u8, a05: *u8, a06: *u8, a07: *u8
@@ -315,9 +328,15 @@ pub mod addrinfo_impl {
 };
 
 pub mod uv_ll_struct_stubgen {
+    use uv_ll::{uv_async_t, uv_connect_t, uv_getaddrinfo_t, uv_tcp_t};
+    use uv_ll::{uv_timer_t, uv_write_t};
+
+    use core::ptr;
+
     pub fn gen_stub_uv_tcp_t() -> uv_tcp_t {
         return gen_stub_os();
         #[cfg(target_os = "linux")]
+        #[cfg(target_os = "android")]
         #[cfg(target_os = "macos")]
         #[cfg(target_os = "freebsd")]
         pub fn gen_stub_os() -> uv_tcp_t {
@@ -348,6 +367,7 @@ pub fn gen_stub_arch() -> uv_tcp_t {
                 };
             }
             #[cfg(target_arch="x86")]
+            #[cfg(target_arch="arm")]
             pub fn gen_stub_arch() -> uv_tcp_t {
                 return { fields: { loop_handle: ptr::null(), type_: 0u32,
                                 close_cb: ptr::null(),
@@ -433,6 +453,7 @@ pub fn gen_stub_arch() -> uv_async_t {
             };
         }
         #[cfg(target_arch = "x86")]
+        #[cfg(target_arch="arm")]
         pub fn gen_stub_arch() -> uv_async_t {
             return { fields: { loop_handle: ptr::null(), type_: 0u32,
                             close_cb: ptr::null(),
@@ -482,6 +503,7 @@ pub fn gen_stub_arch() -> uv_timer_t {
             };
         }
         #[cfg(target_arch = "x86")]
+        #[cfg(target_arch="arm")]
         pub fn gen_stub_arch() -> uv_timer_t {
             return { fields: { loop_handle: ptr::null(), type_: 0u32,
                             close_cb: ptr::null(),
@@ -531,6 +553,7 @@ pub fn gen_stub_arch() -> uv_write_t {
             };
         }
         #[cfg(target_arch="x86")]
+        #[cfg(target_arch="arm")]
         pub fn gen_stub_arch() -> uv_write_t {
             return { fields: { loop_handle: ptr::null(), type_: 0u32,
                             close_cb: ptr::null(),
@@ -571,127 +594,142 @@ pub fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t {
 #[nolink]
 extern mod rustrt {
     // libuv public API
-    fn rust_uv_loop_new() -> *libc::c_void;
-    fn rust_uv_loop_delete(lp: *libc::c_void);
-    fn rust_uv_loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int;
-    fn rust_uv_run(loop_handle: *libc::c_void);
-    fn rust_uv_close(handle: *libc::c_void, cb: *u8);
-    fn rust_uv_async_send(handle: *uv_async_t);
-    fn rust_uv_async_init(loop_handle: *libc::c_void,
+    unsafe fn rust_uv_loop_new() -> *libc::c_void;
+    unsafe fn rust_uv_loop_delete(lp: *libc::c_void);
+    unsafe fn rust_uv_loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int;
+    unsafe fn rust_uv_run(loop_handle: *libc::c_void);
+    unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8);
+    unsafe fn rust_uv_async_send(handle: *uv_async_t);
+    unsafe fn rust_uv_async_init(loop_handle: *libc::c_void,
                           async_handle: *uv_async_t,
                           cb: *u8) -> libc::c_int;
-    fn rust_uv_tcp_init(
+    unsafe fn rust_uv_tcp_init(
         loop_handle: *libc::c_void,
         handle_ptr: *uv_tcp_t) -> libc::c_int;
     // FIXME ref #2604 .. ?
-    fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
+    unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
                         len: libc::size_t);
-    fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
+    unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
     // FIXME ref #2064
-    fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
+    unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
     // FIXME ref #2064
-    fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
-    fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
+    unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
+    unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
         -> sockaddr_in;
-    fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
+    unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
         -> sockaddr_in6;
-    fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: libc::size_t)
-        -> libc::c_int;
-    fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: libc::size_t)
-        -> libc::c_int;
-    fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
-    fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
+    unsafe fn rust_uv_ip4_name(src: *sockaddr_in,
+                               dst: *u8,
+                               size: libc::size_t)
+                            -> libc::c_int;
+    unsafe fn rust_uv_ip6_name(src: *sockaddr_in6,
+                               dst: *u8,
+                               size: libc::size_t)
+                            -> libc::c_int;
+    unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
+    unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
     // FIXME ref #2064
-    fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
-                           tcp_handle_ptr: *uv_tcp_t,
-                           ++after_cb: *u8,
-                           ++addr: *sockaddr_in) -> libc::c_int;
+    unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
+                                  tcp_handle_ptr: *uv_tcp_t,
+                                  ++after_cb: *u8,
+                                  ++addr: *sockaddr_in) -> libc::c_int;
     // FIXME ref #2064
-    fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
-                        ++addr: *sockaddr_in) -> libc::c_int;
+    unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
+                               ++addr: *sockaddr_in) -> libc::c_int;
     // FIXME ref #2064
-    fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
-                           tcp_handle_ptr: *uv_tcp_t,
-                           ++after_cb: *u8,
-                           ++addr: *sockaddr_in6) -> libc::c_int;
+    unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
+                                   tcp_handle_ptr: *uv_tcp_t,
+                                   ++after_cb: *u8,
+                                   ++addr: *sockaddr_in6) -> libc::c_int;
     // FIXME ref #2064
-    fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
-                        ++addr: *sockaddr_in6) -> libc::c_int;
-    fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
-                               ++name: *sockaddr_in) -> libc::c_int;
-    fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
-                                ++name: *sockaddr_in6) ->libc::c_int;
-    fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int,
-                      cb: *u8) -> libc::c_int;
-    fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
-        -> libc::c_int;
-    fn rust_uv_write(req: *libc::c_void, stream: *libc::c_void,
-             ++buf_in: *uv_buf_t, buf_cnt: libc::c_int,
-             cb: *u8) -> libc::c_int;
-    fn rust_uv_read_start(stream: *libc::c_void, on_alloc: *u8,
-                          on_read: *u8) -> libc::c_int;
-    fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
-    fn rust_uv_timer_init(loop_handle: *libc::c_void,
-                          timer_handle: *uv_timer_t) -> libc::c_int;
-    fn rust_uv_timer_start(
+    unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
+                                ++addr: *sockaddr_in6) -> libc::c_int;
+    unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
+                                      ++name: *sockaddr_in) -> libc::c_int;
+    unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
+                                       ++name: *sockaddr_in6) ->libc::c_int;
+    unsafe fn rust_uv_listen(stream: *libc::c_void,
+                             backlog: libc::c_int,
+                             cb: *u8) -> libc::c_int;
+    unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
+                          -> libc::c_int;
+    unsafe fn rust_uv_write(req: *libc::c_void,
+                            stream: *libc::c_void,
+                            ++buf_in: *uv_buf_t,
+                            buf_cnt: libc::c_int,
+                            cb: *u8)
+                         -> libc::c_int;
+    unsafe fn rust_uv_read_start(stream: *libc::c_void,
+                                 on_alloc: *u8,
+                                 on_read: *u8)
+                              -> libc::c_int;
+    unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
+    unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void,
+                                 timer_handle: *uv_timer_t)
+                              -> libc::c_int;
+    unsafe fn rust_uv_timer_start(
         timer_handle: *uv_timer_t,
         cb: *u8,
         timeout: libc::c_uint,
         repeat: libc::c_uint) -> libc::c_int;
-    fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
-
-    fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
-                           handle: *uv_getaddrinfo_t,
-                           cb: *u8,
-                           node_name_ptr: *u8,
-                           service_name_ptr: *u8,
-                           // should probably only pass ptr::null()
-                           hints: *addrinfo) -> libc::c_int;
-    fn rust_uv_freeaddrinfo(res: *addrinfo);
+    unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
+
+    unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
+                                  handle: *uv_getaddrinfo_t,
+                                  cb: *u8,
+                                  node_name_ptr: *u8,
+                                  service_name_ptr: *u8,
+                                  // should probably only pass ptr::null()
+                                  hints: *addrinfo)
+                               -> libc::c_int;
+    unsafe fn rust_uv_freeaddrinfo(res: *addrinfo);
 
     // data accessors/helpers for rust-mapped uv structs
-    fn rust_uv_helper_get_INADDR_NONE() -> u32;
-    fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
-    fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
-    fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
-    fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in;
-    fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6;
-    fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
-    fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
-    fn rust_uv_get_stream_handle_from_connect_req(
+    unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32;
+    unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
+    unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
+    unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
+    unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo)
+                                           -> *sockaddr_in;
+    unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo)
+                                            -> *sockaddr_in6;
+    unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
+    unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
+    unsafe fn rust_uv_get_stream_handle_from_connect_req(
         connect_req: *uv_connect_t)
         -> *uv_stream_t;
-    fn rust_uv_get_stream_handle_from_write_req(
+    unsafe fn rust_uv_get_stream_handle_from_write_req(
         write_req: *uv_write_t)
         -> *uv_stream_t;
-    fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
-        -> *libc::c_void;
-    fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void) -> *libc::c_void;
-    fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void,
-                                    data: *libc::c_void);
-    fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
+    unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
         -> *libc::c_void;
-    fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
-                                      data: *libc::c_void);
-    fn rust_uv_get_data_for_req(req: *libc::c_void) -> *libc::c_void;
-    fn rust_uv_set_data_for_req(req: *libc::c_void,
-                                data: *libc::c_void);
-    fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
-    fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
+    unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void)
+                                        -> *libc::c_void;
+    unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void,
+                                           data: *libc::c_void);
+    unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
+                                          -> *libc::c_void;
+    unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
+                                             data: *libc::c_void);
+    unsafe fn rust_uv_get_data_for_req(req: *libc::c_void) -> *libc::c_void;
+    unsafe fn rust_uv_set_data_for_req(req: *libc::c_void,
+                                       data: *libc::c_void);
+    unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
+    unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
 
     // sizeof testing helpers
-    fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
-    fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
-    fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
-    fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
-    fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
-    fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
-    fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
-    fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
-    fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
-    fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
-    fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
-    fn rust_uv_helper_addr_in_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
+    unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint;
 }
 
 pub unsafe fn loop_new() -> *libc::c_void {
@@ -1034,6 +1072,17 @@ pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
 
 #[cfg(test)]
 pub mod test {
+    use core::prelude::*;
+
+    use uv_ll::*;
+
+    use core::libc;
+    use core::oldcomm;
+    use core::ptr;
+    use core::str;
+    use core::sys;
+    use core::task;
+    use core::vec;
 
     enum tcp_read_data {
         tcp_read_eof,
@@ -1535,16 +1584,20 @@ fn impl_uv_tcp_server_and_request() unsafe {
     #[cfg(target_os="win32")]
     #[cfg(target_os="darwin")]
     #[cfg(target_os="linux")]
+    #[cfg(target_os="android")]
     pub mod tcp_and_server_client_test {
         #[cfg(target_arch="x86_64")]
         pub mod impl64 {
+            use uv_ll::test::*;
             #[test]
             pub fn test_uv_ll_tcp_server_and_request() unsafe {
                 impl_uv_tcp_server_and_request();
             }
         }
         #[cfg(target_arch="x86")]
+        #[cfg(target_arch="arm")]
         pub mod impl32 {
+            use uv_ll::test::*;
             #[test]
             #[ignore(cfg(target_os = "linux"))]
             pub fn test_uv_ll_tcp_server_and_request() unsafe {
@@ -1556,124 +1609,148 @@ pub fn test_uv_ll_tcp_server_and_request() unsafe {
     // struct size tests
     #[test]
     fn test_uv_ll_struct_size_uv_tcp_t() {
-        let foreign_handle_size = rustrt::rust_uv_helper_uv_tcp_t_size();
-        let rust_handle_size = sys::size_of::<uv_tcp_t>();
-        let output = fmt!("uv_tcp_t -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        assert foreign_handle_size as uint == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_uv_tcp_t_size();
+            let rust_handle_size = sys::size_of::<uv_tcp_t>();
+            let output = fmt!("uv_tcp_t -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            assert foreign_handle_size as uint == rust_handle_size;
+        }
     }
     #[test]
     fn test_uv_ll_struct_size_uv_connect_t() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_uv_connect_t_size();
-        let rust_handle_size = sys::size_of::<uv_connect_t>();
-        let output = fmt!("uv_connect_t -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        assert foreign_handle_size as uint == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_uv_connect_t_size();
+            let rust_handle_size = sys::size_of::<uv_connect_t>();
+            let output = fmt!("uv_connect_t -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            assert foreign_handle_size as uint == rust_handle_size;
+        }
     }
     #[test]
     fn test_uv_ll_struct_size_uv_buf_t() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_uv_buf_t_size();
-        let rust_handle_size = sys::size_of::<uv_buf_t>();
-        let output = fmt!("uv_buf_t -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        assert foreign_handle_size as uint == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_uv_buf_t_size();
+            let rust_handle_size = sys::size_of::<uv_buf_t>();
+            let output = fmt!("uv_buf_t -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            assert foreign_handle_size as uint == rust_handle_size;
+        }
     }
     #[test]
     fn test_uv_ll_struct_size_uv_write_t() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_uv_write_t_size();
-        let rust_handle_size = sys::size_of::<uv_write_t>();
-        let output = fmt!("uv_write_t -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        assert foreign_handle_size as uint == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_uv_write_t_size();
+            let rust_handle_size = sys::size_of::<uv_write_t>();
+            let output = fmt!("uv_write_t -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            assert foreign_handle_size as uint == rust_handle_size;
+        }
     }
 
     #[test]
     fn test_uv_ll_struct_size_sockaddr_in() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_sockaddr_in_size();
-        let rust_handle_size = sys::size_of::<sockaddr_in>();
-        let output = fmt!("sockaddr_in -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        assert foreign_handle_size as uint == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_sockaddr_in_size();
+            let rust_handle_size = sys::size_of::<sockaddr_in>();
+            let output = fmt!("sockaddr_in -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            assert foreign_handle_size as uint == rust_handle_size;
+        }
     }
     #[test]
     fn test_uv_ll_struct_size_sockaddr_in6() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_sockaddr_in6_size();
-        let rust_handle_size = sys::size_of::<sockaddr_in6>();
-        let output = fmt!("sockaddr_in6 -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        // FIXME #1645 .. rust appears to pad structs to the nearest byte..?
-        // .. can't get the uv::ll::sockaddr_in6 to == 28 :/
-        // .. so the type always appears to be 32 in size.. which is
-        // good, i guess.. better too big than too little
-        assert (4u+foreign_handle_size as uint) == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_sockaddr_in6_size();
+            let rust_handle_size = sys::size_of::<sockaddr_in6>();
+            let output = fmt!("sockaddr_in6 -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            // FIXME #1645 .. rust appears to pad structs to the nearest
+            // byte..?
+            // .. can't get the uv::ll::sockaddr_in6 to == 28 :/
+            // .. so the type always appears to be 32 in size.. which is
+            // good, i guess.. better too big than too little
+            assert (4u+foreign_handle_size as uint) == rust_handle_size;
+        }
     }
     #[test]
     #[ignore(reason = "questionable size calculations")]
     fn test_uv_ll_struct_size_addr_in() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_addr_in_size();
-        let rust_handle_size = sys::size_of::<addr_in>();
-        let output = fmt!("addr_in -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        // FIXME #1645 .. see note above about struct padding
-        assert (4u+foreign_handle_size as uint) == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_addr_in_size();
+            let rust_handle_size = sys::size_of::<addr_in>();
+            let output = fmt!("addr_in -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            // FIXME #1645 .. see note above about struct padding
+            assert (4u+foreign_handle_size as uint) == rust_handle_size;
+        }
     }
 
     #[test]
     fn test_uv_ll_struct_size_uv_async_t() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_uv_async_t_size();
-        let rust_handle_size = sys::size_of::<uv_async_t>();
-        let output = fmt!("uv_async_t -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        assert foreign_handle_size as uint == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_uv_async_t_size();
+            let rust_handle_size = sys::size_of::<uv_async_t>();
+            let output = fmt!("uv_async_t -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            assert foreign_handle_size as uint == rust_handle_size;
+        }
     }
 
     #[test]
     fn test_uv_ll_struct_size_uv_timer_t() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_uv_timer_t_size();
-        let rust_handle_size = sys::size_of::<uv_timer_t>();
-        let output = fmt!("uv_timer_t -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        assert foreign_handle_size as uint == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_uv_timer_t_size();
+            let rust_handle_size = sys::size_of::<uv_timer_t>();
+            let output = fmt!("uv_timer_t -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            assert foreign_handle_size as uint == rust_handle_size;
+        }
     }
 
     #[test]
     #[ignore(cfg(target_os = "win32"))]
     fn test_uv_ll_struct_size_uv_getaddrinfo_t() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_uv_getaddrinfo_t_size();
-        let rust_handle_size = sys::size_of::<uv_getaddrinfo_t>();
-        let output = fmt!("uv_getaddrinfo_t -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        assert foreign_handle_size as uint == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_uv_getaddrinfo_t_size();
+            let rust_handle_size = sys::size_of::<uv_getaddrinfo_t>();
+            let output = fmt!("uv_getaddrinfo_t -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            assert foreign_handle_size as uint == rust_handle_size;
+        }
     }
     #[test]
     #[ignore(cfg(target_os = "macos"))]
     #[ignore(cfg(target_os = "win32"))]
     fn test_uv_ll_struct_size_addrinfo() {
-        let foreign_handle_size =
-            rustrt::rust_uv_helper_addrinfo_size();
-        let rust_handle_size = sys::size_of::<addrinfo>();
-        let output = fmt!("addrinfo -- foreign: %u rust: %u",
-                          foreign_handle_size as uint, rust_handle_size);
-        log(debug, output);
-        assert foreign_handle_size as uint == rust_handle_size;
+        unsafe {
+            let foreign_handle_size =
+                ::uv_ll::rustrt::rust_uv_helper_addrinfo_size();
+            let rust_handle_size = sys::size_of::<addrinfo>();
+            let output = fmt!("addrinfo -- foreign: %u rust: %u",
+                              foreign_handle_size as uint, rust_handle_size);
+            log(debug, output);
+            assert foreign_handle_size as uint == rust_handle_size;
+        }
     }
 }
index 4d49e98a8b7ec7a3bba244f7904105e90965e803..6b35f3af29a0742a7d3273e5f1efd0cf43b63ae0 100644 (file)
@@ -8,15 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::cmp::Eq;
-use send_map::linear::LinearMap;
-use pipes::{recv, oneshot, PortOne, send_one};
-use either::{Right,Left,Either};
-
 use json;
 use sha1;
 use serialize::{Encoder, Encodable, Decoder, Decodable};
 
+use core::either::{Either, Left, Right};
+use core::io;
+use core::option;
+use core::pipes::{recv, oneshot, PortOne, send_one};
+use core::prelude::*;
+use core::result;
+use core::run;
+use core::send_map::linear::LinearMap;
+use core::task;
+use core::to_bytes;
+
 /**
 *
 * This is a loose clone of the fbuild build system, made a touch more
@@ -102,7 +108,7 @@ impl WorkKey {
 type WorkMap = LinearMap<WorkKey, ~str>;
 
 struct Database {
-    // XXX: Fill in.
+    // FIXME #4432: Fill in.
     a: ()
 }
 
@@ -111,7 +117,7 @@ impl Database {
                     _declared_inputs: &const WorkMap,
                     _declared_outputs: &const WorkMap) ->
         Option<(WorkMap, WorkMap, ~str)> {
-        // XXX: load
+        // FIXME #4432: load
         None
     }
     pure fn cache(_fn_name: &str,
@@ -120,12 +126,12 @@ impl Database {
                   _discovered_inputs: &WorkMap,
                   _discovered_outputs: &WorkMap,
                   _result: &str) {
-        // XXX: store
+        // FIXME #4432: store
     }
 }
 
 struct Logger {
-    // XXX: Fill in
+    // FIXME #4432: Fill in
     a: ()
 }
 
@@ -165,7 +171,7 @@ fn digest<T:Encodable<json::Encoder>
             Decodable<json::Decoder>>(t: &T) -> ~str {
     let sha = sha1::sha1();
     let s = do io::with_str_writer |wr| {
-        // XXX: sha1 should be a writer itself, shouldn't
+        // FIXME #4432: sha1 should be a writer itself, shouldn't
         // go via strings.
         t.encode(&json::Encoder(wr));
     };
@@ -327,6 +333,7 @@ fn unwrap<T:Owned
 #[test]
 fn test() {
     use io::WriterUtil;
+
     let db = @Database { a: () };
     let lg = @Logger { a: () };
     let cfg = @LinearMap();
index da49340e24adf0fb5c63e9db7185b31e23cbbb4a..2cd873414c44a79504903d2eeac701380f446fb3 100644 (file)
 
 // The Rust abstract syntax tree.
 
-use std::serialize::{Encodable, Decodable, Encoder, Decoder};
+use ast;
 use codemap::{span, FileName};
-use parse::token;
+
+use core::cast;
+use core::cmp;
+use core::option::{None, Option, Some};
+use core::ptr;
+use core::task;
+use core::to_bytes;
+use core::to_str::ToStr;
+use std::serialize::{Encodable, Decodable, Encoder, Decoder};
 
 #[auto_encode]
 #[auto_decode]
-type spanned<T> = {node: T, span: span};
-
+struct spanned<T> { node: T, span: span }
 
 /* can't import macros yet, so this is copied from token.rs. See its comment
  * there. */
 macro_rules! interner_key (
-    () => (cast::transmute::<(uint, uint), &fn(+v: @@token::ident_interner)>(
+    () => (cast::transmute::<(uint, uint),
+            &fn(+v: @@::parse::token::ident_interner)>(
         (-3 as uint, 0u)))
 )
 
@@ -102,7 +110,10 @@ impl def_id : cmp::Eq {
 // typeck::collect::compute_bounds matches these against
 // the "special" built-in traits (see middle::lang_items) and
 // detects Copy, Send, Owned, and Const.
-enum ty_param_bound = @Ty;
+enum ty_param_bound {
+    TraitTyParamBound(@Ty),
+    RegionTyParamBound
+}
 
 #[auto_encode]
 #[auto_decode]
@@ -408,6 +419,7 @@ impl mutability : cmp::Eq {
 
 #[auto_encode]
 #[auto_decode]
+#[deriving_eq]
 pub enum Proto {
     ProtoBare,     // bare functions (deprecated)
     ProtoUniq,     // ~fn
@@ -415,13 +427,6 @@ pub enum Proto {
     ProtoBorrowed, // &fn
 }
 
-impl Proto : cmp::Eq {
-    pure fn eq(&self, other: &Proto) -> bool {
-        ((*self) as uint) == ((*other) as uint)
-    }
-    pure fn ne(&self, other: &Proto) -> bool { !(*self).eq(other) }
-}
-
 impl Proto : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
         (*self as uint).iter_bytes(lsb0, f);
@@ -761,10 +766,10 @@ enum expr_ {
 #[auto_decode]
 #[doc="For macro invocations; parsing is delegated to the macro"]
 enum token_tree {
-    tt_tok(span, token::Token),
+    tt_tok(span, ::parse::token::Token),
     tt_delim(~[token_tree]),
     // These only make sense for right-hand-sides of MBE macros
-    tt_seq(span, ~[token_tree], Option<token::Token>, bool),
+    tt_seq(span, ~[token_tree], Option<::parse::token::Token>, bool),
     tt_nonterminal(span, ident)
 }
 
@@ -826,10 +831,10 @@ enum token_tree {
 #[auto_decode]
 enum matcher_ {
     // match one token
-    match_tok(token::Token),
+    match_tok(::parse::token::Token),
     // match repetitions of a sequence: body, separator, zero ok?,
     // lo, hi position-in-match-array used:
-    match_seq(~[matcher], Option<token::Token>, bool, uint, uint),
+    match_seq(~[matcher], Option<::parse::token::Token>, bool, uint, uint),
     // parse a Rust NT: name to bind, name of NT, position in match array:
     match_nonterminal(ident, ident, uint)
 }
@@ -1061,20 +1066,24 @@ enum region_ {
 
 #[auto_encode]
 #[auto_decode]
+#[deriving_eq]
 enum Onceness {
     Once,
     Many
 }
 
-impl Onceness : cmp::Eq {
-    pure fn eq(&self, other: &Onceness) -> bool {
-        match ((*self), *other) {
-            (Once, Once) | (Many, Many) => true,
-            _ => false
+impl Onceness : ToStr {
+    pure fn to_str() -> ~str {
+        match self {
+            ast::Once => ~"once",
+            ast::Many => ~"many"
         }
     }
-    pure fn ne(&self, other: &Onceness) -> bool {
-        !(*self).eq(other)
+}
+
+impl Onceness : to_bytes::IterBytes {
+    pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
+        (*self as uint).iter_bytes(lsb0, f);
     }
 }
 
@@ -1142,13 +1151,24 @@ impl Ty : to_bytes::IterBytes {
 
 #[auto_encode]
 #[auto_decode]
-enum purity {
+pub enum purity {
     pure_fn, // declared with "pure fn"
     unsafe_fn, // declared with "unsafe fn"
     impure_fn, // declared with "fn"
     extern_fn, // declared with "extern fn"
 }
 
+impl purity : ToStr {
+    pure fn to_str() -> ~str {
+        match self {
+            impure_fn => ~"impure",
+            unsafe_fn => ~"unsafe",
+            pure_fn => ~"pure",
+            extern_fn => ~"extern"
+        }
+    }
+}
+
 impl purity : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
         (*self as u8).iter_bytes(lsb0, f)
index 6e684d0daf4f32262acc9be2a9b46f09cbda152f..fffed43e5f1deda0ffc00f9536ae24bf7e7dbe23 100644 (file)
@@ -8,13 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::map;
-use std::map::HashMap;
+use core::prelude::*;
+
 use ast::*;
-use print::pprust;
+use ast;
 use ast_util::{path_to_ident, stmt_id};
+use ast_util;
+use attr;
+use codemap;
 use diagnostic::span_handler;
 use parse::token::ident_interner;
+use print::pprust;
+use visit;
+
+use core::cmp;
+use core::either;
+use core::str;
+use core::vec;
+use std::map::HashMap;
+use std::map;
+use std;
 
 enum path_elt {
     path_mod(ident),
@@ -67,6 +80,13 @@ fn path_to_str(p: path, itr: @ident_interner) -> ~str {
     path_to_str_with_sep(p, ~"::", itr)
 }
 
+fn path_elt_to_str(pe: path_elt, itr: @ident_interner) -> ~str {
+    match pe {
+        path_mod(s) => *itr.get(s),
+        path_name(s) => *itr.get(s)
+    }
+}
+
 enum ast_node {
     node_item(@item, @path),
     node_foreign_item(@foreign_item, foreign_abi, @path),
@@ -97,7 +117,7 @@ fn extend(cx: ctx, +elt: ident) -> @path {
 }
 
 fn mk_ast_map_visitor() -> vt {
-    return visit::mk_vt(@{
+    return visit::mk_vt(@visit::Visitor {
         visit_item: map_item,
         visit_expr: map_expr,
         visit_stmt: map_stmt,
@@ -163,12 +183,15 @@ fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
         cx.local_id += 1u;
     }
     match fk {
-      visit::fk_dtor(tps, ref attrs, self_id, parent_id) => {
-          let dt = @{node: {id: id, attrs: (*attrs), self_id: self_id,
-                     body: /* FIXME (#2543) */ copy body}, span: sp};
-          cx.map.insert(id, node_dtor(/* FIXME (#2543) */ copy tps, dt,
-                                      parent_id,
-                                      @/* FIXME (#2543) */ copy cx.path));
+        visit::fk_dtor(tps, ref attrs, self_id, parent_id) => {
+            let dt = @spanned {
+                node: {id: id, attrs: (*attrs), self_id: self_id,
+                     body: /* FIXME (#2543) */ copy body},
+                span: sp,
+            };
+            cx.map.insert(id, node_dtor(/* FIXME (#2543) */ copy tps, dt,
+                                        parent_id,
+                                        @/* FIXME (#2543) */ copy cx.path));
       }
       _ => ()
     }
index 521114bf2973aba8303ea09f81110fd445d09d57..898c89ff2c8b2bff87483f6d1140885665ec4db1 100644 (file)
@@ -8,15 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use codemap::{span, BytePos};
+use core::prelude::*;
+
 use ast::*;
+use ast;
+use ast_util;
+use codemap::{span, BytePos};
+use parse::token;
+use visit;
+
+use core::cmp;
+use core::int;
+use core::option;
+use core::str;
+use core::to_bytes;
+use core::vec;
 
 pure fn spanned<T>(+lo: BytePos, +hi: BytePos, +t: T) -> spanned<T> {
     respan(mk_sp(lo, hi), move t)
 }
 
 pure fn respan<T>(sp: span, +t: T) -> spanned<T> {
-    {node: move t, span: sp}
+    spanned {node: t, span: sp}
 }
 
 pure fn dummy_spanned<T>(+t: T) -> spanned<T> {
@@ -33,7 +46,7 @@
 
 
 
-pure fn path_name_i(idents: ~[ident], intr: @token::ident_interner) -> ~str {
+pure fn path_name_i(idents: &[ident], intr: @token::ident_interner) -> ~str {
     // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
     str::connect(idents.map(|i| *intr.get(*i)), ~"::")
 }
@@ -262,16 +275,16 @@ fn is_exported(i: ident, m: _mod) -> bool {
 }
 
 // This makes def_id hashable
-impl def_id : core::to_bytes::IterBytes {
+impl def_id : to_bytes::IterBytes {
     #[inline(always)]
-    pure fn iter_bytes(&self, +lsb0: bool, f: core::to_bytes::Cb) {
-        core::to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f);
+    pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
+        to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f);
     }
 }
 
 fn block_from_expr(e: @expr) -> blk {
     let blk_ = default_block(~[], option::Some::<@expr>(e), e.id);
-    return {node: blk_, span: e.span};
+    return spanned {node: blk_, span: e.span};
 }
 
 fn default_block(+stmts1: ~[@stmt], expr1: Option<@expr>, id1: node_id) ->
@@ -303,11 +316,12 @@ fn ident_to_pat(id: node_id, s: span, +i: ident) -> @pat {
 }
 
 fn public_methods(ms: ~[@method]) -> ~[@method] {
-    vec::filter(ms,
-                |m| match m.vis {
-                    public => true,
-                    _   => false
-                })
+    do ms.filtered |m| {
+        match m.vis {
+            public => true,
+            _   => false
+        }
+    }
 }
 
 // extract a ty_method from a trait_method. if the trait_method is
@@ -426,10 +440,8 @@ fn empty(range: id_range) -> bool {
 }
 
 fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> {
-    visit::mk_simple_visitor(@{
-        visit_mod: fn@(_m: _mod, _sp: span, id: node_id) {
-            vfn(id)
-        },
+    visit::mk_simple_visitor(@visit::SimpleVisitor {
+        visit_mod: |_m, _sp, id| vfn(id),
 
         visit_view_item: fn@(vi: @view_item) {
             match vi.node {
index aadea886407cd20d4b42cfc817db2dd3824143f4..f80ef965d1ef33f4f561de45cbd2f84098bd878c 100644 (file)
 
 // Functions dealing with attributes and meta_items
 
-use std::map;
-use std::map::HashMap;
-use either::Either;
-use diagnostic::span_handler;
+use core::prelude::*;
+
+use ast;
 use ast_util::{spanned, dummy_spanned};
-use parse::comments::{doc_comment_style, strip_doc_comment_decoration};
+use attr;
 use codemap::BytePos;
+use diagnostic::span_handler;
+use parse::comments::{doc_comment_style, strip_doc_comment_decoration};
+
+use core::cmp;
+use core::either::Either;
+use core::either;
+use core::option;
+use core::vec;
+use std::map::HashMap;
+use std::map;
+use std;
 
 // Constructors
 export mk_name_value_item_str;
@@ -170,15 +180,15 @@ fn get_name_value_str_pair(item: @ast::meta_item) -> Option<(~str, ~str)> {
 /* Searching */
 
 /// Search a list of attributes and return only those with a specific name
-fn find_attrs_by_name(attrs: ~[ast::attribute], name: ~str) ->
+fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) ->
    ~[ast::attribute] {
-    let filter = (
-        fn@(a: &ast::attribute) -> Option<ast::attribute> {
-            if get_attr_name(*a) == name {
-                option::Some(*a)
-            } else { option::None }
+    let filter: &fn(a: &ast::attribute) -> Option<ast::attribute> = |a| {
+        if name == get_attr_name(*a) {
+            option::Some(*a)
+        } else {
+            option::None
         }
-    );
+    };
     return vec::filter_map(attrs, filter);
 }
 
@@ -232,7 +242,7 @@ fn contains_name(metas: ~[@ast::meta_item], name: ~str) -> bool {
     return vec::len(matches) > 0u;
 }
 
-fn attrs_contains_name(attrs: ~[ast::attribute], name: ~str) -> bool {
+fn attrs_contains_name(attrs: &[ast::attribute], name: &str) -> bool {
     vec::is_not_empty(find_attrs_by_name(attrs, name))
 }
 
index 974455972f15e1d4957255c7e6743f4437908fbc..1e4a40405fd3ae0af9a2bed02a5a1ae8165656ea 100644 (file)
 
 */
 
-use dvec::DVec;
+use core::prelude::*;
+
+use ast_util;
+
+use core::cmp;
+use core::dvec::DVec;
+use core::str;
+use core::to_bytes;
+use core::uint;
+use core::vec;
 use std::serialize::{Encodable, Decodable, Encoder, Decoder};
 
 trait Pos {
@@ -308,6 +317,10 @@ pub fn adjust_span(&self, sp: span) -> span {
     }
 
     pub fn span_to_str(&self, sp: span) -> ~str {
+        if self.files.len() == 0 && sp == ast_util::dummy_sp() {
+            return ~"no-location";
+        }
+
         let lo = self.lookup_char_pos_adj(sp.lo);
         let hi = self.lookup_char_pos_adj(sp.hi);
         return fmt!("%s:%u:%u: %u:%u", lo.filename,
index e42bb00c2129d1b429390d3ba745d1d9a0a78bd6..7e9d257a742b1ddb4481d0602cc908c3762eff57 100644 (file)
@@ -8,11 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::term;
-use io::WriterUtil;
+use core::prelude::*;
+
 use codemap::span;
+use codemap;
 
-export emitter, emit;
+use core::cmp;
+use core::io::WriterUtil;
+use core::io;
+use core::option;
+use core::str;
+use core::vec;
+use core::dvec::DVec;
+
+use std::term;
+
+export emitter, collect, emit;
 export level, fatal, error, warning, note;
 export span_handler, handler, mk_span_handler, mk_handler;
 export codemap_span_handler, codemap_handler;
@@ -136,7 +147,7 @@ fn mk_handler(emitter: Option<emitter>) -> handler {
       Some(e) => e,
       None => {
         let f = fn@(cmsp: Option<(@codemap::CodeMap, span)>,
-            msg: &str, t: level) {
+                    msg: &str, t: level) {
             emit(cmsp, msg, t);
         };
         f
@@ -199,6 +210,12 @@ fn print_diagnostic(topic: ~str, lvl: level, msg: &str) {
     io::stderr().write_str(fmt!(" %s\n", msg));
 }
 
+fn collect(messages: @DVec<~str>)
+    -> fn@(Option<(@codemap::CodeMap, span)>, &str, level)
+{
+    |_o, msg: &str, _l| { messages.push(msg.to_str()); }
+}
+
 fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) {
     match cmsp {
       Some((cm, sp)) => {
index 680fa169afe79cca14d536376c55cb717eca0f9d..4afd2e1f7f8fb101420ac50c84b3e8d0477110ac 100644 (file)
@@ -88,8 +88,16 @@ impl<
 
 */
 
-use ext::base::*;
+use core::prelude::*;
+
+use ast;
+use ast_util;
+use attr;
 use codemap::span;
+use ext::base::*;
+use parse;
+
+use core::vec;
 use std::map;
 use std::map::HashMap;
 
@@ -113,7 +121,7 @@ fn is_auto_encode(a: &ast::attribute) -> bool {
     }
 
     fn filter_attrs(item: @ast::item) -> @ast::item {
-        @{attrs: vec::filter(item.attrs, |a| !is_auto_encode(a)),
+        @{attrs: item.attrs.filtered(|a| !is_auto_encode(a)),
           .. *item}
     }
 
@@ -177,7 +185,7 @@ fn is_auto_decode(a: &ast::attribute) -> bool {
     }
 
     fn filter_attrs(item: @ast::item) -> @ast::item {
-        @{attrs: vec::filter(item.attrs, |a| !is_auto_decode(a)),
+        @{attrs: item.attrs.filtered(|a| !is_auto_decode(a)),
           .. *item}
     }
 
@@ -237,7 +245,7 @@ fn bind_path(
         path: @ast::path,
         bounds: @~[ast::ty_param_bound]
     ) -> ast::ty_param {
-        let bound = ast::ty_param_bound(@{
+        let bound = ast::TraitTyParamBound(@{
             id: self.next_id(),
             node: ast::ty_path(path, self.next_id()),
             span: span,
@@ -259,11 +267,20 @@ fn path(span: span, strs: ~[ast::ident]) -> @ast::path {
         @{span: span, global: false, idents: strs, rp: None, types: ~[]}
     }
 
+    fn path_global(span: span, strs: ~[ast::ident]) -> @ast::path {
+        @{span: span, global: true, idents: strs, rp: None, types: ~[]}
+    }
+
     fn path_tps(span: span, strs: ~[ast::ident],
                 tps: ~[@ast::Ty]) -> @ast::path {
         @{span: span, global: false, idents: strs, rp: None, types: tps}
     }
 
+    fn path_tps_global(span: span, strs: ~[ast::ident],
+                       tps: ~[@ast::Ty]) -> @ast::path {
+        @{span: span, global: true, idents: strs, rp: None, types: tps}
+    }
+
     fn ty_path(span: span, strs: ~[ast::ident],
                tps: ~[@ast::Ty]) -> @ast::Ty {
         @{id: self.next_id(),
@@ -282,8 +299,8 @@ fn binder_pat(span: span, nm: ast::ident) -> @ast::pat {
     }
 
     fn stmt(expr: @ast::expr) -> @ast::stmt {
-        @{node: ast::stmt_semi(expr, self.next_id()),
-          span: expr.span}
+        @ast::spanned { node: ast::stmt_semi(expr, self.next_id()),
+                       span: expr.span }
     }
 
     fn lit_str(span: span, s: @~str) -> @ast::expr {
@@ -293,8 +310,8 @@ fn lit_str(span: span, s: @~str) -> @ast::expr {
                 self.expr(
                     span,
                     ast::expr_lit(
-                        @{node: ast::lit_str(s),
-                          span: span})),
+                        @ast::spanned { node: ast::lit_str(s),
+                                        span: span})),
                 ast::expr_vstore_uniq))
     }
 
@@ -302,8 +319,8 @@ fn lit_uint(span: span, i: uint) -> @ast::expr {
         self.expr(
             span,
             ast::expr_lit(
-                @{node: ast::lit_uint(i as u64, ast::ty_u),
-                  span: span}))
+                @ast::spanned { node: ast::lit_uint(i as u64, ast::ty_u),
+                                span: span}))
     }
 
     fn lambda(blk: ast::blk) -> @ast::expr {
@@ -313,27 +330,31 @@ fn lambda(blk: ast::blk) -> @ast::expr {
     }
 
     fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk {
-        {node: {view_items: ~[],
-                stmts: stmts,
-                expr: None,
-                id: self.next_id(),
-                rules: ast::default_blk},
-         span: span}
+        ast::spanned { node: { view_items: ~[],
+                               stmts: stmts,
+                               expr: None,
+                               id: self.next_id(),
+                               rules: ast::default_blk},
+                       span: span }
     }
 
     fn expr_blk(expr: @ast::expr) -> ast::blk {
-        {node: {view_items: ~[],
-                stmts: ~[],
-                expr: Some(expr),
-                id: self.next_id(),
-                rules: ast::default_blk},
-         span: expr.span}
+        ast::spanned { node: { view_items: ~[],
+                               stmts: ~[],
+                               expr: Some(expr),
+                               id: self.next_id(),
+                               rules: ast::default_blk},
+                       span: expr.span }
     }
 
     fn expr_path(span: span, strs: ~[ast::ident]) -> @ast::expr {
         self.expr(span, ast::expr_path(self.path(span, strs)))
     }
 
+    fn expr_path_global(span: span, strs: ~[ast::ident]) -> @ast::expr {
+        self.expr(span, ast::expr_path(self.path_global(span, strs)))
+    }
+
     fn expr_var(span: span, var: ~str) -> @ast::expr {
         self.expr_path(span, ~[self.ident_of(var)])
     }
@@ -376,7 +397,7 @@ fn mk_impl(
     let mut trait_tps = vec::append(
         ~[ty_param],
          do tps.map |tp| {
-            let t_bound = ast::ty_param_bound(@{
+            let t_bound = ast::TraitTyParamBound(@{
                 id: cx.next_id(),
                 node: ast::ty_path(path, cx.next_id()),
                 span: span,
@@ -404,7 +425,7 @@ fn mk_impl(
     @{
         // This is a new-style impl declaration.
         // XXX: clownshoes
-        ident: ast::token::special_idents::clownshoes_extensions,
+        ident: parse::token::special_idents::clownshoes_extensions,
         attrs: ~[],
         id: cx.next_id(),
         node: ast::item_impl(trait_tps, opt_trait, ty, ~[f(ty)]),
@@ -424,7 +445,7 @@ fn mk_ser_impl(
     let ty_param = cx.bind_path(
         span,
         cx.ident_of(~"__S"),
-        cx.path(
+        cx.path_global(
             span,
             ~[
                 cx.ident_of(~"std"),
@@ -436,7 +457,7 @@ fn mk_ser_impl(
     );
 
     // Make a path to the std::serialize::Encodable trait.
-    let path = cx.path_tps(
+    let path = cx.path_tps_global(
         span,
         ~[
             cx.ident_of(~"std"),
@@ -468,7 +489,7 @@ fn mk_deser_impl(
     let ty_param = cx.bind_path(
         span,
         cx.ident_of(~"__D"),
-        cx.path(
+        cx.path_global(
             span,
             ~[
                 cx.ident_of(~"std"),
@@ -480,7 +501,7 @@ fn mk_deser_impl(
     );
 
     // Make a path to the std::serialize::Decodable trait.
-    let path = cx.path_tps(
+    let path = cx.path_tps_global(
         span,
         ~[
             cx.ident_of(~"std"),
@@ -549,7 +570,8 @@ fn mk_ser_method(
         ident: cx.ident_of(~"encode"),
         attrs: ~[],
         tps: ~[],
-        self_ty: { node: ast::sty_region(ast::m_imm), span: span },
+        self_ty: ast::spanned { node: ast::sty_region(ast::m_imm),
+                                span: span },
         purity: ast::impure_fn,
         decl: ser_decl,
         body: ser_body,
@@ -603,7 +625,8 @@ fn mk_deser_method(
         ident: cx.ident_of(~"decode"),
         attrs: ~[],
         tps: ~[],
-        self_ty: { node: ast::sty_static, span: span },
+        self_ty: ast::spanned { node: ast::sty_static,
+                                span: span },
         purity: ast::impure_fn,
         decl: deser_decl,
         body: deser_body,
@@ -817,7 +840,7 @@ fn mk_deser_fields(
             cx.expr_blk(
                 cx.expr_call(
                     span,
-                    cx.expr_path(span, ~[
+                    cx.expr_path_global(span, ~[
                         cx.ident_of(~"std"),
                         cx.ident_of(~"serialize"),
                         cx.ident_of(~"Decodable"),
@@ -843,7 +866,7 @@ fn mk_deser_fields(
             ]
         );
 
-        {
+        ast::spanned {
             node: { mutbl: field.mutbl, ident: field.ident, expr: expr },
             span: span,
         }
@@ -1021,7 +1044,7 @@ fn mk_enum_deser_variant_nary(
         let expr_lambda = cx.lambda_expr(
             cx.expr_call(
                 span,
-                cx.expr_path(span, ~[
+                cx.expr_path_global(span, ~[
                     cx.ident_of(~"std"),
                     cx.ident_of(~"serialize"),
                     cx.ident_of(~"Decodable"),
index cf994e0ea52240ebf5485904d0814ad789e383db..7b69084a827a3392b96a14f5b81cbff6dfae8c1c 100644 (file)
@@ -8,12 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::map::HashMap;
-use parse::parser;
-use diagnostic::span_handler;
-use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom};
+use core::prelude::*;
+
+use ast;
 use ast_util::dummy_sp;
-use parse::token;
+use codemap;
+use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom};
+use diagnostic::span_handler;
+use ext;
+use parse;
+use parse::{parser, token};
+
+use core::io;
+use core::vec;
+use std::map::HashMap;
 
 // new-style macro! tt code:
 //
index 1e7d27bee6e489790a4a1eb8fce87357b61c011d..288ef1b273eba32c60205ed167dc7e1b1576f19d 100644 (file)
@@ -8,8 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
+use ast;
+use codemap;
 use codemap::span;
 use ext::base::ext_ctxt;
+use ext::build;
+
+use core::dvec;
+use core::option;
 
 fn mk_expr(cx: ext_ctxt, sp: codemap::span, expr: ast::expr_) ->
     @ast::expr {
@@ -18,7 +26,7 @@ fn mk_expr(cx: ext_ctxt, sp: codemap::span, expr: ast::expr_) ->
 }
 
 fn mk_lit(cx: ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr {
-    let sp_lit = @{node: lit, span: sp};
+    let sp_lit = @ast::spanned { node: lit, span: sp };
     mk_expr(cx, sp, ast::expr_lit(sp_lit))
 }
 fn mk_int(cx: ext_ctxt, sp: span, i: int) -> @ast::expr {
@@ -55,10 +63,19 @@ fn mk_raw_path_(sp: span,
              -> @ast::path {
     @{ span: sp, global: false, idents: idents, rp: None, types: move types }
 }
+fn mk_raw_path_global(sp: span, idents: ~[ast::ident]) -> @ast::path {
+    let p : @ast::path = @{span: sp, global: true, idents: idents,
+                           rp: None, types: ~[]};
+    return p;
+}
 fn mk_path(cx: ext_ctxt, sp: span, idents: ~[ast::ident]) ->
     @ast::expr {
     mk_expr(cx, sp, ast::expr_path(mk_raw_path(sp, idents)))
 }
+fn mk_path_global(cx: ext_ctxt, sp: span, idents: ~[ast::ident]) ->
+    @ast::expr {
+    mk_expr(cx, sp, ast::expr_path(mk_raw_path_global(sp, idents)))
+}
 fn mk_access_(cx: ext_ctxt, sp: span, p: @ast::expr, m: ast::ident)
     -> @ast::expr {
     mk_expr(cx, sp, ast::expr_field(p, m, ~[]))
@@ -80,6 +97,11 @@ fn mk_call(cx: ext_ctxt, sp: span, fn_path: ~[ast::ident],
     let pathexpr = mk_path(cx, sp, fn_path);
     return mk_call_(cx, sp, pathexpr, args);
 }
+fn mk_call_global(cx: ext_ctxt, sp: span, fn_path: ~[ast::ident],
+                  args: ~[@ast::expr]) -> @ast::expr {
+    let pathexpr = mk_path_global(cx, sp, fn_path);
+    return mk_call_(cx, sp, pathexpr, args);
+}
 // e = expr, t = type
 fn mk_base_vec_e(cx: ext_ctxt, sp: span, exprs: ~[@ast::expr]) ->
    @ast::expr {
@@ -114,7 +136,8 @@ fn mk_uniq_str(cx: ext_ctxt, sp: span, s: ~str) -> @ast::expr {
 }
 fn mk_field(sp: span, f: &{ident: ast::ident, ex: @ast::expr})
     -> ast::field {
-    {node: {mutbl: ast::m_imm, ident: f.ident, expr: f.ex}, span: sp}
+    ast::spanned { node: {mutbl: ast::m_imm, ident: f.ident, expr: f.ex},
+                   span: sp }
 }
 fn mk_fields(sp: span, fields: ~[{ident: ast::ident, ex: @ast::expr}]) ->
     ~[ast::field] {
@@ -137,9 +160,10 @@ fn mk_struct_e(cx: ext_ctxt, sp: span,
 }
 fn mk_glob_use(cx: ext_ctxt, sp: span,
                path: ~[ast::ident]) -> @ast::view_item {
-    let glob = @{node: ast::view_path_glob(mk_raw_path(sp, path),
-                                          cx.next_id()),
-                span: sp};
+    let glob = @ast::spanned {
+        node: ast::view_path_glob(mk_raw_path(sp, path), cx.next_id()),
+        span: sp,
+    };
     @{node: ast::view_item_import(~[glob]),
       attrs: ~[],
       vis: ast::private,
@@ -154,29 +178,29 @@ fn mk_local(cx: ext_ctxt, sp: span, mutbl: bool,
                                                  None),
                            span: sp};
     let ty : @ast::Ty = @{ id: cx.next_id(), node: ast::ty_infer, span: sp };
-    let local : @ast::local = @{node: {is_mutbl: mutbl,
-                                       ty: ty,
-                                       pat: pat,
-                                       init: Some(ex),
-                                       id: cx.next_id()},
-                                span: sp};
-    let decl = {node: ast::decl_local(~[local]), span: sp};
-    @{ node: ast::stmt_decl(@decl, cx.next_id()), span: sp }
+    let local : @ast::local = @ast::spanned { node: { is_mutbl: mutbl,
+                                                      ty: ty,
+                                                      pat: pat,
+                                                      init: Some(ex),
+                                                      id: cx.next_id()},
+                                              span: sp};
+    let decl = ast::spanned {node: ast::decl_local(~[local]), span: sp};
+    @ast::spanned { node: ast::stmt_decl(@decl, cx.next_id()), span: sp }
 }
 fn mk_block(cx: ext_ctxt, sp: span,
             view_items: ~[@ast::view_item],
             stmts: ~[@ast::stmt],
             expr: Option<@ast::expr>) -> @ast::expr {
-    let blk = {node: {view_items: view_items,
-                      stmts: stmts,
-                      expr: expr,
-                      id: cx.next_id(),
-                      rules: ast::default_blk },
-               span: sp };
+    let blk = ast::spanned { node: { view_items: view_items,
+                                     stmts: stmts,
+                                     expr: expr,
+                                     id: cx.next_id(),
+                                     rules: ast::default_blk },
+                             span: sp };
     mk_expr(cx, sp, ast::expr_block(blk))
 }
 fn mk_block_(cx: ext_ctxt, sp: span, +stmts: ~[@ast::stmt]) -> ast::blk {
-    {
+    ast::spanned {
         node: {
             view_items: ~[],
             stmts: move stmts,
@@ -195,7 +219,7 @@ fn mk_simple_block(cx: ext_ctxt, span: span, expr: @ast::expr) -> ast::blk {
         id: cx.next_id(),
         rules: ast::default_blk
     };
-    { node: move block, span: span }
+    ast::spanned { node: block, span: span }
 }
 fn mk_copy(cx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
     mk_expr(cx, sp, ast::expr_copy(e))
@@ -228,12 +252,13 @@ fn mk_pat_struct(cx: ext_ctxt,
     mk_pat(cx, span, move pat)
 }
 fn mk_bool(cx: ext_ctxt, span: span, value: bool) -> @ast::expr {
-    let lit_expr = ast::expr_lit(@{ node: ast::lit_bool(value), span: span });
+    let lit_expr = ast::expr_lit(@ast::spanned { node: ast::lit_bool(value),
+                                                 span: span });
     build::mk_expr(cx, span, move lit_expr)
 }
 fn mk_stmt(cx: ext_ctxt, span: span, expr: @ast::expr) -> @ast::stmt {
     let stmt_ = ast::stmt_semi(expr, cx.next_id());
-    @{ node: move stmt_, span: span }
+    @ast::spanned { node: move stmt_, span: span }
 }
 fn mk_ty_path(cx: ext_ctxt,
               span: span,
@@ -244,6 +269,15 @@ fn mk_ty_path(cx: ext_ctxt,
     let ty = @{ id: cx.next_id(), node: move ty, span: span };
     ty
 }
+fn mk_ty_path_global(cx: ext_ctxt,
+                     span: span,
+                     idents: ~[ ast::ident ])
+                  -> @ast::Ty {
+    let ty = build::mk_raw_path_global(span, idents);
+    let ty = ast::ty_path(ty, cx.next_id());
+    let ty = @{ id: cx.next_id(), node: move ty, span: span };
+    ty
+}
 fn mk_simple_ty_path(cx: ext_ctxt,
                      span: span,
                      ident: ast::ident)
index d84d79082a4f8a33212388adf278bf1d403efaf3..d847cfee053a7ace3dab4be31363e5cac057b4c3 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
+
 use ext::base::*;
+use ext::base;
 
 fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
     -> base::mac_result {
index d1ba835a3e5198326dbe5a270589a9474aff993c..afce1edf158cbf69dd7ef89225e014084f17b975 100644 (file)
 /// The compiler code necessary to implement the #[deriving_eq] and
 /// #[deriving_iter_bytes] extensions.
 
-use ast::{Ty, and, bind_by_ref, binop, deref, enum_def, enum_variant_kind};
-use ast::{expr, expr_match, ident, item, item_, item_struct, item_enum};
-use ast::{item_impl, m_imm, meta_item, method, named_field, or, pat};
-use ast::{pat_ident, pat_wild, public, pure_fn, re_anon, stmt, struct_def};
-use ast::{struct_variant_kind, sty_by_ref, sty_region, tuple_variant_kind};
-use ast::{ty_nil, ty_param, ty_param_bound, ty_path, ty_rptr, unnamed_field};
-use ast::{variant};
+use core::prelude::*;
+
+use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def};
+use ast::{enum_variant_kind, expr, expr_match, ident, item, item_};
+use ast::{item_enum, item_impl, item_struct, m_imm, meta_item, method};
+use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
+use ast::{re_anon, spanned, stmt, struct_def, struct_variant_kind};
+use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, ty_param};
+use ast::{ty_param_bound, ty_path, ty_rptr, unnamed_field, variant};
 use ext::base::ext_ctxt;
+use ext::build;
 use codemap::span;
 use parse::token::special_idents::clownshoes_extensions;
 
+use core::dvec;
+use core::uint;
+
 enum Junction {
     Conjunction,
     Disjunction,
@@ -153,7 +159,7 @@ fn create_eq_method(cx: ext_ctxt,
     let body_block = build::mk_simple_block(cx, span, body);
 
     // Create the method.
-    let self_ty = { node: sty_region(m_imm), span: span };
+    let self_ty = spanned { node: sty_region(m_imm), span: span };
     return @{
         ident: method_ident,
         attrs: ~[],
@@ -202,8 +208,10 @@ fn create_derived_impl(cx: ext_ctxt,
     // Create the type parameters.
     let impl_ty_params = dvec::DVec();
     for ty_params.each |ty_param| {
-        let bound = build::mk_ty_path(cx, span, trait_path.map(|x| *x));
-        let bounds = @~[ ty_param_bound(bound) ];
+        let bound = build::mk_ty_path_global(cx,
+                                             span,
+                                             trait_path.map(|x| *x));
+        let bounds = @~[ TraitTyParamBound(bound) ];
         let impl_ty_param = build::mk_ty_param(cx, ty_param.ident, bounds);
         impl_ty_params.push(move impl_ty_param);
     }
@@ -212,7 +220,7 @@ fn create_derived_impl(cx: ext_ctxt,
     // Create the reference to the trait.
     let trait_path = {
         span: span,
-        global: false,
+        global: true,
         idents: trait_path.map(|x| *x),
         rp: None,
         types: ~[]
@@ -301,7 +309,7 @@ fn create_iter_bytes_method(cx: ext_ctxt,
     let body_block = build::mk_block_(cx, span, move statements);
 
     // Create the method.
-    let self_ty = { node: sty_region(m_imm), span: span };
+    let self_ty = spanned { node: sty_region(m_imm), span: span };
     let method_ident = cx.ident_of(~"iter_bytes");
     return @{
         ident: method_ident,
index b5c55437d70b325c24b6ba419a9fbb270d1648b6..c07853a400bbc763408b765a1d174cc03c125522 100644 (file)
  * should all get sucked into either the compiler syntax extension plugin
  * interface.
  */
+
 use ext::base::*;
+use ext::base;
 use ext::build::mk_uniq_str;
+
+use core::option;
+use core::os;
+
 export expand_syntax_ext;
 
 fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
index 41d5c8ee0bbd31baec4b941dab279ee4bd12a996..11abec941e8cf622a807610cc9fec2e6e159e945 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::map::HashMap;
+use core::prelude::*;
 
-use ast::{crate, expr_, expr_mac, mac_invoc_tt,
-          tt_delim, tt_tok, item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi};
-use fold::*;
+use ast::{crate, expr_, expr_mac, mac_invoc_tt};
+use ast::{tt_delim, tt_tok, item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi};
+use ast;
+use codemap::{span, ExpandedFrom};
 use ext::base::*;
+use fold::*;
 use parse::{parser, parse_expr_from_source_str, new_parser_from_tts};
 
-
-use codemap::{span, ExpandedFrom};
-
+use core::option;
+use core::vec;
+use std::map::HashMap;
 
 fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
                e: expr_, s: span, fld: ast_fold,
@@ -154,7 +156,9 @@ fn expand_item_mac(exts: HashMap<~str, syntax_extension>,
                    fld: ast_fold) -> Option<@ast::item> {
 
     let (pth, tts) = match it.node {
-        item_mac({node: mac_invoc_tt(pth, ref tts), _}) => (pth, (*tts)),
+        item_mac(ast::spanned { node: mac_invoc_tt(pth, ref tts), _}) => {
+            (pth, (*tts))
+        }
         _ => cx.span_bug(it.span, ~"invalid item macro invocation")
     };
 
@@ -232,7 +236,8 @@ fn expand_stmt(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
                 {call_site: sp, callie: {name: *extname, span: exp_sp}}));
             let expanded = match exp(cx, mac.span, tts) {
                 mr_expr(e) =>
-                    @{node: stmt_expr(e, cx.next_id()), span: e.span},
+                    @ast::spanned { node: stmt_expr(e, cx.next_id()),
+                                    span: e.span},
                 mr_any(_,_,stmt_mkr) => stmt_mkr(),
                 _ => cx.span_fatal(
                     pth.span,
@@ -276,18 +281,17 @@ fn core_macros() -> ~str {
     macro_rules! ignore (($($x:tt)*) => (()))
 
     macro_rules! error ( ($( $arg:expr ),+) => (
-        log(core::error, fmt!( $($arg),+ )) ))
+        log(::core::error, fmt!( $($arg),+ )) ))
     macro_rules! warn ( ($( $arg:expr ),+) => (
-        log(core::warn, fmt!( $($arg),+ )) ))
+        log(::core::warn, fmt!( $($arg),+ )) ))
     macro_rules! info ( ($( $arg:expr ),+) => (
-        log(core::info, fmt!( $($arg),+ )) ))
+        log(::core::info, fmt!( $($arg),+ )) ))
     macro_rules! debug ( ($( $arg:expr ),+) => (
-        log(core::debug, fmt!( $($arg),+ )) ))
+        log(::core::debug, fmt!( $($arg),+ )) ))
 
     macro_rules! die(
         ($msg: expr) => (
-            core::sys::begin_unwind($msg,
-                                    file!().to_owned(), line!())
+            ::core::sys::begin_unwind($msg, file!().to_owned(), line!())
         );
         () => (
             die!(~\"explicit failure\")
@@ -299,11 +303,11 @@ macro_rules! condition (
         { $c:ident: $in:ty -> $out:ty; } => {
 
             mod $c {
-                fn key(_x: @core::condition::Handler<$in,$out>) { }
+                fn key(_x: @::core::condition::Handler<$in,$out>) { }
 
-                pub const cond : core::condition::Condition<$in,$out> =
-                    core::condition::Condition {
-                    name: stringify!(c),
+                pub const cond : ::core::condition::Condition<$in,$out> =
+                    ::core::condition::Condition {
+                    name: stringify!($c),
                     key: key
                 };
             }
@@ -318,13 +322,13 @@ fn expand_crate(parse_sess: parse::parse_sess,
     let exts = syntax_expander_table();
     let afp = default_ast_fold();
     let cx: ext_ctxt = mk_ctxt(parse_sess, cfg);
-    let f_pre =
-        @{fold_expr: |a,b,c| expand_expr(exts, cx, a, b, c, afp.fold_expr),
-          fold_mod: |a,b| expand_mod_items(exts, cx, a, b, afp.fold_mod),
-          fold_item: |a,b| expand_item(exts, cx, a, b, afp.fold_item),
-          fold_stmt: |a,b,c| expand_stmt(exts, cx, a, b, c, afp.fold_stmt),
-          new_span: |a| new_span(cx, a),
-          .. *afp};
+    let f_pre = @AstFoldFns {
+        fold_expr: |a,b,c| expand_expr(exts, cx, a, b, c, afp.fold_expr),
+        fold_mod: |a,b| expand_mod_items(exts, cx, a, b, afp.fold_mod),
+        fold_item: |a,b| expand_item(exts, cx, a, b, afp.fold_item),
+        fold_stmt: |a,b,c| expand_stmt(exts, cx, a, b, c, afp.fold_stmt),
+        new_span: |a| new_span(cx, a),
+        .. *afp};
     let f = make_fold(f_pre);
     let cm = parse_expr_from_source_str(~"<core-macros>",
                                         @core_macros(),
index 2b5f95c4066dae38a4a5f5c03c0c236c34faeef2..0eaa983ccad8b175af2667cc8d273a3b3ef56b5f 100644 (file)
  * should all get sucked into either the standard library extfmt module or the
  * compiler syntax extension plugin interface.
  */
-use extfmt::ct::*;
-use ext::base::*;
+
+use core::prelude::*;
+
+use ast;
 use codemap::span;
+use ext::base::*;
+use ext::base;
 use ext::build::*;
+use extfmt::ct::*;
+
 export expand_syntax_ext;
 
 fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
@@ -57,7 +63,7 @@ fn make_path_vec(_cx: ext_ctxt, ident: @~str) -> ~[ast::ident] {
     }
     fn make_rt_path_expr(cx: ext_ctxt, sp: span, nm: @~str) -> @ast::expr {
         let path = make_path_vec(cx, nm);
-        return mk_path(cx, sp, path);
+        return mk_path_global(cx, sp, path);
     }
     // Produces an AST expression that represents a RT::conv record,
     // which tells the RT::conv* functions how to perform the conversion
@@ -87,7 +93,7 @@ fn make_count(cx: ext_ctxt, sp: span, cnt: Count) -> @ast::expr {
                 let count_lit = mk_uint(cx, sp, c as uint);
                 let count_is_path = make_path_vec(cx, @~"CountIs");
                 let count_is_args = ~[count_lit];
-                return mk_call(cx, sp, count_is_path, count_is_args);
+                return mk_call_global(cx, sp, count_is_path, count_is_args);
               }
               _ => cx.span_unimpl(sp, ~"unimplemented fmt! conversion")
             }
@@ -129,7 +135,7 @@ fn make_conv_call(cx: ext_ctxt, sp: span, conv_type: ~str, cnv: Conv,
         let path = make_path_vec(cx, @fname);
         let cnv_expr = make_rt_conv_expr(cx, sp, cnv);
         let args = ~[cnv_expr, arg];
-        return mk_call(cx, arg.span, path, args);
+        return mk_call_global(cx, arg.span, path, args);
     }
 
     fn make_new_conv(cx: ext_ctxt, sp: span, cnv: Conv, arg: @ast::expr) ->
@@ -285,10 +291,11 @@ fn log_conv(c: Conv) {
     }
 
     let arg_vec = mk_fixed_vec_e(cx, fmt_sp, piece_exprs);
-    return mk_call(cx, fmt_sp,
-                   ~[cx.parse_sess().interner.intern(@~"str"),
-                     cx.parse_sess().interner.intern(@~"concat")],
-                   ~[arg_vec]);
+    return mk_call_global(cx,
+                          fmt_sp,
+                          ~[cx.parse_sess().interner.intern(@~"str"),
+                            cx.parse_sess().interner.intern(@~"concat")],
+                          ~[arg_vec]);
 }
 //
 // Local Variables:
index 47096182fe848140073277ef3ce3db3e8129efe4..563c56e02b5069ecfc9edeb3a022e3be2158a2c1 100644 (file)
@@ -8,8 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use ast;
+use codemap;
 use ext::base::*;
-use io::WriterUtil;
+use ext::base;
+use print;
+
+use core::io::WriterUtil;
+use core::option;
 
 fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, tt: ~[ast::token_tree])
     -> base::mac_result {
index 56f426e3853bfc78dec06c5afb392d2f9b41b9d6..3e265de04a394236766f98f78332c5a14ab8cda0 100644 (file)
 // To start with, it will be use dummy spans, but it might someday do
 // something smarter.
 
+use core::prelude::*;
+
 use ast::{ident, node_id};
+use ast;
 use ast_util::{ident_to_path, respan, dummy_sp};
+use ast_util;
+use attr;
 use codemap::span;
-use ext::base::mk_ctxt;
+use ext::base::{ext_ctxt, mk_ctxt};
 use ext::quote::rt::*;
 
+use core::vec;
+
 // Transitional reexports so qquote can find the paths it is looking for
 mod syntax {
     #[legacy_exports];
@@ -34,6 +41,14 @@ fn path(ids: ~[ident], span: span) -> @ast::path {
       types: ~[]}
 }
 
+fn path_global(ids: ~[ident], span: span) -> @ast::path {
+    @{span: span,
+      global: true,
+      idents: ids,
+      rp: None,
+      types: ~[]}
+}
+
 trait append_types {
     fn add_ty(ty: @ast::Ty) -> @ast::path;
     fn add_tys(+tys: ~[@ast::Ty]) -> @ast::path;
@@ -82,6 +97,7 @@ fn item_ty_poly(name: ident,
                     +params: ~[ast::ty_param]) -> @ast::item;
     fn item_ty(name: ident, span: span, ty: @ast::Ty) -> @ast::item;
     fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty];
+    fn ty_vars_global(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty];
     fn ty_field_imm(name: ident, ty: @ast::Ty) -> ast::ty_field;
     fn ty_rec(+v: ~[ast::ty_field]) -> @ast::Ty;
     fn field_imm(name: ident, e: @ast::expr) -> ast::field;
@@ -98,9 +114,11 @@ fn item_ty_poly(name: ident,
 
 impl ext_ctxt: ext_ctxt_ast_builder {
     fn ty_option(ty: @ast::Ty) -> @ast::Ty {
-        self.ty_path_ast_builder(path(~[self.ident_of(~"Option")],
-                                      dummy_sp())
-                                 .add_ty(ty))
+        self.ty_path_ast_builder(path_global(~[
+            self.ident_of(~"core"),
+            self.ident_of(~"option"),
+            self.ident_of(~"Option")
+        ], dummy_sp()).add_ty(ty))
     }
 
     fn block_expr(b: ast::blk) -> @ast::expr {
@@ -118,8 +136,8 @@ fn move_expr(e: @ast::expr) -> @ast::expr {
     }
 
     fn stmt_expr(e: @ast::expr) -> @ast::stmt {
-        @{node: ast::stmt_expr(e, self.next_id()),
-          span: dummy_sp()}
+        @spanned { node: ast::stmt_expr(e, self.next_id()),
+                   span: dummy_sp()}
     }
 
     fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt {
@@ -128,8 +146,8 @@ fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt {
     }
 
     fn field_imm(name: ident, e: @ast::expr) -> ast::field {
-        {node: {mutbl: ast::m_imm, ident: name, expr: e},
-         span: dummy_sp()}
+        spanned { node: { mutbl: ast::m_imm, ident: name, expr: e },
+                  span: dummy_sp()}
     }
 
     fn rec(+fields: ~[ast::field]) -> @ast::expr {
@@ -140,8 +158,8 @@ fn rec(+fields: ~[ast::field]) -> @ast::expr {
     }
 
     fn ty_field_imm(name: ident, ty: @ast::Ty) -> ast::ty_field {
-        {node: {ident: name, mt: { ty: ty, mutbl: ast::m_imm } },
-          span: dummy_sp()}
+        spanned { node: { ident: name, mt: { ty: ty, mutbl: ast::m_imm } },
+                  span: dummy_sp() }
     }
 
     fn ty_rec(+fields: ~[ast::ty_field]) -> @ast::Ty {
@@ -181,8 +199,7 @@ fn block(+stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk {
                    id: self.next_id(),
                    rules: ast::default_blk};
 
-        {node: blk,
-         span: dummy_sp()}
+        spanned { node: blk, span: dummy_sp() }
     }
 
     fn expr_block(e: @ast::expr) -> ast::blk {
@@ -257,22 +274,49 @@ fn variant(name: ident,
                +tys: ~[@ast::Ty]) -> ast::variant {
         let args = tys.map(|ty| {ty: *ty, id: self.next_id()});
 
-        {node: {name: name,
-                attrs: ~[],
-                kind: ast::tuple_variant_kind(args),
-                id: self.next_id(),
-                disr_expr: None,
-                vis: ast::public},
-         span: span}
+        spanned { node: { name: name,
+                          attrs: ~[],
+                          kind: ast::tuple_variant_kind(args),
+                          id: self.next_id(),
+                          disr_expr: None,
+                          vis: ast::public},
+                  span: span}
     }
 
     fn item_mod(name: ident,
                 span: span,
                 +items: ~[@ast::item]) -> @ast::item {
+        // XXX: Total hack: import `core::kinds::Owned` to work around a
+        // parser bug whereby `fn f<T: ::kinds::Owned>` doesn't parse.
+        let vi = ast::view_item_import(~[
+            @ast::spanned {
+                node: ast::view_path_simple(
+                    self.ident_of(~"Owned"),
+                    path(
+                        ~[
+                            self.ident_of(~"core"),
+                            self.ident_of(~"kinds"),
+                            self.ident_of(~"Owned")
+                        ],
+                        ast_util::dummy_sp()
+                    ),
+                    ast::type_value_ns,
+                    self.next_id()
+                ),
+                span: ast_util::dummy_sp()
+            }
+        ]);
+        let vi = @{
+            node: vi,
+            attrs: ~[],
+            vis: ast::private,
+            span: ast_util::dummy_sp()
+        };
+
         self.item(name,
                   span,
                   ast::item_mod({
-                      view_items: ~[],
+                      view_items: ~[vi],
                       items: items}))
     }
 
@@ -303,4 +347,9 @@ fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] {
         ty_params.map(|p| self.ty_path_ast_builder(
             path(~[p.ident], dummy_sp())))
     }
+
+    fn ty_vars_global(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] {
+        ty_params.map(|p| self.ty_path_ast_builder(
+            path(~[p.ident], dummy_sp())))
+    }
 }
index 7193a00950e28fd33cf305ee137dc6ede3c21dab..f2ba413dd38dfea43b101dd134cdc3046f03416a 100644 (file)
 
 */
 
-use ext::base::ext_ctxt;
+use core::prelude::*;
 
+use ast;
+use codemap::span;
+use ext::base::ext_ctxt;
 use ext::pipes::proto::{state, protocol, next_state};
+use ext::pipes::proto;
 
 impl ext_ctxt: proto::visitor<(), (), ()>  {
     fn visit_proto(_proto: protocol,
index 1323042eb6254fa0bd1b0ee5848c0a06a7e037fe..01e995940835db7c52ef047f953694e1d003467c 100644 (file)
 
 */
 
+use core::prelude::*;
+
+use ext::base::ext_ctxt;
+use ext::pipes::protocol;
+
+use core::str;
 use std::bitv::{Bitv};
 
 fn analyze(proto: protocol, _cx: ext_ctxt) {
index 0a02bca88ca99859045a029f0998c9a39a1d2590..cb17e56e99073da56f634c0f15fba703e9f28e06 100644 (file)
 
 */
 
+use ast;
+use ast::tt_delim;
 use codemap::span;
+use ext::base;
 use ext::base::ext_ctxt;
-use ast::tt_delim;
+use ext::pipes::parse_proto::proto_parser;
+use ext::pipes::proto::{visit, protocol};
 use parse::lexer::{new_tt_reader, reader};
 use parse::parser::Parser;
 
-use ext::pipes::parse_proto::proto_parser;
-use ext::pipes::proto::{visit, protocol};
+use core::option::None;
 
 #[legacy_exports]
 mod ast_builder;
index 0f6b9dbda284349bc3bd3de97130367f2c1103ff..6a6e895bd401f6554e2961de9fdd32d6850aa989 100644 (file)
 
 // Parsing pipes protocols from token trees.
 
+use ext::pipes::pipec::*;
 use parse::parser;
 use parse::token;
 
-use ext::pipes::pipec::*;
+use core::prelude::*;
 
 trait proto_parser {
     fn parse_proto(id: ~str) -> protocol;
index c07170e5c364097e4ae7bab3aff1e2c58e7bf03d..e88ddb841be1bc4702573bdf9d36b7b888685284 100644 (file)
 
 // A protocol compiler for Rust.
 
-use to_str::ToStr;
-
-use dvec::DVec;
-
 use ast::ident;
 use ast_util::dummy_sp;
-use util::interner;
 use ext::base::ext_ctxt;
-use parse::*;
+use ext::pipes::ast_builder::{append_types, path, path_global};
 use ext::pipes::proto::*;
 use ext::quote::rt::*;
-use ext::pipes::ast_builder::{append_types, path};
+use parse::*;
+use util::interner;
+
+use core::dvec::DVec;
+use core::prelude::*;
+use core::str;
+use core::to_str::ToStr;
+use core::vec;
 
 trait gen_send {
     fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item;
@@ -59,13 +61,14 @@ fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item {
 
             let pipe_ty = cx.ty_path_ast_builder(
                 path(~[this.data_name()], span)
-                .add_tys(cx.ty_vars(this.ty_params)));
+                .add_tys(cx.ty_vars_global(this.ty_params)));
             let args_ast = vec::append(
                 ~[cx.arg(cx.ident_of(~"pipe"),
                               pipe_ty)],
                 args_ast);
 
             let mut body = ~"{\n";
+            body += fmt!("use super::%s;\n", self.name());
 
             if this.proto.is_bounded() {
                 let (sp, rp) = match (this.dir, next.dir) {
@@ -76,11 +79,11 @@ fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item {
                 };
 
                 body += ~"let b = pipe.reuse_buffer();\n";
-                body += fmt!("let %s = pipes::SendPacketBuffered(\
-                              ptr::addr_of(&(b.buffer.data.%s)));\n",
+                body += fmt!("let %s = ::pipes::SendPacketBuffered(\
+                              ::ptr::addr_of(&(b.buffer.data.%s)));\n",
                              sp, next.name);
-                body += fmt!("let %s = pipes::RecvPacketBuffered(\
-                              ptr::addr_of(&(b.buffer.data.%s)));\n",
+                body += fmt!("let %s = ::pipes::RecvPacketBuffered(\
+                              ::ptr::addr_of(&(b.buffer.data.%s)));\n",
                              rp, next.name);
             }
             else {
@@ -91,24 +94,23 @@ fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item {
                   (recv, recv) => "(move c, move s)"
                 };
 
-                body += fmt!("let %s = pipes::entangle();\n", pat);
+                body += fmt!("let %s = ::pipes::entangle();\n", pat);
             }
-            body += fmt!("let message = %s::%s(%s);\n",
-                         this.proto.name,
+            body += fmt!("let message = %s(%s);\n",
                          self.name(),
                          str::connect(vec::append_one(
                            arg_names.map(|x| ~"move " + cx.str_of(*x)),
                              ~"move s"), ~", "));
 
             if !try {
-                body += fmt!("pipes::send(move pipe, move message);\n");
+                body += fmt!("::pipes::send(move pipe, move message);\n");
                 // return the new channel
                 body += ~"move c }";
             }
             else {
-                body += fmt!("if pipes::send(move pipe, move message) {\n \
-                                  pipes::rt::make_some(move c) \
-                              } else { pipes::rt::make_none() } }");
+                body += fmt!("if ::pipes::send(move pipe, move message) {\n \
+                                  ::pipes::rt::make_some(move c) \
+                              } else { ::pipes::rt::make_none() } }");
             }
 
             let body = cx.parse_expr(body);
@@ -142,7 +144,8 @@ fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item {
                     ~[cx.arg(cx.ident_of(~"pipe"),
                                   cx.ty_path_ast_builder(
                                       path(~[this.data_name()], span)
-                                      .add_tys(cx.ty_vars(this.ty_params))))],
+                                      .add_tys(cx.ty_vars_global(
+                                        this.ty_params))))],
                     args_ast);
 
                 let message_args = if arg_names.len() == 0 {
@@ -154,18 +157,21 @@ fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item {
                 };
 
                 let mut body = ~"{ ";
-                body += fmt!("let message = %s::%s%s;\n",
-                             this.proto.name,
+                body += fmt!("use super::%s;\n", self.name());
+                body += fmt!("let message = %s%s;\n",
                              self.name(),
                              message_args);
 
                 if !try {
-                    body += fmt!("pipes::send(move pipe, move message);\n");
+                    body += fmt!("::pipes::send(move pipe, move message);\n");
                     body += ~" }";
                 } else {
-                    body += fmt!("if pipes::send(move pipe, move message) { \
-                                      pipes::rt::make_some(()) \
-                                  } else { pipes::rt::make_none() } }");
+                    body += fmt!("if ::pipes::send(move pipe, move message) \
+                                        { \
+                                      ::pipes::rt::make_some(()) \
+                                  } else { \
+                                    ::pipes::rt::make_none() \
+                                  } }");
                 }
 
                 let body = cx.parse_expr(body);
@@ -190,7 +196,7 @@ fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item {
 
     fn to_ty(cx: ext_ctxt) -> @ast::Ty {
         cx.ty_path_ast_builder(path(~[cx.ident_of(self.name())], self.span())
-          .add_tys(cx.ty_vars(self.get_params())))
+          .add_tys(cx.ty_vars_global(self.get_params())))
     }
 }
 
@@ -261,14 +267,14 @@ fn to_endpoint_decls(cx: ext_ctxt, dir: direction) -> ~[@ast::item] {
                     self.data_name(),
                     self.span,
                     cx.ty_path_ast_builder(
-                        path(~[cx.ident_of(~"pipes"),
-                               cx.ident_of(dir.to_str() + ~"Packet")],
+                        path_global(~[cx.ident_of(~"pipes"),
+                                      cx.ident_of(dir.to_str() + ~"Packet")],
                              dummy_sp())
                         .add_ty(cx.ty_path_ast_builder(
-                            path(~[cx.ident_of(self.proto.name),
+                            path(~[cx.ident_of(~"super"),
                                    self.data_name()],
                                  dummy_sp())
-                            .add_tys(cx.ty_vars(self.ty_params))))),
+                            .add_tys(cx.ty_vars_global(self.ty_params))))),
                     self.ty_params));
         }
         else {
@@ -277,15 +283,15 @@ fn to_endpoint_decls(cx: ext_ctxt, dir: direction) -> ~[@ast::item] {
                     self.data_name(),
                     self.span,
                     cx.ty_path_ast_builder(
-                        path(~[cx.ident_of(~"pipes"),
-                               cx.ident_of(dir.to_str()
-                                           + ~"PacketBuffered")],
+                        path_global(~[cx.ident_of(~"pipes"),
+                                      cx.ident_of(dir.to_str()
+                                                  + ~"PacketBuffered")],
                              dummy_sp())
                         .add_tys(~[cx.ty_path_ast_builder(
-                            path(~[cx.ident_of(self.proto.name),
+                            path(~[cx.ident_of(~"super"),
                                    self.data_name()],
-                                 dummy_sp())
-                            .add_tys(cx.ty_vars(self.ty_params))),
+                                        dummy_sp())
+                            .add_tys(cx.ty_vars_global(self.ty_params))),
                                    self.proto.buffer_ty_path(cx)])),
                     self.ty_params));
         };
@@ -303,10 +309,10 @@ fn gen_init(cx: ext_ctxt) -> @ast::item {
 
         let body = if !self.is_bounded() {
             match start_state.dir {
-              send => quote_expr!( pipes::entangle() ),
+              send => quote_expr!( ::pipes::entangle() ),
               recv => {
                 quote_expr!({
-                    let (s, c) = pipes::entangle();
+                    let (s, c) = ::pipes::entangle();
                     (move c, move s)
                 })
               }
@@ -338,7 +344,7 @@ fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr {
             let fty = s.to_ty(ext_cx);
             ext_cx.field_imm(ext_cx.ident_of(s.name),
                              quote_expr!(
-                                 pipes::mk_packet::<$fty>()
+                                 ::pipes::mk_packet::<$fty>()
                              ))
         }))
     }
@@ -347,7 +353,7 @@ fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr {
         debug!("gen_init_bounded");
         let buffer_fields = self.gen_buffer_init(ext_cx);
         let buffer = quote_expr!(
-            ~{header: pipes::BufferHeader(),
+            ~{header: ::pipes::BufferHeader(),
               data: $buffer_fields}
         );
 
@@ -358,12 +364,12 @@ fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr {
                         fmt!("data.%s.set_buffer_(buffer)",
                              s.name))),
                 ext_cx.parse_expr(
-                    fmt!("ptr::addr_of(&(data.%s))",
+                    fmt!("::ptr::addr_of(&(data.%s))",
                          self.states[0].name))));
 
         quote_expr!({
             let buffer = $buffer;
-            do pipes::entangle_buffer(move buffer) |buffer, data| {
+            do ::pipes::entangle_buffer(move buffer) |buffer, data| {
                 $entangle_body
             }
         })
@@ -380,8 +386,9 @@ fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty {
             }
         }
 
-        cx.ty_path_ast_builder(path(~[cx.ident_of(~"__Buffer")], self.span)
-                               .add_tys(cx.ty_vars(params)))
+        cx.ty_path_ast_builder(path(~[cx.ident_of(~"super"),
+                                      cx.ident_of(~"__Buffer")], self.span)
+                               .add_tys(cx.ty_vars_global(params)))
     }
 
     fn gen_buffer_type(cx: ext_ctxt) -> @ast::item {
@@ -395,7 +402,7 @@ fn gen_buffer_type(cx: ext_ctxt) -> @ast::item {
                 }
             }
             let ty = s.to_ty(cx);
-            let fty = quote_ty!( pipes::Packet<$ty> );
+            let fty = quote_ty!( ::pipes::Packet<$ty> );
 
             cx.ty_field_imm(cx.ident_of(s.name), fty)
         };
index b00a2aab69f13d50b970e12b42990fc5b69351c6..9953b4de50d46a6b4ff33aa1acae40dc0e0e2692 100644 (file)
@@ -8,11 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use to_str::ToStr;
-use dvec::DVec;
+use core::prelude::*;
 
+use ast;
+use codemap::span;
+use ext::base::ext_ctxt;
 use ext::pipes::ast_builder::{path, append_types};
 
+use core::cmp;
+use core::dvec::DVec;
+use core::to_str::ToStr;
+
 enum direction { send, recv }
 
 impl direction : cmp::Eq {
index c498c3407c28ab523d4fc9eb6e5d9502b450925d..4aed5b647479a6bd63951d9311f99b16e51aeef2 100644 (file)
@@ -8,12 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use mod ast;
-use mod parse::token;
-
+use ast;
+use attr;
 use codemap::{span, BytePos};
 use ext::base::ext_ctxt;
+use ext::base;
+use ext::build;
 use parse::token::*;
+use parse::token;
+use parse;
+
+use core::prelude::*;
+use core::str;
 
 /**
 *
 */
 
 pub mod rt {
+    use ast;
+    use ext::base::ext_ctxt;
+    use parse;
+    use print::pprust;
+
+    use core::str;
+
     pub use ast::*;
     pub use parse::token::*;
     pub use parse::new_parser_from_tts;
@@ -577,15 +590,15 @@ fn expand_parse_call(cx: ext_ctxt,
                                  id_ext(cx, ~"parse_sess")), ~[]);
 
     let new_parser_call =
-        build::mk_call(cx, sp,
-                       ids_ext(cx, ~[~"syntax",
-                                     ~"ext",
-                                     ~"quote",
-                                     ~"rt",
-                                     ~"new_parser_from_tts"]),
-                       ~[parse_sess_call(),
-                         cfg_call(),
-                         tts_expr]);
+        build::mk_call_global(cx, sp,
+                              ids_ext(cx, ~[~"syntax",
+                                            ~"ext",
+                                            ~"quote",
+                                            ~"rt",
+                                            ~"new_parser_from_tts"]),
+                              ~[parse_sess_call(),
+                                cfg_call(),
+                                tts_expr]);
 
     build::mk_call_(cx, sp,
                     build::mk_access_(cx, sp, new_parser_call,
index e407431568966f605a3c764448fbb4652de89c9a..3d012b393bb21330498ea4fc0e4d83fa8caaa7d2 100644 (file)
@@ -8,10 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ext::base::*;
+use codemap;
 use codemap::{span, Loc, FileMap};
-use print::pprust;
+use ext::base::*;
+use ext::base;
 use ext::build::{mk_base_vec_e, mk_uint, mk_u8, mk_base_str};
+use print::pprust;
+
+use core::io;
+use core::prelude::*;
+use core::result;
+use core::str;
+use core::vec;
 
 export expand_line;
 export expand_col;
index 6bf7437e152771a214492e3ac5591d97c4dd8558..d5031b97718cd743d7dc04a22031a39fc6b2e77f 100644 (file)
@@ -8,15 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use ast::tt_delim;
+use ast;
 use codemap::span;
 use ext::base::ext_ctxt;
-use ast::tt_delim;
+use ext::base;
 use parse::lexer::{new_tt_reader, reader};
 use parse::parser::Parser;
 
+use core::option::None;
+
 fn expand_trace_macros(cx: ext_ctxt, sp: span,
-                       tt: ~[ast::token_tree]) -> base::mac_result
-{
+                       tt: ~[ast::token_tree]) -> base::mac_result {
     let sess = cx.parse_sess();
     let cfg = cx.cfg();
     let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic,
index ad4677942accd7bd49c664944b652ac5e91eb41e..2449db17c0f47702d64038bdcac2017f0535cbe3 100644 (file)
@@ -9,19 +9,25 @@
 // except according to those terms.
 
 // Earley-like parser for macros.
-use parse::token;
-use parse::token::{Token, EOF, to_str, nonterminal};
-use parse::lexer::*; //resolve bug?
-//import parse::lexer::{reader, tt_reader, tt_reader_as_reader};
-use parse::parser::Parser;
-//import parse::common::parser_common;
-use parse::common::*; //resolve bug?
-use parse::parse_sess;
-use dvec::DVec;
 use ast::{matcher, match_tok, match_seq, match_nonterminal, ident};
 use ast_util::mk_sp;
-use std::map::HashMap;
 use codemap::BytePos;
+use codemap;
+use parse::common::*; //resolve bug?
+use parse::lexer::*; //resolve bug?
+use parse::parse_sess;
+use parse::parser::Parser;
+use parse::token::{Token, EOF, to_str, nonterminal};
+use parse::token;
+
+use core::dvec::DVec;
+use core::dvec;
+use core::io;
+use core::option;
+use core::str;
+use core::uint;
+use core::vec;
+use std::map::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
@@ -183,13 +189,13 @@ fn nameize(p_s: parse_sess, ms: ~[matcher], res: ~[@named_match])
     fn n_rec(p_s: parse_sess, m: matcher, res: ~[@named_match],
              ret_val: HashMap<ident, @named_match>) {
         match m {
-          {node: match_tok(_), span: _} => (),
-          {node: match_seq(ref more_ms, _, _, _, _), span: _} => {
+          spanned {node: match_tok(_), _} => (),
+          spanned {node: match_seq(ref more_ms, _, _, _, _), _} => {
             for (*more_ms).each() |next_m| {
                 n_rec(p_s, *next_m, res, ret_val)
             };
           }
-          {node: match_nonterminal(bind_name, _, idx), span: sp} => {
+          spanned {node: match_nonterminal(bind_name, _, idx), span: sp} => {
             if ret_val.contains_key(bind_name) {
                 p_s.span_diagnostic.span_fatal(sp, ~"Duplicated bind name: "+
                                                *p_s.interner.get(bind_name))
@@ -239,7 +245,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
 
             /* at end of sequence */
             if idx >= len {
-                // can't move out of `alt`s, so:
+                // can't move out of `match`es, so:
                 if is_some(ei.up) {
                     // hack: a matcher sequence is repeating iff it has a
                     // parent (the top level is just a container)
index e93f3d6e38b24d8538e3b6979d74641857898c0f..069eb1e0d82535f767f74a796bcdb7e8d9a0ba03 100644 (file)
@@ -8,25 +8,32 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ext::base::{ext_ctxt, mac_result, mr_any, mr_def, normal_tt};
+use core::prelude::*;
+
+use ast::{ident, matcher_, matcher, match_tok, match_nonterminal, match_seq};
+use ast::{tt_delim};
+use ast;
+use ast_util::dummy_sp;
 use codemap::span;
-use ast::{ident, matcher_, matcher, match_tok,
-             match_nonterminal, match_seq, tt_delim};
+use ext::base::{ext_ctxt, mac_result, mr_any, mr_def, normal_tt};
+use ext::base;
+use ext::tt::macro_parser::{error};
+use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
+use ext::tt::macro_parser::{parse, parse_or_else, success, failure};
 use parse::lexer::{new_tt_reader, reader};
-use parse::token::{FAT_ARROW, SEMI, LBRACE, RBRACE, nt_matchers, nt_tt};
 use parse::parser::Parser;
-use ext::tt::macro_parser::{parse, parse_or_else, success, failure,
-                            named_match, matched_seq, matched_nonterminal,
-                            error};
-use std::map::HashMap;
 use parse::token::special_idents;
-use ast_util::dummy_sp;
+use parse::token::{FAT_ARROW, SEMI, LBRACE, RBRACE, nt_matchers, nt_tt};
+use print;
+
+use core::io;
+use std::map::HashMap;
 
 fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
                      arg: ~[ast::token_tree]) -> base::mac_result {
     // these spans won't matter, anyways
     fn ms(m: matcher_) -> matcher {
-        {node: m, span: dummy_sp()}
+        ast::spanned { node: m, span: dummy_sp() }
     }
 
     let lhs_nm =  cx.parse_sess().interner.gensym(@~"lhs");
index a68482ea46b3653484df210b69017ba2ad3e69d4..47489034a0f518c20ce321d6aab3321b4e2ad857 100644 (file)
@@ -8,11 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use diagnostic::span_handler;
+use core::prelude::*;
+
+use ast;
 use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident};
-use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
+use ast_util;
 use codemap::span;
+use diagnostic::span_handler;
+use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
 use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident, ident_interner};
+
+use core::option;
+use core::vec;
+use std;
 use std::map::HashMap;
 
 export tt_reader,  new_tt_reader, dup_tt_reader, tt_next_token;
index 0b1ff4f56eced3b12853e91681443ed53113c5c3..bca2336bc8cf46d9e66d671aab8696bac0b19efe 100644 (file)
@@ -8,10 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use codemap::span;
+use core::prelude::*;
+
 use ast::*;
+use ast;
+use codemap::span;
 
-export ast_fold_precursor;
+use core::option;
+use core::vec;
+
+export ast_fold_fns;
 export ast_fold;
 export default_ast_fold;
 export make_fold;
@@ -28,6 +34,7 @@
 export fold_ty_params;
 export fold_fn_decl;
 export extensions;
+export AstFoldFns;
 
 trait ast_fold {
     fn fold_crate(crate) -> crate;
@@ -57,7 +64,7 @@ trait ast_fold {
 
 // We may eventually want to be able to fold over type parameters, too
 
-type ast_fold_precursor = @{
+struct AstFoldFns {
     //unlike the others, item_ is non-trivial
     fold_crate: fn@(crate_, span, ast_fold) -> (crate_, span),
     fold_view_item: fn@(view_item_, ast_fold) -> view_item_,
@@ -81,33 +88,36 @@ trait ast_fold {
     fold_local: fn@(local_, span, ast_fold) -> (local_, span),
     map_exprs: fn@(fn@(&&v: @expr) -> @expr, ~[@expr]) -> ~[@expr],
     new_id: fn@(node_id) -> node_id,
-    new_span: fn@(span) -> span};
+    new_span: fn@(span) -> span
+}
+
+type ast_fold_fns = @AstFoldFns;
 
 /* some little folds that probably aren't useful to have in ast_fold itself*/
 
 //used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive
 fn fold_meta_item_(&&mi: @meta_item, fld: ast_fold) -> @meta_item {
-    return @{node:
-              match mi.node {
+    @spanned {
+        node:
+            match mi.node {
                 meta_word(ref id) => meta_word((*id)),
                 meta_list(ref id, mis) => {
-                  let fold_meta_item = |x|fold_meta_item_(x, fld);
-                  meta_list(/* FIXME: (#2543) */ copy (*id),
-                            vec::map(mis, |e| fold_meta_item(*e)))
+                    let fold_meta_item = |x|fold_meta_item_(x, fld);
+                    meta_list(/* FIXME: (#2543) */ copy (*id),
+                        vec::map(mis, |e| fold_meta_item(*e)))
                 }
                 meta_name_value(ref id, s) => {
-                  meta_name_value((*id), /* FIXME (#2543) */ copy s)
+                    meta_name_value((*id), /* FIXME (#2543) */ copy s)
                 }
-              },
-          span: fld.new_span(mi.span)};
+            },
+        span: fld.new_span(mi.span) }
 }
 //used in noop_fold_item and noop_fold_crate
-fn fold_attribute_(at: attribute, fld: ast_fold) ->
-   attribute {
-    return {node: {style: at.node.style,
-                value: *fold_meta_item_(@at.node.value, fld),
-                is_sugared_doc: at.node.is_sugared_doc },
-         span: fld.new_span(at.span)};
+fn fold_attribute_(at: attribute, fld: ast_fold) -> attribute {
+    spanned { node: { style: at.node.style,
+                      value: *fold_meta_item_(@at.node.value, fld),
+                      is_sugared_doc: at.node.is_sugared_doc },
+              span: fld.new_span(at.span) }
 }
 //used in noop_fold_foreign_item and noop_fold_fn_decl
 fn fold_arg_(a: arg, fld: ast_fold) -> arg {
@@ -118,11 +128,10 @@ fn fold_arg_(a: arg, fld: ast_fold) -> arg {
 }
 //used in noop_fold_expr, and possibly elsewhere in the future
 fn fold_mac_(m: mac, fld: ast_fold) -> mac {
-    return {node:
-             match m.node {
-               mac_invoc_tt(*) => m.node,
-             },
-         span: fld.new_span(m.span)};
+    spanned { node: match m.node {
+                        mac_invoc_tt(*) => m.node,
+                    },
+              span: fld.new_span(m.span) }
 }
 
 fn fold_fn_decl(decl: ast::fn_decl, fld: ast_fold) -> ast::fn_decl {
@@ -132,7 +141,10 @@ fn fold_fn_decl(decl: ast::fn_decl, fld: ast_fold) -> ast::fn_decl {
 }
 
 fn fold_ty_param_bound(tpb: ty_param_bound, fld: ast_fold) -> ty_param_bound {
-    ty_param_bound(fld.fold_ty(*tpb))
+    match tpb {
+        TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_ty(ty)),
+        RegionTyParamBound => RegionTyParamBound
+    }
 }
 
 fn fold_ty_param(tp: ty_param, fld: ast_fold) -> ty_param {
@@ -200,10 +212,10 @@ fn noop_fold_item(&&i: @item, fld: ast_fold) -> Option<@item> {
 
 fn noop_fold_struct_field(&&sf: @struct_field, fld: ast_fold)
                        -> @struct_field {
-    @{node: {kind: copy sf.node.kind,
-             id: sf.node.id,
-             ty: fld.fold_ty(sf.node.ty)},
-      span: sf.span}
+    @spanned { node: { kind: copy sf.node.kind,
+                       id: sf.node.id,
+                       ty: fld.fold_ty(sf.node.ty) },
+               span: sf.span }
 }
 
 fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
@@ -260,9 +272,10 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold)
     let dtor = do option::map(&struct_def.dtor) |dtor| {
         let dtor_body = fld.fold_block(dtor.node.body);
         let dtor_id   = fld.new_id(dtor.node.id);
-        {node: {body: dtor_body,
-                id: dtor_id,.. dtor.node},
-            .. *dtor}};
+        spanned { node: { body: dtor_body,
+                          id: dtor_id, .. dtor.node},
+                  span: dtor.span }
+    };
     return @{
         fields: vec::map(struct_def.fields, |f| fold_struct_field(*f, fld)),
         dtor: dtor,
@@ -275,10 +288,10 @@ fn fold_trait_ref(&&p: @trait_ref, fld: ast_fold) -> @trait_ref {
 }
 
 fn fold_struct_field(&&f: @struct_field, fld: ast_fold) -> @struct_field {
-    @{node: {kind: copy f.node.kind,
-             id: fld.new_id(f.node.id),
-             ty: fld.fold_ty(f.node.ty)},
-      span: fld.new_span(f.span)}
+    @spanned { node: { kind: copy f.node.kind,
+                       id: fld.new_id(f.node.id),
+                       ty: fld.fold_ty(f.node.ty) },
+               span: fld.new_span(f.span) }
 }
 
 fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method {
@@ -384,11 +397,10 @@ fn wrap<T>(f: fn@(T, ast_fold) -> T)
 
 fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
     fn fold_field_(field: field, fld: ast_fold) -> field {
-        return {node:
-                 {mutbl: field.node.mutbl,
-                  ident: fld.fold_ident(field.node.ident),
-                  expr: fld.fold_expr(field.node.expr)},
-             span: fld.new_span(field.span)};
+        spanned { node: { mutbl: field.node.mutbl,
+                          ident: fld.fold_ident(field.node.ident),
+                          expr: fld.fold_expr(field.node.expr)},
+                  span: fld.new_span(field.span) }
     }
     let fold_field = |x| fold_field_(x, fld);
 
@@ -502,9 +514,9 @@ fn fold_mt(mt: mt, fld: ast_fold) -> mt {
         {ty: fld.fold_ty(mt.ty), mutbl: mt.mutbl}
     }
     fn fold_field(f: ty_field, fld: ast_fold) -> ty_field {
-        {node: {ident: fld.fold_ident(f.node.ident),
-                mt: fold_mt(f.node.mt, fld)},
-         span: fld.new_span(f.span)}
+        spanned { node: { ident: fld.fold_ident(f.node.ident),
+                          mt: fold_mt(f.node.mt, fld) },
+                  span: fld.new_span(f.span) }
     }
     match t {
       ty_nil | ty_bot | ty_infer => copy t,
@@ -560,9 +572,10 @@ fn fold_variant_arg_(va: variant_arg, fld: ast_fold) -> variant_arg {
             let dtor = do option::map(&struct_def.dtor) |dtor| {
                 let dtor_body = fld.fold_block(dtor.node.body);
                 let dtor_id   = fld.new_id(dtor.node.id);
-                {node: {body: dtor_body,
-                        id: dtor_id,.. dtor.node},
-                    .. *dtor}};
+                spanned { node: { body: dtor_body,
+                                  id: dtor_id, .. dtor.node},
+                          .. *dtor }
+            };
             kind = struct_variant_kind(@{
                 fields: vec::map(struct_def.fields,
                                  |f| fld.fold_struct_field(*f)),
@@ -625,8 +638,8 @@ fn noop_map_exprs(f: fn@(&&v: @expr) -> @expr, es: ~[@expr]) -> ~[@expr] {
 
 fn noop_span(sp: span) -> span { return sp; }
 
-fn default_ast_fold() -> ast_fold_precursor {
-    return @{fold_crate: wrap(noop_fold_crate),
+fn default_ast_fold() -> ast_fold_fns {
+    return @AstFoldFns {fold_crate: wrap(noop_fold_crate),
           fold_view_item: noop_fold_view_item,
           fold_foreign_item: noop_fold_foreign_item,
           fold_item: noop_fold_item,
@@ -651,11 +664,11 @@ fn default_ast_fold() -> ast_fold_precursor {
           new_span: noop_span};
 }
 
-impl ast_fold_precursor: ast_fold {
+impl ast_fold_fns: ast_fold {
     /* naturally, a macro to write these would be nice */
     fn fold_crate(c: crate) -> crate {
         let (n, s) = (self.fold_crate)(c.node, c.span, self as ast_fold);
-        return {node: n, span: (self.new_span)(s)};
+        spanned { node: n, span: (self.new_span)(s) }
     }
     fn fold_view_item(&&x: @view_item) ->
        @view_item {
@@ -673,10 +686,10 @@ fn fold_item(&&i: @item) -> Option<@item> {
         return (self.fold_item)(i, self as ast_fold);
     }
     fn fold_struct_field(&&sf: @struct_field) -> @struct_field {
-        @{node: {kind: copy sf.node.kind,
-                 id: sf.node.id,
-                 ty: (self as ast_fold).fold_ty(sf.node.ty)},
-          span: (self.new_span)(sf.span)}
+        @spanned { node: { kind: copy sf.node.kind,
+                           id: sf.node.id,
+                           ty: (self as ast_fold).fold_ty(sf.node.ty) },
+                   span: (self.new_span)(sf.span) }
     }
     fn fold_item_underscore(i: item_) ->
        item_ {
@@ -688,11 +701,11 @@ fn fold_method(&&x: @method)
     }
     fn fold_block(x: blk) -> blk {
         let (n, s) = (self.fold_block)(x.node, x.span, self as ast_fold);
-        return {node: n, span: (self.new_span)(s)};
+        spanned { node: n, span: (self.new_span)(s) }
     }
     fn fold_stmt(&&x: @stmt) -> @stmt {
         let (n, s) = (self.fold_stmt)(x.node, x.span, self as ast_fold);
-        return @{node: n, span: (self.new_span)(s)};
+        @spanned { node: n, span: (self.new_span)(s) }
     }
     fn fold_arm(x: arm) -> arm {
         return (self.fold_arm)(x, self as ast_fold);
@@ -705,7 +718,7 @@ fn fold_pat(&&x: @pat) -> @pat {
     }
     fn fold_decl(&&x: @decl) -> @decl {
         let (n, s) = (self.fold_decl)(x.node, x.span, self as ast_fold);
-        return @{node: n, span: (self.new_span)(s)};
+        @spanned { node: n, span: (self.new_span)(s) }
     }
     fn fold_expr(&&x: @expr) -> @expr {
         let (n, s) = (self.fold_expr)(x.node, x.span, self as ast_fold);
@@ -728,7 +741,7 @@ fn fold_foreign_mod(x: foreign_mod) ->
     fn fold_variant(x: variant) ->
        variant {
         let (n, s) = (self.fold_variant)(x.node, x.span, self as ast_fold);
-        return {node: n, span: (self.new_span)(s)};
+        spanned { node: n, span: (self.new_span)(s) }
     }
     fn fold_ident(&&x: ident) -> ident {
         return (self.fold_ident)(x, self as ast_fold);
@@ -738,7 +751,7 @@ fn fold_path(&&x: @path) -> @path {
     }
     fn fold_local(&&x: @local) -> @local {
         let (n, s) = (self.fold_local)(x.node, x.span, self as ast_fold);
-        return @{node: n, span: (self.new_span)(s)};
+        @spanned { node: n, span: (self.new_span)(s) }
     }
     fn map_exprs(f: fn@(&&v: @expr) -> @expr, e: ~[@expr]) -> ~[@expr] {
         (self.map_exprs)(f, e)
@@ -757,7 +770,7 @@ fn fold_attributes(attrs: ~[attribute]) -> ~[attribute] {
     }
 }
 
-fn make_fold(afp: ast_fold_precursor) -> ast_fold {
+fn make_fold(afp: ast_fold_fns) -> ast_fold {
     afp as ast_fold
 }
 
index a4bef47fdf290bfa89171a6166ad29252d49ae9a..49197be4bb9740bb07f02a77983ed2e9d00657d6 100644 (file)
@@ -8,9 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use either::{Either, Left, Right};
+use core::prelude::*;
+
+use ast;
 use ast_util::spanned;
+use codemap::BytePos;
 use parse::common::*; //resolve bug?
+use parse::token;
+
+use core::either::{Either, Left, Right};
 
 export parser_attr;
 
index 0ff5c296125f07ae6c188ef71850245dbc0e8325..04316e05b64750653bb5030881f788fd2598492c 100644 (file)
@@ -12,6 +12,7 @@
   Predicates on exprs and stmts that the pretty-printer and parser use
  */
 
+use ast;
 use ast_util::operator_prec;
 
 fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
@@ -29,7 +30,8 @@ fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
 
 fn expr_is_simple_block(e: @ast::expr) -> bool {
     match e.node {
-      ast::expr_block({node: {rules: ast::default_blk, _}, _}) => true,
+      ast::expr_block(ast::spanned {node: {rules: ast::default_blk, _}, _}) =>
+        true,
       _ => false
     }
 }
index 22b40736748b54238fc6bb8e0b10778807ea70be..0e101d54ba3ef1ebbfb4831948d295ddec245d0e 100644 (file)
@@ -8,11 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use io::ReaderUtil;
+use core::prelude::*;
+
+use ast;
+use codemap::{BytePos, CharPos, CodeMap, FileMap};
+use diagnostic;
+use parse::lexer::{is_whitespace, get_str_from, reader};
+use parse::lexer::{string_reader, bump, is_eof, nextch};
+use parse::lexer;
+use parse::token;
+use parse;
 use util::interner;
-use parse::lexer::{string_reader, bump, is_eof, nextch,
-                   is_whitespace, get_str_from, reader};
-use codemap::{FileMap, CharPos};
+
+use core::cmp;
+use core::io::ReaderUtil;
+use core::io;
+use core::str;
+use core::uint;
+use core::vec;
 
 export cmnt;
 export lit;
@@ -72,7 +85,7 @@ fn vertical_trim(lines: ~[~str]) -> ~[~str] {
     // drop leftmost columns that contain only values in chars
     fn block_trim(lines: ~[~str], chars: ~str, max: Option<uint>) -> ~[~str] {
 
-        let mut i = max.get_default(uint::max_value);
+        let mut i = max.get_or_default(uint::max_value);
         for lines.each |line| {
             if line.trim().is_empty() {
                 loop;
index 246a8fa9c7c55075b6e7689e89ab2d7c6642f415..1c6022130dc4a0d9127929cc0a22615e62042675 100644 (file)
@@ -8,10 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::map::{HashMap};
+use core::prelude::*;
+
+use ast;
 use ast_util::spanned;
-use parse::parser::Parser;
+use codemap::BytePos;
 use parse::lexer::reader;
+use parse::parser::Parser;
+use parse::token;
+
+use core::option::{None, Option, Some};
+use core::option;
+use std::map::HashMap;
 
 type seq_sep = {
     sep: Option<token::Token>,
index c4e34311b889838841e221ed7483d2726c9230c9..573c36e619b8aa9ab668be90d2ad742ab302d302 100644 (file)
@@ -8,10 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use diagnostic::span_handler;
+use core::prelude::*;
+
+use ast;
+use ast_util;
 use codemap::{span, CodeMap, CharPos, BytePos};
-use ext::tt::transcribe::{tt_reader,  new_tt_reader, dup_tt_reader,
-                             tt_next_token};
+use codemap;
+use diagnostic::span_handler;
+use ext::tt::transcribe::{tt_next_token};
+use ext::tt::transcribe::{tt_reader, new_tt_reader, dup_tt_reader};
+use parse::token;
+
+use core::char;
+use core::either;
+use core::str;
+use core::u64;
+
+use std;
 
 export reader, string_reader, new_string_reader, is_whitespace;
 export tt_reader,  new_tt_reader;
index 803135f7599e20dcb76e1f3c9081b0699e066b09..b14b60af1345cd01b920bb720304aa10fc9b6b9f 100644 (file)
 
 //! The main parser interface
 
-#[legacy_exports];
-
-export parser;
-export common;
-export lexer;
-export token;
-export comments;
-export prec;
-export classify;
-export attr;
-export obsolete;
-
-export parse_sess;
-export new_parse_sess, new_parse_sess_special_handler;
-export next_node_id;
-export new_parser_from_file, new_parser_etc_from_file;
-export new_parser_from_source_str;
-export new_parser_from_tts;
-export new_sub_parser_from_file;
-export parse_crate_from_file, parse_crate_from_crate_file;
-export parse_crate_from_source_str;
-export parse_expr_from_source_str, parse_item_from_source_str;
-export parse_stmt_from_source_str;
-export parse_tts_from_source_str;
-export parse_from_source_str;
-
 use ast::node_id;
+use ast;
 use codemap::{span, CodeMap, FileMap, CharPos, BytePos};
+use codemap;
 use diagnostic::{span_handler, mk_span_handler, mk_handler, emitter};
 use parse::attr::parser_attr;
 use parse::lexer::{reader, string_reader};
 use parse::token::{ident_interner, mk_ident_interner};
 use util::interner;
 
+use core::io;
+use core::option::{None, Option, Some};
+use core::path::Path;
+use core::result::{Err, Ok, Result};
+use core::result;
 
 #[legacy_exports]
-mod lexer;
+pub mod lexer;
 #[legacy_exports]
-mod parser;
+pub mod parser;
 #[legacy_exports]
-mod token;
+pub mod token;
 #[legacy_exports]
-mod comments;
+pub mod comments;
 #[legacy_exports]
-mod attr;
+pub mod attr;
 #[legacy_exports]
 
 /// Common routines shared by parser mods
 #[legacy_exports]
-mod common;
+pub mod common;
 
 /// Functions dealing with operator precedence
 #[legacy_exports]
-mod prec;
+pub mod prec;
 
 /// Routines the parser uses to classify AST nodes
 #[legacy_exports]
-mod classify;
+pub mod classify;
 
 /// Reporting obsolete syntax
 #[legacy_exports]
-mod obsolete;
-
+pub mod obsolete;
 
-type parse_sess = @{
+pub type parse_sess = @{
     cm: @codemap::CodeMap,
     mut next_id: node_id,
     span_diagnostic: span_handler,
     interner: @ident_interner,
 };
 
-fn new_parse_sess(demitter: Option<emitter>) -> parse_sess {
+pub fn new_parse_sess(demitter: Option<emitter>) -> parse_sess {
     let cm = @CodeMap::new();
     return @{cm: cm,
              mut next_id: 1,
@@ -91,7 +71,7 @@ fn new_parse_sess(demitter: Option<emitter>) -> parse_sess {
             };
 }
 
-fn new_parse_sess_special_handler(sh: span_handler, cm: @codemap::CodeMap)
+pub fn new_parse_sess_special_handler(sh: span_handler, cm: @codemap::CodeMap)
     -> parse_sess {
     return @{cm: cm,
              mut next_id: 1,
@@ -100,15 +80,17 @@ fn new_parse_sess_special_handler(sh: span_handler, cm: @codemap::CodeMap)
              };
 }
 
-fn parse_crate_from_file(input: &Path, cfg: ast::crate_cfg,
+pub fn parse_crate_from_file(input: &Path, cfg: ast::crate_cfg,
                          sess: parse_sess) -> @ast::crate {
     let p = new_crate_parser_from_file(sess, cfg, input);
     let r = p.parse_crate_mod(cfg);
     return r;
 }
 
-fn parse_crate_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
-                               sess: parse_sess) -> @ast::crate {
+pub fn parse_crate_from_source_str(name: ~str,
+                                   source: @~str,
+                                   cfg: ast::crate_cfg,
+                                   sess: parse_sess) -> @ast::crate {
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
     let r = p.parse_crate_mod(cfg);
@@ -116,8 +98,10 @@ fn parse_crate_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
     return r;
 }
 
-fn parse_expr_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
-                              sess: parse_sess) -> @ast::expr {
+pub fn parse_expr_from_source_str(name: ~str,
+                                  source: @~str,
+                                  cfg: ast::crate_cfg,
+                                  sess: parse_sess) -> @ast::expr {
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
     let r = p.parse_expr();
@@ -125,9 +109,12 @@ fn parse_expr_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
     return r;
 }
 
-fn parse_item_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
-                              +attrs: ~[ast::attribute],
-                              sess: parse_sess) -> Option<@ast::item> {
+pub fn parse_item_from_source_str(name: ~str,
+                                  source: @~str,
+                                  cfg: ast::crate_cfg,
+                                  +attrs: ~[ast::attribute],
+                                  sess: parse_sess)
+                               -> Option<@ast::item> {
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
     let r = p.parse_item(attrs);
@@ -135,9 +122,11 @@ fn parse_item_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
     return r;
 }
 
-fn parse_stmt_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
-                              +attrs: ~[ast::attribute],
-                              sess: parse_sess) -> @ast::stmt {
+pub fn parse_stmt_from_source_str(name: ~str,
+                                  source: @~str,
+                                  cfg: ast::crate_cfg,
+                                  +attrs: ~[ast::attribute],
+                                  sess: parse_sess) -> @ast::stmt {
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
     let r = p.parse_stmt(attrs);
@@ -145,8 +134,10 @@ fn parse_stmt_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
     return r;
 }
 
-fn parse_tts_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
-                             sess: parse_sess) -> ~[ast::token_tree] {
+pub fn parse_tts_from_source_str(name: ~str,
+                                 source: @~str,
+                                 cfg: ast::crate_cfg,
+                                 sess: parse_sess) -> ~[ast::token_tree] {
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
     p.quote_depth += 1u;
@@ -155,7 +146,7 @@ fn parse_tts_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
     return r;
 }
 
-fn parse_from_source_str<T>(f: fn (p: Parser) -> T,
+pub fn parse_from_source_str<T>(f: fn (p: Parser) -> T,
                             name: ~str, ss: codemap::FileSubstr,
                             source: @~str, cfg: ast::crate_cfg,
                             sess: parse_sess)
@@ -171,7 +162,7 @@ fn parse_from_source_str<T>(f: fn (p: Parser) -> T,
     move r
 }
 
-fn next_node_id(sess: parse_sess) -> node_id {
+pub fn next_node_id(sess: parse_sess) -> node_id {
     let rv = sess.next_id;
     sess.next_id += 1;
     // ID 0 is reserved for the crate and doesn't actually exist in the AST
@@ -179,7 +170,7 @@ fn next_node_id(sess: parse_sess) -> node_id {
     return rv;
 }
 
-fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
+pub fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
                               +name: ~str, +ss: codemap::FileSubstr,
                               source: @~str) -> Parser {
     let filemap = sess.cm.new_filemap_w_substr(name, ss, source);
@@ -188,7 +179,7 @@ fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
     return Parser(sess, cfg, srdr as reader);
 }
 
-fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
+pub fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
                         path: &Path) -> Result<Parser, ~str> {
     match io::read_whole_file_str(path) {
       result::Ok(move src) => {
@@ -206,7 +197,7 @@ fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
 
 /// Create a new parser for an entire crate, handling errors as appropriate
 /// if the file doesn't exist
-fn new_crate_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
+pub fn new_crate_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
                               path: &Path) -> Parser {
     match new_parser_from_file(sess, cfg, path) {
         Ok(move parser) => move parser,
@@ -218,7 +209,7 @@ fn new_crate_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
 
 /// Create a new parser based on a span from an existing parser. Handles
 /// error messages correctly when the file does not exist.
-fn new_sub_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
+pub fn new_sub_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
                             path: &Path, sp: span) -> Parser {
     match new_parser_from_file(sess, cfg, path) {
         Ok(move parser) => move parser,
@@ -228,7 +219,7 @@ fn new_sub_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
     }
 }
 
-fn new_parser_from_tts(sess: parse_sess, cfg: ast::crate_cfg,
+pub fn new_parser_from_tts(sess: parse_sess, cfg: ast::crate_cfg,
                        tts: ~[ast::token_tree]) -> Parser {
     let trdr = lexer::new_tt_reader(sess.span_diagnostic, sess.interner,
                                     None, tts);
index 3db635f3b431d3fba362eaa45e9c7694d0acbf07..15905c090db4d94aa2df543e9e1cdc506fe1e834 100644 (file)
 removed.
 */
 
-use codemap::span;
+use core::prelude::*;
+
 use ast::{expr, expr_lit, lit_nil};
+use ast;
 use ast_util::{respan};
+use codemap::span;
+use parse::parser::Parser;
 use parse::token::Token;
+use parse::token;
+
+use core::cmp;
+use core::option;
+use core::str;
+use core::to_bytes;
 
 /// The specific types of unsupported syntax
 pub enum ObsoleteSyntax {
index 2b83404e065e2262229222de47978633c6b1589f..6974ac508aade245d5ca59c6e150ab52f20f3ba7 100644 (file)
@@ -8,76 +8,84 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use print::pprust::expr_to_str;
-
-use result::Result;
-use either::{Either, Left, Right};
-use std::map::HashMap;
-use parse::token::{can_begin_expr, is_ident, is_ident_or_path, is_plain_ident,
-                   INTERPOLATED, special_idents};
-use codemap::{span,FssNone, BytePos};
-use util::interner::Interner;
+use core::prelude::*;
+
+use ast::{ProtoBox, ProtoUniq, RegionTyParamBound, TraitTyParamBound};
+use ast::{provided, public, pure_fn, purity, re_static};
+use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer};
+use ast::{bind_by_value, bind_by_move, bitand, bitor, bitxor, blk};
+use ast::{blk_check_mode, box, by_copy, by_move, by_ref, by_val};
+use ast::{capture_clause, capture_item, crate, crate_cfg, decl, decl_item};
+use ast::{decl_local, default_blk, deref, div, enum_def, enum_variant_kind};
+use ast::{expl, expr, expr_, expr_addr_of, expr_match, expr_again};
+use ast::{expr_assert, expr_assign, expr_assign_op, expr_binary, expr_block};
+use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body};
+use ast::{expr_fail, expr_field, expr_fn, expr_fn_block, expr_if, expr_index};
+use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac};
+use ast::{expr_method_call, expr_paren, expr_path, expr_rec, expr_repeat};
+use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary};
+use ast::{expr_unary_move, expr_vec, expr_vstore, expr_vstore_mut_box};
+use ast::{expr_vstore_fixed, expr_vstore_slice, expr_vstore_box};
+use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
+use ast::{expr_vstore_uniq, TyFn, Onceness, Once, Many};
+use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod};
+use ast::{ident, impure_fn, infer, inherited, item, item_, item_const};
+use ast::{item_const, item_enum, item_fn, item_foreign_mod, item_impl};
+use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
+use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int};
+use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const};
+use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal};
+use ast::{match_seq, match_tok, method, mode, module_ns, mt, mul, mutability};
+use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum};
+use ast::{pat_ident, pat_lit, pat_range, pat_rec, pat_region, pat_struct};
+use ast::{pat_tup, pat_uniq, pat_wild, path, private, Proto, ProtoBare};
+use ast::{ProtoBorrowed, re_self, re_anon, re_named, region, rem, required};
+use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl};
+use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field};
+use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract};
+use ast::{sty_box, sty_by_ref, sty_region, sty_static, sty_uniq, sty_value};
+use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok};
+use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box};
+use ast::{ty_field, ty_fixed_length_vec, ty_fn, ty_infer, ty_mac, ty_method};
+use ast::{ty_nil, ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr};
+use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, type_value_ns, uniq};
+use ast::{unnamed_field, unsafe_blk, unsafe_fn, variant, view_item};
+use ast::{view_item_, view_item_export, view_item_import, view_item_use};
+use ast::{view_path, view_path_glob, view_path_list, view_path_simple};
+use ast::{visibility, vstore, vstore_box, vstore_fixed, vstore_slice};
+use ast::{vstore_uniq};
+use ast;
 use ast_util::{spanned, respan, mk_sp, ident_to_path, operator_prec};
+use ast_util;
+use classify;
+use codemap::{span,FssNone, BytePos};
+use codemap;
+use parse::attr::parser_attr;
+use parse::common::{seq_sep_none, token_to_str};
+use parse::common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed};
 use parse::lexer::reader;
+use parse::obsolete::{ObsoleteClassTraits, ObsoleteModeInFnType};
+use parse::obsolete::{ObsoleteLet, ObsoleteFieldTerminator};
+use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove};
+use parse::obsolete::{ObsoleteStructCtor, ObsoleteWith, ObsoleteClassMethod};
+use parse::obsolete::{ObsoleteSyntax, ObsoleteLowerCaseKindBounds};
 use parse::prec::{as_prec, token_to_binop};
-use parse::attr::parser_attr;
-use parse::common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed,
-                    seq_sep_none, token_to_str};
-use dvec::DVec;
-use vec::{push};
-use parse::obsolete::{
-    ObsoleteSyntax,
-    ObsoleteLowerCaseKindBounds, ObsoleteLet,
-    ObsoleteFieldTerminator, ObsoleteStructCtor,
-    ObsoleteWith, ObsoleteClassMethod, ObsoleteClassTraits,
-    ObsoleteModeInFnType, ObsoleteMoveInit, ObsoleteBinaryMove,
-};
-use ast::{_mod, add, arg, arm, attribute,
-             bind_by_ref, bind_infer, bind_by_value, bind_by_move,
-             bitand, bitor, bitxor, blk, blk_check_mode, box, by_copy,
-             by_move, by_ref, by_val, capture_clause,
-             capture_item, struct_immutable, struct_mutable,
-             crate, crate_cfg, decl, decl_item, decl_local,
-             default_blk, deref, div, enum_def, enum_variant_kind, expl, expr,
-             expr_, expr_addr_of, expr_match, expr_again, expr_assert,
-             expr_assign, expr_assign_op, expr_binary, expr_block, expr_break,
-             expr_call, expr_cast, expr_copy, expr_do_body, expr_fail,
-             expr_field, expr_fn, expr_fn_block, expr_if, expr_index,
-             expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac,
-             expr_method_call, expr_paren, expr_path, expr_rec, expr_repeat,
-             expr_ret, expr_swap, expr_struct, expr_tup, expr_unary,
-             expr_unary_move, expr_vec, expr_vstore, expr_vstore_mut_box,
-             expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl,
-             foreign_item, foreign_item_const, foreign_item_fn, foreign_mod,
-             ident, impure_fn, infer, inherited,
-             item, item_, item_struct, item_const, item_enum, item_fn,
-             item_foreign_mod, item_impl, item_mac, item_mod, item_trait,
-             item_ty, lit, lit_, lit_bool, lit_float, lit_float_unsuffixed,
-             lit_int, lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local,
-             m_const, m_imm, m_mutbl, mac_,
-             mac_invoc_tt, matcher, match_nonterminal, match_seq,
-             match_tok, method, mode, module_ns, mt, mul, mutability,
-             named_field, neg, noreturn, not, pat, pat_box, pat_enum,
-             pat_ident, pat_lit, pat_range, pat_rec, pat_region, pat_struct,
-             pat_tup, pat_uniq, pat_wild, path, private, Proto, ProtoBare,
-             ProtoBorrowed, ProtoBox, ProtoUniq, provided, public, pure_fn,
-             purity, re_static, re_self, re_anon, re_named, region,
-             rem, required, ret_style, return_val, self_ty, shl, shr, stmt,
-             stmt_decl, stmt_expr, stmt_semi, stmt_mac, struct_def,
-             struct_field, struct_variant_kind, subtract, sty_box, sty_by_ref,
-             sty_region, sty_static, sty_uniq, sty_value, token_tree,
-             trait_method, trait_ref, tt_delim, tt_seq, tt_tok,
-             tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot,
-             ty_box, ty_field, ty_fn, ty_infer, ty_mac, ty_method, ty_nil,
-             ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr,
-             ty_tup, ty_u32, ty_uniq, ty_vec, ty_fixed_length_vec,
-             type_value_ns, uniq, unnamed_field, unsafe_blk, unsafe_fn,
-             variant, view_item, view_item_, view_item_export,
-             view_item_import, view_item_use, view_path, view_path_glob,
-             view_path_list, view_path_simple, visibility, vstore, vstore_box,
-             vstore_fixed, vstore_slice, vstore_uniq,
-             expr_vstore_fixed, expr_vstore_slice, expr_vstore_box,
-             expr_vstore_uniq, TyFn, Onceness, Once, Many};
+use parse::token::{can_begin_expr, is_ident, is_ident_or_path};
+use parse::token::{is_plain_ident, INTERPOLATED, special_idents};
+use parse::token;
+use parse::{new_sub_parser_from_file, next_node_id, parse_sess};
+use print::pprust::expr_to_str;
+use util::interner::Interner;
+
+use core::cmp;
+use core::dvec::DVec;
+use core::dvec;
+use core::either::{Either, Left, Right};
+use core::either;
+use core::result::Result;
+use core::vec::push;
+use core::vec;
+use std::map::HashMap;
 
 export Parser;
 
@@ -195,7 +203,7 @@ fn Parser(sess: parse_sess, cfg: ast::crate_cfg,
         keywords: token::keyword_table(),
         strict_keywords: token::strict_keyword_table(),
         reserved_keywords: token::reserved_keyword_table(),
-        obsolete_set: std::map::HashMap(),
+        obsolete_set: HashMap(),
         mod_path_stack: ~[],
     }
 }
@@ -765,7 +773,7 @@ fn parse_lit() -> lit {
             self.bump();
             self.lit_from_token(tok)
         };
-        return {node: lit, span: mk_sp(lo, self.last_span.hi)};
+        spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
     }
 
     fn parse_path_without_tps() -> @path {
@@ -837,7 +845,7 @@ fn parse_path_with_tps(colons: bool) -> @path {
                 self.parse_seq_lt_gt(Some(token::COMMA),
                                      |p| p.parse_ty(false))
             } else {
-                {node: ~[], span: path.span}
+                spanned {node: ~[], span: path.span}
             }
         };
 
@@ -873,14 +881,14 @@ fn mk_expr(+lo: BytePos, +hi: BytePos, +node: expr_) -> @expr {
     fn mk_mac_expr(+lo: BytePos, +hi: BytePos, m: mac_) -> @expr {
         return @{id: self.get_id(),
               callee_id: self.get_id(),
-              node: expr_mac({node: m, span: mk_sp(lo, hi)}),
+              node: expr_mac(spanned {node: m, span: mk_sp(lo, hi)}),
               span: mk_sp(lo, hi)};
     }
 
     fn mk_lit_u32(i: u32) -> @expr {
         let span = self.span;
-        let lv_lit = @{node: lit_uint(i as u64, ty_u32),
-                       span: span};
+        let lv_lit = @spanned { node: lit_uint(i as u64, ty_u32),
+                                span: span };
 
         return @{id: self.get_id(), callee_id: self.get_id(),
               node: expr_lit(lv_lit), span: span};
@@ -937,7 +945,7 @@ fn parse_bottom_expr() -> @expr {
         } else if self.eat_keyword(~"loop") {
             return self.parse_loop_expr();
         } else if self.eat_keyword(~"match") {
-            return self.parse_alt_expr();
+            return self.parse_match_expr();
         } else if self.eat_keyword(~"fn") {
             let opt_proto = self.parse_fn_ty_proto();
             let proto = match opt_proto {
@@ -1356,7 +1364,7 @@ fn parse_prefix_expr() -> @expr {
                 hi = e.span.hi;
                 // HACK: turn &[...] into a &-evec
                 ex = match e.node {
-                  expr_vec(*) | expr_lit(@{node: lit_str(_), span: _})
+                  expr_vec(*) | expr_lit(@spanned {node: lit_str(_), span: _})
                   if m == m_imm => {
                     expr_vstore(e, expr_vstore_slice)
                   }
@@ -1379,7 +1387,7 @@ fn parse_prefix_expr() -> @expr {
               expr_vec(*) if m == m_mutbl =>
                 expr_vstore(e, expr_vstore_mut_box),
               expr_vec(*) if m == m_imm => expr_vstore(e, expr_vstore_box),
-              expr_lit(@{node: lit_str(_), span: _}) if m == m_imm =>
+              expr_lit(@spanned {node: lit_str(_), span: _}) if m == m_imm =>
                 expr_vstore(e, expr_vstore_box),
               _ => expr_unary(box(m), e)
             };
@@ -1391,7 +1399,7 @@ fn parse_prefix_expr() -> @expr {
             hi = e.span.hi;
             // HACK: turn ~[...] into a ~-evec
             ex = match e.node {
-              expr_vec(*) | expr_lit(@{node: lit_str(_), span: _})
+              expr_vec(*) | expr_lit(@spanned {node: lit_str(_), span: _})
               if m == m_imm => expr_vstore(e, expr_vstore_uniq),
               _ => expr_unary(uniq(m), e)
             };
@@ -1719,7 +1727,7 @@ fn parse_record_literal() -> expr_ {
         return expr_rec(fields, base);
     }
 
-    fn parse_alt_expr() -> @expr {
+    fn parse_match_expr() -> @expr {
         let lo = self.last_span.lo;
         let discriminant = self.parse_expr();
         self.expect(token::LBRACE);
@@ -1741,12 +1749,12 @@ fn parse_alt_expr() -> @expr {
                 self.eat(token::COMMA);
             }
 
-            let blk = {node: {view_items: ~[],
-                              stmts: ~[],
-                              expr: Some(expr),
-                              id: self.get_id(),
-                              rules: default_blk},
-                       span: expr.span};
+            let blk = spanned { node: { view_items: ~[],
+                                        stmts: ~[],
+                                        expr: Some(expr),
+                                        id: self.get_id(),
+                                        rules: default_blk},
+                                span: expr.span };
 
             arms.push({pats: pats, guard: guard, body: blk});
         }
@@ -1886,7 +1894,7 @@ fn parse_pat(refutable: bool) -> @pat {
             // HACK: parse @"..." as a literal of a vstore @str
             pat = match sub.node {
               pat_lit(e@@{
-                node: expr_lit(@{node: lit_str(_), span: _}), _
+                node: expr_lit(@spanned {node: lit_str(_), span: _}), _
               }) => {
                 let vst = @{id: self.get_id(), callee_id: self.get_id(),
                             node: expr_vstore(e, expr_vstore_box),
@@ -1903,7 +1911,7 @@ fn parse_pat(refutable: bool) -> @pat {
             // HACK: parse ~"..." as a literal of a vstore ~str
             pat = match sub.node {
               pat_lit(e@@{
-                node: expr_lit(@{node: lit_str(_), span: _}), _
+                node: expr_lit(@spanned {node: lit_str(_), span: _}), _
               }) => {
                 let vst = @{id: self.get_id(), callee_id: self.get_id(),
                             node: expr_vstore(e, expr_vstore_uniq),
@@ -1922,7 +1930,7 @@ fn parse_pat(refutable: bool) -> @pat {
               // HACK: parse &"..." as a literal of a borrowed str
               pat = match sub.node {
                   pat_lit(e@@{
-                      node: expr_lit(@{node: lit_str(_), span: _}), _
+                      node: expr_lit(@spanned {node: lit_str(_), span: _}), _
                   }) => {
                       let vst = @{
                           id: self.get_id(),
@@ -1947,7 +1955,7 @@ fn parse_pat(refutable: bool) -> @pat {
             if self.token == token::RPAREN {
                 hi = self.span.hi;
                 self.bump();
-                let lit = @{node: lit_nil, span: mk_sp(lo, hi)};
+                let lit = @spanned {node: lit_nil, span: mk_sp(lo, hi)};
                 let expr = self.mk_expr(lo, hi, expr_lit(lit));
                 pat = pat_lit(expr);
             } else {
@@ -2312,8 +2320,9 @@ fn parse_block_tail_(lo: BytePos, s: blk_check_mode,
                             match self.token {
                                 token::SEMI => {
                                     self.bump();
-                                    stmts.push(@{node: stmt_semi(e, stmt_id),
-                                                 ..*stmt});
+                                    stmts.push(@spanned {
+                                        node: stmt_semi(e, stmt_id),
+                                        .. *stmt});
                                 }
                                 token::RBRACE => {
                                     expr = Some(e);
@@ -2336,8 +2345,9 @@ fn parse_block_tail_(lo: BytePos, s: blk_check_mode,
                             match self.token {
                                 token::SEMI => {
                                     self.bump();
-                                    stmts.push(@{node: stmt_mac((*m), true),
-                                                 ..*stmt});
+                                    stmts.push(@spanned {
+                                        node: stmt_mac((*m), true),
+                                        .. *stmt});
                                 }
                                 token::RBRACE => {
                                     // if a block ends in `m!(arg)` without
@@ -2392,8 +2402,16 @@ fn parse_optional_onceness() -> ast::Onceness {
     fn parse_optional_ty_param_bounds() -> @~[ty_param_bound] {
         let mut bounds = ~[];
         if self.eat(token::COLON) {
-            while is_ident(self.token) {
-                if is_ident(self.token) {
+            loop {
+                if self.eat(token::BINOP(token::AND)) {
+                    if self.eat_keyword(~"static") {
+                        bounds.push(RegionTyParamBound);
+                    } else {
+                        self.span_err(copy self.span,
+                                      ~"`&static` is the only permissible \
+                                        region bound here");
+                    }
+                } else if is_ident(self.token) {
                     let maybe_bound = match self.token {
                       token::IDENT(copy sid, _) => {
                         match *self.id_to_str(sid) {
@@ -2406,7 +2424,7 @@ fn parse_optional_ty_param_bounds() -> @~[ty_param_bound] {
                                           ObsoleteLowerCaseKindBounds);
                             // Bogus value, but doesn't matter, since
                             // is an error
-                            Some(ty_param_bound(self.mk_ty_path(sid)))
+                            Some(TraitTyParamBound(self.mk_ty_path(sid)))
                           }
 
                           _ => None
@@ -2421,11 +2439,12 @@ fn parse_optional_ty_param_bounds() -> @~[ty_param_bound] {
                             bounds.push(bound);
                         }
                         None => {
-                            bounds.push(ty_param_bound(self.parse_ty(false)));
+                            let ty = self.parse_ty(false);
+                            bounds.push(TraitTyParamBound(ty));
                         }
                     }
                 } else {
-                    bounds.push(ty_param_bound(self.parse_ty(false)));
+                    break;
                 }
             }
         }
@@ -2804,11 +2823,11 @@ fn parse_item_struct() -> item_info {
 
         let actual_dtor = do the_dtor.map |dtor| {
             let (d_body, d_attrs, d_s) = *dtor;
-            {node: {id: self.get_id(),
-                    attrs: d_attrs,
-                    self_id: self.get_id(),
-                    body: d_body},
-             span: d_s}};
+            spanned { node: { id: self.get_id(),
+                              attrs: d_attrs,
+                              self_id: self.get_id(),
+                              body: d_body},
+                       span: d_s}};
         let _ = self.get_id();  // XXX: Workaround for crazy bug.
         let new_id = self.get_id();
         (class_name,
@@ -3301,11 +3320,11 @@ fn parse_struct_def() -> @struct_def {
         self.bump();
         let mut actual_dtor = do the_dtor.map |dtor| {
             let (d_body, d_attrs, d_s) = *dtor;
-            {node: {id: self.get_id(),
-                    attrs: d_attrs,
-                    self_id: self.get_id(),
-                    body: d_body},
-             span: d_s}
+            spanned { node: { id: self.get_id(),
+                              attrs: d_attrs,
+                              self_id: self.get_id(),
+                              body: d_body },
+                      span: d_s }
         };
 
         return @{
@@ -3585,9 +3604,9 @@ fn parse_item_or_view_item(+attrs: ~[attribute], items_allowed: bool,
               _ => self.fatal(~"expected open delimiter")
             };
             let m = ast::mac_invoc_tt(pth, tts);
-            let m: ast::mac = {node: m,
-                               span: mk_sp(self.span.lo,
-                                           self.span.hi)};
+            let m: ast::mac = spanned { node: m,
+                                        span: mk_sp(self.span.lo,
+                                                    self.span.hi) };
             let item_ = item_mac(m);
             return iovi_item(self.mk_item(lo, self.last_span.hi, id, item_,
                                           visibility, attrs));
index 4663b875bb5d7a23cf3b73dc852014a229da9a86..107547771292b7abb1333a5f5ab4f8663e12c351 100644 (file)
 export unop_prec;
 export token_to_binop;
 
+use ast::*;
 use parse::token::*;
 use parse::token::Token;
-use ast::*;
+
+use core::prelude::*;
 
 /// Unary operators have higher precedence than binary
 const unop_prec: uint = 100u;
index 04e6e187dbb2248cdb0ab54082c8b1638c63b391..93c030636239a8705782da2649ba5ad1593377af 100644 (file)
@@ -8,8 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use util::interner;
+use core::prelude::*;
+
+use ast;
+use ast_util;
+use parse::token;
 use util::interner::Interner;
+use util::interner;
+
+use core::cast;
+use core::char;
+use core::cmp;
+use core::str;
+use core::task;
 use std::map::HashMap;
 
 #[auto_encode]
@@ -329,10 +340,11 @@ mod special_idents {
     const clownshoes_foreign_mod: ident = ident { repr: 33 };
     const unnamed_field: ident = ident { repr: 34 };
     const c_abi: ident = ident { repr: 35 };
+    const type_self: ident = ident { repr: 36 };    // `Self`
 }
 
 struct ident_interner {
-    priv interner: util::interner::Interner<@~str>,
+    priv interner: Interner<@~str>,
 }
 
 impl ident_interner {
@@ -368,15 +380,43 @@ fn mk_ident_interner() -> @ident_interner {
                 // the indices here must correspond to the numbers in
                 // special_idents.
                 let init_vec = ~[
-                    @~"_", @~"anon", @~"drop", @~"", @~"unary", @~"!",
-                    @~"[]", @~"unary-", @~"__extensions__", @~"self",
-                    @~"item", @~"block", @~"stmt", @~"pat", @~"expr",
-                    @~"ty", @~"ident", @~"path", @~"tt", @~"matchers",
-                    @~"str", @~"TyVisitor", @~"arg", @~"descrim",
-                    @~"__rust_abi", @~"__rust_stack_shim", @~"TyDesc",
-                    @~"dtor", @~"main", @~"<opaque>", @~"blk", @~"static",
-                    @~"intrinsic", @~"__foreign_mod__", @~"__field__",
-                    @~"C"
+                    @~"_",                  // 0
+                    @~"anon",               // 1
+                    @~"drop",               // 2
+                    @~"",                   // 3
+                    @~"unary",              // 4
+                    @~"!",                  // 5
+                    @~"[]",                 // 6
+                    @~"unary-",             // 7
+                    @~"__extensions__",     // 8
+                    @~"self",               // 9
+                    @~"item",               // 10
+                    @~"block",              // 11
+                    @~"stmt",               // 12
+                    @~"pat",                // 13
+                    @~"expr",               // 14
+                    @~"ty",                 // 15
+                    @~"ident",              // 16
+                    @~"path",               // 17
+                    @~"tt",                 // 18
+                    @~"matchers",           // 19
+                    @~"str",                // 20
+                    @~"TyVisitor",          // 21
+                    @~"arg",                // 22
+                    @~"descrim",            // 23
+                    @~"__rust_abi",         // 24
+                    @~"__rust_stack_shim",  // 25
+                    @~"TyDesc",             // 26
+                    @~"dtor",               // 27
+                    @~"main",               // 28
+                    @~"<opaque>",           // 29
+                    @~"blk",                // 30
+                    @~"static",             // 31
+                    @~"intrinsic",          // 32
+                    @~"__foreign_mod__",    // 33
+                    @~"__field__",          // 34
+                    @~"C",                  // 35
+                    @~"Self",               // 36
                 ];
 
                 let rv = @ident_interner {
index d90341254cc3404e93b1d9d76052da86e7e56d5b..b3b267027ce7e8fe8c4e6a817441a9ad338037bd 100644 (file)
@@ -8,8 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use io::WriterUtil;
-use dvec::DVec;
+use core::prelude::*;
+
+use core::cmp;
+use core::dvec::DVec;
+use core::io::WriterUtil;
+use core::io;
+use core::str;
+use core::vec;
 
 /*
  * This pretty-printer is a direct reimplementation of Philip Karlton's
index 3b995addd62b3451a1d89b09d750a71bf40ac09f..f7117cc7043e2882e8d9afd27dcfd01927ea51fa 100644 (file)
@@ -8,16 +8,34 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use parse::{comments, lexer, token};
+use core::prelude::*;
+
+use ast::{RegionTyParamBound, TraitTyParamBound, required, provided};
+use ast;
+use ast_util;
+use ast_util::{operator_prec};
+use attr;
 use codemap::{CodeMap, BytePos};
+use codemap;
+use diagnostic;
+use parse::classify::{expr_is_simple_block, expr_requires_semi_to_be_stmt};
+use parse::classify::{stmt_ends_with_semi};
+use parse::token::ident_interner;
+use parse::{comments, lexer, token};
+use parse;
 use print::pp::{break_offset, word, printer, space, zerobreak, hardbreak};
 use print::pp::{breaks, consistent, inconsistent, eof};
-use ast::{required, provided};
-use ast_util::{operator_prec};
-use dvec::DVec;
-use parse::classify::*;
-use parse::token::ident_interner;
-use str::{push_str, push_char};
+use print::pp;
+use print::pprust;
+
+use core::char;
+use core::dvec::DVec;
+use core::io;
+use core::option;
+use core::str::{push_str, push_char};
+use core::str;
+use core::u64;
+use core::vec;
 
 // The ps is stored here to prevent recursive type.
 enum ann_node {
@@ -26,11 +44,14 @@ enum ann_node {
     node_expr(ps, @ast::expr),
     node_pat(ps, @ast::pat),
 }
-type pp_ann = {pre: fn@(ann_node), post: fn@(ann_node)};
+struct pp_ann {
+    pre: fn@(ann_node),
+    post: fn@(ann_node)
+}
 
 fn no_ann() -> pp_ann {
     fn ignore(_node: ann_node) { }
-    return {pre: ignore, post: ignore};
+    return pp_ann {pre: ignore, post: ignore};
 }
 
 type ps =
@@ -67,7 +88,7 @@ fn rust_printer(writer: io::Writer, intr: @ident_interner) -> ps {
 }
 
 const indent_unit: uint = 4u;
-const alt_indent_unit: uint = 2u;
+const match_indent_unit: uint = 2u;
 
 const default_columns: uint = 78u;
 
@@ -581,7 +602,8 @@ fn print_item(s: ps, &&item: @ast::item) {
         }
         bclose(s, item.span);
       }
-      ast::item_mac({node: ast::mac_invoc_tt(pth, ref tts), _}) => {
+      ast::item_mac(ast::spanned { node: ast::mac_invoc_tt(pth, ref tts),
+                                   _}) => {
         print_visibility(s, item.vis);
         print_path(s, pth, false);
         word(s.s, ~"! ");
@@ -1235,7 +1257,7 @@ fn print_field(s: ps, field: ast::field) {
         print_block(s, (*blk));
       }
       ast::expr_match(expr, ref arms) => {
-        cbox(s, alt_indent_unit);
+        cbox(s, match_indent_unit);
         ibox(s, 4);
         word_nbsp(s, ~"match");
         print_expr(s, expr);
@@ -1244,7 +1266,7 @@ fn print_field(s: ps, field: ast::field) {
         let len = (*arms).len();
         for (*arms).eachi |i, arm| {
             space(s.s);
-            cbox(s, alt_indent_unit);
+            cbox(s, match_indent_unit);
             ibox(s, 0u);
             let mut first = true;
             for arm.pats.each |p| {
@@ -1277,7 +1299,7 @@ fn print_field(s: ps, field: ast::field) {
                             ast::expr_block(ref blk) => {
                                 // the block will close the pattern's ibox
                                 print_block_unclosed_indent(
-                                    s, (*blk), alt_indent_unit);
+                                    s, (*blk), match_indent_unit);
                             }
                             _ => {
                                 end(s); // close the ibox for the pattern
@@ -1294,10 +1316,10 @@ fn print_field(s: ps, field: ast::field) {
                 }
             } else {
                 // the block will close the pattern's ibox
-                print_block_unclosed_indent(s, arm.body, alt_indent_unit);
+                print_block_unclosed_indent(s, arm.body, match_indent_unit);
             }
         }
-        bclose_(s, expr.span, alt_indent_unit);
+        bclose_(s, expr.span, match_indent_unit);
       }
       ast::expr_fn(proto, decl, ref body, cap_clause) => {
         // containing cbox, will be closed by print-block at }
@@ -1769,9 +1791,12 @@ fn print_arg_mode(s: ps, m: ast::mode) {
 fn print_bounds(s: ps, bounds: @~[ast::ty_param_bound]) {
     if bounds.is_not_empty() {
         word(s.s, ~":");
-        for vec::each(*bounds) |bound| {
+        for vec::each(*bounds) |&bound| {
             nbsp(s);
-            print_type(s, **bound);
+            match bound {
+                TraitTyParamBound(ty) => print_type(s, ty),
+                RegionTyParamBound => word(s.s, ~"&static"),
+            }
         }
     }
 }
index 687504b873e3773ebaf9d12bd6f5adcfcb4f98a3..0777269f8f7fc3e27cd659fa45e734844e6f97e4 100644 (file)
@@ -16,8 +16,6 @@
 
 #[crate_type = "lib"];
 
-#[no_core];
-
 #[legacy_modes];
 #[legacy_exports];
 
 #[allow(deprecated_mode)];
 #[warn(deprecated_pattern)];
 
-extern mod core(vers = "0.6");
-extern mod std(vers = "0.6");
+#[no_core];
 
+extern mod core(vers = "0.6");
 use core::*;
 
+extern mod std(vers = "0.6");
+
 pub mod syntax {
     pub use ext;
     pub use parse;
index cfa3a4224c50a5438c7960f25c9bb2cf2b7a2ac7..fd759a3294158f1180649498110cdb442aded075 100644 (file)
 // 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 std::map;
+
+use core::prelude::*;
+
+use core::dvec::DVec;
 use std::map::HashMap;
-use dvec::DVec;
-use cmp::Eq;
-use hash::Hash;
-use to_bytes::IterBytes;
+use std::map;
 
 type hash_interner<T: Const> =
     {map: HashMap<T, uint>,
index 9a47edfeb05a6707bb8fa4138c88dc1d67231ac2..25ea76d9b513609ea878217357c8331c9be93485 100644 (file)
@@ -8,9 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::prelude::*;
 
 use ast::*;
+use ast;
+use ast_util;
 use codemap::span;
+use parse;
+
+use core::option;
+use core::vec;
 
 // 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
@@ -52,51 +59,56 @@ fn tps_of_fn(fk: fn_kind) -> ~[ty_param] {
     }
 }
 
-type visitor<E> =
-    @{visit_mod: fn@(_mod, span, node_id, E, vt<E>),
-      visit_view_item: fn@(@view_item, E, vt<E>),
-      visit_foreign_item: fn@(@foreign_item, E, vt<E>),
-      visit_item: fn@(@item, E, vt<E>),
-      visit_local: fn@(@local, E, vt<E>),
-      visit_block: fn@(ast::blk, E, vt<E>),
-      visit_stmt: fn@(@stmt, E, vt<E>),
-      visit_arm: fn@(arm, E, vt<E>),
-      visit_pat: fn@(@pat, E, vt<E>),
-      visit_decl: fn@(@decl, E, vt<E>),
-      visit_expr: fn@(@expr, E, vt<E>),
-      visit_expr_post: fn@(@expr, E, vt<E>),
-      visit_ty: fn@(@Ty, E, vt<E>),
-      visit_ty_params: fn@(~[ty_param], E, vt<E>),
-      visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>),
-      visit_ty_method: fn@(ty_method, E, vt<E>),
-      visit_trait_method: fn@(trait_method, E, vt<E>),
-      visit_struct_def: fn@(@struct_def, ident, ~[ty_param], node_id, E,
-                            vt<E>),
-      visit_struct_field: fn@(@struct_field, E, vt<E>),
-      visit_struct_method: fn@(@method, E, vt<E>)};
+struct Visitor<E> {
+    visit_mod: fn@(_mod, span, node_id, E, vt<E>),
+    visit_view_item: fn@(@view_item, E, vt<E>),
+    visit_foreign_item: fn@(@foreign_item, E, vt<E>),
+    visit_item: fn@(@item, E, vt<E>),
+    visit_local: fn@(@local, E, vt<E>),
+    visit_block: fn@(ast::blk, E, vt<E>),
+    visit_stmt: fn@(@stmt, E, vt<E>),
+    visit_arm: fn@(arm, E, vt<E>),
+    visit_pat: fn@(@pat, E, vt<E>),
+    visit_decl: fn@(@decl, E, vt<E>),
+    visit_expr: fn@(@expr, E, vt<E>),
+    visit_expr_post: fn@(@expr, E, vt<E>),
+    visit_ty: fn@(@Ty, E, vt<E>),
+    visit_ty_params: fn@(~[ty_param], E, vt<E>),
+    visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>),
+    visit_ty_method: fn@(ty_method, E, vt<E>),
+    visit_trait_method: fn@(trait_method, E, vt<E>),
+    visit_struct_def: fn@(@struct_def, ident, ~[ty_param], node_id, E,
+                          vt<E>),
+    visit_struct_field: fn@(@struct_field, E, vt<E>),
+    visit_struct_method: fn@(@method, E, vt<E>)
+}
+
+type visitor<E> = @Visitor<E>;
 
 fn default_visitor<E>() -> visitor<E> {
-    return @{visit_mod: |a,b,c,d,e|visit_mod::<E>(a, b, c, d, e),
-          visit_view_item: |a,b,c|visit_view_item::<E>(a, b, c),
-          visit_foreign_item: |a,b,c|visit_foreign_item::<E>(a, b, c),
-          visit_item: |a,b,c|visit_item::<E>(a, b, c),
-          visit_local: |a,b,c|visit_local::<E>(a, b, c),
-          visit_block: |a,b,c|visit_block::<E>(a, b, c),
-          visit_stmt: |a,b,c|visit_stmt::<E>(a, b, c),
-          visit_arm: |a,b,c|visit_arm::<E>(a, b, c),
-          visit_pat: |a,b,c|visit_pat::<E>(a, b, c),
-          visit_decl: |a,b,c|visit_decl::<E>(a, b, c),
-          visit_expr: |a,b,c|visit_expr::<E>(a, b, c),
-          visit_expr_post: |_a,_b,_c| (),
-          visit_ty: |a,b,c|skip_ty::<E>(a, b, c),
-          visit_ty_params: |a,b,c|visit_ty_params::<E>(a, b, c),
-          visit_fn: |a,b,c,d,e,f,g|visit_fn::<E>(a, b, c, d, e, f, g),
-          visit_ty_method: |a,b,c|visit_ty_method::<E>(a, b, c),
-          visit_trait_method: |a,b,c|visit_trait_method::<E>(a, b, c),
-          visit_struct_def: |a,b,c,d,e,f|visit_struct_def::<E>(a, b, c,
-                                                               d, e, f),
-          visit_struct_field: |a,b,c|visit_struct_field::<E>(a, b, c),
-          visit_struct_method: |a,b,c|visit_struct_method::<E>(a, b, c)};
+    return @Visitor {
+        visit_mod: |a,b,c,d,e|visit_mod::<E>(a, b, c, d, e),
+        visit_view_item: |a,b,c|visit_view_item::<E>(a, b, c),
+        visit_foreign_item: |a,b,c|visit_foreign_item::<E>(a, b, c),
+        visit_item: |a,b,c|visit_item::<E>(a, b, c),
+        visit_local: |a,b,c|visit_local::<E>(a, b, c),
+        visit_block: |a,b,c|visit_block::<E>(a, b, c),
+        visit_stmt: |a,b,c|visit_stmt::<E>(a, b, c),
+        visit_arm: |a,b,c|visit_arm::<E>(a, b, c),
+        visit_pat: |a,b,c|visit_pat::<E>(a, b, c),
+        visit_decl: |a,b,c|visit_decl::<E>(a, b, c),
+        visit_expr: |a,b,c|visit_expr::<E>(a, b, c),
+        visit_expr_post: |_a,_b,_c| (),
+        visit_ty: |a,b,c|skip_ty::<E>(a, b, c),
+        visit_ty_params: |a,b,c|visit_ty_params::<E>(a, b, c),
+        visit_fn: |a,b,c,d,e,f,g|visit_fn::<E>(a, b, c, d, e, f, g),
+        visit_ty_method: |a,b,c|visit_ty_method::<E>(a, b, c),
+        visit_trait_method: |a,b,c|visit_trait_method::<E>(a, b, c),
+        visit_struct_def: |a,b,c,d,e,f|visit_struct_def::<E>(a, b, c,
+                                                             d, e, f),
+        visit_struct_field: |a,b,c|visit_struct_field::<E>(a, b, c),
+        visit_struct_method: |a,b,c|visit_struct_method::<E>(a, b, c)
+    };
 }
 
 fn visit_crate<E>(c: crate, e: E, v: vt<E>) {
@@ -276,8 +288,11 @@ fn visit_foreign_item<E>(ni: @foreign_item, e: E, v: vt<E>) {
 }
 
 fn visit_ty_param_bounds<E>(bounds: @~[ty_param_bound], e: E, v: vt<E>) {
-    for vec::each(*bounds) |bound| {
-        (v.visit_ty)(**bound, e, v)
+    for bounds.each |&bound| {
+        match bound {
+            TraitTyParamBound(ty) => (v.visit_ty)(ty, e, v),
+            RegionTyParamBound => ()
+        }
     }
 }
 
@@ -492,43 +507,46 @@ fn visit_arm<E>(a: arm, e: E, v: vt<E>) {
 // Simpler, non-context passing interface. Always walks the whole tree, simply
 // calls the given functions on the nodes.
 
-type simple_visitor =
-    @{visit_mod: fn@(_mod, span, node_id),
-      visit_view_item: fn@(@view_item),
-      visit_foreign_item: fn@(@foreign_item),
-      visit_item: fn@(@item),
-      visit_local: fn@(@local),
-      visit_block: fn@(ast::blk),
-      visit_stmt: fn@(@stmt),
-      visit_arm: fn@(arm),
-      visit_pat: fn@(@pat),
-      visit_decl: fn@(@decl),
-      visit_expr: fn@(@expr),
-      visit_expr_post: fn@(@expr),
-      visit_ty: fn@(@Ty),
-      visit_ty_params: fn@(~[ty_param]),
-      visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id),
-      visit_ty_method: fn@(ty_method),
-      visit_trait_method: fn@(trait_method),
-      visit_struct_def: fn@(@struct_def, ident, ~[ty_param], node_id),
-      visit_struct_field: fn@(@struct_field),
-      visit_struct_method: fn@(@method)};
+struct SimpleVisitor {
+    visit_mod: fn@(_mod, span, node_id),
+    visit_view_item: fn@(@view_item),
+    visit_foreign_item: fn@(@foreign_item),
+    visit_item: fn@(@item),
+    visit_local: fn@(@local),
+    visit_block: fn@(ast::blk),
+    visit_stmt: fn@(@stmt),
+    visit_arm: fn@(arm),
+    visit_pat: fn@(@pat),
+    visit_decl: fn@(@decl),
+    visit_expr: fn@(@expr),
+    visit_expr_post: fn@(@expr),
+    visit_ty: fn@(@Ty),
+    visit_ty_params: fn@(~[ty_param]),
+    visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id),
+    visit_ty_method: fn@(ty_method),
+    visit_trait_method: fn@(trait_method),
+    visit_struct_def: fn@(@struct_def, ident, ~[ty_param], node_id),
+    visit_struct_field: fn@(@struct_field),
+    visit_struct_method: fn@(@method)
+}
+
+type simple_visitor = @SimpleVisitor;
 
 fn simple_ignore_ty(_t: @Ty) {}
 
-fn default_simple_visitor() -> simple_visitor {
-    return @{visit_mod: fn@(_m: _mod, _sp: span, _id: node_id) { },
-          visit_view_item: fn@(_vi: @view_item) { },
-          visit_foreign_item: fn@(_ni: @foreign_item) { },
-          visit_item: fn@(_i: @item) { },
-          visit_local: fn@(_l: @local) { },
-          visit_block: fn@(_b: ast::blk) { },
-          visit_stmt: fn@(_s: @stmt) { },
-          visit_arm: fn@(_a: arm) { },
-          visit_pat: fn@(_p: @pat) { },
-          visit_decl: fn@(_d: @decl) { },
-          visit_expr: fn@(_e: @expr) { },
-          visit_expr_post: fn@(_e: @expr) { },
+fn default_simple_visitor() -> @SimpleVisitor {
+    return @SimpleVisitor {visit_mod: |_m: _mod, _sp: span, _id: node_id| { },
+          visit_view_item: |_vi: @view_item| { },
+          visit_foreign_item: |_ni: @foreign_item| { },
+          visit_item: |_i: @item| { },
+          visit_local: |_l: @local| { },
+          visit_block: |_b: ast::blk| { },
+          visit_stmt: |_s: @stmt| { },
+          visit_arm: |_a: arm| { },
+          visit_pat: |_p: @pat| { },
+          visit_decl: |_d: @decl| { },
+          visit_expr: |_e: @expr| { },
+          visit_expr_post: |_e: @expr| { },
           visit_ty: simple_ignore_ty,
           visit_ty_params: fn@(_ps: ~[ty_param]) {},
           visit_fn: fn@(_fk: fn_kind, _d: fn_decl, _b: blk, _sp: span,
@@ -633,37 +651,37 @@ fn v_struct_method(f: fn@(@method), m: @method, &&e: (), v: vt<()>) {
         f(m);
         visit_struct_method(m, e, v);
     }
-    return mk_vt(@{visit_mod: |a,b,c,d,e|v_mod(v.visit_mod, a, b, c, d, e),
-                visit_view_item: |a,b,c|
-                    v_view_item(v.visit_view_item, a, b, c),
-                visit_foreign_item:
-                    |a,b,c|v_foreign_item(v.visit_foreign_item, a, b, c),
-                visit_item: |a,b,c|v_item(v.visit_item, a, b, c),
-                visit_local: |a,b,c|v_local(v.visit_local, a, b, c),
-                visit_block: |a,b,c|v_block(v.visit_block, a, b, c),
-                visit_stmt: |a,b,c|v_stmt(v.visit_stmt, a, b, c),
-                visit_arm: |a,b,c|v_arm(v.visit_arm, a, b, c),
-                visit_pat: |a,b,c|v_pat(v.visit_pat, a, b, c),
-                visit_decl: |a,b,c|v_decl(v.visit_decl, a, b, c),
-                visit_expr: |a,b,c|v_expr(v.visit_expr, a, b, c),
-                visit_expr_post: |a,b,c| v_expr_post(v.visit_expr_post,
-                                                     a, b, c),
-                visit_ty: visit_ty,
-                visit_ty_params: |a,b,c|
-                    v_ty_params(v.visit_ty_params, a, b, c),
-                visit_fn: |a,b,c,d,e,f,g|
-                    v_fn(v.visit_fn, a, b, c, d, e, f, g),
-                visit_ty_method: |a,b,c|
-                    v_ty_method(v.visit_ty_method, a, b, c),
-                visit_trait_method: |a,b,c|
-                    v_trait_method(v.visit_trait_method, a, b, c),
-                visit_struct_def: |a,b,c,d,e,f|
-                    v_struct_def(v.visit_struct_def, a, b, c, d, e, f),
-                visit_struct_field: |a,b,c|
-                    v_struct_field(v.visit_struct_field, a, b, c),
-                visit_struct_method: |a,b,c|
-                    v_struct_method(v.visit_struct_method, a, b, c)
-               });
+    return mk_vt(@Visitor {
+        visit_mod: |a,b,c,d,e|v_mod(v.visit_mod, a, b, c, d, e),
+        visit_view_item: |a,b,c| v_view_item(v.visit_view_item, a, b, c),
+        visit_foreign_item:
+            |a,b,c|v_foreign_item(v.visit_foreign_item, a, b, c),
+        visit_item: |a,b,c|v_item(v.visit_item, a, b, c),
+        visit_local: |a,b,c|v_local(v.visit_local, a, b, c),
+        visit_block: |a,b,c|v_block(v.visit_block, a, b, c),
+        visit_stmt: |a,b,c|v_stmt(v.visit_stmt, a, b, c),
+        visit_arm: |a,b,c|v_arm(v.visit_arm, a, b, c),
+        visit_pat: |a,b,c|v_pat(v.visit_pat, a, b, c),
+        visit_decl: |a,b,c|v_decl(v.visit_decl, a, b, c),
+        visit_expr: |a,b,c|v_expr(v.visit_expr, a, b, c),
+        visit_expr_post: |a,b,c| v_expr_post(v.visit_expr_post,
+                                             a, b, c),
+        visit_ty: visit_ty,
+        visit_ty_params: |a,b,c|
+            v_ty_params(v.visit_ty_params, a, b, c),
+        visit_fn: |a,b,c,d,e,f,g|
+            v_fn(v.visit_fn, a, b, c, d, e, f, g),
+        visit_ty_method: |a,b,c|
+            v_ty_method(v.visit_ty_method, a, b, c),
+        visit_trait_method: |a,b,c|
+            v_trait_method(v.visit_trait_method, a, b, c),
+        visit_struct_def: |a,b,c,d,e,f|
+            v_struct_def(v.visit_struct_def, a, b, c, d, e, f),
+        visit_struct_field: |a,b,c|
+            v_struct_field(v.visit_struct_field, a, b, c),
+        visit_struct_method: |a,b,c|
+            v_struct_method(v.visit_struct_method, a, b, c)
+    });
 }
 
 // Local Variables:
index 1170ffba3ac5191930b40c897d4569a9d8a296a3..4d392c86feb6389f550d8110d36fa90d66c09251 160000 (submodule)
--- a/src/libuv
+++ b/src/libuv
@@ -1 +1 @@
-Subproject commit 1170ffba3ac5191930b40c897d4569a9d8a296a3
+Subproject commit 4d392c86feb6389f550d8110d36fa90d66c09251
diff --git a/src/rt/arch/arm/_context.S b/src/rt/arch/arm/_context.S
new file mode 100644 (file)
index 0000000..8d370c2
--- /dev/null
@@ -0,0 +1,47 @@
+.text
+.code 32
+.arm
+.align
+
+
+.globl swap_registers
+swap_registers:
+       str r0, [r0, #0]
+       str r3, [r0, #12]
+       str r4, [r0, #16]
+       str r5, [r0, #20]
+       str r6, [r0, #24]
+       str r7, [r0, #28]
+       str r8, [r0, #32]
+       str r9, [r0, #36]
+       str r10, [r0, #40]
+       str r11, [r0, #44]
+       str r12, [r0, #48]
+       str sp, [r0, #52] 
+       str lr, [r0, #56]
+
+       mrs r2, cpsr
+       str r2, [r0, #64]
+       
+
+       ldr r0, [r1, #0]
+       ldr r3, [r1, #12]
+       ldr r4, [r1, #16]
+       ldr r5, [r1, #20]
+       ldr r6, [r1, #24]
+       ldr r7, [r1, #28]
+       ldr r8, [r1, #32]
+       ldr r9, [r1, #36]
+       ldr r10, [r1, #40]
+       ldr r11, [r1, #44]
+       ldr r12, [r1, #48]
+       
+       ldr sp, [r1, #52]
+       ldr lr, [r1, #56]
+        
+       ldr r2, [r1, #64]
+       msr cpsr_cxsf, r2
+
+       mov pc, lr
+
+
diff --git a/src/rt/arch/arm/ccall.S b/src/rt/arch/arm/ccall.S
new file mode 100644 (file)
index 0000000..4b89cc9
--- /dev/null
@@ -0,0 +1,27 @@
+.text
+.code 32
+.arm
+.align
+
+.globl __morestack
+.hidden __morestack
+__morestack:
+       mov r3, sp
+       mov sp, r2
+       
+       str r3, [sp]
+       str lr, [sp, #-4]
+       
+       sub sp, #8
+       
+       blx r1
+
+       add sp, #8
+       
+       ldr lr, [sp, #-4]
+       ldr r3, [sp] 
+       
+       mov sp, r3
+       mov pc, lr
+       
+
diff --git a/src/rt/arch/arm/context.cpp b/src/rt/arch/arm/context.cpp
new file mode 100644 (file)
index 0000000..dbf06a5
--- /dev/null
@@ -0,0 +1,36 @@
+
+#include "context.h"
+#include "../../rust_globals.h"
+
+extern "C" void CDECL swap_registers(registers_t *oregs,
+                                     registers_t *regs)
+asm ("swap_registers");
+
+context::context()
+{
+    assert((void*)&regs == (void*)this);
+    memset(&regs, 0, sizeof(regs));
+}
+
+void context::swap(context &out)
+{
+    swap_registers(&out.regs, &regs);
+}
+
+void context::call(void *f, void *arg, void *stack)
+{
+  // Get the current context, which we will then modify to call the
+  // given function.
+  swap(*this);
+
+  // set up the stack
+  uint32_t *sp = ( uint32_t *)stack;
+  //sp = align_down(sp);
+  // The final return address. 0 indicates the bottom of the stack
+  *--sp = 0;
+
+  regs.data[0] = ( uint32_t )arg; // r0
+  regs.data[13] = ( uint32_t )sp; //#52 sp, r13
+  regs.data[14] = ( uint32_t )f;  //#60 pc, r15 --> lr,
+  // Last base pointer on the stack should be 0
+}
diff --git a/src/rt/arch/arm/context.h b/src/rt/arch/arm/context.h
new file mode 100644 (file)
index 0000000..6c7db76
--- /dev/null
@@ -0,0 +1,43 @@
+// -*- mode: c++ -*-
+
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+#include <cstdlib>
+#include <inttypes.h>
+#include <stdint.h>
+//#include <xmmintrin.h>
+
+#include "vg/memcheck.h"
+
+template<typename T>
+T align_down(T sp)
+{
+    // There is no platform we care about that needs more than a
+    // 16-byte alignment.
+    return (T)((uint32_t)sp & ~(16 - 1));
+}
+
+// The struct in which we store the saved data.  This is mostly the
+// volatile registers and instruction pointer, but it also includes
+// RCX/RDI which are used to pass arguments.  The indices for each
+// register are found in "regs.h".  Note that the alignment must be
+// 16 bytes so that SSE instructions can be used.
+#include "regs.h"
+struct registers_t {
+    uint32_t data[RUSTRT_MAX];
+} __attribute__((aligned(16)));
+
+class context {
+public:
+    registers_t regs;
+
+    context();
+
+    context *next;
+
+    void swap(context &out);
+    void call(void *f, void *arg, void *sp);
+};
+
+#endif
diff --git a/src/rt/arch/arm/gpr.cpp b/src/rt/arch/arm/gpr.cpp
new file mode 100644 (file)
index 0000000..32a68d0
--- /dev/null
@@ -0,0 +1,15 @@
+#include "gpr.h"
+
+#define LOAD(rn) do { \
+    uintptr_t tmp; \
+    asm("mov %%" #rn ",%0" : "=r" (tmp) :); \
+    this->rn = tmp; \
+} while (0)
+
+void rust_gpr::load() {
+    LOAD(r0); LOAD(r1); LOAD(r2); LOAD(r3);
+    LOAD(r4); LOAD(r5); LOAD(r6); LOAD(r7);
+    LOAD(r8);  LOAD(r9);  LOAD(r10); LOAD(r11);
+    LOAD(r12); LOAD(r13); LOAD(r14); LOAD(r15);
+}
+
diff --git a/src/rt/arch/arm/gpr.h b/src/rt/arch/arm/gpr.h
new file mode 100644 (file)
index 0000000..472c8a0
--- /dev/null
@@ -0,0 +1,23 @@
+// General-purpose registers. This structure is used during stack crawling.
+
+#ifndef GPR_H
+#define GPR_H
+
+#include "rust_gpr_base.h"
+
+class rust_gpr : public rust_gpr_base {
+public:
+    uintptr_t r0, r1, r2, r3, r4, r5, r6, r7;
+    uintptr_t  r8,  r9, r10, r11, r12, r13, r14, r15;
+
+    inline uintptr_t get_fp() { return r11; }
+    inline uintptr_t get_ip() { return r12; }
+
+    inline void set_fp(uintptr_t new_fp) { r11 = new_fp; }
+    inline void set_ip(uintptr_t new_ip) { r12 = new_ip; }
+
+    void load();
+};
+
+#endif
+
diff --git a/src/rt/arch/arm/record_sp.S b/src/rt/arch/arm/record_sp.S
new file mode 100644 (file)
index 0000000..193104d
--- /dev/null
@@ -0,0 +1,61 @@
+.text
+.code 32
+.arm
+.align
+
+
+.globl record_sp_limit
+.globl get_sp_limit
+.globl get_sp
+
+record_sp_limit:
+       mov r3, r0
+       ldr r0, =my_cpu
+       mov r1, #0
+       mov r2, #0
+    stmfd   sp!, {r3, r7}
+    ldr     r7, =345
+    swi     #0
+    ldmfd   sp!, {r3, r7}
+    movs    r0, r0
+       movmi   r0, #0
+
+       ldr r1, =my_array
+       str r3, [r1, r0]
+       mov pc, lr
+
+
+get_sp_limit:
+    ldr r0, =my_cpu
+       mov r1, #0
+       mov r2, #0
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =345
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+       movmi   r0, #0
+       mov r3, r0
+
+       ldr r1, =my_array
+       ldr r0, [r1, r3]
+       mov pc, lr
+
+
+get_sp:
+       mov r0, sp
+       mov pc, lr
+       
+.data
+my_cpu:        .long   0
+.global my_array
+my_array:      
+       .long   0
+       .long   0
+       .long   0
+       .long   0
+       .long   0
+       .long   0
+       .long   0
+       .long   0       
+.end
diff --git a/src/rt/arch/arm/regs.h b/src/rt/arch/arm/regs.h
new file mode 100644 (file)
index 0000000..a49fcab
--- /dev/null
@@ -0,0 +1,21 @@
+#define RUSTRT_RBX   0
+#define RUSTRT_RSP   1
+#define RUSTRT_RBP   2
+// RCX on Windows, RDI elsewhere
+#define RUSTRT_ARG0  3
+#define RUSTRT_R12   4
+#define RUSTRT_R13   5
+#define RUSTRT_R14   6
+#define RUSTRT_R15   7
+#define RUSTRT_IP    8
+
+#define RUSTRT_MAX  32
+
+// ARG0 is the register in which the first argument goes.
+// Naturally this depends on your operating system.
+#   define RUSTRT_ARG0_S r0
+#   define RUSTRT_ARG1_S r1
+#   define RUSTRT_ARG2_S r2
+#   define RUSTRT_ARG3_S r3
+
+
diff --git a/src/rt/bigint/bigint.h b/src/rt/bigint/bigint.h
deleted file mode 100644 (file)
index b4c48f0..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/* bigint.h - include file for bigint package
-**
-** This library lets you do math on arbitrarily large integers.  It's
-** pretty fast - compared with the multi-precision routines in the "bc"
-** calculator program, these routines are between two and twelve times faster,
-** except for division which is maybe half as fast.
-**
-** The calling convention is a little unusual.  There's a basic problem
-** with writing a math library in a language that doesn't do automatic
-** garbage collection - what do you do about intermediate results?
-** You'd like to be able to write code like this:
-**
-**     d = bi_sqrt( bi_add( bi_multiply( x, x ), bi_multiply( y, y ) ) );
-**
-** That works fine when the numbers being passed back and forth are
-** actual values - ints, floats, or even fixed-size structs.  However,
-** when the numbers can be any size, as in this package, then you have
-** to pass them around as pointers to dynamically-allocated objects.
-** Those objects have to get de-allocated after you are done with them.
-** But how do you de-allocate the intermediate results in a complicated
-** multiple-call expression like the above?
-**
-** There are two common solutions to this problem.  One, switch all your
-** code to a language that provides automatic garbage collection, for
-** example Java.  This is a fine idea and I recommend you do it wherever
-** it's feasible.  Two, change your routines to use a calling convention
-** that prevents people from writing multiple-call expressions like that.
-** The resulting code will be somewhat clumsy-looking, but it will work
-** just fine.
-**
-** This package uses a third method, which I haven't seen used anywhere
-** before.  It's simple: each number can be used precisely once, after
-** which it is automatically de-allocated.  This handles the anonymous
-** intermediate values perfectly.  Named values still need to be copied
-** and freed explicitly.  Here's the above example using this convention:
-**
-**     d = bi_sqrt( bi_add(
-**             bi_multiply( bi_copy( x ), bi_copy( x ) ),
-**             bi_multiply( bi_copy( y ), bi_copy( y ) ) ) );
-**     bi_free( x );
-**     bi_free( y );
-**
-** Or, since the package contains a square routine, you could just write:
-**
-**     d = bi_sqrt( bi_add( bi_square( x ), bi_square( y ) ) );
-**
-** This time the named values are only being used once, so you don't
-** have to copy and free them.
-**
-** This really works, however you do have to be very careful when writing
-** your code.  If you leave out a bi_copy() and use a value more than once,
-** you'll get a runtime error about "zero refs" and a SIGFPE.  Run your
-** code in a debugger, get a backtrace to see where the call was, and then
-** eyeball the code there to see where you need to add the bi_copy().
-**
-**
-** Copyright © 2000 by Jef Poskanzer <jef@mail.acme.com>.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions
-** are met:
-** 1. Redistributions of source code must retain the above copyright
-**    notice, this list of conditions and the following disclaimer.
-** 2. Redistributions in binary form must reproduce the above copyright
-**    notice, this list of conditions and the following disclaimer in the
-**    documentation and/or other materials provided with the distribution.
-**
-** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-** SUCH DAMAGE.
-*/
-
-
-/* Type definition for bigints - it's an opaque type, the real definition
-** is in bigint.c.
-*/
-typedef void* bigint;
-
-
-/* Some convenient pre-initialized numbers.  These are all permanent,
-** so you can use them as many times as you want without calling bi_copy().
-*/
-extern bigint bi_0, bi_1, bi_2, bi_10, bi_m1, bi_maxint, bi_minint;
-
-
-/* Initialize the bigint package.  You must call this when your program
-** starts up.
-*/
-void bi_initialize( void );
-
-/* Shut down the bigint package.  You should call this when your program
-** exits.  It's not actually required, but it does do some consistency
-** checks which help keep your program bug-free, so you really ought
-** to call it.
-*/
-void bi_terminate( void );
-
-/* Run in unsafe mode, skipping most runtime checks.  Slightly faster.
-** Once your code is debugged you can add this call after bi_initialize().
-*/
-void bi_no_check( void );
-
-/* Make a copy of a bigint.  You must call this if you want to use a
-** bigint more than once.  (Or you can make the bigint permanent.)
-** Note that this routine is very cheap - all it actually does is
-** increment a reference counter.
-*/
-bigint bi_copy( bigint bi );
-
-/* Make a bigint permanent, so it doesn't get automatically freed when
-** used as an operand.
-*/
-void bi_permanent( bigint bi );
-
-/* Undo bi_permanent().  The next use will free the bigint. */
-void bi_depermanent( bigint bi );
-
-/* Explicitly free a bigint.  Normally bigints get freed automatically
-** when they are used as an operand.  This routine lets you free one
-** without using it.  If the bigint is permanent, this doesn't do
-** anything, you have to depermanent it first.
-*/
-void bi_free( bigint bi );
-
-/* Compare two bigints.  Returns -1, 0, or 1. */
-int bi_compare( bigint bia, bigint bib );
-
-/* Convert an int to a bigint. */
-bigint int_to_bi( int i );
-
-/* Convert a string to a bigint. */
-bigint str_to_bi( char* str );
-
-/* Convert a bigint to an int.  SIGFPE on overflow. */
-int bi_to_int( bigint bi );
-
-/* Write a bigint to a file. */
-void bi_print( FILE* f, bigint bi );
-
-/* Read a bigint from a file. */
-bigint bi_scan( FILE* f );
-
-
-/* Operations on a bigint and a regular int. */
-
-/* Add an int to a bigint. */
-bigint bi_int_add( bigint bi, int i );
-
-/* Subtract an int from a bigint. */
-bigint bi_int_subtract( bigint bi, int i );
-
-/* Multiply a bigint by an int. */
-bigint bi_int_multiply( bigint bi, int i );
-
-/* Divide a bigint by an int.  SIGFPE on divide-by-zero. */
-bigint bi_int_divide( bigint binumer, int denom );
-
-/* Take the remainder of a bigint by an int, with an int result.
-** SIGFPE if m is zero.
-*/
-int bi_int_rem( bigint bi, int m );
-
-/* Take the modulus of a bigint by an int, with an int result.
-** Note that mod is not rem: mod is always within [0..m), while
-** rem can be negative.  SIGFPE if m is zero or negative.
-*/
-int bi_int_mod( bigint bi, int m );
-
-
-/* Basic operations on two bigints. */
-
-/* Add two bigints. */
-bigint bi_add( bigint bia, bigint bib );
-
-/* Subtract bib from bia. */
-bigint bi_subtract( bigint bia, bigint bib );
-
-/* Multiply two bigints. */
-bigint bi_multiply( bigint bia, bigint bib );
-
-/* Divide one bigint by another.  SIGFPE on divide-by-zero. */
-bigint bi_divide( bigint binumer, bigint bidenom );
-
-/* Binary division of one bigint by another.  SIGFPE on divide-by-zero.
-** This is here just for testing.  It's about five times slower than
-** regular division.
-*/
-bigint bi_binary_divide( bigint binumer, bigint bidenom );
-
-/* Take the remainder of one bigint by another.  SIGFPE if bim is zero. */
-bigint bi_rem( bigint bia, bigint bim );
-
-/* Take the modulus of one bigint by another.  Note that mod is not rem:
-** mod is always within [0..bim), while rem can be negative.  SIGFPE if
-** bim is zero or negative.
-*/
-bigint bi_mod( bigint bia, bigint bim );
-
-
-/* Some less common operations. */
-
-/* Negate a bigint. */
-bigint bi_negate( bigint bi );
-
-/* Absolute value of a bigint. */
-bigint bi_abs( bigint bi );
-
-/* Divide a bigint in half. */
-bigint bi_half( bigint bi );
-
-/* Multiply a bigint by two. */
-bigint bi_double( bigint bi );
-
-/* Square a bigint. */
-bigint bi_square( bigint bi );
-
-/* Raise bi to the power of biexp.  SIGFPE if biexp is negative. */
-bigint bi_power( bigint bi, bigint biexp );
-
-/* Integer square root. */
-bigint bi_sqrt( bigint bi );
-
-/* Factorial. */
-bigint bi_factorial( bigint bi );
-
-
-/* Some predicates. */
-
-/* 1 if the bigint is odd, 0 if it's even. */
-int bi_is_odd( bigint bi );
-
-/* 1 if the bigint is even, 0 if it's odd. */
-int bi_is_even( bigint bi );
-
-/* 1 if the bigint equals zero, 0 if it's nonzero. */
-int bi_is_zero( bigint bi );
-
-/* 1 if the bigint equals one, 0 otherwise. */
-int bi_is_one( bigint bi );
-
-/* 1 if the bigint is less than zero, 0 if it's zero or greater. */
-int bi_is_negative( bigint bi );
-
-
-/* Now we get into the esoteric number-theory stuff used for cryptography. */
-
-/* Modular exponentiation.  Much faster than bi_mod(bi_power(bi,biexp),bim).
-** Also, biexp can be negative.
-*/
-bigint bi_mod_power( bigint bi, bigint biexp, bigint bim );
-
-/* Modular inverse.  mod( bi * modinv(bi), bim ) == 1.  SIGFPE if bi is not
-** relatively prime to bim.
-*/
-bigint bi_mod_inverse( bigint bi, bigint bim );
-
-/* Produce a random number in the half-open interval [0..bi).  You need
-** to have called srandom() before using this.
-*/
-bigint bi_random( bigint bi );
-
-/* Greatest common divisor of two bigints.  Euclid's algorithm. */
-bigint bi_gcd( bigint bim, bigint bin );
-
-/* Greatest common divisor of two bigints, plus the corresponding multipliers.
-** Extended Euclid's algorithm.
-*/
-bigint bi_egcd( bigint bim, bigint bin, bigint* bim_mul, bigint* bin_mul );
-
-/* Least common multiple of two bigints. */
-bigint bi_lcm( bigint bia, bigint bib );
-
-/* The Jacobi symbol.  SIGFPE if bib is even. */
-bigint bi_jacobi( bigint bia, bigint bib );
-
-/* Probabalistic prime checking.  A non-zero return means the probability
-** that bi is prime is at least 1 - 1/2 ^ certainty.
-*/
-int bi_is_probable_prime( bigint bi, int certainty );
-
-/* Random probabilistic prime with the specified number of bits. */
-bigint bi_generate_prime( int bits, int certainty );
-
-/* Number of bits in the number.  The log base 2, approximately. */
-int bi_bits( bigint bi );
diff --git a/src/rt/bigint/bigint_ext.cpp b/src/rt/bigint/bigint_ext.cpp
deleted file mode 100644 (file)
index 66d7910..0000000
+++ /dev/null
@@ -1,553 +0,0 @@
-/* bigint_ext - external portion of large integer package
-**
-** Copyright © 2000 by Jef Poskanzer <jef@mail.acme.com>.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions
-** are met:
-** 1. Redistributions of source code must retain the above copyright
-**    notice, this list of conditions and the following disclaimer.
-** 2. Redistributions in binary form must reproduce the above copyright
-**    notice, this list of conditions and the following disclaimer in the
-**    documentation and/or other materials provided with the distribution.
-**
-** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-** SUCH DAMAGE.
-*/
-
-#include <sys/types.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "bigint.h"
-#include "low_primes.h"
-
-
-bigint bi_0, bi_1, bi_2, bi_10, bi_m1, bi_maxint, bi_minint;
-
-
-/* Forwards. */
-static void print_pos( FILE* f, bigint bi );
-
-
-bigint
-str_to_bi( char* str )
-    {
-    int sign;
-    bigint biR;
-
-    sign = 1;
-    if ( *str == '-' )
-       {
-       sign = -1;
-       ++str;
-       }
-    for ( biR = bi_0; *str >= '0' && *str <= '9'; ++str )
-       biR = bi_int_add( bi_int_multiply( biR, 10 ), *str - '0' );
-    if ( sign == -1 )
-       biR = bi_negate( biR );
-    return biR;
-    }
-
-
-void
-bi_print( FILE* f, bigint bi )
-    {
-    if ( bi_is_negative( bi_copy( bi ) ) )
-       {
-       putc( '-', f );
-       bi = bi_negate( bi );
-       }
-    print_pos( f, bi );
-    }
-
-
-bigint
-bi_scan( FILE* f )
-    {
-    int sign;
-    int c;
-    bigint biR;
-
-    sign = 1;
-    c = getc( f );
-    if ( c == '-' )
-       sign = -1;
-    else
-       ungetc( c, f );
-
-    biR = bi_0;
-    for (;;)
-       {
-       c = getc( f );
-       if ( c < '0' || c > '9' )
-           break;
-       biR = bi_int_add( bi_int_multiply( biR, 10 ), c - '0' );
-       }
-
-    if ( sign == -1 )
-       biR = bi_negate( biR );
-    return biR;
-    }
-
-
-static void
-print_pos( FILE* f, bigint bi )
-    {
-    if ( bi_compare( bi_copy( bi ), bi_10 ) >= 0 )
-       print_pos( f, bi_int_divide( bi_copy( bi ), 10 ) );
-    putc( bi_int_mod( bi, 10 ) + '0', f );
-    }
-
-
-int
-bi_int_mod( bigint bi, int m )
-    {
-    int r;
-
-    if ( m <= 0 )
-       {
-       (void) fprintf( stderr, "bi_int_mod: zero or negative modulus\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    r = bi_int_rem( bi, m );
-    if ( r < 0 )
-       r += m;
-    return r;
-    }
-
-
-bigint
-bi_rem( bigint bia, bigint bim )
-    {
-    return bi_subtract(
-       bia, bi_multiply( bi_divide( bi_copy( bia ), bi_copy( bim ) ), bim ) );
-    }
-
-
-bigint
-bi_mod( bigint bia, bigint bim )
-    {
-    bigint biR;
-
-    if ( bi_compare( bi_copy( bim ), bi_0 ) <= 0 )
-       {
-       (void) fprintf( stderr, "bi_mod: zero or negative modulus\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    biR = bi_rem( bia, bi_copy( bim ) );
-    if ( bi_is_negative( bi_copy( biR ) ) )
-       biR = bi_add( biR, bim );
-    else
-       bi_free( bim );
-    return biR;
-    }
-
-
-bigint
-bi_square( bigint bi )
-    {
-    bigint biR;
-
-    biR = bi_multiply( bi_copy( bi ), bi_copy( bi ) );
-    bi_free( bi );
-    return biR;
-    }
-
-
-bigint
-bi_power( bigint bi, bigint biexp )
-    {
-    bigint biR;
-
-    if ( bi_is_negative( bi_copy( biexp ) ) )
-       {
-       (void) fprintf( stderr, "bi_power: negative exponent\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    biR = bi_1;
-    for (;;)
-       {
-       if ( bi_is_odd( bi_copy( biexp ) ) )
-           biR = bi_multiply( biR, bi_copy( bi ) );
-       biexp = bi_half( biexp );
-       if ( bi_compare( bi_copy( biexp ), bi_0 ) <= 0 )
-           break;
-       bi = bi_multiply( bi_copy( bi ), bi );
-       }
-    bi_free( bi );
-    bi_free( biexp );
-    return biR;
-    }
-
-
-bigint
-bi_factorial( bigint bi )
-    {
-    bigint biR;
-
-    biR = bi_1;
-    while ( bi_compare( bi_copy( bi ), bi_1 ) > 0 )
-       {
-       biR = bi_multiply( biR, bi_copy( bi ) );
-       bi = bi_int_subtract( bi, 1 );
-       }
-    bi_free( bi );
-    return biR;
-    }
-
-
-int
-bi_is_even( bigint bi )
-    {
-    return ! bi_is_odd( bi );
-    }
-
-
-bigint
-bi_mod_power( bigint bi, bigint biexp, bigint bim )
-    {
-    int invert;
-    bigint biR;
-
-    invert = 0;
-    if ( bi_is_negative( bi_copy( biexp ) ) )
-       {
-       biexp = bi_negate( biexp );
-       invert = 1;
-       }
-
-    biR = bi_1;
-    for (;;)
-       {
-       if ( bi_is_odd( bi_copy( biexp ) ) )
-           biR = bi_mod( bi_multiply( biR, bi_copy( bi ) ), bi_copy( bim ) );
-       biexp = bi_half( biexp );
-       if ( bi_compare( bi_copy( biexp ), bi_0 ) <= 0 )
-           break;
-       bi = bi_mod( bi_multiply( bi_copy( bi ), bi ), bi_copy( bim ) );
-       }
-    bi_free( bi );
-    bi_free( biexp );
-
-    if ( invert )
-       biR = bi_mod_inverse( biR, bim );
-    else
-       bi_free( bim );
-    return biR;
-    }
-
-
-bigint
-bi_mod_inverse( bigint bi, bigint bim )
-    {
-    bigint gcd, mul0, mul1;
-
-    gcd = bi_egcd( bi_copy( bim ), bi, &mul0, &mul1 );
-
-    /* Did we get gcd == 1? */
-    if ( ! bi_is_one( gcd ) )
-       {
-       (void) fprintf( stderr, "bi_mod_inverse: not relatively prime\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-
-    bi_free( mul0 );
-    return bi_mod( mul1, bim );
-    }
-
-
-/* Euclid's algorithm. */
-bigint
-bi_gcd( bigint bim, bigint bin )
-    {
-    bigint bit;
-
-    bim = bi_abs( bim );
-    bin = bi_abs( bin );
-    while ( ! bi_is_zero( bi_copy( bin ) ) )
-       {
-       bit = bi_mod( bim, bi_copy( bin ) );
-       bim = bin;
-       bin = bit;
-       }
-    bi_free( bin );
-    return bim;
-    }
-
-
-/* Extended Euclidean algorithm. */
-bigint
-bi_egcd( bigint bim, bigint bin, bigint* bim_mul, bigint* bin_mul )
-    {
-    bigint a0, b0, c0, a1, b1, c1, q, t;
-
-    if ( bi_is_negative( bi_copy( bim ) ) )
-       {
-       bigint biR;
-
-       biR = bi_egcd( bi_negate( bim ), bin, &t, bin_mul );
-       *bim_mul = bi_negate( t );
-       return biR;
-       }
-    if ( bi_is_negative( bi_copy( bin ) ) )
-       {
-       bigint biR;
-
-       biR = bi_egcd( bim, bi_negate( bin ), bim_mul, &t );
-       *bin_mul = bi_negate( t );
-       return biR;
-       }
-
-    a0 = bi_1;  b0 = bi_0;  c0 = bim;
-    a1 = bi_0;  b1 = bi_1;  c1 = bin;
-
-    while ( ! bi_is_zero( bi_copy( c1 ) ) )
-       {
-       q = bi_divide( bi_copy( c0 ), bi_copy( c1 ) );
-       t = a0;
-       a0 = bi_copy( a1 );
-       a1 = bi_subtract( t, bi_multiply( bi_copy( q ), a1 ) );
-       t = b0;
-       b0 = bi_copy( b1 );
-       b1 = bi_subtract( t, bi_multiply( bi_copy( q ), b1 ) );
-       t = c0;
-       c0 = bi_copy( c1 );
-       c1 = bi_subtract( t, bi_multiply( bi_copy( q ), c1 ) );
-       bi_free( q );
-       }
-
-    bi_free( a1 );
-    bi_free( b1 );
-    bi_free( c1 );
-    *bim_mul = a0;
-    *bin_mul = b0;
-    return c0;
-    }
-
-
-bigint
-bi_lcm( bigint bia, bigint bib )
-    {
-    bigint biR;
-
-    biR = bi_divide(
-       bi_multiply( bi_copy( bia ), bi_copy( bib ) ),
-       bi_gcd( bi_copy( bia ), bi_copy( bib ) ) );
-    bi_free( bia );
-    bi_free( bib );
-    return biR;
-    }
-
-
-/* The Jacobi symbol. */
-bigint
-bi_jacobi( bigint bia, bigint bib )
-    {
-    bigint biR;
-
-    if ( bi_is_even( bi_copy( bib ) ) )
-       {
-       (void) fprintf( stderr, "bi_jacobi: don't know how to compute Jacobi(n, even)\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-
-    if ( bi_compare( bi_copy( bia ), bi_copy( bib ) ) >= 0 )
-       return bi_jacobi( bi_mod( bia, bi_copy( bib ) ), bib );
-
-    if ( bi_is_zero( bi_copy( bia ) ) || bi_is_one( bi_copy( bia ) ) )
-       {
-       bi_free( bib );
-       return bia;
-       }
-
-    if ( bi_compare( bi_copy( bia ), bi_2 ) == 0 )
-       {
-       bi_free( bia );
-       switch ( bi_int_mod( bib, 8 ) )
-           {
-           case 1: case 7:
-           return bi_1;
-           case 3: case 5:
-           return bi_m1;
-           }
-       }
-
-    if ( bi_is_even( bi_copy( bia ) ) )
-       {
-       biR = bi_multiply(
-           bi_jacobi( bi_2, bi_copy( bib ) ),
-           bi_jacobi( bi_half( bia ), bi_copy( bib ) ) );
-       bi_free( bib );
-       return biR;
-       }
-
-    if ( bi_int_mod( bi_copy( bia ), 4 ) == 3 &&
-         bi_int_mod( bi_copy( bib ), 4 ) == 3 )
-       return bi_negate( bi_jacobi( bib, bia ) );
-    else
-       return bi_jacobi( bib, bia );
-    }
-
-
-/* Probabalistic prime checking. */
-int
-bi_is_probable_prime( bigint bi, int certainty )
-    {
-    int i, p;
-    bigint bim1;
-
-    /* First do trial division by a list of small primes.  This eliminates
-    ** many candidates.
-    */
-    for ( i = 0; i < sizeof(low_primes)/sizeof(*low_primes); ++i )
-       {
-       p = low_primes[i];
-       switch ( bi_compare( int_to_bi( p ), bi_copy( bi ) ) )
-           {
-           case 0:
-           bi_free( bi );
-           return 1;
-           case 1:
-           bi_free( bi );
-           return 0;
-           }
-       if ( bi_int_mod( bi_copy( bi ), p ) == 0 )
-           {
-           bi_free( bi );
-           return 0;
-           }
-       }
-
-    /* Now do the probabilistic tests. */
-    bim1 = bi_int_subtract( bi_copy( bi ), 1 );
-    for ( i = 0; i < certainty; ++i )
-       {
-       bigint a, j, jac;
-
-       /* Pick random test number. */
-       a = bi_random( bi_copy( bi ) );
-
-       /* Decide whether to run the Fermat test or the Solovay-Strassen
-       ** test.  The Fermat test is fast but lets some composite numbers
-       ** through.  Solovay-Strassen runs slower but is more certain.
-       ** So the compromise here is we run the Fermat test a couple of
-       ** times to quickly reject most composite numbers, and then do
-       ** the rest of the iterations with Solovay-Strassen so nothing
-       ** slips through.
-       */
-       if ( i < 2 && certainty >= 5 )
-           {
-           /* Fermat test.  Note that this is not state of the art.  There's a
-           ** class of numbers called Carmichael numbers which are composite
-           ** but look prime to this test - it lets them slip through no
-           ** matter how many reps you run.  However, it's nice and fast so
-           ** we run it anyway to help quickly reject most of the composites.
-           */
-           if ( ! bi_is_one( bi_mod_power( bi_copy( a ), bi_copy( bim1 ), bi_copy( bi ) ) ) )
-               {
-               bi_free( bi );
-               bi_free( bim1 );
-               bi_free( a );
-               return 0;
-               }
-           }
-       else
-           {
-           /* GCD test.  This rarely hits, but we need it for Solovay-Strassen. */
-           if ( ! bi_is_one( bi_gcd( bi_copy( bi ), bi_copy( a ) ) ) )
-               {
-               bi_free( bi );
-               bi_free( bim1 );
-               bi_free( a );
-               return 0;
-               }
-
-           /* Solovay-Strassen test.  First compute pseudo Jacobi. */
-           j = bi_mod_power(
-                   bi_copy( a ), bi_half( bi_copy( bim1 ) ), bi_copy( bi ) );
-           if ( bi_compare( bi_copy( j ), bi_copy( bim1 ) ) == 0 )
-               {
-               bi_free( j );
-               j = bi_m1;
-               }
-
-           /* Now compute real Jacobi. */
-           jac = bi_jacobi( bi_copy( a ), bi_copy( bi ) );
-
-           /* If they're not equal, the number is definitely composite. */
-           if ( bi_compare( j, jac ) != 0 )
-               {
-               bi_free( bi );
-               bi_free( bim1 );
-               bi_free( a );
-               return 0;
-               }
-           }
-
-       bi_free( a );
-       }
-
-    bi_free( bim1 );
-
-    bi_free( bi );
-    return 1;
-    }
-
-
-bigint
-bi_generate_prime( int bits, int certainty )
-    {
-    bigint bimo2, bip;
-    int i, inc = 0;
-
-    bimo2 = bi_power( bi_2, int_to_bi( bits - 1 ) );
-    for (;;)
-       {
-       bip = bi_add( bi_random( bi_copy( bimo2 ) ), bi_copy( bimo2 ) );
-       /* By shoving the candidate numbers up to the next highest multiple
-       ** of six plus or minus one, we pre-eliminate all multiples of
-       ** two and/or three.
-       */
-       switch ( bi_int_mod( bi_copy( bip ), 6 ) )
-           {
-           case 0: inc = 4; bip = bi_int_add( bip, 1 ); break;
-           case 1: inc = 4;                             break;
-           case 2: inc = 2; bip = bi_int_add( bip, 3 ); break;
-           case 3: inc = 2; bip = bi_int_add( bip, 2 ); break;
-           case 4: inc = 2; bip = bi_int_add( bip, 1 ); break;
-           case 5: inc = 2;                             break;
-           }
-       /* Starting from the generated random number, check a bunch of
-       ** numbers in sequence.  This is just to avoid calls to bi_random(),
-       ** which is more expensive than a simple add.
-       */
-       for ( i = 0; i < 1000; ++i )    /* arbitrary */
-           {
-           if ( bi_is_probable_prime( bi_copy( bip ), certainty ) )
-               {
-               bi_free( bimo2 );
-               return bip;
-               }
-           bip = bi_int_add( bip, inc );
-           inc = 6 - inc;
-           }
-       /* We ran through the whole sequence and didn't find a prime.
-       ** Shrug, just try a different random starting point.
-       */
-       bi_free( bip );
-       }
-    }
diff --git a/src/rt/bigint/bigint_int.cpp b/src/rt/bigint/bigint_int.cpp
deleted file mode 100644 (file)
index 194ddcb..0000000
+++ /dev/null
@@ -1,1428 +0,0 @@
-/* bigint - internal portion of large integer package
-**
-** Copyright © 2000 by Jef Poskanzer <jef@mail.acme.com>.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions
-** are met:
-** 1. Redistributions of source code must retain the above copyright
-**    notice, this list of conditions and the following disclaimer.
-** 2. Redistributions in binary form must reproduce the above copyright
-**    notice, this list of conditions and the following disclaimer in the
-**    documentation and/or other materials provided with the distribution.
-**
-** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-** SUCH DAMAGE.
-*/
-
-#include <sys/types.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "bigint.h"
-
-#define max(a,b) ((a)>(b)?(a):(b))
-#define min(a,b) ((a)<(b)?(a):(b))
-
-/* MAXINT and MININT extracted from <values.h>, which gives a warning
-** message if included.
-*/
-#define BITSPERBYTE 8
-#define BITS(type)  (BITSPERBYTE * (int)sizeof(type))
-#define INTBITS     BITS(int)
-#define MININT      (1 << (INTBITS - 1))
-#define MAXINT      (~MININT)
-
-
-/* The package represents arbitrary-precision integers as a sign and a sum
-** of components multiplied by successive powers of the basic radix, i.e.:
-**
-**   sign * ( comp0 + comp1 * radix + comp2 * radix^2 + comp3 * radix^3 )
-**
-** To make good use of the computer's word size, the radix is chosen
-** to be a power of two.  It could be chosen to be the full word size,
-** however this would require a lot of finagling in the middle of the
-** algorithms to get the inter-word overflows right.  That would slow things
-** down.  Instead, the radix is chosen to be *half* the actual word size.
-** With just a little care, this means the words can hold all intermediate
-** values, and the overflows can be handled all at once at the end, in a
-** normalization step.  This simplifies the coding enormously, and is probably
-** somewhat faster to run.  The cost is that numbers use twice as much
-** storage as they would with the most efficient representation, but storage
-** is cheap.
-**
-** A few more notes on the representation:
-**
-**  - The sign is always 1 or -1, never 0.  The number 0 is represented
-**    with a sign of 1.
-**  - The components are signed numbers, to allow for negative intermediate
-**    values.  After normalization, all components are >= 0 and the sign is
-**    updated.
-*/
-
-/* Type definition for bigints. */
-typedef int64_t comp;  /* should be the largest signed int type you have */
-struct _real_bigint {
-    int refs;
-    struct _real_bigint* next;
-    int num_comps, max_comps;
-    int sign;
-    comp* comps;
-    };
-typedef struct _real_bigint* real_bigint;
-
-
-#undef DUMP
-
-
-#define PERMANENT 123456789
-
-static comp bi_radix, bi_radix_o2;
-static int bi_radix_sqrt, bi_comp_bits;
-
-static real_bigint active_list, free_list;
-static int active_count, free_count;
-static int check_level;
-
-
-/* Forwards. */
-static bigint regular_multiply( real_bigint bia, real_bigint bib );
-static bigint multi_divide( bigint binumer, real_bigint bidenom );
-static bigint multi_divide2( bigint binumer, real_bigint bidenom );
-static void more_comps( real_bigint bi, int n );
-static real_bigint alloc( int num_comps );
-static real_bigint clone( real_bigint bi );
-static void normalize( real_bigint bi );
-static void check( real_bigint bi );
-static void double_check( void );
-static void triple_check( void );
-#ifdef DUMP
-static void dump( char* str, bigint bi );
-#endif /* DUMP */
-static int csqrt( comp c );
-static int cbits( comp c );
-
-
-void
-bi_initialize( void )
-    {
-    /* Set the radix.  This does not actually have to be a power of
-    ** two, that's just the most efficient value.  It does have to
-    ** be even for bi_half() to work.
-    */
-    bi_radix = 1;
-    bi_radix <<= BITS(comp) / 2 - 1;
-
-    /* Halve the radix.  Only used by bi_half(). */
-    bi_radix_o2 = bi_radix >> 1;
-
-    /* Take the square root of the radix.  Only used by bi_divide(). */
-    bi_radix_sqrt = csqrt( bi_radix );
-
-    /* Figure out how many bits in a component.  Only used by bi_bits(). */
-    bi_comp_bits = cbits( bi_radix - 1 );
-
-    /* Init various globals. */
-    active_list = (real_bigint) 0;
-    active_count = 0;
-    free_list = (real_bigint) 0;
-    free_count = 0;
-
-    /* This can be 0 through 3. */
-    check_level = 3;
-
-    /* Set up some convenient bigints. */
-    bi_0 = int_to_bi( 0 ); bi_permanent( bi_0 );
-    bi_1 = int_to_bi( 1 ); bi_permanent( bi_1 );
-    bi_2 = int_to_bi( 2 ); bi_permanent( bi_2 );
-    bi_10 = int_to_bi( 10 ); bi_permanent( bi_10 );
-    bi_m1 = int_to_bi( -1 ); bi_permanent( bi_m1 );
-    bi_maxint = int_to_bi( MAXINT ); bi_permanent( bi_maxint );
-    bi_minint = int_to_bi( MININT ); bi_permanent( bi_minint );
-    }
-
-
-void
-bi_terminate( void )
-    {
-    real_bigint p, pn;
-
-    bi_depermanent( bi_0 ); bi_free( bi_0 );
-    bi_depermanent( bi_1 ); bi_free( bi_1 );
-    bi_depermanent( bi_2 ); bi_free( bi_2 );
-    bi_depermanent( bi_10 ); bi_free( bi_10 );
-    bi_depermanent( bi_m1 ); bi_free( bi_m1 );
-    bi_depermanent( bi_maxint ); bi_free( bi_maxint );
-    bi_depermanent( bi_minint ); bi_free( bi_minint );
-
-    if ( active_count != 0 )
-       (void) fprintf(
-           stderr, "bi_terminate: there were %d un-freed bigints\n",
-           active_count );
-    if ( check_level >= 2 )
-       double_check();
-    if ( check_level >= 3 )
-       {
-       triple_check();
-       for ( p = active_list; p != (bigint) 0; p = pn )
-           {
-           pn = p->next;
-           free( p->comps );
-           free( p );
-           }
-       }
-    for ( p = free_list; p != (bigint) 0; p = pn )
-       {
-       pn = p->next;
-       free( p->comps );
-       free( p );
-       }
-    }
-
-
-void
-bi_no_check( void )
-    {
-    check_level = 0;
-    }
-
-
-bigint
-bi_copy( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-
-    check( bi );
-    if ( bi->refs != PERMANENT )
-       ++bi->refs;
-    return bi;
-    }
-
-
-void
-bi_permanent( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-
-    check( bi );
-    if ( check_level >= 1 && bi->refs != 1 )
-       {
-       (void) fprintf( stderr, "bi_permanent: refs was not 1\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    bi->refs = PERMANENT;
-    }
-
-
-void
-bi_depermanent( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-
-    check( bi );
-    if ( check_level >= 1 && bi->refs != PERMANENT )
-       {
-       (void) fprintf( stderr, "bi_depermanent: bigint was not permanent\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    bi->refs = 1;
-    }
-
-
-void
-bi_free( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-
-    check( bi );
-    if ( bi->refs == PERMANENT )
-       return;
-    --bi->refs;
-    if ( bi->refs > 0 )
-       return;
-    if ( check_level >= 3 )
-       {
-       /* The active list only gets maintained at check levels 3 or higher. */
-       real_bigint* nextP;
-       for ( nextP = &active_list; *nextP != (real_bigint) 0; nextP = &((*nextP)->next) )
-           if ( *nextP == bi )
-               {
-               *nextP = bi->next;
-               break;
-               }
-       }
-    --active_count;
-    bi->next = free_list;
-    free_list = bi;
-    ++free_count;
-    if ( check_level >= 1 && active_count < 0 )
-       {
-       (void) fprintf( stderr,
-           "bi_free: active_count went negative - double-freed bigint?\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    }
-
-
-int
-bi_compare( bigint obia, bigint obib )
-    {
-    real_bigint bia = (real_bigint) obia;
-    real_bigint bib = (real_bigint) obib;
-    int r, c;
-
-    check( bia );
-    check( bib );
-
-    /* First check for pointer equality. */
-    if ( bia == bib )
-       r = 0;
-    else
-       {
-       /* Compare signs. */
-       if ( bia->sign > bib->sign )
-           r = 1;
-       else if ( bia->sign < bib->sign )
-           r = -1;
-       /* Signs are the same.  Check the number of components. */
-       else if ( bia->num_comps > bib->num_comps )
-           r = bia->sign;
-       else if ( bia->num_comps < bib->num_comps )
-           r = -bia->sign;
-       else
-           {
-           /* Same number of components.  Compare starting from the high end
-           ** and working down.
-           */
-           r = 0;      /* if we complete the loop, the numbers are equal */
-           for ( c = bia->num_comps - 1; c >= 0; --c )
-               {
-               if ( bia->comps[c] > bib->comps[c] )
-                   { r = bia->sign; break; }
-               else if ( bia->comps[c] < bib->comps[c] )
-                   { r = -bia->sign; break; }
-               }
-           }
-       }
-
-    bi_free( bia );
-    bi_free( bib );
-    return r;
-    }
-
-
-bigint
-int_to_bi( int i )
-    {
-    real_bigint biR;
-
-    biR = alloc( 1 );
-    biR->sign = 1;
-    biR->comps[0] = i;
-    normalize( biR );
-    check( biR );
-    return biR;
-    }
-
-
-int
-bi_to_int( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    comp v, m;
-    int c, r;
-
-    check( bi );
-    if ( bi_compare( bi_copy( bi ), bi_maxint ) > 0 ||
-        bi_compare( bi_copy( bi ), bi_minint ) < 0 )
-       {
-       (void) fprintf( stderr, "bi_to_int: overflow\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    v = 0;
-    m = 1;
-    for ( c = 0; c < bi->num_comps; ++c )
-       {
-       v += bi->comps[c] * m;
-       m *= bi_radix;
-       }
-    r = (int) ( bi->sign * v );
-    bi_free( bi );
-    return r;
-    }
-
-
-bigint
-bi_int_add( bigint obi, int i )
-    {
-    real_bigint bi = (real_bigint) obi;
-    real_bigint biR;
-
-    check( bi );
-    biR = clone( bi );
-    if ( biR->sign == 1 )
-       biR->comps[0] += i;
-    else
-       biR->comps[0] -= i;
-    normalize( biR );
-    check( biR );
-    return biR;
-    }
-
-
-bigint
-bi_int_subtract( bigint obi, int i )
-    {
-    real_bigint bi = (real_bigint) obi;
-    real_bigint biR;
-
-    check( bi );
-    biR = clone( bi );
-    if ( biR->sign == 1 )
-       biR->comps[0] -= i;
-    else
-       biR->comps[0] += i;
-    normalize( biR );
-    check( biR );
-    return biR;
-    }
-
-
-bigint
-bi_int_multiply( bigint obi, int i )
-    {
-    real_bigint bi = (real_bigint) obi;
-    real_bigint biR;
-    int c;
-
-    check( bi );
-    biR = clone( bi );
-    if ( i < 0 )
-       {
-       i = -i;
-       biR->sign = -biR->sign;
-       }
-    for ( c = 0; c < biR->num_comps; ++c )
-       biR->comps[c] *= i;
-    normalize( biR );
-    check( biR );
-    return biR;
-    }
-
-
-bigint
-bi_int_divide( bigint obinumer, int denom )
-    {
-    real_bigint binumer = (real_bigint) obinumer;
-    real_bigint biR;
-    int c;
-    comp r;
-
-    check( binumer );
-    if ( denom == 0 )
-       {
-       (void) fprintf( stderr, "bi_int_divide: divide by zero\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    biR = clone( binumer );
-    if ( denom < 0 )
-       {
-       denom = -denom;
-       biR->sign = -biR->sign;
-       }
-    r = 0;
-    for ( c = biR->num_comps - 1; c >= 0; --c )
-       {
-       r = r * bi_radix + biR->comps[c];
-       biR->comps[c] = r / denom;
-       r = r % denom;
-       }
-    normalize( biR );
-    check( biR );
-    return biR;
-    }
-
-
-int
-bi_int_rem( bigint obi, int m )
-    {
-    real_bigint bi = (real_bigint) obi;
-    comp rad_r, r;
-    int  c;
-
-    check( bi );
-    if ( m == 0 )
-       {
-       (void) fprintf( stderr, "bi_int_rem: divide by zero\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    if ( m < 0 )
-       m = -m;
-    rad_r = 1;
-    r = 0;
-    for ( c = 0; c < bi->num_comps; ++c )
-       {
-       r = ( r + bi->comps[c] * rad_r ) % m;
-       rad_r = ( rad_r * bi_radix ) % m;
-       }
-    if ( bi->sign < 1 )
-       r = -r;
-    bi_free( bi );
-    return (int) r;
-    }
-
-
-bigint
-bi_add( bigint obia, bigint obib )
-    {
-    real_bigint bia = (real_bigint) obia;
-    real_bigint bib = (real_bigint) obib;
-    real_bigint biR;
-    int c;
-
-    check( bia );
-    check( bib );
-    biR = clone( bia );
-    more_comps( biR, max( biR->num_comps, bib->num_comps ) );
-    for ( c = 0; c < bib->num_comps; ++c )
-       if ( biR->sign == bib->sign )
-           biR->comps[c] += bib->comps[c];
-       else
-           biR->comps[c] -= bib->comps[c];
-    bi_free( bib );
-    normalize( biR );
-    check( biR );
-    return biR;
-    }
-
-
-bigint
-bi_subtract( bigint obia, bigint obib )
-    {
-    real_bigint bia = (real_bigint) obia;
-    real_bigint bib = (real_bigint) obib;
-    real_bigint biR;
-    int c;
-
-    check( bia );
-    check( bib );
-    biR = clone( bia );
-    more_comps( biR, max( biR->num_comps, bib->num_comps ) );
-    for ( c = 0; c < bib->num_comps; ++c )
-       if ( biR->sign == bib->sign )
-           biR->comps[c] -= bib->comps[c];
-       else
-           biR->comps[c] += bib->comps[c];
-    bi_free( bib );
-    normalize( biR );
-    check( biR );
-    return biR;
-    }
-
-
-/* Karatsuba multiplication.  This is supposedly O(n^1.59), better than
-** regular multiplication for large n.  The define below sets the crossover
-** point - below that we use regular multiplication, above it we
-** use Karatsuba.  Note that Karatsuba is a recursive algorithm, so
-** all Karatsuba calls involve regular multiplications as the base
-** steps.
-*/
-#define KARATSUBA_THRESH 12
-bigint
-bi_multiply( bigint obia, bigint obib )
-    {
-    real_bigint bia = (real_bigint) obia;
-    real_bigint bib = (real_bigint) obib;
-
-    check( bia );
-    check( bib );
-    if ( min( bia->num_comps, bib->num_comps ) < KARATSUBA_THRESH )
-       return regular_multiply( bia, bib );
-    else
-       {
-       /* The factors are large enough that Karatsuba multiplication
-       ** is a win.  The basic idea here is you break each factor up
-       ** into two parts, like so:
-       **     i * r^n + j        k * r^n + l
-       ** r is the radix we're representing numbers with, so this
-       ** breaking up just means shuffling components around, no
-       ** math required.  With regular multiplication the product
-       ** would be:
-       **     ik * r^(n*2) + ( il + jk ) * r^n + jl
-       ** That's four sub-multiplies and one addition, not counting the
-       ** radix-shifting.  With Karatsuba, you instead do:
-       **     ik * r^(n*2) + ( (i+j)(k+l) - ik - jl ) * r^n  + jl
-       ** This is only three sub-multiplies.  The number of adds
-       ** (and subtracts) increases to four, but those run in linear time
-       ** so they are cheap.  The sub-multiplies are accomplished by
-       ** recursive calls, eventually reducing to regular multiplication.
-       */
-       int n, c;
-       real_bigint bi_i, bi_j, bi_k, bi_l;
-       real_bigint bi_ik, bi_mid, bi_jl;
-
-       n = ( max( bia->num_comps, bib->num_comps ) + 1 ) / 2;
-       bi_i = alloc( n );
-       bi_j = alloc( n );
-       bi_k = alloc( n );
-       bi_l = alloc( n );
-       for ( c = 0; c < n; ++c )
-           {
-           if ( c + n < bia->num_comps )
-               bi_i->comps[c] = bia->comps[c + n];
-           else
-               bi_i->comps[c] = 0;
-           if ( c < bia->num_comps )
-               bi_j->comps[c] = bia->comps[c];
-           else
-               bi_j->comps[c] = 0;
-           if ( c + n < bib->num_comps )
-               bi_k->comps[c] = bib->comps[c + n];
-           else
-               bi_k->comps[c] = 0;
-           if ( c < bib->num_comps )
-               bi_l->comps[c] = bib->comps[c];
-           else
-               bi_l->comps[c] = 0;
-           }
-       bi_i->sign = bi_j->sign = bi_k->sign = bi_l->sign = 1;
-       normalize( bi_i );
-       normalize( bi_j );
-       normalize( bi_k );
-       normalize( bi_l );
-       bi_ik = bi_multiply( bi_copy( bi_i ), bi_copy( bi_k ) );
-       bi_jl = bi_multiply( bi_copy( bi_j ), bi_copy( bi_l ) );
-       bi_mid = bi_subtract(
-           bi_subtract(
-               bi_multiply( bi_add( bi_i, bi_j ), bi_add( bi_k, bi_l ) ),
-               bi_copy( bi_ik ) ),
-           bi_copy( bi_jl ) );
-       more_comps(
-           bi_jl, max( bi_mid->num_comps + n, bi_ik->num_comps + n * 2 ) );
-       for ( c = 0; c < bi_mid->num_comps; ++c )
-           bi_jl->comps[c + n] += bi_mid->comps[c];
-       for ( c = 0; c < bi_ik->num_comps; ++c )
-           bi_jl->comps[c + n * 2] += bi_ik->comps[c];
-       bi_free( bi_ik );
-       bi_free( bi_mid );
-       bi_jl->sign = bia->sign * bib->sign;
-       bi_free( bia );
-       bi_free( bib );
-       normalize( bi_jl );
-       check( bi_jl );
-       return bi_jl;
-       }
-    }
-
-
-/* Regular O(n^2) multiplication. */
-static bigint
-regular_multiply( real_bigint bia, real_bigint bib )
-    {
-    real_bigint biR;
-    int new_comps, c1, c2;
-
-    check( bia );
-    check( bib );
-    biR = clone( bi_0 );
-    new_comps = bia->num_comps + bib->num_comps;
-    more_comps( biR, new_comps );
-    for ( c1 = 0; c1 < bia->num_comps; ++c1 )
-       {
-       for ( c2 = 0; c2 < bib->num_comps; ++c2 )
-           biR->comps[c1 + c2] += bia->comps[c1] * bib->comps[c2];
-       /* Normalize after each inner loop to avoid overflowing any
-       ** components.  But be sure to reset biR's components count,
-       ** in case a previous normalization lowered it.
-       */
-       biR->num_comps = new_comps;
-       normalize( biR );
-       }
-    check( biR );
-    if ( ! bi_is_zero( bi_copy( biR ) ) )
-       biR->sign = bia->sign * bib->sign;
-    bi_free( bia );
-    bi_free( bib );
-    return biR;
-    }
-
-
-/* The following three routines implement a multi-precision divide method
-** that I haven't seen used anywhere else.  It is not quite as fast as
-** the standard divide method, but it is a lot simpler.  In fact it's
-** about as simple as the binary shift-and-subtract method, which goes
-** about five times slower than this.
-**
-** The method assumes you already have multi-precision multiply and subtract
-** routines, and also a multi-by-single precision divide routine.  The latter
-** is used to generate approximations, which are then checked and corrected
-** using the former.  The result converges to the correct value by about
-** 16 bits per loop.
-*/
-
-/* Public routine to divide two arbitrary numbers. */
-bigint
-bi_divide( bigint binumer, bigint obidenom )
-    {
-    real_bigint bidenom = (real_bigint) obidenom;
-    int sign;
-    bigint biquotient;
-
-    /* Check signs and trivial cases. */
-    sign = 1;
-    switch ( bi_compare( bi_copy( bidenom ), bi_0 ) )
-       {
-       case 0:
-       (void) fprintf( stderr, "bi_divide: divide by zero\n" );
-       (void) kill( getpid(), SIGFPE );
-       case -1:
-       sign *= -1;
-       bidenom = bi_negate( bidenom );
-       break;
-       }
-    switch ( bi_compare( bi_copy( binumer ), bi_0 ) )
-       {
-       case 0:
-       bi_free( binumer );
-       bi_free( bidenom );
-       return bi_0;
-       case -1:
-       sign *= -1;
-       binumer = bi_negate( binumer );
-       break;
-       }
-    switch ( bi_compare( bi_copy( binumer ), bi_copy( bidenom ) ) )
-       {
-       case -1:
-       bi_free( binumer );
-       bi_free( bidenom );
-       return bi_0;
-       case 0:
-       bi_free( binumer );
-       bi_free( bidenom );
-       if ( sign == 1 )
-           return bi_1;
-       else
-           return bi_m1;
-       }
-
-    /* Is the denominator small enough to do an int divide? */
-    if ( bidenom->num_comps == 1 )
-       {
-       /* Win! */
-       biquotient = bi_int_divide( binumer, bidenom->comps[0] );
-       bi_free( bidenom );
-       }
-    else
-       {
-       /* No, we have to do a full multi-by-multi divide. */
-       biquotient = multi_divide( binumer, bidenom );
-       }
-
-    if ( sign == -1 )
-       biquotient = bi_negate( biquotient );
-    return biquotient;
-    }
-
-
-/* Divide two multi-precision positive numbers. */
-static bigint
-multi_divide( bigint binumer, real_bigint bidenom )
-    {
-    /* We use a successive approximation method that is kind of like a
-    ** continued fraction.  The basic approximation is to do an int divide
-    ** by the high-order component of the denominator.  Then we correct
-    ** based on the remainder from that.
-    **
-    ** However, if the high-order component is too small, this doesn't
-    ** work well.  In particular, if the high-order component is 1 it
-    ** doesn't work at all.  Easily fixed, though - if the component
-    ** is too small, increase it!
-    */
-    if ( bidenom->comps[bidenom->num_comps-1] < bi_radix_sqrt )
-       {
-       /* We use the square root of the radix as the threshhold here
-       ** because that's the largest value guaranteed to not make the
-       ** high-order component overflow and become too small again.
-       **
-       ** We increase binumer along with bidenom to keep the end result
-       ** the same.
-       */
-       binumer = bi_int_multiply( binumer, bi_radix_sqrt );
-       bidenom = bi_int_multiply( bidenom, bi_radix_sqrt );
-       }
-
-    /* Now start the recursion. */
-    return multi_divide2( binumer, bidenom );
-    }
-
-
-/* Divide two multi-precision positive conditioned numbers. */
-static bigint
-multi_divide2( bigint binumer, real_bigint bidenom )
-    {
-    real_bigint biapprox;
-    bigint birem, biquotient;
-    int c, o;
-
-    /* Figure out the approximate quotient.   Since we're dividing by only
-    ** the top component of the denominator, which is less than or equal to
-    ** the full denominator, the result is guaranteed to be greater than or
-    ** equal to the correct quotient.
-    */
-    o = bidenom->num_comps - 1;
-    biapprox = bi_int_divide( bi_copy( binumer ), bidenom->comps[o] );
-    /* And downshift the result to get the approximate quotient. */
-    for ( c = o; c < biapprox->num_comps; ++c )
-       biapprox->comps[c - o] = biapprox->comps[c];
-    biapprox->num_comps -= o;
-
-    /* Find the remainder from the approximate quotient. */
-    birem = bi_subtract(
-       bi_multiply( bi_copy( biapprox ), bi_copy( bidenom ) ), binumer );
-
-    /* If the remainder is negative, zero, or in fact any value less
-    ** than bidenom, then we have the correct quotient and we're done.
-    */
-    if ( bi_compare( bi_copy( birem ), bi_copy( bidenom ) ) < 0 )
-       {
-       biquotient = biapprox;
-       bi_free( birem );
-       bi_free( bidenom );
-       }
-    else
-       {
-       /* The real quotient is now biapprox - birem / bidenom.  We still
-       ** have to do a divide.  However, birem is smaller than binumer,
-       ** so the next divide will go faster.  We do the divide by
-       ** recursion.  Since this is tail-recursion or close to it, we
-       ** could probably re-arrange things and make it a non-recursive
-       ** loop, but the overhead of recursion is small and the bookkeeping
-       ** is simpler this way.
-       **
-       ** Note that since the sub-divide uses the same denominator, it
-       ** doesn't have to adjust the values again - the high-order component
-       ** will still be good.
-       */
-       biquotient = bi_subtract( biapprox, multi_divide2( birem, bidenom ) );
-       }
-
-    return biquotient;
-    }
-
-
-/* Binary division - about five times slower than the above. */
-bigint
-bi_binary_divide( bigint binumer, bigint obidenom )
-    {
-    real_bigint bidenom = (real_bigint) obidenom;
-    int sign;
-    bigint biquotient;
-
-    /* Check signs and trivial cases. */
-    sign = 1;
-    switch ( bi_compare( bi_copy( bidenom ), bi_0 ) )
-       {
-       case 0:
-       (void) fprintf( stderr, "bi_divide: divide by zero\n" );
-       (void) kill( getpid(), SIGFPE );
-       case -1:
-       sign *= -1;
-       bidenom = bi_negate( bidenom );
-       break;
-       }
-    switch ( bi_compare( bi_copy( binumer ), bi_0 ) )
-       {
-       case 0:
-       bi_free( binumer );
-       bi_free( bidenom );
-       return bi_0;
-       case -1:
-       sign *= -1;
-       binumer = bi_negate( binumer );
-       break;
-       }
-    switch ( bi_compare( bi_copy( binumer ), bi_copy( bidenom ) ) )
-       {
-       case -1:
-       bi_free( binumer );
-       bi_free( bidenom );
-       return bi_0;
-       case 0:
-       bi_free( binumer );
-       bi_free( bidenom );
-       if ( sign == 1 )
-           return bi_1;
-       else
-           return bi_m1;
-       }
-
-    /* Is the denominator small enough to do an int divide? */
-    if ( bidenom->num_comps == 1 )
-       {
-       /* Win! */
-       biquotient = bi_int_divide( binumer, bidenom->comps[0] );
-       bi_free( bidenom );
-       }
-    else
-       {
-       /* No, we have to do a full multi-by-multi divide. */
-       int num_bits, den_bits, i;
-
-       num_bits = bi_bits( bi_copy( binumer ) );
-       den_bits = bi_bits( bi_copy( bidenom ) );
-       bidenom = bi_multiply( bidenom, bi_power( bi_2, int_to_bi( num_bits - den_bits ) ) );
-       biquotient = bi_0;
-       for ( i = den_bits; i <= num_bits; ++i )
-           {
-           biquotient = bi_double( biquotient );
-           if ( bi_compare( bi_copy( binumer ), bi_copy( bidenom ) ) >= 0 )
-               {
-               biquotient = bi_int_add( biquotient, 1 );
-               binumer = bi_subtract( binumer, bi_copy( bidenom ) );
-               }
-           bidenom = bi_half( bidenom );
-           }
-       bi_free( binumer );
-       bi_free( bidenom );
-       }
-
-    if ( sign == -1 )
-       biquotient = bi_negate( biquotient );
-    return biquotient;
-    }
-
-
-bigint
-bi_negate( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    real_bigint biR;
-
-    check( bi );
-    biR = clone( bi );
-    biR->sign = -biR->sign;
-    check( biR );
-    return biR;
-    }
-
-
-bigint
-bi_abs( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    real_bigint biR;
-
-    check( bi );
-    biR = clone( bi );
-    biR->sign = 1;
-    check( biR );
-    return biR;
-    }
-
-
-bigint
-bi_half( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    real_bigint biR;
-    int c;
-
-    check( bi );
-    /* This depends on the radix being even. */
-    biR = clone( bi );
-    for ( c = 0; c < biR->num_comps; ++c )
-       {
-       if ( biR->comps[c] & 1 )
-           if ( c > 0 )
-               biR->comps[c - 1] += bi_radix_o2;
-       biR->comps[c] = biR->comps[c] >> 1;
-       }
-    /* Avoid normalization. */
-    if ( biR->num_comps > 1 && biR->comps[biR->num_comps-1] == 0 )
-       --biR->num_comps;
-    check( biR );
-    return biR;
-    }
-
-
-bigint
-bi_double( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    real_bigint biR;
-    int c;
-
-    check( bi );
-    biR = clone( bi );
-    for ( c = biR->num_comps - 1; c >= 0; --c )
-       {
-       biR->comps[c] = biR->comps[c] << 1;
-       if ( biR->comps[c] >= bi_radix )
-           {
-           if ( c + 1 >= biR->num_comps )
-               more_comps( biR, biR->num_comps + 1 );
-           biR->comps[c] -= bi_radix;
-           biR->comps[c + 1] += 1;
-           }
-       }
-    check( biR );
-    return biR;
-    }
-
-
-/* Find integer square root by Newton's method. */
-bigint
-bi_sqrt( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    bigint biR, biR2, bidiff;
-
-    switch ( bi_compare( bi_copy( bi ), bi_0 ) )
-       {
-       case -1:
-       (void) fprintf( stderr, "bi_sqrt: imaginary result\n" );
-       (void) kill( getpid(), SIGFPE );
-       case 0:
-       return bi;
-       }
-    if ( bi_is_one( bi_copy( bi ) ) )
-       return bi;
-
-    /* Newton's method converges reasonably fast, but it helps to have
-    ** a good initial guess.  We can make a *very* good initial guess
-    ** by taking the square root of the top component times the square
-    ** root of the radix part.  Both of those are easy to compute.
-    */
-    biR = bi_int_multiply(
-       bi_power( int_to_bi( bi_radix_sqrt ), int_to_bi( bi->num_comps - 1 ) ),
-       csqrt( bi->comps[bi->num_comps - 1] ) );
-
-    /* Now do the Newton loop until we have the answer. */
-    for (;;)
-       {
-       biR2 = bi_divide( bi_copy( bi ), bi_copy( biR ) );
-       bidiff = bi_subtract( bi_copy( biR ), bi_copy( biR2 ) );
-       if ( bi_is_zero( bi_copy( bidiff ) ) ||
-            bi_compare( bi_copy( bidiff ), bi_m1 ) == 0 )
-           {
-           bi_free( bi );
-           bi_free( bidiff );
-           bi_free( biR2 );
-           return biR;
-           }
-       if ( bi_is_one( bi_copy( bidiff ) ) )
-           {
-           bi_free( bi );
-           bi_free( bidiff );
-           bi_free( biR );
-           return biR2;
-           }
-       bi_free( bidiff );
-       biR = bi_half( bi_add( biR, biR2 ) );
-       }
-    }
-
-
-int
-bi_is_odd( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    int r;
-
-    check( bi );
-    r = bi->comps[0] & 1;
-    bi_free( bi );
-    return r;
-    }
-
-
-int
-bi_is_zero( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    int r;
-
-    check( bi );
-    r = ( bi->sign == 1 && bi->num_comps == 1 && bi->comps[0] == 0 );
-    bi_free( bi );
-    return r;
-    }
-
-
-int
-bi_is_one( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    int r;
-
-    check( bi );
-    r = ( bi->sign == 1 && bi->num_comps == 1 && bi->comps[0] == 1 );
-    bi_free( bi );
-    return r;
-    }
-
-
-int
-bi_is_negative( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    int r;
-
-    check( bi );
-    r = ( bi->sign == -1 );
-    bi_free( bi );
-    return r;
-    }
-
-
-bigint
-bi_random( bigint bi )
-    {
-    real_bigint biR;
-    int c;
-
-    biR = bi_multiply( bi_copy( bi ), bi_copy( bi ) );
-    for ( c = 0; c < biR->num_comps; ++c )
-       biR->comps[c] = random();
-    normalize( biR );
-    biR = bi_mod( biR, bi );
-    return biR;
-    }
-
-
-int
-bi_bits( bigint obi )
-    {
-    real_bigint bi = (real_bigint) obi;
-    int bits;
-
-    bits =
-       bi_comp_bits * ( bi->num_comps - 1 ) +
-       cbits( bi->comps[bi->num_comps - 1] );
-    bi_free( bi );
-    return bits;
-    }
-
-
-/* Allocate and zero more components.  Does not consume bi, of course. */
-static void
-more_comps( real_bigint bi, int n )
-    {
-    if ( n > bi->max_comps )
-       {
-       bi->max_comps = max( bi->max_comps * 2, n );
-       bi->comps = (comp*) realloc(
-           (void*) bi->comps, bi->max_comps * sizeof(comp) );
-       if ( bi->comps == (comp*) 0 )
-           {
-           (void) fprintf( stderr, "out of memory\n" );
-           exit( 1 );
-           }
-       }
-    for ( ; bi->num_comps < n; ++bi->num_comps )
-       bi->comps[bi->num_comps] = 0;
-    }
-
-
-/* Make a new empty bigint.  Fills in everything except sign and the
-** components.
-*/
-static real_bigint
-alloc( int num_comps )
-    {
-    real_bigint biR;
-
-    /* Can we recycle an old bigint? */
-    if ( free_list != (real_bigint) 0 )
-       {
-       biR = free_list;
-       free_list = biR->next;
-       --free_count;
-       if ( check_level >= 1 && biR->refs != 0 )
-           {
-           (void) fprintf( stderr, "alloc: refs was not 0\n" );
-           (void) kill( getpid(), SIGFPE );
-           }
-       more_comps( biR, num_comps );
-       }
-    else
-       {
-       /* No free bigints available - create a new one. */
-       biR = (real_bigint) malloc( sizeof(struct _real_bigint) );
-       if ( biR == (real_bigint) 0 )
-           {
-           (void) fprintf( stderr, "out of memory\n" );
-           exit( 1 );
-           }
-       biR->comps = (comp*) malloc( num_comps * sizeof(comp) );
-       if ( biR->comps == (comp*) 0 )
-           {
-           (void) fprintf( stderr, "out of memory\n" );
-           exit( 1 );
-           }
-       biR->max_comps = num_comps;
-       }
-    biR->num_comps = num_comps;
-    biR->refs = 1;
-    if ( check_level >= 3 )
-       {
-       /* The active list only gets maintained at check levels 3 or higher. */
-       biR->next = active_list;
-       active_list = biR;
-       }
-    else
-       biR->next = (real_bigint) 0;
-    ++active_count;
-    return biR;
-    }
-
-
-/* Make a modifiable copy of bi.  DOES consume bi. */
-static real_bigint
-clone( real_bigint bi )
-    {
-    real_bigint biR;
-    int c;
-
-    /* Very clever optimization. */
-    if ( bi->refs != PERMANENT && bi->refs == 1 )
-       return bi;
-
-    biR = alloc( bi->num_comps );
-    biR->sign = bi->sign;
-    for ( c = 0; c < bi->num_comps; ++c )
-       biR->comps[c] = bi->comps[c];
-    bi_free( bi );
-    return biR;
-    }
-
-
-/* Put bi into normal form.  Does not consume bi, of course.
-**
-** Normal form is:
-**  - All components >= 0 and < bi_radix.
-**  - Leading 0 components removed.
-**  - Sign either 1 or -1.
-**  - The number zero represented by a single 0 component and a sign of 1.
-*/
-static void
-normalize( real_bigint bi )
-    {
-    int c;
-
-    /* Borrow for negative components.  Got to be careful with the math here:
-    **   -9 / 10 == 0    -9 % 10 == -9
-    **   -10 / 10 == -1  -10 % 10 == 0
-    **   -11 / 10 == -1  -11 % 10 == -1
-    */
-    for ( c = 0; c < bi->num_comps - 1; ++c )
-       if ( bi->comps[c] < 0 )
-           {
-           bi->comps[c+1] += bi->comps[c] / bi_radix - 1;
-           bi->comps[c] = bi->comps[c] % bi_radix;
-           if ( bi->comps[c] != 0 )
-               bi->comps[c] += bi_radix;
-           else
-               bi->comps[c+1] += 1;
-           }
-    /* Is the top component negative? */
-    if ( bi->comps[bi->num_comps - 1] < 0 )
-       {
-       /* Switch the sign of the number, and fix up the components. */
-       bi->sign = -bi->sign;
-       for ( c = 0; c < bi->num_comps - 1; ++c )
-           {
-           bi->comps[c] =  bi_radix - bi->comps[c];
-           bi->comps[c + 1] += 1;
-           }
-       bi->comps[bi->num_comps - 1] = -bi->comps[bi->num_comps - 1];
-       }
-
-    /* Carry for components larger than the radix. */
-    for ( c = 0; c < bi->num_comps; ++c )
-       if ( bi->comps[c] >= bi_radix )
-           {
-           if ( c + 1 >= bi->num_comps )
-               more_comps( bi, bi->num_comps + 1 );
-           bi->comps[c+1] += bi->comps[c] / bi_radix;
-           bi->comps[c] = bi->comps[c] % bi_radix;
-           }
-
-    /* Trim off any leading zero components. */
-    for ( ; bi->num_comps > 1 && bi->comps[bi->num_comps-1] == 0; --bi->num_comps )
-       ;
-
-    /* Check for -0. */
-    if ( bi->num_comps == 1 && bi->comps[0] == 0 && bi->sign == -1 )
-       bi->sign = 1;
-    }
-
-
-static void
-check( real_bigint bi )
-    {
-    if ( check_level == 0 )
-       return;
-    if ( bi->refs == 0 )
-       {
-       (void) fprintf( stderr, "check: zero refs in bigint\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    if ( bi->refs < 0 )
-       {
-       (void) fprintf( stderr, "check: negative refs in bigint\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-    if ( check_level < 3 )
-       {
-       /* At check levels less than 3, active bigints have a zero next. */
-       if ( bi->next != (real_bigint) 0 )
-           {
-           (void) fprintf(
-               stderr, "check: attempt to use a bigint from the free list\n" );
-           (void) kill( getpid(), SIGFPE );
-           }
-       }
-    else
-       {
-       /* At check levels 3 or higher, active bigints must be on the active
-       ** list.
-       */
-       real_bigint p;
-
-       for ( p = active_list; p != (real_bigint) 0; p = p->next )
-           if ( p == bi )
-               break;
-       if ( p == (real_bigint) 0 )
-           {
-           (void) fprintf( stderr,
-               "check: attempt to use a bigint not on the active list\n" );
-           (void) kill( getpid(), SIGFPE );
-           }
-       }
-    if ( check_level >= 2 )
-       double_check();
-    if ( check_level >= 3 )
-       triple_check();
-    }
-
-
-static void
-double_check( void )
-    {
-    real_bigint p;
-    int c;
-
-    for ( p = free_list, c = 0; p != (real_bigint) 0; p = p->next, ++c )
-       if ( p->refs != 0 )
-           {
-           (void) fprintf( stderr,
-               "double_check: found a non-zero ref on the free list\n" );
-           (void) kill( getpid(), SIGFPE );
-           }
-    if ( c != free_count )
-       {
-       (void) fprintf( stderr,
-           "double_check: free_count is %d but the free list has %d items\n",
-           free_count, c );
-       (void) kill( getpid(), SIGFPE );
-       }
-    }
-
-
-static void
-triple_check( void )
-    {
-    real_bigint p;
-    int c;
-
-    for ( p = active_list, c = 0; p != (real_bigint) 0; p = p->next, ++c )
-       if ( p->refs == 0 )
-           {
-           (void) fprintf( stderr,
-               "triple_check: found a zero ref on the active list\n" );
-           (void) kill( getpid(), SIGFPE );
-           }
-    if ( c != active_count )
-       {
-       (void) fprintf( stderr,
-           "triple_check: active_count is %d but active_list has %d items\n",
-           free_count, c );
-       (void) kill( getpid(), SIGFPE );
-       }
-    }
-
-
-#ifdef DUMP
-/* Debug routine to dump out a complete bigint.  Does not consume bi. */
-static void
-dump( char* str, bigint obi )
-    {
-    int c;
-    real_bigint bi = (real_bigint) obi;
-
-    (void) fprintf( stdout, "dump %s at 0x%08x:\n", str, (unsigned int) bi );
-    (void) fprintf( stdout, "  refs: %d\n", bi->refs );
-    (void) fprintf( stdout, "  next: 0x%08x\n", (unsigned int) bi->next );
-    (void) fprintf( stdout, "  num_comps: %d\n", bi->num_comps );
-    (void) fprintf( stdout, "  max_comps: %d\n", bi->max_comps );
-    (void) fprintf( stdout, "  sign: %d\n", bi->sign );
-    for ( c = bi->num_comps - 1; c >= 0; --c )
-       (void) fprintf( stdout, "    comps[%d]: %11lld (0x%016llx)\n", c, (long long) bi->comps[c], (long long) bi->comps[c] );
-    (void) fprintf( stdout, "  print: " );
-    bi_print( stdout, bi_copy( bi ) );
-    (void) fprintf( stdout, "\n" );
-    }
-#endif /* DUMP */
-
-
-/* Trivial square-root routine so that we don't have to link in the math lib. */
-static int
-csqrt( comp c )
-    {
-    comp r, r2, diff;
-
-    if ( c < 0 )
-       {
-       (void) fprintf( stderr, "csqrt: imaginary result\n" );
-       (void) kill( getpid(), SIGFPE );
-       }
-
-    r = c / 2;
-    for (;;)
-       {
-       r2 = c / r;
-       diff = r - r2;
-       if ( diff == 0 || diff == -1 )
-           return (int) r;
-       if ( diff == 1 )
-           return (int) r2;
-       r = ( r + r2 ) / 2;
-       }
-    }
-
-
-/* Figure out how many bits are in a number. */
-static int
-cbits( comp c )
-    {
-    int b;
-
-    for ( b = 0; c != 0; ++b )
-       c >>= 1;
-    return b;
-    }
diff --git a/src/rt/bigint/low_primes.h b/src/rt/bigint/low_primes.h
deleted file mode 100644 (file)
index c9d3df0..0000000
+++ /dev/null
@@ -1,1069 +0,0 @@
-/* Primes up to 100000. */
-static long low_primes[] = {
-        2,     3,     5,     7,    11,    13,    17,    19,    23,
-       29,    31,    37,    41,    43,    47,    53,    59,    61,
-       67,    71,    73,    79,    83,    89,    97,   101,   103,
-      107,   109,   113,   127,   131,   137,   139,   149,   151,
-      157,   163,   167,   173,   179,   181,   191,   193,   197,
-      199,   211,   223,   227,   229,   233,   239,   241,   251,
-      257,   263,   269,   271,   277,   281,   283,   293,   307,
-      311,   313,   317,   331,   337,   347,   349,   353,   359,
-      367,   373,   379,   383,   389,   397,   401,   409,   419,
-      421,   431,   433,   439,   443,   449,   457,   461,   463,
-      467,   479,   487,   491,   499,   503,   509,   521,   523,
-      541,   547,   557,   563,   569,   571,   577,   587,   593,
-      599,   601,   607,   613,   617,   619,   631,   641,   643,
-      647,   653,   659,   661,   673,   677,   683,   691,   701,
-      709,   719,   727,   733,   739,   743,   751,   757,   761,
-      769,   773,   787,   797,   809,   811,   821,   823,   827,
-      829,   839,   853,   857,   859,   863,   877,   881,   883,
-      887,   907,   911,   919,   929,   937,   941,   947,   953,
-      967,   971,   977,   983,   991,   997,  1009,  1013,  1019,
-     1021,  1031,  1033,  1039,  1049,  1051,  1061,  1063,  1069,
-     1087,  1091,  1093,  1097,  1103,  1109,  1117,  1123,  1129,
-     1151,  1153,  1163,  1171,  1181,  1187,  1193,  1201,  1213,
-     1217,  1223,  1229,  1231,  1237,  1249,  1259,  1277,  1279,
-     1283,  1289,  1291,  1297,  1301,  1303,  1307,  1319,  1321,
-     1327,  1361,  1367,  1373,  1381,  1399,  1409,  1423,  1427,
-     1429,  1433,  1439,  1447,  1451,  1453,  1459,  1471,  1481,
-     1483,  1487,  1489,  1493,  1499,  1511,  1523,  1531,  1543,
-     1549,  1553,  1559,  1567,  1571,  1579,  1583,  1597,  1601,
-     1607,  1609,  1613,  1619,  1621,  1627,  1637,  1657,  1663,
-     1667,  1669,  1693,  1697,  1699,  1709,  1721,  1723,  1733,
-     1741,  1747,  1753,  1759,  1777,  1783,  1787,  1789,  1801,
-     1811,  1823,  1831,  1847,  1861,  1867,  1871,  1873,  1877,
-     1879,  1889,  1901,  1907,  1913,  1931,  1933,  1949,  1951,
-     1973,  1979,  1987,  1993,  1997,  1999,  2003,  2011,  2017,
-     2027,  2029,  2039,  2053,  2063,  2069,  2081,  2083,  2087,
-     2089,  2099,  2111,  2113,  2129,  2131,  2137,  2141,  2143,
-     2153,  2161,  2179,  2203,  2207,  2213,  2221,  2237,  2239,
-     2243,  2251,  2267,  2269,  2273,  2281,  2287,  2293,  2297,
-     2309,  2311,  2333,  2339,  2341,  2347,  2351,  2357,  2371,
-     2377,  2381,  2383,  2389,  2393,  2399,  2411,  2417,  2423,
-     2437,  2441,  2447,  2459,  2467,  2473,  2477,  2503,  2521,
-     2531,  2539,  2543,  2549,  2551,  2557,  2579,  2591,  2593,
-     2609,  2617,  2621,  2633,  2647,  2657,  2659,  2663,  2671,
-     2677,  2683,  2687,  2689,  2693,  2699,  2707,  2711,  2713,
-     2719,  2729,  2731,  2741,  2749,  2753,  2767,  2777,  2789,
-     2791,  2797,  2801,  2803,  2819,  2833,  2837,  2843,  2851,
-     2857,  2861,  2879,  2887,  2897,  2903,  2909,  2917,  2927,
-     2939,  2953,  2957,  2963,  2969,  2971,  2999,  3001,  3011,
-     3019,  3023,  3037,  3041,  3049,  3061,  3067,  3079,  3083,
-     3089,  3109,  3119,  3121,  3137,  3163,  3167,  3169,  3181,
-     3187,  3191,  3203,  3209,  3217,  3221,  3229,  3251,  3253,
-     3257,  3259,  3271,  3299,  3301,  3307,  3313,  3319,  3323,
-     3329,  3331,  3343,  3347,  3359,  3361,  3371,  3373,  3389,
-     3391,  3407,  3413,  3433,  3449,  3457,  3461,  3463,  3467,
-     3469,  3491,  3499,  3511,  3517,  3527,  3529,  3533,  3539,
-     3541,  3547,  3557,  3559,  3571,  3581,  3583,  3593,  3607,
-     3613,  3617,  3623,  3631,  3637,  3643,  3659,  3671,  3673,
-     3677,  3691,  3697,  3701,  3709,  3719,  3727,  3733,  3739,
-     3761,  3767,  3769,  3779,  3793,  3797,  3803,  3821,  3823,
-     3833,  3847,  3851,  3853,  3863,  3877,  3881,  3889,  3907,
-     3911,  3917,  3919,  3923,  3929,  3931,  3943,  3947,  3967,
-     3989,  4001,  4003,  4007,  4013,  4019,  4021,  4027,  4049,
-     4051,  4057,  4073,  4079,  4091,  4093,  4099,  4111,  4127,
-     4129,  4133,  4139,  4153,  4157,  4159,  4177,  4201,  4211,
-     4217,  4219,  4229,  4231,  4241,  4243,  4253,  4259,  4261,
-     4271,  4273,  4283,  4289,  4297,  4327,  4337,  4339,  4349,
-     4357,  4363,  4373,  4391,  4397,  4409,  4421,  4423,  4441,
-     4447,  4451,  4457,  4463,  4481,  4483,  4493,  4507,  4513,
-     4517,  4519,  4523,  4547,  4549,  4561,  4567,  4583,  4591,
-     4597,  4603,  4621,  4637,  4639,  4643,  4649,  4651,  4657,
-     4663,  4673,  4679,  4691,  4703,  4721,  4723,  4729,  4733,
-     4751,  4759,  4783,  4787,  4789,  4793,  4799,  4801,  4813,
-     4817,  4831,  4861,  4871,  4877,  4889,  4903,  4909,  4919,
-     4931,  4933,  4937,  4943,  4951,  4957,  4967,  4969,  4973,
-     4987,  4993,  4999,  5003,  5009,  5011,  5021,  5023,  5039,
-     5051,  5059,  5077,  5081,  5087,  5099,  5101,  5107,  5113,
-     5119,  5147,  5153,  5167,  5171,  5179,  5189,  5197,  5209,
-     5227,  5231,  5233,  5237,  5261,  5273,  5279,  5281,  5297,
-     5303,  5309,  5323,  5333,  5347,  5351,  5381,  5387,  5393,
-     5399,  5407,  5413,  5417,  5419,  5431,  5437,  5441,  5443,
-     5449,  5471,  5477,  5479,  5483,  5501,  5503,  5507,  5519,
-     5521,  5527,  5531,  5557,  5563,  5569,  5573,  5581,  5591,
-     5623,  5639,  5641,  5647,  5651,  5653,  5657,  5659,  5669,
-     5683,  5689,  5693,  5701,  5711,  5717,  5737,  5741,  5743,
-     5749,  5779,  5783,  5791,  5801,  5807,  5813,  5821,  5827,
-     5839,  5843,  5849,  5851,  5857,  5861,  5867,  5869,  5879,
-     5881,  5897,  5903,  5923,  5927,  5939,  5953,  5981,  5987,
-     6007,  6011,  6029,  6037,  6043,  6047,  6053,  6067,  6073,
-     6079,  6089,  6091,  6101,  6113,  6121,  6131,  6133,  6143,
-     6151,  6163,  6173,  6197,  6199,  6203,  6211,  6217,  6221,
-     6229,  6247,  6257,  6263,  6269,  6271,  6277,  6287,  6299,
-     6301,  6311,  6317,  6323,  6329,  6337,  6343,  6353,  6359,
-     6361,  6367,  6373,  6379,  6389,  6397,  6421,  6427,  6449,
-     6451,  6469,  6473,  6481,  6491,  6521,  6529,  6547,  6551,
-     6553,  6563,  6569,  6571,  6577,  6581,  6599,  6607,  6619,
-     6637,  6653,  6659,  6661,  6673,  6679,  6689,  6691,  6701,
-     6703,  6709,  6719,  6733,  6737,  6761,  6763,  6779,  6781,
-     6791,  6793,  6803,  6823,  6827,  6829,  6833,  6841,  6857,
-     6863,  6869,  6871,  6883,  6899,  6907,  6911,  6917,  6947,
-     6949,  6959,  6961,  6967,  6971,  6977,  6983,  6991,  6997,
-     7001,  7013,  7019,  7027,  7039,  7043,  7057,  7069,  7079,
-     7103,  7109,  7121,  7127,  7129,  7151,  7159,  7177,  7187,
-     7193,  7207,  7211,  7213,  7219,  7229,  7237,  7243,  7247,
-     7253,  7283,  7297,  7307,  7309,  7321,  7331,  7333,  7349,
-     7351,  7369,  7393,  7411,  7417,  7433,  7451,  7457,  7459,
-     7477,  7481,  7487,  7489,  7499,  7507,  7517,  7523,  7529,
-     7537,  7541,  7547,  7549,  7559,  7561,  7573,  7577,  7583,
-     7589,  7591,  7603,  7607,  7621,  7639,  7643,  7649,  7669,
-     7673,  7681,  7687,  7691,  7699,  7703,  7717,  7723,  7727,
-     7741,  7753,  7757,  7759,  7789,  7793,  7817,  7823,  7829,
-     7841,  7853,  7867,  7873,  7877,  7879,  7883,  7901,  7907,
-     7919,  7927,  7933,  7937,  7949,  7951,  7963,  7993,  8009,
-     8011,  8017,  8039,  8053,  8059,  8069,  8081,  8087,  8089,
-     8093,  8101,  8111,  8117,  8123,  8147,  8161,  8167,  8171,
-     8179,  8191,  8209,  8219,  8221,  8231,  8233,  8237,  8243,
-     8263,  8269,  8273,  8287,  8291,  8293,  8297,  8311,  8317,
-     8329,  8353,  8363,  8369,  8377,  8387,  8389,  8419,  8423,
-     8429,  8431,  8443,  8447,  8461,  8467,  8501,  8513,  8521,
-     8527,  8537,  8539,  8543,  8563,  8573,  8581,  8597,  8599,
-     8609,  8623,  8627,  8629,  8641,  8647,  8663,  8669,  8677,
-     8681,  8689,  8693,  8699,  8707,  8713,  8719,  8731,  8737,
-     8741,  8747,  8753,  8761,  8779,  8783,  8803,  8807,  8819,
-     8821,  8831,  8837,  8839,  8849,  8861,  8863,  8867,  8887,
-     8893,  8923,  8929,  8933,  8941,  8951,  8963,  8969,  8971,
-     8999,  9001,  9007,  9011,  9013,  9029,  9041,  9043,  9049,
-     9059,  9067,  9091,  9103,  9109,  9127,  9133,  9137,  9151,
-     9157,  9161,  9173,  9181,  9187,  9199,  9203,  9209,  9221,
-     9227,  9239,  9241,  9257,  9277,  9281,  9283,  9293,  9311,
-     9319,  9323,  9337,  9341,  9343,  9349,  9371,  9377,  9391,
-     9397,  9403,  9413,  9419,  9421,  9431,  9433,  9437,  9439,
-     9461,  9463,  9467,  9473,  9479,  9491,  9497,  9511,  9521,
-     9533,  9539,  9547,  9551,  9587,  9601,  9613,  9619,  9623,
-     9629,  9631,  9643,  9649,  9661,  9677,  9679,  9689,  9697,
-     9719,  9721,  9733,  9739,  9743,  9749,  9767,  9769,  9781,
-     9787,  9791,  9803,  9811,  9817,  9829,  9833,  9839,  9851,
-     9857,  9859,  9871,  9883,  9887,  9901,  9907,  9923,  9929,
-     9931,  9941,  9949,  9967,  9973, 10007, 10009, 10037, 10039,
-    10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111,
-    10133, 10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181,
-    10193, 10211, 10223, 10243, 10247, 10253, 10259, 10267, 10271,
-    10273, 10289, 10301, 10303, 10313, 10321, 10331, 10333, 10337,
-    10343, 10357, 10369, 10391, 10399, 10427, 10429, 10433, 10453,
-    10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529,
-    10531, 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627,
-    10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, 10709,
-    10711, 10723, 10729, 10733, 10739, 10753, 10771, 10781, 10789,
-    10799, 10831, 10837, 10847, 10853, 10859, 10861, 10867, 10883,
-    10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957, 10973,
-    10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069,
-    11071, 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149,
-    11159, 11161, 11171, 11173, 11177, 11197, 11213, 11239, 11243,
-    11251, 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317,
-    11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, 11411,
-    11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491,
-    11497, 11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593,
-    11597, 11617, 11621, 11633, 11657, 11677, 11681, 11689, 11699,
-    11701, 11717, 11719, 11731, 11743, 11777, 11779, 11783, 11789,
-    11801, 11807, 11813, 11821, 11827, 11831, 11833, 11839, 11863,
-    11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, 11939,
-    11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011,
-    12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107,
-    12109, 12113, 12119, 12143, 12149, 12157, 12161, 12163, 12197,
-    12203, 12211, 12227, 12239, 12241, 12251, 12253, 12263, 12269,
-    12277, 12281, 12289, 12301, 12323, 12329, 12343, 12347, 12373,
-    12377, 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437,
-    12451, 12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511,
-    12517, 12527, 12539, 12541, 12547, 12553, 12569, 12577, 12583,
-    12589, 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653,
-    12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, 12743,
-    12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829,
-    12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919,
-    12923, 12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001,
-    13003, 13007, 13009, 13033, 13037, 13043, 13049, 13063, 13093,
-    13099, 13103, 13109, 13121, 13127, 13147, 13151, 13159, 13163,
-    13171, 13177, 13183, 13187, 13217, 13219, 13229, 13241, 13249,
-    13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
-    13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441,
-    13451, 13457, 13463, 13469, 13477, 13487, 13499, 13513, 13523,
-    13537, 13553, 13567, 13577, 13591, 13597, 13613, 13619, 13627,
-    13633, 13649, 13669, 13679, 13681, 13687, 13691, 13693, 13697,
-    13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763,
-    13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873,
-    13877, 13879, 13883, 13901, 13903, 13907, 13913, 13921, 13931,
-    13933, 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033,
-    14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, 14149,
-    14153, 14159, 14173, 14177, 14197, 14207, 14221, 14243, 14249,
-    14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347,
-    14369, 14387, 14389, 14401, 14407, 14411, 14419, 14423, 14431,
-    14437, 14447, 14449, 14461, 14479, 14489, 14503, 14519, 14533,
-    14537, 14543, 14549, 14551, 14557, 14561, 14563, 14591, 14593,
-    14621, 14627, 14629, 14633, 14639, 14653, 14657, 14669, 14683,
-    14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753,
-    14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827,
-    14831, 14843, 14851, 14867, 14869, 14879, 14887, 14891, 14897,
-    14923, 14929, 14939, 14947, 14951, 14957, 14969, 14983, 15013,
-    15017, 15031, 15053, 15061, 15073, 15077, 15083, 15091, 15101,
-    15107, 15121, 15131, 15137, 15139, 15149, 15161, 15173, 15187,
-    15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269,
-    15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329,
-    15331, 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401,
-    15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, 15493,
-    15497, 15511, 15527, 15541, 15551, 15559, 15569, 15581, 15583,
-    15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649, 15661,
-    15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739,
-    15749, 15761, 15767, 15773, 15787, 15791, 15797, 15803, 15809,
-    15817, 15823, 15859, 15877, 15881, 15887, 15889, 15901, 15907,
-    15913, 15919, 15923, 15937, 15959, 15971, 15973, 15991, 16001,
-    16007, 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087,
-    16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187,
-    16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267,
-    16273, 16301, 16319, 16333, 16339, 16349, 16361, 16363, 16369,
-    16381, 16411, 16417, 16421, 16427, 16433, 16447, 16451, 16453,
-    16477, 16481, 16487, 16493, 16519, 16529, 16547, 16553, 16561,
-    16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649, 16651,
-    16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741,
-    16747, 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843,
-    16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, 16931,
-    16937, 16943, 16963, 16979, 16981, 16987, 16993, 17011, 17021,
-    17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, 17099,
-    17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191,
-    17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299,
-    17317, 17321, 17327, 17333, 17341, 17351, 17359, 17377, 17383,
-    17387, 17389, 17393, 17401, 17417, 17419, 17431, 17443, 17449,
-    17467, 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519,
-    17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, 17609,
-    17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713,
-    17729, 17737, 17747, 17749, 17761, 17783, 17789, 17791, 17807,
-    17827, 17837, 17839, 17851, 17863, 17881, 17891, 17903, 17909,
-    17911, 17921, 17923, 17929, 17939, 17957, 17959, 17971, 17977,
-    17981, 17987, 17989, 18013, 18041, 18043, 18047, 18049, 18059,
-    18061, 18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133,
-    18143, 18149, 18169, 18181, 18191, 18199, 18211, 18217, 18223,
-    18229, 18233, 18251, 18253, 18257, 18269, 18287, 18289, 18301,
-    18307, 18311, 18313, 18329, 18341, 18353, 18367, 18371, 18379,
-    18397, 18401, 18413, 18427, 18433, 18439, 18443, 18451, 18457,
-    18461, 18481, 18493, 18503, 18517, 18521, 18523, 18539, 18541,
-    18553, 18583, 18587, 18593, 18617, 18637, 18661, 18671, 18679,
-    18691, 18701, 18713, 18719, 18731, 18743, 18749, 18757, 18773,
-    18787, 18793, 18797, 18803, 18839, 18859, 18869, 18899, 18911,
-    18913, 18917, 18919, 18947, 18959, 18973, 18979, 19001, 19009,
-    19013, 19031, 19037, 19051, 19069, 19073, 19079, 19081, 19087,
-    19121, 19139, 19141, 19157, 19163, 19181, 19183, 19207, 19211,
-    19213, 19219, 19231, 19237, 19249, 19259, 19267, 19273, 19289,
-    19301, 19309, 19319, 19333, 19373, 19379, 19381, 19387, 19391,
-    19403, 19417, 19421, 19423, 19427, 19429, 19433, 19441, 19447,
-    19457, 19463, 19469, 19471, 19477, 19483, 19489, 19501, 19507,
-    19531, 19541, 19543, 19553, 19559, 19571, 19577, 19583, 19597,
-    19603, 19609, 19661, 19681, 19687, 19697, 19699, 19709, 19717,
-    19727, 19739, 19751, 19753, 19759, 19763, 19777, 19793, 19801,
-    19813, 19819, 19841, 19843, 19853, 19861, 19867, 19889, 19891,
-    19913, 19919, 19927, 19937, 19949, 19961, 19963, 19973, 19979,
-    19991, 19993, 19997, 20011, 20021, 20023, 20029, 20047, 20051,
-    20063, 20071, 20089, 20101, 20107, 20113, 20117, 20123, 20129,
-    20143, 20147, 20149, 20161, 20173, 20177, 20183, 20201, 20219,
-    20231, 20233, 20249, 20261, 20269, 20287, 20297, 20323, 20327,
-    20333, 20341, 20347, 20353, 20357, 20359, 20369, 20389, 20393,
-    20399, 20407, 20411, 20431, 20441, 20443, 20477, 20479, 20483,
-    20507, 20509, 20521, 20533, 20543, 20549, 20551, 20563, 20593,
-    20599, 20611, 20627, 20639, 20641, 20663, 20681, 20693, 20707,
-    20717, 20719, 20731, 20743, 20747, 20749, 20753, 20759, 20771,
-    20773, 20789, 20807, 20809, 20849, 20857, 20873, 20879, 20887,
-    20897, 20899, 20903, 20921, 20929, 20939, 20947, 20959, 20963,
-    20981, 20983, 21001, 21011, 21013, 21017, 21019, 21023, 21031,
-    21059, 21061, 21067, 21089, 21101, 21107, 21121, 21139, 21143,
-    21149, 21157, 21163, 21169, 21179, 21187, 21191, 21193, 21211,
-    21221, 21227, 21247, 21269, 21277, 21283, 21313, 21317, 21319,
-    21323, 21341, 21347, 21377, 21379, 21383, 21391, 21397, 21401,
-    21407, 21419, 21433, 21467, 21481, 21487, 21491, 21493, 21499,
-    21503, 21517, 21521, 21523, 21529, 21557, 21559, 21563, 21569,
-    21577, 21587, 21589, 21599, 21601, 21611, 21613, 21617, 21647,
-    21649, 21661, 21673, 21683, 21701, 21713, 21727, 21737, 21739,
-    21751, 21757, 21767, 21773, 21787, 21799, 21803, 21817, 21821,
-    21839, 21841, 21851, 21859, 21863, 21871, 21881, 21893, 21911,
-    21929, 21937, 21943, 21961, 21977, 21991, 21997, 22003, 22013,
-    22027, 22031, 22037, 22039, 22051, 22063, 22067, 22073, 22079,
-    22091, 22093, 22109, 22111, 22123, 22129, 22133, 22147, 22153,
-    22157, 22159, 22171, 22189, 22193, 22229, 22247, 22259, 22271,
-    22273, 22277, 22279, 22283, 22291, 22303, 22307, 22343, 22349,
-    22367, 22369, 22381, 22391, 22397, 22409, 22433, 22441, 22447,
-    22453, 22469, 22481, 22483, 22501, 22511, 22531, 22541, 22543,
-    22549, 22567, 22571, 22573, 22613, 22619, 22621, 22637, 22639,
-    22643, 22651, 22669, 22679, 22691, 22697, 22699, 22709, 22717,
-    22721, 22727, 22739, 22741, 22751, 22769, 22777, 22783, 22787,
-    22807, 22811, 22817, 22853, 22859, 22861, 22871, 22877, 22901,
-    22907, 22921, 22937, 22943, 22961, 22963, 22973, 22993, 23003,
-    23011, 23017, 23021, 23027, 23029, 23039, 23041, 23053, 23057,
-    23059, 23063, 23071, 23081, 23087, 23099, 23117, 23131, 23143,
-    23159, 23167, 23173, 23189, 23197, 23201, 23203, 23209, 23227,
-    23251, 23269, 23279, 23291, 23293, 23297, 23311, 23321, 23327,
-    23333, 23339, 23357, 23369, 23371, 23399, 23417, 23431, 23447,
-    23459, 23473, 23497, 23509, 23531, 23537, 23539, 23549, 23557,
-    23561, 23563, 23567, 23581, 23593, 23599, 23603, 23609, 23623,
-    23627, 23629, 23633, 23663, 23669, 23671, 23677, 23687, 23689,
-    23719, 23741, 23743, 23747, 23753, 23761, 23767, 23773, 23789,
-    23801, 23813, 23819, 23827, 23831, 23833, 23857, 23869, 23873,
-    23879, 23887, 23893, 23899, 23909, 23911, 23917, 23929, 23957,
-    23971, 23977, 23981, 23993, 24001, 24007, 24019, 24023, 24029,
-    24043, 24049, 24061, 24071, 24077, 24083, 24091, 24097, 24103,
-    24107, 24109, 24113, 24121, 24133, 24137, 24151, 24169, 24179,
-    24181, 24197, 24203, 24223, 24229, 24239, 24247, 24251, 24281,
-    24317, 24329, 24337, 24359, 24371, 24373, 24379, 24391, 24407,
-    24413, 24419, 24421, 24439, 24443, 24469, 24473, 24481, 24499,
-    24509, 24517, 24527, 24533, 24547, 24551, 24571, 24593, 24611,
-    24623, 24631, 24659, 24671, 24677, 24683, 24691, 24697, 24709,
-    24733, 24749, 24763, 24767, 24781, 24793, 24799, 24809, 24821,
-    24841, 24847, 24851, 24859, 24877, 24889, 24907, 24917, 24919,
-    24923, 24943, 24953, 24967, 24971, 24977, 24979, 24989, 25013,
-    25031, 25033, 25037, 25057, 25073, 25087, 25097, 25111, 25117,
-    25121, 25127, 25147, 25153, 25163, 25169, 25171, 25183, 25189,
-    25219, 25229, 25237, 25243, 25247, 25253, 25261, 25301, 25303,
-    25307, 25309, 25321, 25339, 25343, 25349, 25357, 25367, 25373,
-    25391, 25409, 25411, 25423, 25439, 25447, 25453, 25457, 25463,
-    25469, 25471, 25523, 25537, 25541, 25561, 25577, 25579, 25583,
-    25589, 25601, 25603, 25609, 25621, 25633, 25639, 25643, 25657,
-    25667, 25673, 25679, 25693, 25703, 25717, 25733, 25741, 25747,
-    25759, 25763, 25771, 25793, 25799, 25801, 25819, 25841, 25847,
-    25849, 25867, 25873, 25889, 25903, 25913, 25919, 25931, 25933,
-    25939, 25943, 25951, 25969, 25981, 25997, 25999, 26003, 26017,
-    26021, 26029, 26041, 26053, 26083, 26099, 26107, 26111, 26113,
-    26119, 26141, 26153, 26161, 26171, 26177, 26183, 26189, 26203,
-    26209, 26227, 26237, 26249, 26251, 26261, 26263, 26267, 26293,
-    26297, 26309, 26317, 26321, 26339, 26347, 26357, 26371, 26387,
-    26393, 26399, 26407, 26417, 26423, 26431, 26437, 26449, 26459,
-    26479, 26489, 26497, 26501, 26513, 26539, 26557, 26561, 26573,
-    26591, 26597, 26627, 26633, 26641, 26647, 26669, 26681, 26683,
-    26687, 26693, 26699, 26701, 26711, 26713, 26717, 26723, 26729,
-    26731, 26737, 26759, 26777, 26783, 26801, 26813, 26821, 26833,
-    26839, 26849, 26861, 26863, 26879, 26881, 26891, 26893, 26903,
-    26921, 26927, 26947, 26951, 26953, 26959, 26981, 26987, 26993,
-    27011, 27017, 27031, 27043, 27059, 27061, 27067, 27073, 27077,
-    27091, 27103, 27107, 27109, 27127, 27143, 27179, 27191, 27197,
-    27211, 27239, 27241, 27253, 27259, 27271, 27277, 27281, 27283,
-    27299, 27329, 27337, 27361, 27367, 27397, 27407, 27409, 27427,
-    27431, 27437, 27449, 27457, 27479, 27481, 27487, 27509, 27527,
-    27529, 27539, 27541, 27551, 27581, 27583, 27611, 27617, 27631,
-    27647, 27653, 27673, 27689, 27691, 27697, 27701, 27733, 27737,
-    27739, 27743, 27749, 27751, 27763, 27767, 27773, 27779, 27791,
-    27793, 27799, 27803, 27809, 27817, 27823, 27827, 27847, 27851,
-    27883, 27893, 27901, 27917, 27919, 27941, 27943, 27947, 27953,
-    27961, 27967, 27983, 27997, 28001, 28019, 28027, 28031, 28051,
-    28057, 28069, 28081, 28087, 28097, 28099, 28109, 28111, 28123,
-    28151, 28163, 28181, 28183, 28201, 28211, 28219, 28229, 28277,
-    28279, 28283, 28289, 28297, 28307, 28309, 28319, 28349, 28351,
-    28387, 28393, 28403, 28409, 28411, 28429, 28433, 28439, 28447,
-    28463, 28477, 28493, 28499, 28513, 28517, 28537, 28541, 28547,
-    28549, 28559, 28571, 28573, 28579, 28591, 28597, 28603, 28607,
-    28619, 28621, 28627, 28631, 28643, 28649, 28657, 28661, 28663,
-    28669, 28687, 28697, 28703, 28711, 28723, 28729, 28751, 28753,
-    28759, 28771, 28789, 28793, 28807, 28813, 28817, 28837, 28843,
-    28859, 28867, 28871, 28879, 28901, 28909, 28921, 28927, 28933,
-    28949, 28961, 28979, 29009, 29017, 29021, 29023, 29027, 29033,
-    29059, 29063, 29077, 29101, 29123, 29129, 29131, 29137, 29147,
-    29153, 29167, 29173, 29179, 29191, 29201, 29207, 29209, 29221,
-    29231, 29243, 29251, 29269, 29287, 29297, 29303, 29311, 29327,
-    29333, 29339, 29347, 29363, 29383, 29387, 29389, 29399, 29401,
-    29411, 29423, 29429, 29437, 29443, 29453, 29473, 29483, 29501,
-    29527, 29531, 29537, 29567, 29569, 29573, 29581, 29587, 29599,
-    29611, 29629, 29633, 29641, 29663, 29669, 29671, 29683, 29717,
-    29723, 29741, 29753, 29759, 29761, 29789, 29803, 29819, 29833,
-    29837, 29851, 29863, 29867, 29873, 29879, 29881, 29917, 29921,
-    29927, 29947, 29959, 29983, 29989, 30011, 30013, 30029, 30047,
-    30059, 30071, 30089, 30091, 30097, 30103, 30109, 30113, 30119,
-    30133, 30137, 30139, 30161, 30169, 30181, 30187, 30197, 30203,
-    30211, 30223, 30241, 30253, 30259, 30269, 30271, 30293, 30307,
-    30313, 30319, 30323, 30341, 30347, 30367, 30389, 30391, 30403,
-    30427, 30431, 30449, 30467, 30469, 30491, 30493, 30497, 30509,
-    30517, 30529, 30539, 30553, 30557, 30559, 30577, 30593, 30631,
-    30637, 30643, 30649, 30661, 30671, 30677, 30689, 30697, 30703,
-    30707, 30713, 30727, 30757, 30763, 30773, 30781, 30803, 30809,
-    30817, 30829, 30839, 30841, 30851, 30853, 30859, 30869, 30871,
-    30881, 30893, 30911, 30931, 30937, 30941, 30949, 30971, 30977,
-    30983, 31013, 31019, 31033, 31039, 31051, 31063, 31069, 31079,
-    31081, 31091, 31121, 31123, 31139, 31147, 31151, 31153, 31159,
-    31177, 31181, 31183, 31189, 31193, 31219, 31223, 31231, 31237,
-    31247, 31249, 31253, 31259, 31267, 31271, 31277, 31307, 31319,
-    31321, 31327, 31333, 31337, 31357, 31379, 31387, 31391, 31393,
-    31397, 31469, 31477, 31481, 31489, 31511, 31513, 31517, 31531,
-    31541, 31543, 31547, 31567, 31573, 31583, 31601, 31607, 31627,
-    31643, 31649, 31657, 31663, 31667, 31687, 31699, 31721, 31723,
-    31727, 31729, 31741, 31751, 31769, 31771, 31793, 31799, 31817,
-    31847, 31849, 31859, 31873, 31883, 31891, 31907, 31957, 31963,
-    31973, 31981, 31991, 32003, 32009, 32027, 32029, 32051, 32057,
-    32059, 32063, 32069, 32077, 32083, 32089, 32099, 32117, 32119,
-    32141, 32143, 32159, 32173, 32183, 32189, 32191, 32203, 32213,
-    32233, 32237, 32251, 32257, 32261, 32297, 32299, 32303, 32309,
-    32321, 32323, 32327, 32341, 32353, 32359, 32363, 32369, 32371,
-    32377, 32381, 32401, 32411, 32413, 32423, 32429, 32441, 32443,
-    32467, 32479, 32491, 32497, 32503, 32507, 32531, 32533, 32537,
-    32561, 32563, 32569, 32573, 32579, 32587, 32603, 32609, 32611,
-    32621, 32633, 32647, 32653, 32687, 32693, 32707, 32713, 32717,
-    32719, 32749, 32771, 32779, 32783, 32789, 32797, 32801, 32803,
-    32831, 32833, 32839, 32843, 32869, 32887, 32909, 32911, 32917,
-    32933, 32939, 32941, 32957, 32969, 32971, 32983, 32987, 32993,
-    32999, 33013, 33023, 33029, 33037, 33049, 33053, 33071, 33073,
-    33083, 33091, 33107, 33113, 33119, 33149, 33151, 33161, 33179,
-    33181, 33191, 33199, 33203, 33211, 33223, 33247, 33287, 33289,
-    33301, 33311, 33317, 33329, 33331, 33343, 33347, 33349, 33353,
-    33359, 33377, 33391, 33403, 33409, 33413, 33427, 33457, 33461,
-    33469, 33479, 33487, 33493, 33503, 33521, 33529, 33533, 33547,
-    33563, 33569, 33577, 33581, 33587, 33589, 33599, 33601, 33613,
-    33617, 33619, 33623, 33629, 33637, 33641, 33647, 33679, 33703,
-    33713, 33721, 33739, 33749, 33751, 33757, 33767, 33769, 33773,
-    33791, 33797, 33809, 33811, 33827, 33829, 33851, 33857, 33863,
-    33871, 33889, 33893, 33911, 33923, 33931, 33937, 33941, 33961,
-    33967, 33997, 34019, 34031, 34033, 34039, 34057, 34061, 34123,
-    34127, 34129, 34141, 34147, 34157, 34159, 34171, 34183, 34211,
-    34213, 34217, 34231, 34253, 34259, 34261, 34267, 34273, 34283,
-    34297, 34301, 34303, 34313, 34319, 34327, 34337, 34351, 34361,
-    34367, 34369, 34381, 34403, 34421, 34429, 34439, 34457, 34469,
-    34471, 34483, 34487, 34499, 34501, 34511, 34513, 34519, 34537,
-    34543, 34549, 34583, 34589, 34591, 34603, 34607, 34613, 34631,
-    34649, 34651, 34667, 34673, 34679, 34687, 34693, 34703, 34721,
-    34729, 34739, 34747, 34757, 34759, 34763, 34781, 34807, 34819,
-    34841, 34843, 34847, 34849, 34871, 34877, 34883, 34897, 34913,
-    34919, 34939, 34949, 34961, 34963, 34981, 35023, 35027, 35051,
-    35053, 35059, 35069, 35081, 35083, 35089, 35099, 35107, 35111,
-    35117, 35129, 35141, 35149, 35153, 35159, 35171, 35201, 35221,
-    35227, 35251, 35257, 35267, 35279, 35281, 35291, 35311, 35317,
-    35323, 35327, 35339, 35353, 35363, 35381, 35393, 35401, 35407,
-    35419, 35423, 35437, 35447, 35449, 35461, 35491, 35507, 35509,
-    35521, 35527, 35531, 35533, 35537, 35543, 35569, 35573, 35591,
-    35593, 35597, 35603, 35617, 35671, 35677, 35729, 35731, 35747,
-    35753, 35759, 35771, 35797, 35801, 35803, 35809, 35831, 35837,
-    35839, 35851, 35863, 35869, 35879, 35897, 35899, 35911, 35923,
-    35933, 35951, 35963, 35969, 35977, 35983, 35993, 35999, 36007,
-    36011, 36013, 36017, 36037, 36061, 36067, 36073, 36083, 36097,
-    36107, 36109, 36131, 36137, 36151, 36161, 36187, 36191, 36209,
-    36217, 36229, 36241, 36251, 36263, 36269, 36277, 36293, 36299,
-    36307, 36313, 36319, 36341, 36343, 36353, 36373, 36383, 36389,
-    36433, 36451, 36457, 36467, 36469, 36473, 36479, 36493, 36497,
-    36523, 36527, 36529, 36541, 36551, 36559, 36563, 36571, 36583,
-    36587, 36599, 36607, 36629, 36637, 36643, 36653, 36671, 36677,
-    36683, 36691, 36697, 36709, 36713, 36721, 36739, 36749, 36761,
-    36767, 36779, 36781, 36787, 36791, 36793, 36809, 36821, 36833,
-    36847, 36857, 36871, 36877, 36887, 36899, 36901, 36913, 36919,
-    36923, 36929, 36931, 36943, 36947, 36973, 36979, 36997, 37003,
-    37013, 37019, 37021, 37039, 37049, 37057, 37061, 37087, 37097,
-    37117, 37123, 37139, 37159, 37171, 37181, 37189, 37199, 37201,
-    37217, 37223, 37243, 37253, 37273, 37277, 37307, 37309, 37313,
-    37321, 37337, 37339, 37357, 37361, 37363, 37369, 37379, 37397,
-    37409, 37423, 37441, 37447, 37463, 37483, 37489, 37493, 37501,
-    37507, 37511, 37517, 37529, 37537, 37547, 37549, 37561, 37567,
-    37571, 37573, 37579, 37589, 37591, 37607, 37619, 37633, 37643,
-    37649, 37657, 37663, 37691, 37693, 37699, 37717, 37747, 37781,
-    37783, 37799, 37811, 37813, 37831, 37847, 37853, 37861, 37871,
-    37879, 37889, 37897, 37907, 37951, 37957, 37963, 37967, 37987,
-    37991, 37993, 37997, 38011, 38039, 38047, 38053, 38069, 38083,
-    38113, 38119, 38149, 38153, 38167, 38177, 38183, 38189, 38197,
-    38201, 38219, 38231, 38237, 38239, 38261, 38273, 38281, 38287,
-    38299, 38303, 38317, 38321, 38327, 38329, 38333, 38351, 38371,
-    38377, 38393, 38431, 38447, 38449, 38453, 38459, 38461, 38501,
-    38543, 38557, 38561, 38567, 38569, 38593, 38603, 38609, 38611,
-    38629, 38639, 38651, 38653, 38669, 38671, 38677, 38693, 38699,
-    38707, 38711, 38713, 38723, 38729, 38737, 38747, 38749, 38767,
-    38783, 38791, 38803, 38821, 38833, 38839, 38851, 38861, 38867,
-    38873, 38891, 38903, 38917, 38921, 38923, 38933, 38953, 38959,
-    38971, 38977, 38993, 39019, 39023, 39041, 39043, 39047, 39079,
-    39089, 39097, 39103, 39107, 39113, 39119, 39133, 39139, 39157,
-    39161, 39163, 39181, 39191, 39199, 39209, 39217, 39227, 39229,
-    39233, 39239, 39241, 39251, 39293, 39301, 39313, 39317, 39323,
-    39341, 39343, 39359, 39367, 39371, 39373, 39383, 39397, 39409,
-    39419, 39439, 39443, 39451, 39461, 39499, 39503, 39509, 39511,
-    39521, 39541, 39551, 39563, 39569, 39581, 39607, 39619, 39623,
-    39631, 39659, 39667, 39671, 39679, 39703, 39709, 39719, 39727,
-    39733, 39749, 39761, 39769, 39779, 39791, 39799, 39821, 39827,
-    39829, 39839, 39841, 39847, 39857, 39863, 39869, 39877, 39883,
-    39887, 39901, 39929, 39937, 39953, 39971, 39979, 39983, 39989,
-    40009, 40013, 40031, 40037, 40039, 40063, 40087, 40093, 40099,
-    40111, 40123, 40127, 40129, 40151, 40153, 40163, 40169, 40177,
-    40189, 40193, 40213, 40231, 40237, 40241, 40253, 40277, 40283,
-    40289, 40343, 40351, 40357, 40361, 40387, 40423, 40427, 40429,
-    40433, 40459, 40471, 40483, 40487, 40493, 40499, 40507, 40519,
-    40529, 40531, 40543, 40559, 40577, 40583, 40591, 40597, 40609,
-    40627, 40637, 40639, 40693, 40697, 40699, 40709, 40739, 40751,
-    40759, 40763, 40771, 40787, 40801, 40813, 40819, 40823, 40829,
-    40841, 40847, 40849, 40853, 40867, 40879, 40883, 40897, 40903,
-    40927, 40933, 40939, 40949, 40961, 40973, 40993, 41011, 41017,
-    41023, 41039, 41047, 41051, 41057, 41077, 41081, 41113, 41117,
-    41131, 41141, 41143, 41149, 41161, 41177, 41179, 41183, 41189,
-    41201, 41203, 41213, 41221, 41227, 41231, 41233, 41243, 41257,
-    41263, 41269, 41281, 41299, 41333, 41341, 41351, 41357, 41381,
-    41387, 41389, 41399, 41411, 41413, 41443, 41453, 41467, 41479,
-    41491, 41507, 41513, 41519, 41521, 41539, 41543, 41549, 41579,
-    41593, 41597, 41603, 41609, 41611, 41617, 41621, 41627, 41641,
-    41647, 41651, 41659, 41669, 41681, 41687, 41719, 41729, 41737,
-    41759, 41761, 41771, 41777, 41801, 41809, 41813, 41843, 41849,
-    41851, 41863, 41879, 41887, 41893, 41897, 41903, 41911, 41927,
-    41941, 41947, 41953, 41957, 41959, 41969, 41981, 41983, 41999,
-    42013, 42017, 42019, 42023, 42043, 42061, 42071, 42073, 42083,
-    42089, 42101, 42131, 42139, 42157, 42169, 42179, 42181, 42187,
-    42193, 42197, 42209, 42221, 42223, 42227, 42239, 42257, 42281,
-    42283, 42293, 42299, 42307, 42323, 42331, 42337, 42349, 42359,
-    42373, 42379, 42391, 42397, 42403, 42407, 42409, 42433, 42437,
-    42443, 42451, 42457, 42461, 42463, 42467, 42473, 42487, 42491,
-    42499, 42509, 42533, 42557, 42569, 42571, 42577, 42589, 42611,
-    42641, 42643, 42649, 42667, 42677, 42683, 42689, 42697, 42701,
-    42703, 42709, 42719, 42727, 42737, 42743, 42751, 42767, 42773,
-    42787, 42793, 42797, 42821, 42829, 42839, 42841, 42853, 42859,
-    42863, 42899, 42901, 42923, 42929, 42937, 42943, 42953, 42961,
-    42967, 42979, 42989, 43003, 43013, 43019, 43037, 43049, 43051,
-    43063, 43067, 43093, 43103, 43117, 43133, 43151, 43159, 43177,
-    43189, 43201, 43207, 43223, 43237, 43261, 43271, 43283, 43291,
-    43313, 43319, 43321, 43331, 43391, 43397, 43399, 43403, 43411,
-    43427, 43441, 43451, 43457, 43481, 43487, 43499, 43517, 43541,
-    43543, 43573, 43577, 43579, 43591, 43597, 43607, 43609, 43613,
-    43627, 43633, 43649, 43651, 43661, 43669, 43691, 43711, 43717,
-    43721, 43753, 43759, 43777, 43781, 43783, 43787, 43789, 43793,
-    43801, 43853, 43867, 43889, 43891, 43913, 43933, 43943, 43951,
-    43961, 43963, 43969, 43973, 43987, 43991, 43997, 44017, 44021,
-    44027, 44029, 44041, 44053, 44059, 44071, 44087, 44089, 44101,
-    44111, 44119, 44123, 44129, 44131, 44159, 44171, 44179, 44189,
-    44201, 44203, 44207, 44221, 44249, 44257, 44263, 44267, 44269,
-    44273, 44279, 44281, 44293, 44351, 44357, 44371, 44381, 44383,
-    44389, 44417, 44449, 44453, 44483, 44491, 44497, 44501, 44507,
-    44519, 44531, 44533, 44537, 44543, 44549, 44563, 44579, 44587,
-    44617, 44621, 44623, 44633, 44641, 44647, 44651, 44657, 44683,
-    44687, 44699, 44701, 44711, 44729, 44741, 44753, 44771, 44773,
-    44777, 44789, 44797, 44809, 44819, 44839, 44843, 44851, 44867,
-    44879, 44887, 44893, 44909, 44917, 44927, 44939, 44953, 44959,
-    44963, 44971, 44983, 44987, 45007, 45013, 45053, 45061, 45077,
-    45083, 45119, 45121, 45127, 45131, 45137, 45139, 45161, 45179,
-    45181, 45191, 45197, 45233, 45247, 45259, 45263, 45281, 45289,
-    45293, 45307, 45317, 45319, 45329, 45337, 45341, 45343, 45361,
-    45377, 45389, 45403, 45413, 45427, 45433, 45439, 45481, 45491,
-    45497, 45503, 45523, 45533, 45541, 45553, 45557, 45569, 45587,
-    45589, 45599, 45613, 45631, 45641, 45659, 45667, 45673, 45677,
-    45691, 45697, 45707, 45737, 45751, 45757, 45763, 45767, 45779,
-    45817, 45821, 45823, 45827, 45833, 45841, 45853, 45863, 45869,
-    45887, 45893, 45943, 45949, 45953, 45959, 45971, 45979, 45989,
-    46021, 46027, 46049, 46051, 46061, 46073, 46091, 46093, 46099,
-    46103, 46133, 46141, 46147, 46153, 46171, 46181, 46183, 46187,
-    46199, 46219, 46229, 46237, 46261, 46271, 46273, 46279, 46301,
-    46307, 46309, 46327, 46337, 46349, 46351, 46381, 46399, 46411,
-    46439, 46441, 46447, 46451, 46457, 46471, 46477, 46489, 46499,
-    46507, 46511, 46523, 46549, 46559, 46567, 46573, 46589, 46591,
-    46601, 46619, 46633, 46639, 46643, 46649, 46663, 46679, 46681,
-    46687, 46691, 46703, 46723, 46727, 46747, 46751, 46757, 46769,
-    46771, 46807, 46811, 46817, 46819, 46829, 46831, 46853, 46861,
-    46867, 46877, 46889, 46901, 46919, 46933, 46957, 46993, 46997,
-    47017, 47041, 47051, 47057, 47059, 47087, 47093, 47111, 47119,
-    47123, 47129, 47137, 47143, 47147, 47149, 47161, 47189, 47207,
-    47221, 47237, 47251, 47269, 47279, 47287, 47293, 47297, 47303,
-    47309, 47317, 47339, 47351, 47353, 47363, 47381, 47387, 47389,
-    47407, 47417, 47419, 47431, 47441, 47459, 47491, 47497, 47501,
-    47507, 47513, 47521, 47527, 47533, 47543, 47563, 47569, 47581,
-    47591, 47599, 47609, 47623, 47629, 47639, 47653, 47657, 47659,
-    47681, 47699, 47701, 47711, 47713, 47717, 47737, 47741, 47743,
-    47777, 47779, 47791, 47797, 47807, 47809, 47819, 47837, 47843,
-    47857, 47869, 47881, 47903, 47911, 47917, 47933, 47939, 47947,
-    47951, 47963, 47969, 47977, 47981, 48017, 48023, 48029, 48049,
-    48073, 48079, 48091, 48109, 48119, 48121, 48131, 48157, 48163,
-    48179, 48187, 48193, 48197, 48221, 48239, 48247, 48259, 48271,
-    48281, 48299, 48311, 48313, 48337, 48341, 48353, 48371, 48383,
-    48397, 48407, 48409, 48413, 48437, 48449, 48463, 48473, 48479,
-    48481, 48487, 48491, 48497, 48523, 48527, 48533, 48539, 48541,
-    48563, 48571, 48589, 48593, 48611, 48619, 48623, 48647, 48649,
-    48661, 48673, 48677, 48679, 48731, 48733, 48751, 48757, 48761,
-    48767, 48779, 48781, 48787, 48799, 48809, 48817, 48821, 48823,
-    48847, 48857, 48859, 48869, 48871, 48883, 48889, 48907, 48947,
-    48953, 48973, 48989, 48991, 49003, 49009, 49019, 49031, 49033,
-    49037, 49043, 49057, 49069, 49081, 49103, 49109, 49117, 49121,
-    49123, 49139, 49157, 49169, 49171, 49177, 49193, 49199, 49201,
-    49207, 49211, 49223, 49253, 49261, 49277, 49279, 49297, 49307,
-    49331, 49333, 49339, 49363, 49367, 49369, 49391, 49393, 49409,
-    49411, 49417, 49429, 49433, 49451, 49459, 49463, 49477, 49481,
-    49499, 49523, 49529, 49531, 49537, 49547, 49549, 49559, 49597,
-    49603, 49613, 49627, 49633, 49639, 49663, 49667, 49669, 49681,
-    49697, 49711, 49727, 49739, 49741, 49747, 49757, 49783, 49787,
-    49789, 49801, 49807, 49811, 49823, 49831, 49843, 49853, 49871,
-    49877, 49891, 49919, 49921, 49927, 49937, 49939, 49943, 49957,
-    49991, 49993, 49999, 50021, 50023, 50033, 50047, 50051, 50053,
-    50069, 50077, 50087, 50093, 50101, 50111, 50119, 50123, 50129,
-    50131, 50147, 50153, 50159, 50177, 50207, 50221, 50227, 50231,
-    50261, 50263, 50273, 50287, 50291, 50311, 50321, 50329, 50333,
-    50341, 50359, 50363, 50377, 50383, 50387, 50411, 50417, 50423,
-    50441, 50459, 50461, 50497, 50503, 50513, 50527, 50539, 50543,
-    50549, 50551, 50581, 50587, 50591, 50593, 50599, 50627, 50647,
-    50651, 50671, 50683, 50707, 50723, 50741, 50753, 50767, 50773,
-    50777, 50789, 50821, 50833, 50839, 50849, 50857, 50867, 50873,
-    50891, 50893, 50909, 50923, 50929, 50951, 50957, 50969, 50971,
-    50989, 50993, 51001, 51031, 51043, 51047, 51059, 51061, 51071,
-    51109, 51131, 51133, 51137, 51151, 51157, 51169, 51193, 51197,
-    51199, 51203, 51217, 51229, 51239, 51241, 51257, 51263, 51283,
-    51287, 51307, 51329, 51341, 51343, 51347, 51349, 51361, 51383,
-    51407, 51413, 51419, 51421, 51427, 51431, 51437, 51439, 51449,
-    51461, 51473, 51479, 51481, 51487, 51503, 51511, 51517, 51521,
-    51539, 51551, 51563, 51577, 51581, 51593, 51599, 51607, 51613,
-    51631, 51637, 51647, 51659, 51673, 51679, 51683, 51691, 51713,
-    51719, 51721, 51749, 51767, 51769, 51787, 51797, 51803, 51817,
-    51827, 51829, 51839, 51853, 51859, 51869, 51871, 51893, 51899,
-    51907, 51913, 51929, 51941, 51949, 51971, 51973, 51977, 51991,
-    52009, 52021, 52027, 52051, 52057, 52067, 52069, 52081, 52103,
-    52121, 52127, 52147, 52153, 52163, 52177, 52181, 52183, 52189,
-    52201, 52223, 52237, 52249, 52253, 52259, 52267, 52289, 52291,
-    52301, 52313, 52321, 52361, 52363, 52369, 52379, 52387, 52391,
-    52433, 52453, 52457, 52489, 52501, 52511, 52517, 52529, 52541,
-    52543, 52553, 52561, 52567, 52571, 52579, 52583, 52609, 52627,
-    52631, 52639, 52667, 52673, 52691, 52697, 52709, 52711, 52721,
-    52727, 52733, 52747, 52757, 52769, 52783, 52807, 52813, 52817,
-    52837, 52859, 52861, 52879, 52883, 52889, 52901, 52903, 52919,
-    52937, 52951, 52957, 52963, 52967, 52973, 52981, 52999, 53003,
-    53017, 53047, 53051, 53069, 53077, 53087, 53089, 53093, 53101,
-    53113, 53117, 53129, 53147, 53149, 53161, 53171, 53173, 53189,
-    53197, 53201, 53231, 53233, 53239, 53267, 53269, 53279, 53281,
-    53299, 53309, 53323, 53327, 53353, 53359, 53377, 53381, 53401,
-    53407, 53411, 53419, 53437, 53441, 53453, 53479, 53503, 53507,
-    53527, 53549, 53551, 53569, 53591, 53593, 53597, 53609, 53611,
-    53617, 53623, 53629, 53633, 53639, 53653, 53657, 53681, 53693,
-    53699, 53717, 53719, 53731, 53759, 53773, 53777, 53783, 53791,
-    53813, 53819, 53831, 53849, 53857, 53861, 53881, 53887, 53891,
-    53897, 53899, 53917, 53923, 53927, 53939, 53951, 53959, 53987,
-    53993, 54001, 54011, 54013, 54037, 54049, 54059, 54083, 54091,
-    54101, 54121, 54133, 54139, 54151, 54163, 54167, 54181, 54193,
-    54217, 54251, 54269, 54277, 54287, 54293, 54311, 54319, 54323,
-    54331, 54347, 54361, 54367, 54371, 54377, 54401, 54403, 54409,
-    54413, 54419, 54421, 54437, 54443, 54449, 54469, 54493, 54497,
-    54499, 54503, 54517, 54521, 54539, 54541, 54547, 54559, 54563,
-    54577, 54581, 54583, 54601, 54617, 54623, 54629, 54631, 54647,
-    54667, 54673, 54679, 54709, 54713, 54721, 54727, 54751, 54767,
-    54773, 54779, 54787, 54799, 54829, 54833, 54851, 54869, 54877,
-    54881, 54907, 54917, 54919, 54941, 54949, 54959, 54973, 54979,
-    54983, 55001, 55009, 55021, 55049, 55051, 55057, 55061, 55073,
-    55079, 55103, 55109, 55117, 55127, 55147, 55163, 55171, 55201,
-    55207, 55213, 55217, 55219, 55229, 55243, 55249, 55259, 55291,
-    55313, 55331, 55333, 55337, 55339, 55343, 55351, 55373, 55381,
-    55399, 55411, 55439, 55441, 55457, 55469, 55487, 55501, 55511,
-    55529, 55541, 55547, 55579, 55589, 55603, 55609, 55619, 55621,
-    55631, 55633, 55639, 55661, 55663, 55667, 55673, 55681, 55691,
-    55697, 55711, 55717, 55721, 55733, 55763, 55787, 55793, 55799,
-    55807, 55813, 55817, 55819, 55823, 55829, 55837, 55843, 55849,
-    55871, 55889, 55897, 55901, 55903, 55921, 55927, 55931, 55933,
-    55949, 55967, 55987, 55997, 56003, 56009, 56039, 56041, 56053,
-    56081, 56087, 56093, 56099, 56101, 56113, 56123, 56131, 56149,
-    56167, 56171, 56179, 56197, 56207, 56209, 56237, 56239, 56249,
-    56263, 56267, 56269, 56299, 56311, 56333, 56359, 56369, 56377,
-    56383, 56393, 56401, 56417, 56431, 56437, 56443, 56453, 56467,
-    56473, 56477, 56479, 56489, 56501, 56503, 56509, 56519, 56527,
-    56531, 56533, 56543, 56569, 56591, 56597, 56599, 56611, 56629,
-    56633, 56659, 56663, 56671, 56681, 56687, 56701, 56711, 56713,
-    56731, 56737, 56747, 56767, 56773, 56779, 56783, 56807, 56809,
-    56813, 56821, 56827, 56843, 56857, 56873, 56891, 56893, 56897,
-    56909, 56911, 56921, 56923, 56929, 56941, 56951, 56957, 56963,
-    56983, 56989, 56993, 56999, 57037, 57041, 57047, 57059, 57073,
-    57077, 57089, 57097, 57107, 57119, 57131, 57139, 57143, 57149,
-    57163, 57173, 57179, 57191, 57193, 57203, 57221, 57223, 57241,
-    57251, 57259, 57269, 57271, 57283, 57287, 57301, 57329, 57331,
-    57347, 57349, 57367, 57373, 57383, 57389, 57397, 57413, 57427,
-    57457, 57467, 57487, 57493, 57503, 57527, 57529, 57557, 57559,
-    57571, 57587, 57593, 57601, 57637, 57641, 57649, 57653, 57667,
-    57679, 57689, 57697, 57709, 57713, 57719, 57727, 57731, 57737,
-    57751, 57773, 57781, 57787, 57791, 57793, 57803, 57809, 57829,
-    57839, 57847, 57853, 57859, 57881, 57899, 57901, 57917, 57923,
-    57943, 57947, 57973, 57977, 57991, 58013, 58027, 58031, 58043,
-    58049, 58057, 58061, 58067, 58073, 58099, 58109, 58111, 58129,
-    58147, 58151, 58153, 58169, 58171, 58189, 58193, 58199, 58207,
-    58211, 58217, 58229, 58231, 58237, 58243, 58271, 58309, 58313,
-    58321, 58337, 58363, 58367, 58369, 58379, 58391, 58393, 58403,
-    58411, 58417, 58427, 58439, 58441, 58451, 58453, 58477, 58481,
-    58511, 58537, 58543, 58549, 58567, 58573, 58579, 58601, 58603,
-    58613, 58631, 58657, 58661, 58679, 58687, 58693, 58699, 58711,
-    58727, 58733, 58741, 58757, 58763, 58771, 58787, 58789, 58831,
-    58889, 58897, 58901, 58907, 58909, 58913, 58921, 58937, 58943,
-    58963, 58967, 58979, 58991, 58997, 59009, 59011, 59021, 59023,
-    59029, 59051, 59053, 59063, 59069, 59077, 59083, 59093, 59107,
-    59113, 59119, 59123, 59141, 59149, 59159, 59167, 59183, 59197,
-    59207, 59209, 59219, 59221, 59233, 59239, 59243, 59263, 59273,
-    59281, 59333, 59341, 59351, 59357, 59359, 59369, 59377, 59387,
-    59393, 59399, 59407, 59417, 59419, 59441, 59443, 59447, 59453,
-    59467, 59471, 59473, 59497, 59509, 59513, 59539, 59557, 59561,
-    59567, 59581, 59611, 59617, 59621, 59627, 59629, 59651, 59659,
-    59663, 59669, 59671, 59693, 59699, 59707, 59723, 59729, 59743,
-    59747, 59753, 59771, 59779, 59791, 59797, 59809, 59833, 59863,
-    59879, 59887, 59921, 59929, 59951, 59957, 59971, 59981, 59999,
-    60013, 60017, 60029, 60037, 60041, 60077, 60083, 60089, 60091,
-    60101, 60103, 60107, 60127, 60133, 60139, 60149, 60161, 60167,
-    60169, 60209, 60217, 60223, 60251, 60257, 60259, 60271, 60289,
-    60293, 60317, 60331, 60337, 60343, 60353, 60373, 60383, 60397,
-    60413, 60427, 60443, 60449, 60457, 60493, 60497, 60509, 60521,
-    60527, 60539, 60589, 60601, 60607, 60611, 60617, 60623, 60631,
-    60637, 60647, 60649, 60659, 60661, 60679, 60689, 60703, 60719,
-    60727, 60733, 60737, 60757, 60761, 60763, 60773, 60779, 60793,
-    60811, 60821, 60859, 60869, 60887, 60889, 60899, 60901, 60913,
-    60917, 60919, 60923, 60937, 60943, 60953, 60961, 61001, 61007,
-    61027, 61031, 61043, 61051, 61057, 61091, 61099, 61121, 61129,
-    61141, 61151, 61153, 61169, 61211, 61223, 61231, 61253, 61261,
-    61283, 61291, 61297, 61331, 61333, 61339, 61343, 61357, 61363,
-    61379, 61381, 61403, 61409, 61417, 61441, 61463, 61469, 61471,
-    61483, 61487, 61493, 61507, 61511, 61519, 61543, 61547, 61553,
-    61559, 61561, 61583, 61603, 61609, 61613, 61627, 61631, 61637,
-    61643, 61651, 61657, 61667, 61673, 61681, 61687, 61703, 61717,
-    61723, 61729, 61751, 61757, 61781, 61813, 61819, 61837, 61843,
-    61861, 61871, 61879, 61909, 61927, 61933, 61949, 61961, 61967,
-    61979, 61981, 61987, 61991, 62003, 62011, 62017, 62039, 62047,
-    62053, 62057, 62071, 62081, 62099, 62119, 62129, 62131, 62137,
-    62141, 62143, 62171, 62189, 62191, 62201, 62207, 62213, 62219,
-    62233, 62273, 62297, 62299, 62303, 62311, 62323, 62327, 62347,
-    62351, 62383, 62401, 62417, 62423, 62459, 62467, 62473, 62477,
-    62483, 62497, 62501, 62507, 62533, 62539, 62549, 62563, 62581,
-    62591, 62597, 62603, 62617, 62627, 62633, 62639, 62653, 62659,
-    62683, 62687, 62701, 62723, 62731, 62743, 62753, 62761, 62773,
-    62791, 62801, 62819, 62827, 62851, 62861, 62869, 62873, 62897,
-    62903, 62921, 62927, 62929, 62939, 62969, 62971, 62981, 62983,
-    62987, 62989, 63029, 63031, 63059, 63067, 63073, 63079, 63097,
-    63103, 63113, 63127, 63131, 63149, 63179, 63197, 63199, 63211,
-    63241, 63247, 63277, 63281, 63299, 63311, 63313, 63317, 63331,
-    63337, 63347, 63353, 63361, 63367, 63377, 63389, 63391, 63397,
-    63409, 63419, 63421, 63439, 63443, 63463, 63467, 63473, 63487,
-    63493, 63499, 63521, 63527, 63533, 63541, 63559, 63577, 63587,
-    63589, 63599, 63601, 63607, 63611, 63617, 63629, 63647, 63649,
-    63659, 63667, 63671, 63689, 63691, 63697, 63703, 63709, 63719,
-    63727, 63737, 63743, 63761, 63773, 63781, 63793, 63799, 63803,
-    63809, 63823, 63839, 63841, 63853, 63857, 63863, 63901, 63907,
-    63913, 63929, 63949, 63977, 63997, 64007, 64013, 64019, 64033,
-    64037, 64063, 64067, 64081, 64091, 64109, 64123, 64151, 64153,
-    64157, 64171, 64187, 64189, 64217, 64223, 64231, 64237, 64271,
-    64279, 64283, 64301, 64303, 64319, 64327, 64333, 64373, 64381,
-    64399, 64403, 64433, 64439, 64451, 64453, 64483, 64489, 64499,
-    64513, 64553, 64567, 64577, 64579, 64591, 64601, 64609, 64613,
-    64621, 64627, 64633, 64661, 64663, 64667, 64679, 64693, 64709,
-    64717, 64747, 64763, 64781, 64783, 64793, 64811, 64817, 64849,
-    64853, 64871, 64877, 64879, 64891, 64901, 64919, 64921, 64927,
-    64937, 64951, 64969, 64997, 65003, 65011, 65027, 65029, 65033,
-    65053, 65063, 65071, 65089, 65099, 65101, 65111, 65119, 65123,
-    65129, 65141, 65147, 65167, 65171, 65173, 65179, 65183, 65203,
-    65213, 65239, 65257, 65267, 65269, 65287, 65293, 65309, 65323,
-    65327, 65353, 65357, 65371, 65381, 65393, 65407, 65413, 65419,
-    65423, 65437, 65447, 65449, 65479, 65497, 65519, 65521, 65537,
-    65539, 65543, 65551, 65557, 65563, 65579, 65581, 65587, 65599,
-    65609, 65617, 65629, 65633, 65647, 65651, 65657, 65677, 65687,
-    65699, 65701, 65707, 65713, 65717, 65719, 65729, 65731, 65761,
-    65777, 65789, 65809, 65827, 65831, 65837, 65839, 65843, 65851,
-    65867, 65881, 65899, 65921, 65927, 65929, 65951, 65957, 65963,
-    65981, 65983, 65993, 66029, 66037, 66041, 66047, 66067, 66071,
-    66083, 66089, 66103, 66107, 66109, 66137, 66161, 66169, 66173,
-    66179, 66191, 66221, 66239, 66271, 66293, 66301, 66337, 66343,
-    66347, 66359, 66361, 66373, 66377, 66383, 66403, 66413, 66431,
-    66449, 66457, 66463, 66467, 66491, 66499, 66509, 66523, 66529,
-    66533, 66541, 66553, 66569, 66571, 66587, 66593, 66601, 66617,
-    66629, 66643, 66653, 66683, 66697, 66701, 66713, 66721, 66733,
-    66739, 66749, 66751, 66763, 66791, 66797, 66809, 66821, 66841,
-    66851, 66853, 66863, 66877, 66883, 66889, 66919, 66923, 66931,
-    66943, 66947, 66949, 66959, 66973, 66977, 67003, 67021, 67033,
-    67043, 67049, 67057, 67061, 67073, 67079, 67103, 67121, 67129,
-    67139, 67141, 67153, 67157, 67169, 67181, 67187, 67189, 67211,
-    67213, 67217, 67219, 67231, 67247, 67261, 67271, 67273, 67289,
-    67307, 67339, 67343, 67349, 67369, 67391, 67399, 67409, 67411,
-    67421, 67427, 67429, 67433, 67447, 67453, 67477, 67481, 67489,
-    67493, 67499, 67511, 67523, 67531, 67537, 67547, 67559, 67567,
-    67577, 67579, 67589, 67601, 67607, 67619, 67631, 67651, 67679,
-    67699, 67709, 67723, 67733, 67741, 67751, 67757, 67759, 67763,
-    67777, 67783, 67789, 67801, 67807, 67819, 67829, 67843, 67853,
-    67867, 67883, 67891, 67901, 67927, 67931, 67933, 67939, 67943,
-    67957, 67961, 67967, 67979, 67987, 67993, 68023, 68041, 68053,
-    68059, 68071, 68087, 68099, 68111, 68113, 68141, 68147, 68161,
-    68171, 68207, 68209, 68213, 68219, 68227, 68239, 68261, 68279,
-    68281, 68311, 68329, 68351, 68371, 68389, 68399, 68437, 68443,
-    68447, 68449, 68473, 68477, 68483, 68489, 68491, 68501, 68507,
-    68521, 68531, 68539, 68543, 68567, 68581, 68597, 68611, 68633,
-    68639, 68659, 68669, 68683, 68687, 68699, 68711, 68713, 68729,
-    68737, 68743, 68749, 68767, 68771, 68777, 68791, 68813, 68819,
-    68821, 68863, 68879, 68881, 68891, 68897, 68899, 68903, 68909,
-    68917, 68927, 68947, 68963, 68993, 69001, 69011, 69019, 69029,
-    69031, 69061, 69067, 69073, 69109, 69119, 69127, 69143, 69149,
-    69151, 69163, 69191, 69193, 69197, 69203, 69221, 69233, 69239,
-    69247, 69257, 69259, 69263, 69313, 69317, 69337, 69341, 69371,
-    69379, 69383, 69389, 69401, 69403, 69427, 69431, 69439, 69457,
-    69463, 69467, 69473, 69481, 69491, 69493, 69497, 69499, 69539,
-    69557, 69593, 69623, 69653, 69661, 69677, 69691, 69697, 69709,
-    69737, 69739, 69761, 69763, 69767, 69779, 69809, 69821, 69827,
-    69829, 69833, 69847, 69857, 69859, 69877, 69899, 69911, 69929,
-    69931, 69941, 69959, 69991, 69997, 70001, 70003, 70009, 70019,
-    70039, 70051, 70061, 70067, 70079, 70099, 70111, 70117, 70121,
-    70123, 70139, 70141, 70157, 70163, 70177, 70181, 70183, 70199,
-    70201, 70207, 70223, 70229, 70237, 70241, 70249, 70271, 70289,
-    70297, 70309, 70313, 70321, 70327, 70351, 70373, 70379, 70381,
-    70393, 70423, 70429, 70439, 70451, 70457, 70459, 70481, 70487,
-    70489, 70501, 70507, 70529, 70537, 70549, 70571, 70573, 70583,
-    70589, 70607, 70619, 70621, 70627, 70639, 70657, 70663, 70667,
-    70687, 70709, 70717, 70729, 70753, 70769, 70783, 70793, 70823,
-    70841, 70843, 70849, 70853, 70867, 70877, 70879, 70891, 70901,
-    70913, 70919, 70921, 70937, 70949, 70951, 70957, 70969, 70979,
-    70981, 70991, 70997, 70999, 71011, 71023, 71039, 71059, 71069,
-    71081, 71089, 71119, 71129, 71143, 71147, 71153, 71161, 71167,
-    71171, 71191, 71209, 71233, 71237, 71249, 71257, 71261, 71263,
-    71287, 71293, 71317, 71327, 71329, 71333, 71339, 71341, 71347,
-    71353, 71359, 71363, 71387, 71389, 71399, 71411, 71413, 71419,
-    71429, 71437, 71443, 71453, 71471, 71473, 71479, 71483, 71503,
-    71527, 71537, 71549, 71551, 71563, 71569, 71593, 71597, 71633,
-    71647, 71663, 71671, 71693, 71699, 71707, 71711, 71713, 71719,
-    71741, 71761, 71777, 71789, 71807, 71809, 71821, 71837, 71843,
-    71849, 71861, 71867, 71879, 71881, 71887, 71899, 71909, 71917,
-    71933, 71941, 71947, 71963, 71971, 71983, 71987, 71993, 71999,
-    72019, 72031, 72043, 72047, 72053, 72073, 72077, 72089, 72091,
-    72101, 72103, 72109, 72139, 72161, 72167, 72169, 72173, 72211,
-    72221, 72223, 72227, 72229, 72251, 72253, 72269, 72271, 72277,
-    72287, 72307, 72313, 72337, 72341, 72353, 72367, 72379, 72383,
-    72421, 72431, 72461, 72467, 72469, 72481, 72493, 72497, 72503,
-    72533, 72547, 72551, 72559, 72577, 72613, 72617, 72623, 72643,
-    72647, 72649, 72661, 72671, 72673, 72679, 72689, 72701, 72707,
-    72719, 72727, 72733, 72739, 72763, 72767, 72797, 72817, 72823,
-    72859, 72869, 72871, 72883, 72889, 72893, 72901, 72907, 72911,
-    72923, 72931, 72937, 72949, 72953, 72959, 72973, 72977, 72997,
-    73009, 73013, 73019, 73037, 73039, 73043, 73061, 73063, 73079,
-    73091, 73121, 73127, 73133, 73141, 73181, 73189, 73237, 73243,
-    73259, 73277, 73291, 73303, 73309, 73327, 73331, 73351, 73361,
-    73363, 73369, 73379, 73387, 73417, 73421, 73433, 73453, 73459,
-    73471, 73477, 73483, 73517, 73523, 73529, 73547, 73553, 73561,
-    73571, 73583, 73589, 73597, 73607, 73609, 73613, 73637, 73643,
-    73651, 73673, 73679, 73681, 73693, 73699, 73709, 73721, 73727,
-    73751, 73757, 73771, 73783, 73819, 73823, 73847, 73849, 73859,
-    73867, 73877, 73883, 73897, 73907, 73939, 73943, 73951, 73961,
-    73973, 73999, 74017, 74021, 74027, 74047, 74051, 74071, 74077,
-    74093, 74099, 74101, 74131, 74143, 74149, 74159, 74161, 74167,
-    74177, 74189, 74197, 74201, 74203, 74209, 74219, 74231, 74257,
-    74279, 74287, 74293, 74297, 74311, 74317, 74323, 74353, 74357,
-    74363, 74377, 74381, 74383, 74411, 74413, 74419, 74441, 74449,
-    74453, 74471, 74489, 74507, 74509, 74521, 74527, 74531, 74551,
-    74561, 74567, 74573, 74587, 74597, 74609, 74611, 74623, 74653,
-    74687, 74699, 74707, 74713, 74717, 74719, 74729, 74731, 74747,
-    74759, 74761, 74771, 74779, 74797, 74821, 74827, 74831, 74843,
-    74857, 74861, 74869, 74873, 74887, 74891, 74897, 74903, 74923,
-    74929, 74933, 74941, 74959, 75011, 75013, 75017, 75029, 75037,
-    75041, 75079, 75083, 75109, 75133, 75149, 75161, 75167, 75169,
-    75181, 75193, 75209, 75211, 75217, 75223, 75227, 75239, 75253,
-    75269, 75277, 75289, 75307, 75323, 75329, 75337, 75347, 75353,
-    75367, 75377, 75389, 75391, 75401, 75403, 75407, 75431, 75437,
-    75479, 75503, 75511, 75521, 75527, 75533, 75539, 75541, 75553,
-    75557, 75571, 75577, 75583, 75611, 75617, 75619, 75629, 75641,
-    75653, 75659, 75679, 75683, 75689, 75703, 75707, 75709, 75721,
-    75731, 75743, 75767, 75773, 75781, 75787, 75793, 75797, 75821,
-    75833, 75853, 75869, 75883, 75913, 75931, 75937, 75941, 75967,
-    75979, 75983, 75989, 75991, 75997, 76001, 76003, 76031, 76039,
-    76079, 76081, 76091, 76099, 76103, 76123, 76129, 76147, 76157,
-    76159, 76163, 76207, 76213, 76231, 76243, 76249, 76253, 76259,
-    76261, 76283, 76289, 76303, 76333, 76343, 76367, 76369, 76379,
-    76387, 76403, 76421, 76423, 76441, 76463, 76471, 76481, 76487,
-    76493, 76507, 76511, 76519, 76537, 76541, 76543, 76561, 76579,
-    76597, 76603, 76607, 76631, 76649, 76651, 76667, 76673, 76679,
-    76697, 76717, 76733, 76753, 76757, 76771, 76777, 76781, 76801,
-    76819, 76829, 76831, 76837, 76847, 76871, 76873, 76883, 76907,
-    76913, 76919, 76943, 76949, 76961, 76963, 76991, 77003, 77017,
-    77023, 77029, 77041, 77047, 77069, 77081, 77093, 77101, 77137,
-    77141, 77153, 77167, 77171, 77191, 77201, 77213, 77237, 77239,
-    77243, 77249, 77261, 77263, 77267, 77269, 77279, 77291, 77317,
-    77323, 77339, 77347, 77351, 77359, 77369, 77377, 77383, 77417,
-    77419, 77431, 77447, 77471, 77477, 77479, 77489, 77491, 77509,
-    77513, 77521, 77527, 77543, 77549, 77551, 77557, 77563, 77569,
-    77573, 77587, 77591, 77611, 77617, 77621, 77641, 77647, 77659,
-    77681, 77687, 77689, 77699, 77711, 77713, 77719, 77723, 77731,
-    77743, 77747, 77761, 77773, 77783, 77797, 77801, 77813, 77839,
-    77849, 77863, 77867, 77893, 77899, 77929, 77933, 77951, 77969,
-    77977, 77983, 77999, 78007, 78017, 78031, 78041, 78049, 78059,
-    78079, 78101, 78121, 78137, 78139, 78157, 78163, 78167, 78173,
-    78179, 78191, 78193, 78203, 78229, 78233, 78241, 78259, 78277,
-    78283, 78301, 78307, 78311, 78317, 78341, 78347, 78367, 78401,
-    78427, 78437, 78439, 78467, 78479, 78487, 78497, 78509, 78511,
-    78517, 78539, 78541, 78553, 78569, 78571, 78577, 78583, 78593,
-    78607, 78623, 78643, 78649, 78653, 78691, 78697, 78707, 78713,
-    78721, 78737, 78779, 78781, 78787, 78791, 78797, 78803, 78809,
-    78823, 78839, 78853, 78857, 78877, 78887, 78889, 78893, 78901,
-    78919, 78929, 78941, 78977, 78979, 78989, 79031, 79039, 79043,
-    79063, 79087, 79103, 79111, 79133, 79139, 79147, 79151, 79153,
-    79159, 79181, 79187, 79193, 79201, 79229, 79231, 79241, 79259,
-    79273, 79279, 79283, 79301, 79309, 79319, 79333, 79337, 79349,
-    79357, 79367, 79379, 79393, 79397, 79399, 79411, 79423, 79427,
-    79433, 79451, 79481, 79493, 79531, 79537, 79549, 79559, 79561,
-    79579, 79589, 79601, 79609, 79613, 79621, 79627, 79631, 79633,
-    79657, 79669, 79687, 79691, 79693, 79697, 79699, 79757, 79769,
-    79777, 79801, 79811, 79813, 79817, 79823, 79829, 79841, 79843,
-    79847, 79861, 79867, 79873, 79889, 79901, 79903, 79907, 79939,
-    79943, 79967, 79973, 79979, 79987, 79997, 79999, 80021, 80039,
-    80051, 80071, 80077, 80107, 80111, 80141, 80147, 80149, 80153,
-    80167, 80173, 80177, 80191, 80207, 80209, 80221, 80231, 80233,
-    80239, 80251, 80263, 80273, 80279, 80287, 80309, 80317, 80329,
-    80341, 80347, 80363, 80369, 80387, 80407, 80429, 80447, 80449,
-    80471, 80473, 80489, 80491, 80513, 80527, 80537, 80557, 80567,
-    80599, 80603, 80611, 80621, 80627, 80629, 80651, 80657, 80669,
-    80671, 80677, 80681, 80683, 80687, 80701, 80713, 80737, 80747,
-    80749, 80761, 80777, 80779, 80783, 80789, 80803, 80809, 80819,
-    80831, 80833, 80849, 80863, 80897, 80909, 80911, 80917, 80923,
-    80929, 80933, 80953, 80963, 80989, 81001, 81013, 81017, 81019,
-    81023, 81031, 81041, 81043, 81047, 81049, 81071, 81077, 81083,
-    81097, 81101, 81119, 81131, 81157, 81163, 81173, 81181, 81197,
-    81199, 81203, 81223, 81233, 81239, 81281, 81283, 81293, 81299,
-    81307, 81331, 81343, 81349, 81353, 81359, 81371, 81373, 81401,
-    81409, 81421, 81439, 81457, 81463, 81509, 81517, 81527, 81533,
-    81547, 81551, 81553, 81559, 81563, 81569, 81611, 81619, 81629,
-    81637, 81647, 81649, 81667, 81671, 81677, 81689, 81701, 81703,
-    81707, 81727, 81737, 81749, 81761, 81769, 81773, 81799, 81817,
-    81839, 81847, 81853, 81869, 81883, 81899, 81901, 81919, 81929,
-    81931, 81937, 81943, 81953, 81967, 81971, 81973, 82003, 82007,
-    82009, 82013, 82021, 82031, 82037, 82039, 82051, 82067, 82073,
-    82129, 82139, 82141, 82153, 82163, 82171, 82183, 82189, 82193,
-    82207, 82217, 82219, 82223, 82231, 82237, 82241, 82261, 82267,
-    82279, 82301, 82307, 82339, 82349, 82351, 82361, 82373, 82387,
-    82393, 82421, 82457, 82463, 82469, 82471, 82483, 82487, 82493,
-    82499, 82507, 82529, 82531, 82549, 82559, 82561, 82567, 82571,
-    82591, 82601, 82609, 82613, 82619, 82633, 82651, 82657, 82699,
-    82721, 82723, 82727, 82729, 82757, 82759, 82763, 82781, 82787,
-    82793, 82799, 82811, 82813, 82837, 82847, 82883, 82889, 82891,
-    82903, 82913, 82939, 82963, 82981, 82997, 83003, 83009, 83023,
-    83047, 83059, 83063, 83071, 83077, 83089, 83093, 83101, 83117,
-    83137, 83177, 83203, 83207, 83219, 83221, 83227, 83231, 83233,
-    83243, 83257, 83267, 83269, 83273, 83299, 83311, 83339, 83341,
-    83357, 83383, 83389, 83399, 83401, 83407, 83417, 83423, 83431,
-    83437, 83443, 83449, 83459, 83471, 83477, 83497, 83537, 83557,
-    83561, 83563, 83579, 83591, 83597, 83609, 83617, 83621, 83639,
-    83641, 83653, 83663, 83689, 83701, 83717, 83719, 83737, 83761,
-    83773, 83777, 83791, 83813, 83833, 83843, 83857, 83869, 83873,
-    83891, 83903, 83911, 83921, 83933, 83939, 83969, 83983, 83987,
-    84011, 84017, 84047, 84053, 84059, 84061, 84067, 84089, 84121,
-    84127, 84131, 84137, 84143, 84163, 84179, 84181, 84191, 84199,
-    84211, 84221, 84223, 84229, 84239, 84247, 84263, 84299, 84307,
-    84313, 84317, 84319, 84347, 84349, 84377, 84389, 84391, 84401,
-    84407, 84421, 84431, 84437, 84443, 84449, 84457, 84463, 84467,
-    84481, 84499, 84503, 84509, 84521, 84523, 84533, 84551, 84559,
-    84589, 84629, 84631, 84649, 84653, 84659, 84673, 84691, 84697,
-    84701, 84713, 84719, 84731, 84737, 84751, 84761, 84787, 84793,
-    84809, 84811, 84827, 84857, 84859, 84869, 84871, 84913, 84919,
-    84947, 84961, 84967, 84977, 84979, 84991, 85009, 85021, 85027,
-    85037, 85049, 85061, 85081, 85087, 85091, 85093, 85103, 85109,
-    85121, 85133, 85147, 85159, 85193, 85199, 85201, 85213, 85223,
-    85229, 85237, 85243, 85247, 85259, 85297, 85303, 85313, 85331,
-    85333, 85361, 85363, 85369, 85381, 85411, 85427, 85429, 85439,
-    85447, 85451, 85453, 85469, 85487, 85513, 85517, 85523, 85531,
-    85549, 85571, 85577, 85597, 85601, 85607, 85619, 85621, 85627,
-    85639, 85643, 85661, 85667, 85669, 85691, 85703, 85711, 85717,
-    85733, 85751, 85781, 85793, 85817, 85819, 85829, 85831, 85837,
-    85843, 85847, 85853, 85889, 85903, 85909, 85931, 85933, 85991,
-    85999, 86011, 86017, 86027, 86029, 86069, 86077, 86083, 86111,
-    86113, 86117, 86131, 86137, 86143, 86161, 86171, 86179, 86183,
-    86197, 86201, 86209, 86239, 86243, 86249, 86257, 86263, 86269,
-    86287, 86291, 86293, 86297, 86311, 86323, 86341, 86351, 86353,
-    86357, 86369, 86371, 86381, 86389, 86399, 86413, 86423, 86441,
-    86453, 86461, 86467, 86477, 86491, 86501, 86509, 86531, 86533,
-    86539, 86561, 86573, 86579, 86587, 86599, 86627, 86629, 86677,
-    86689, 86693, 86711, 86719, 86729, 86743, 86753, 86767, 86771,
-    86783, 86813, 86837, 86843, 86851, 86857, 86861, 86869, 86923,
-    86927, 86929, 86939, 86951, 86959, 86969, 86981, 86993, 87011,
-    87013, 87037, 87041, 87049, 87071, 87083, 87103, 87107, 87119,
-    87121, 87133, 87149, 87151, 87179, 87181, 87187, 87211, 87221,
-    87223, 87251, 87253, 87257, 87277, 87281, 87293, 87299, 87313,
-    87317, 87323, 87337, 87359, 87383, 87403, 87407, 87421, 87427,
-    87433, 87443, 87473, 87481, 87491, 87509, 87511, 87517, 87523,
-    87539, 87541, 87547, 87553, 87557, 87559, 87583, 87587, 87589,
-    87613, 87623, 87629, 87631, 87641, 87643, 87649, 87671, 87679,
-    87683, 87691, 87697, 87701, 87719, 87721, 87739, 87743, 87751,
-    87767, 87793, 87797, 87803, 87811, 87833, 87853, 87869, 87877,
-    87881, 87887, 87911, 87917, 87931, 87943, 87959, 87961, 87973,
-    87977, 87991, 88001, 88003, 88007, 88019, 88037, 88069, 88079,
-    88093, 88117, 88129, 88169, 88177, 88211, 88223, 88237, 88241,
-    88259, 88261, 88289, 88301, 88321, 88327, 88337, 88339, 88379,
-    88397, 88411, 88423, 88427, 88463, 88469, 88471, 88493, 88499,
-    88513, 88523, 88547, 88589, 88591, 88607, 88609, 88643, 88651,
-    88657, 88661, 88663, 88667, 88681, 88721, 88729, 88741, 88747,
-    88771, 88789, 88793, 88799, 88801, 88807, 88811, 88813, 88817,
-    88819, 88843, 88853, 88861, 88867, 88873, 88883, 88897, 88903,
-    88919, 88937, 88951, 88969, 88993, 88997, 89003, 89009, 89017,
-    89021, 89041, 89051, 89057, 89069, 89071, 89083, 89087, 89101,
-    89107, 89113, 89119, 89123, 89137, 89153, 89189, 89203, 89209,
-    89213, 89227, 89231, 89237, 89261, 89269, 89273, 89293, 89303,
-    89317, 89329, 89363, 89371, 89381, 89387, 89393, 89399, 89413,
-    89417, 89431, 89443, 89449, 89459, 89477, 89491, 89501, 89513,
-    89519, 89521, 89527, 89533, 89561, 89563, 89567, 89591, 89597,
-    89599, 89603, 89611, 89627, 89633, 89653, 89657, 89659, 89669,
-    89671, 89681, 89689, 89753, 89759, 89767, 89779, 89783, 89797,
-    89809, 89819, 89821, 89833, 89839, 89849, 89867, 89891, 89897,
-    89899, 89909, 89917, 89923, 89939, 89959, 89963, 89977, 89983,
-    89989, 90001, 90007, 90011, 90017, 90019, 90023, 90031, 90053,
-    90059, 90067, 90071, 90073, 90089, 90107, 90121, 90127, 90149,
-    90163, 90173, 90187, 90191, 90197, 90199, 90203, 90217, 90227,
-    90239, 90247, 90263, 90271, 90281, 90289, 90313, 90353, 90359,
-    90371, 90373, 90379, 90397, 90401, 90403, 90407, 90437, 90439,
-    90469, 90473, 90481, 90499, 90511, 90523, 90527, 90529, 90533,
-    90547, 90583, 90599, 90617, 90619, 90631, 90641, 90647, 90659,
-    90677, 90679, 90697, 90703, 90709, 90731, 90749, 90787, 90793,
-    90803, 90821, 90823, 90833, 90841, 90847, 90863, 90887, 90901,
-    90907, 90911, 90917, 90931, 90947, 90971, 90977, 90989, 90997,
-    91009, 91019, 91033, 91079, 91081, 91097, 91099, 91121, 91127,
-    91129, 91139, 91141, 91151, 91153, 91159, 91163, 91183, 91193,
-    91199, 91229, 91237, 91243, 91249, 91253, 91283, 91291, 91297,
-    91303, 91309, 91331, 91367, 91369, 91373, 91381, 91387, 91393,
-    91397, 91411, 91423, 91433, 91453, 91457, 91459, 91463, 91493,
-    91499, 91513, 91529, 91541, 91571, 91573, 91577, 91583, 91591,
-    91621, 91631, 91639, 91673, 91691, 91703, 91711, 91733, 91753,
-    91757, 91771, 91781, 91801, 91807, 91811, 91813, 91823, 91837,
-    91841, 91867, 91873, 91909, 91921, 91939, 91943, 91951, 91957,
-    91961, 91967, 91969, 91997, 92003, 92009, 92033, 92041, 92051,
-    92077, 92083, 92107, 92111, 92119, 92143, 92153, 92173, 92177,
-    92179, 92189, 92203, 92219, 92221, 92227, 92233, 92237, 92243,
-    92251, 92269, 92297, 92311, 92317, 92333, 92347, 92353, 92357,
-    92363, 92369, 92377, 92381, 92383, 92387, 92399, 92401, 92413,
-    92419, 92431, 92459, 92461, 92467, 92479, 92489, 92503, 92507,
-    92551, 92557, 92567, 92569, 92581, 92593, 92623, 92627, 92639,
-    92641, 92647, 92657, 92669, 92671, 92681, 92683, 92693, 92699,
-    92707, 92717, 92723, 92737, 92753, 92761, 92767, 92779, 92789,
-    92791, 92801, 92809, 92821, 92831, 92849, 92857, 92861, 92863,
-    92867, 92893, 92899, 92921, 92927, 92941, 92951, 92957, 92959,
-    92987, 92993, 93001, 93047, 93053, 93059, 93077, 93083, 93089,
-    93097, 93103, 93113, 93131, 93133, 93139, 93151, 93169, 93179,
-    93187, 93199, 93229, 93239, 93241, 93251, 93253, 93257, 93263,
-    93281, 93283, 93287, 93307, 93319, 93323, 93329, 93337, 93371,
-    93377, 93383, 93407, 93419, 93427, 93463, 93479, 93481, 93487,
-    93491, 93493, 93497, 93503, 93523, 93529, 93553, 93557, 93559,
-    93563, 93581, 93601, 93607, 93629, 93637, 93683, 93701, 93703,
-    93719, 93739, 93761, 93763, 93787, 93809, 93811, 93827, 93851,
-    93871, 93887, 93889, 93893, 93901, 93911, 93913, 93923, 93937,
-    93941, 93949, 93967, 93971, 93979, 93983, 93997, 94007, 94009,
-    94033, 94049, 94057, 94063, 94079, 94099, 94109, 94111, 94117,
-    94121, 94151, 94153, 94169, 94201, 94207, 94219, 94229, 94253,
-    94261, 94273, 94291, 94307, 94309, 94321, 94327, 94331, 94343,
-    94349, 94351, 94379, 94397, 94399, 94421, 94427, 94433, 94439,
-    94441, 94447, 94463, 94477, 94483, 94513, 94529, 94531, 94541,
-    94543, 94547, 94559, 94561, 94573, 94583, 94597, 94603, 94613,
-    94621, 94649, 94651, 94687, 94693, 94709, 94723, 94727, 94747,
-    94771, 94777, 94781, 94789, 94793, 94811, 94819, 94823, 94837,
-    94841, 94847, 94849, 94873, 94889, 94903, 94907, 94933, 94949,
-    94951, 94961, 94993, 94999, 95003, 95009, 95021, 95027, 95063,
-    95071, 95083, 95087, 95089, 95093, 95101, 95107, 95111, 95131,
-    95143, 95153, 95177, 95189, 95191, 95203, 95213, 95219, 95231,
-    95233, 95239, 95257, 95261, 95267, 95273, 95279, 95287, 95311,
-    95317, 95327, 95339, 95369, 95383, 95393, 95401, 95413, 95419,
-    95429, 95441, 95443, 95461, 95467, 95471, 95479, 95483, 95507,
-    95527, 95531, 95539, 95549, 95561, 95569, 95581, 95597, 95603,
-    95617, 95621, 95629, 95633, 95651, 95701, 95707, 95713, 95717,
-    95723, 95731, 95737, 95747, 95773, 95783, 95789, 95791, 95801,
-    95803, 95813, 95819, 95857, 95869, 95873, 95881, 95891, 95911,
-    95917, 95923, 95929, 95947, 95957, 95959, 95971, 95987, 95989,
-    96001, 96013, 96017, 96043, 96053, 96059, 96079, 96097, 96137,
-    96149, 96157, 96167, 96179, 96181, 96199, 96211, 96221, 96223,
-    96233, 96259, 96263, 96269, 96281, 96289, 96293, 96323, 96329,
-    96331, 96337, 96353, 96377, 96401, 96419, 96431, 96443, 96451,
-    96457, 96461, 96469, 96479, 96487, 96493, 96497, 96517, 96527,
-    96553, 96557, 96581, 96587, 96589, 96601, 96643, 96661, 96667,
-    96671, 96697, 96703, 96731, 96737, 96739, 96749, 96757, 96763,
-    96769, 96779, 96787, 96797, 96799, 96821, 96823, 96827, 96847,
-    96851, 96857, 96893, 96907, 96911, 96931, 96953, 96959, 96973,
-    96979, 96989, 96997, 97001, 97003, 97007, 97021, 97039, 97073,
-    97081, 97103, 97117, 97127, 97151, 97157, 97159, 97169, 97171,
-    97177, 97187, 97213, 97231, 97241, 97259, 97283, 97301, 97303,
-    97327, 97367, 97369, 97373, 97379, 97381, 97387, 97397, 97423,
-    97429, 97441, 97453, 97459, 97463, 97499, 97501, 97511, 97523,
-    97547, 97549, 97553, 97561, 97571, 97577, 97579, 97583, 97607,
-    97609, 97613, 97649, 97651, 97673, 97687, 97711, 97729, 97771,
-    97777, 97787, 97789, 97813, 97829, 97841, 97843, 97847, 97849,
-    97859, 97861, 97871, 97879, 97883, 97919, 97927, 97931, 97943,
-    97961, 97967, 97973, 97987, 98009, 98011, 98017, 98041, 98047,
-    98057, 98081, 98101, 98123, 98129, 98143, 98179, 98207, 98213,
-    98221, 98227, 98251, 98257, 98269, 98297, 98299, 98317, 98321,
-    98323, 98327, 98347, 98369, 98377, 98387, 98389, 98407, 98411,
-    98419, 98429, 98443, 98453, 98459, 98467, 98473, 98479, 98491,
-    98507, 98519, 98533, 98543, 98561, 98563, 98573, 98597, 98621,
-    98627, 98639, 98641, 98663, 98669, 98689, 98711, 98713, 98717,
-    98729, 98731, 98737, 98773, 98779, 98801, 98807, 98809, 98837,
-    98849, 98867, 98869, 98873, 98887, 98893, 98897, 98899, 98909,
-    98911, 98927, 98929, 98939, 98947, 98953, 98963, 98981, 98993,
-    98999, 99013, 99017, 99023, 99041, 99053, 99079, 99083, 99089,
-    99103, 99109, 99119, 99131, 99133, 99137, 99139, 99149, 99173,
-    99181, 99191, 99223, 99233, 99241, 99251, 99257, 99259, 99277,
-    99289, 99317, 99347, 99349, 99367, 99371, 99377, 99391, 99397,
-    99401, 99409, 99431, 99439, 99469, 99487, 99497, 99523, 99527,
-    99529, 99551, 99559, 99563, 99571, 99577, 99581, 99607, 99611,
-    99623, 99643, 99661, 99667, 99679, 99689, 99707, 99709, 99713,
-    99719, 99721, 99733, 99761, 99767, 99787, 99793, 99809, 99817,
-    99823, 99829, 99833, 99839, 99859, 99871, 99877, 99881, 99901,
-    99907, 99923, 99929, 99961, 99971, 99989, 99991,
-    };
index 8ecb4acfd9fa8a691483d2adcc25a95dfe2a6f7a..f21a7441640c0b0edb0a86cf66ea617d487726b9 100644 (file)
 #include "rust_scheduler.h"
 #include "rust_gc_metadata.h"
 
-// Creates a rust argument vector from the platform argument vector
-struct
-command_line_args : public kernel_owned<command_line_args>
-{
-    rust_kernel *kernel;
-    rust_task *task;
-    int argc;
-    char **argv;
-
-    // [str] passed to rust_task::start.
-    rust_vec_box *args;
-
-    command_line_args(rust_task *task,
-                      int sys_argc,
-                      char **sys_argv)
-        : kernel(task->kernel),
-          task(task),
-          argc(sys_argc),
-          argv(sys_argv)
-    {
-#if defined(__WIN32__)
-        LPCWSTR cmdline = GetCommandLineW();
-        LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc);
-        kernel->win32_require("CommandLineToArgvW", wargv != NULL);
-        argv = (char **) kernel->malloc(sizeof(char*) * argc,
-                                        "win32 command line");
-        for (int i = 0; i < argc; ++i) {
-            int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
-                                              NULL, 0, NULL, NULL);
-            kernel->win32_require("WideCharToMultiByte(0)", n_chars != 0);
-            argv[i] = (char *) kernel->malloc(n_chars,
-                                              "win32 command line arg");
-            n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
-                                          argv[i], n_chars, NULL, NULL);
-            kernel->win32_require("WideCharToMultiByte(1)", n_chars != 0);
-        }
-        LocalFree(wargv);
-#endif
-
-        args = make_str_vec(kernel, argc, argv);
-    }
-
-    ~command_line_args() {
-        for (int i = 0; i < argc; ++i) {
-            rust_vec *s = ((rust_vec**)&args->body.data)[i];
-            kernel->free(s);
-        }
-        kernel->free(args);
-
-#ifdef __WIN32__
-        for (int i = 0; i < argc; ++i) {
-            kernel->free(argv[i]);
-        }
-        kernel->free(argv);
-#endif
-    }
-};
-
 void* global_crate_map = NULL;
 
 /**
@@ -107,19 +49,8 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
     assert(sched != NULL);
     rust_task *root_task = sched->create_task(NULL, "main");
 
-    // Build the command line arguments to pass to the root task
-    command_line_args *args
-        = new (kernel, "main command line args")
-        command_line_args(root_task, argc, argv);
-
-    LOG(root_task, dom, "startup: %d args in 0x%" PRIxPTR,
-        args->argc, (uintptr_t)args->args);
-    for (int i = 0; i < args->argc; i++) {
-        LOG(root_task, dom, "startup: arg[%d] = '%s'", i, args->argv[i]);
-    }
-
     // Schedule the main Rust task
-    root_task->start((spawn_fn)main_fn, NULL, args->args);
+    root_task->start((spawn_fn)main_fn, NULL, NULL);
 
     // At this point the task lifecycle is responsible for it
     // and our pointer may not be valid
@@ -128,7 +59,6 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
     // Run the kernel until all schedulers exit
     int ret = kernel->run();
 
-    delete args;
     delete kernel;
     free_env(env);
 
diff --git a/src/rt/rust_android_dummy.cpp b/src/rt/rust_android_dummy.cpp
new file mode 100644 (file)
index 0000000..76aa517
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "rust_android_dummy.h"
+#include <math.h>
+
+#ifdef __ANDROID__
+
+int backtrace(void **array, int size) { return 0; }
+
+char **backtrace_symbols(void *const *array, int size) { return 0; }
+
+void backtrace_symbols_fd (void *const *array, int size, int fd) {}
+
+
+extern "C" float log2f(float f)
+{
+    return logf( f ) / logf( 2 );
+}
+
+extern "C" double log2( double n )
+{
+    return log( n ) / log( 2 );
+}
+
+extern "C" void telldir()
+{
+}
+
+extern "C" void seekdir()
+{
+}
+
+extern "C" void mkfifo()
+{
+}
+
+extern "C" void abs()
+{
+}
+
+extern "C" void labs()
+{
+}
+
+extern "C" void rand()
+{
+}
+
+extern "C" void srand()
+{
+}
+
+extern "C" void atof()
+{
+}
+extern "C" void tgammaf()
+{
+}
+#endif
diff --git a/src/rt/rust_android_dummy.h b/src/rt/rust_android_dummy.h
new file mode 100644 (file)
index 0000000..95a1774
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef _RUST_ANDROID_DUMMY_H
+#define _RUST_ANDROID_DUMMY_H
+
+int backtrace (void **__array, int __size);
+
+char **backtrace_symbols (void *__const *__array, int __size);
+
+void backtrace_symbols_fd (void *__const *__array, int __size, int __fd);
+
+#endif
+
index a3c7486fa3a8ccae8119b98fee833b9399135add..de69272aca174214786f43bf712742951e1cfb6c 100644 (file)
@@ -15,6 +15,7 @@
 #include "rust_util.h"
 #include "rust_scheduler.h"
 #include "sync/timer.h"
+#include "sync/rust_thread.h"
 #include "rust_abi.h"
 #include "rust_port.h"
 
 extern char **environ;
 #endif
 
+#ifdef __ANDROID__
+time_t
+timegm(struct tm *tm)
+{
+    time_t ret;
+    char *tz;
+
+    tz = getenv("TZ");
+    setenv("TZ", "", 1);
+    tzset();
+    ret = mktime(tm);
+    if (tz)
+        setenv("TZ", tz, 1);
+    else
+        unsetenv("TZ");
+    tzset();
+    return ret;
+}
+#endif
+
+
 extern "C" CDECL rust_str*
 last_os_error() {
     rust_task *task = rust_get_current_task();
@@ -51,7 +73,7 @@ last_os_error() {
         task->fail();
         return NULL;
     }
-#elif defined(_GNU_SOURCE)
+#elif defined(_GNU_SOURCE) && !defined(__ANDROID__)
     char cbuf[BUF_BYTES];
     char *buf = strerror_r(errno, cbuf, sizeof(cbuf));
     if (!buf) {
@@ -972,6 +994,36 @@ rust_log_str(uint32_t level, const char *str, size_t size) {
     task->sched_loop->get_log().log(task, level, "%.*s", (int)size, str);
 }
 
+extern "C" CDECL void      record_sp_limit(void *limit);
+
+class raw_thread: public rust_thread {
+public:
+    fn_env_pair *fn;
+
+    raw_thread(fn_env_pair *fn) : fn(fn) { }
+
+    virtual void run() {
+        record_sp_limit(0);
+        fn->f(NULL, fn->env, NULL);
+    }
+};
+
+extern "C" raw_thread*
+rust_raw_thread_start(fn_env_pair *fn) {
+    assert(fn);
+    raw_thread *thread = new raw_thread(fn);
+    thread->start();
+    return thread;
+}
+
+extern "C" void
+rust_raw_thread_join_delete(raw_thread *thread) {
+    assert(thread);
+    thread->join();
+    delete thread;
+}
+
+
 //
 // Local Variables:
 // mode: C++
index f6b061a5bbc63229eea2df6dcc82fbeb51a240b4..5ddfd88d4b4a7896796fc67ed6f045719ef1e55d 100644 (file)
@@ -28,6 +28,7 @@ rust_sched_loop::rust_sched_loop(rust_scheduler *sched, int id, bool killed) :
     id(id),
     should_exit(false),
     cached_c_stack(NULL),
+    extra_c_stack(NULL),
     dead_task(NULL),
     killed(killed),
     pump_signal(NULL),
@@ -100,6 +101,7 @@ rust_sched_loop::kill_all_tasks() {
 
 size_t
 rust_sched_loop::number_of_live_tasks() {
+    lock.must_have_lock();
     return running_tasks.length() + blocked_tasks.length();
 }
 
@@ -148,14 +150,10 @@ rust_sched_loop::release_task(rust_task *task) {
 rust_task *
 rust_sched_loop::schedule_task() {
     lock.must_have_lock();
-    assert(this);
     if (running_tasks.length() > 0) {
         size_t k = isaac_rand(&rctx);
-        // Look around for a runnable task, starting at k.
-        for(size_t j = 0; j < running_tasks.length(); ++j) {
-            size_t  i = (j + k) % running_tasks.length();
-            return (rust_task *)running_tasks[i];
-        }
+        size_t i = k % running_tasks.length();
+        return (rust_task *)running_tasks[i];
     }
     return NULL;
 }
index 9dd7c62f8674375ac0dd08bd1a4babffcc3c059e..435f563713e0dac4a538da5414e015561a34ed6f 100644 (file)
 
 
 #ifndef __WIN32__
+#ifdef __ANDROID__
+#include "rust_android_dummy.h"
+#else
 #include <execinfo.h>
 #endif
+#endif
 #include <iostream>
 #include <algorithm>
 
index 27694becdfbcfc9f97c6c63a41270ce06da535a3..20c9a48f1ddeff18b7e5fd742fcaab5351ffa2ed 100644 (file)
 #define RED_ZONE_SIZE RZ_BSD_64
 #endif
 #endif
+#ifdef __ANDROID__
+#define RED_ZONE_SIZE RZ_MAC_32
+#endif
 
 struct rust_box;
 
index c916de111235cf8c2803f368a25a6ebe04a1ef4a..8197d9c5450e80cc4b8966d14f8a0429c2c7f77a 100644 (file)
@@ -158,8 +158,7 @@ upcall_s_exchange_malloc(s_exchange_malloc_args *args) {
     LOG_UPCALL_ENTRY(task);
 
     size_t total_size = get_box_size(args->size, args->td->align);
-    // FIXME--does this have to be calloc? (Issue #2682)
-    void *p = task->kernel->calloc(total_size, "exchange malloc");
+    void *p = task->kernel->malloc(total_size, "exchange malloc");
 
     rust_opaque_box *header = static_cast<rust_opaque_box*>(p);
     header->ref_count = -1; // This is not ref counted
@@ -234,8 +233,7 @@ upcall_s_malloc(s_malloc_args *args) {
     LOG_UPCALL_ENTRY(task);
     LOG(task, mem, "upcall malloc(0x%" PRIxPTR ")", args->td);
 
-    // FIXME--does this have to be calloc? (Issue #2682)
-    rust_opaque_box *box = task->boxed.calloc(args->td, args->size);
+    rust_opaque_box *box = task->boxed.malloc(args->td, args->size);
     void *body = box_body(box);
 
     debug::maybe_track_origin(task, box);
index 020008c38421c645fe328a2ce904bda40c509bd1..cce4e411e02c792639907f6ef0f75238e606047c 100644 (file)
@@ -208,3 +208,5 @@ linenoiseHistoryAdd
 linenoiseHistorySetMaxLen
 linenoiseHistorySave
 linenoiseHistoryLoad
+rust_raw_thread_start
+rust_raw_thread_join_delete
index bb00f04a6f976979f1fcb8bc563789965be7f325..3c38f3c6215d494c1480e9619b19f1a474fd4b32 100644 (file)
@@ -91,6 +91,12 @@ void LLVMInitializeX86TargetMC();
 void LLVMInitializeX86AsmPrinter();
 void LLVMInitializeX86AsmParser();
 
+
+void LLVMInitializeARMTargetInfo();
+void LLVMInitializeARMTarget();
+void LLVMInitializeARMTargetMC();
+void LLVMInitializeARMAsmPrinter();
+void LLVMInitializeARMAsmParser();
 // Only initialize the platforms supported by Rust here,
 // because using --llvm-root will have multiple platforms
 // that rustllvm doesn't actually link to and it's pointless to put target info
@@ -102,6 +108,12 @@ void LLVMRustInitializeTargets() {
   LLVMInitializeX86TargetMC();
   LLVMInitializeX86AsmPrinter();
   LLVMInitializeX86AsmParser();
+       
+  LLVMInitializeARMTargetInfo();
+  LLVMInitializeARMTarget();
+  LLVMInitializeARMTargetMC();
+  LLVMInitializeARMAsmPrinter();
+  LLVMInitializeARMAsmParser();        
 }
 
 // Custom memory manager for MCJITting. It needs special features
@@ -281,7 +293,7 @@ void *RustMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
   if (Name == "mknod") return (void*)(intptr_t)&mknod;
 #endif
 
-  if (Name == "__morestack") return &__morestack;
+  if (Name == "__morestack" || Name == "___morestack") return &__morestack;
 
   const char *NameStr = Name.c_str();
 
index 44636f4f36b16c1c2d7e63cda5db796d8f2142ac..d3cbc490ada453491980364661010a10e2cd7b8f 100644 (file)
@@ -383,19 +383,19 @@ LLVMInitializeInstCombine
 LLVMInitializeScalarOpts
 LLVMInitializeTarget
 LLVMInitializeTransformUtils
+LLVMInitializeARMAsmLexer
 LLVMInitializeX86AsmLexer
-LLVMInitializeX86AsmLexer
-LLVMInitializeX86AsmParser
+LLVMInitializeARMAsmParser
 LLVMInitializeX86AsmParser
+LLVMInitializeARMAsmPrinter
 LLVMInitializeX86AsmPrinter
-LLVMInitializeX86AsmPrinter
-LLVMInitializeX86Disassembler
+LLVMInitializeARMDisassembler
 LLVMInitializeX86Disassembler
+LLVMInitializeARMTarget
 LLVMInitializeX86Target
-LLVMInitializeX86Target
-LLVMInitializeX86TargetMC
+LLVMInitializeARMTargetMC
 LLVMInitializeX86TargetMC
-LLVMInitializeX86TargetInfo
+LLVMInitializeARMTargetInfo
 LLVMInitializeX86TargetInfo
 LLVMInsertBasicBlock
 LLVMInsertBasicBlockInContext
index a558de338762917ae6b336f5e53c48244592fc35..c22047287e624a41c53b3bc34b0e18344ec21e57 100644 (file)
@@ -8,13 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[legacy_exports];
-
-export foo;
-
 use core::oldcomm::*;
 
-fn foo<T: Owned Copy>(x: T) -> Port<T> {
+pub fn foo<T: Owned Copy>(x: T) -> Port<T> {
     let p = Port();
     let c = Chan(&p);
     do task::spawn() |copy c, copy x| {
index 032a01178f3bbd21871187216ecc138af3a37ed1..1225e2fe8a7475cfeecc6c63bf072793d3ed3ada 100644 (file)
@@ -8,21 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[legacy_exports];
+use core::to_str::*;
 
-use to_str::*;
-use to_str::ToStr;
-
-mod kitty {
-    #[legacy_exports];
-
-struct cat {
-  priv mut meows : uint,
-  mut how_hungry : int,
-  name : ~str,
-}
+pub mod kitty {
+    pub struct cat {
+      priv mut meows : uint,
+      mut how_hungry : int,
+      name : ~str,
+    }
 
-    impl cat : ToStr {
+    pub impl cat : ToStr {
        pure fn to_str() -> ~str { copy self.name }
     }
 
@@ -37,7 +32,7 @@ fn meow() {
 
     }
 
-    impl cat {
+    pub impl cat {
         fn speak() { self.meow(); }
 
         fn eat() -> bool {
@@ -52,14 +47,14 @@ fn eat() -> bool {
             }
         }
     }
-fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat {
-    cat {
-        meows: in_x,
-        how_hungry: in_y,
-        name: in_name
-    }
-}
 
+    pub fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat {
+        cat {
+            meows: in_x,
+            how_hungry: in_y,
+            name: in_name
+        }
+    }
 }
 
 
index d55302481a9ca156c3b243413c66a73be128fe23..291a506c4ebb05e41df3394c89a1a8787b93dc85 100644 (file)
@@ -14,7 +14,7 @@
 use dvec::DVec;
 
 type entry<A,B> = {key: A, value: B};
-type alist<A,B> = { eq_fn: fn@(A,A) -> bool, data: DVec<entry<A,B>> };
+struct alist<A,B> { eq_fn: fn@(A,A) -> bool, data: DVec<entry<A,B>> }
 
 fn alist_add<A: Copy, B: Copy>(lst: alist<A,B>, k: A, v: B) {
     lst.data.push({key:k, value:v});
@@ -31,12 +31,12 @@ fn alist_get<A: Copy, B: Copy>(lst: alist<A,B>, k: A) -> B {
 #[inline]
 fn new_int_alist<B: Copy>() -> alist<int, B> {
     fn eq_int(&&a: int, &&b: int) -> bool { a == b }
-    return {eq_fn: eq_int, data: DVec()};
+    return alist {eq_fn: eq_int, data: DVec()};
 }
 
 #[inline]
 fn new_int_alist_2<B: Copy>() -> alist<int, B> {
     #[inline]
     fn eq_int(&&a: int, &&b: int) -> bool { a == b }
-    return {eq_fn: eq_int, data: DVec()};
+    return alist {eq_fn: eq_int, data: DVec()};
 }
index 71425659584fdd5c3a3482695bede265298fe13d..197ad8402349ba25211eb3e3c94480ea95aace84 100644 (file)
 
 #[link(name = "req")];
 #[crate_type = "lib"];
-#[legacy_exports];
 
 extern mod std;
 
-use dvec::*;
-use dvec::DVec;
+use core::dvec::*;
 use std::map::HashMap;
 
-type header_map = HashMap<~str, @DVec<@~str>>;
+pub type header_map = HashMap<~str, @DVec<@~str>>;
 
 // the unused ty param is necessary so this gets monomorphized
-fn request<T: Copy>(req: header_map) {
+pub fn request<T: Copy>(req: header_map) {
   let _x = copy *(copy *req.get(~"METHOD"))[0u];
 }
diff --git a/src/test/auxiliary/issue_3882.rc b/src/test/auxiliary/issue_3882.rc
new file mode 100644 (file)
index 0000000..f612408
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+#[link(name = "linenoise",
+       vers = "0.1")];
+#[crate_type = "lib"];
+
+pub mod issue_3882;
diff --git a/src/test/auxiliary/issue_3882.rs b/src/test/auxiliary/issue_3882.rs
new file mode 100644 (file)
index 0000000..c2b95e4
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+mod issue_3882 {
+    struct Completions {
+        mut len: libc::size_t,
+    }
+    
+    extern mod c {
+        fn linenoiseAddCompletion(lc: *Completions);
+    }
+}
index 57e2e53ac7255f6065f4c828671e1a726780809b..4e9e3688ecdbf2dd1a845818fb72b046211409b4 100644 (file)
@@ -8,7 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[legacy_exports];
-export foo;
 type oint = Option<int>;
-fn foo() -> oint { Some(3) }
+pub fn foo() -> oint { Some(3) }
index 0ae0423e6be69b7a3ebbeaab17525cf403fd9c85..530309536d9df153762207164b1d629b973481b0 100644 (file)
        vers = "0.1")];
 
 #[crate_type = "lib"];
-#[legacy_exports];
-export read, readMaybe;
 
-trait read {
+pub trait read {
     static fn readMaybe(s: ~str) -> Option<self>;
 }
 
@@ -35,7 +33,7 @@ impl bool: read {
     }
 }
 
-fn read<T: read Copy>(s: ~str) -> T {
+pub fn read<T: read Copy>(s: ~str) -> T {
     match read::readMaybe(s) {
       Some(x) => x,
       _ => fail ~"read failed!"
index c85ff320bc82d7ca7fae7880206d508e16936f09..2a1cce54783fa407a7e854561431e657348a6a65 100644 (file)
@@ -16,7 +16,7 @@ pub trait Num2 {
 }
 
 pub mod float {
-    impl float: num::Num2 {
+    impl float: ::num::Num2 {
         #[inline]
         static pure fn from_int2(n: int) -> float { return n as float;  }
     }
index e67d46553cfc2497c9266ec14584b702258997d9..40659da8dae1bccb923f914ece7ce30c624f28d3 100644 (file)
@@ -5,7 +5,7 @@ pub trait Num2 {
 }
 
 pub mod float {
-    impl float: num::Num2 {
+    impl float: ::num::Num2 {
         static pure fn from_int2(n: int) -> float { return n as float;  }
     }
-}
\ No newline at end of file
+}
index 0ae2dc5340e276036cde646895e6e0712e8f436d..72000f2f0a9f0df5644a4dfa2499369be96b25be 100644 (file)
 
   Could probably be more minimal.
  */
-#[legacy_exports];
 
-use libc::size_t;
-
-export port;
-export recv;
+use core::libc::size_t;
 
 
 /**
  * transmitted. If a port value is copied, both copies refer to the same
  * port.  Ports may be associated with multiple `chan`s.
  */
-enum port<T: Owned> {
+pub enum port<T: Owned> {
     port_t(@port_ptr<T>)
 }
 
 /// Constructs a port
-fn port<T: Owned>() -> port<T> {
+pub fn port<T: Owned>() -> port<T> {
     port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>() as size_t)))
 }
 
@@ -74,11 +70,11 @@ fn port_ptr<T: Owned>(po: *rust_port) -> port_ptr<T> {
  * Receive from a port.  If no data is available on the port then the
  * task will block until data becomes available.
  */
-fn recv<T: Owned>(p: port<T>) -> T { recv_((**p).po) }
+pub fn recv<T: Owned>(p: port<T>) -> T { recv_((**p).po) }
 
 
 /// Receive on a raw port pointer
-fn recv_<T: Owned>(p: *rust_port) -> T {
+pub fn recv_<T: Owned>(p: *rust_port) -> T {
     let yield = 0;
     let yieldp = ptr::addr_of(&yield);
     let mut res;
index 04c224211b1b850970f103ec714558577b739607..83ca9fd06c9eda3004f5713311bf1f1812cac567 100644 (file)
@@ -16,9 +16,9 @@
 
 extern mod std;
 use std::map;
-use mutable::Mut;
-use send_map::linear::*;
-use io::WriterUtil;
+use core::mutable::Mut;
+use core::send_map::linear::*;
+use core::io::WriterUtil;
 
 struct Results {
     sequential_ints: float,
@@ -185,4 +185,4 @@ fn main() {
             rng, num_keys, &mut results);
         write_results("libstd::map::hashmap", &results);
     }
-}
\ No newline at end of file
+}
index bd5ce036bb2fd1f0134726eaa677451060a8e125..45fec9edeb96de9ea04de0536b3afbdfa637d845 100644 (file)
@@ -25,9 +25,9 @@
 use std::deque;
 use std::deque::Deque;
 use std::par;
-use io::WriterUtil;
-use oldcomm::*;
-use int::abs;
+use core::io::WriterUtil;
+use core::oldcomm::*;
+use core::int::abs;
 
 type node_id = i64;
 type graph = ~[~[node_id]];
index 62226a1c44de1b6b1c5a531995c9342a687de047..43b20ed2db41bbd5b59d13fb334807250e173c82 100644 (file)
@@ -14,7 +14,8 @@
 // that things will look really good once we get that lock out of the
 // message path.
 
-use oldcomm::*;
+use core::oldcomm::*;
+use core::oldcomm;
 
 extern mod std;
 use std::time;
index f85d6f6fdaaac211b5ce25c395edc28f172c9f8f..6133f9befcf3f3929a5a80fdebfe6d379c19a622 100644 (file)
@@ -83,7 +83,7 @@ fn fillbyte(x: cmplx, incr: f64) -> u8 {
     rv
 }
 
-fn chanmb(i: uint, size: uint, ch: oldcomm::Chan<Line>) -> ()
+fn chanmb(i: uint, size: uint) -> Line
 {
     let mut crv = ~[];
     let incr = 2f64/(size as f64);
@@ -93,12 +93,12 @@ fn chanmb(i: uint, size: uint, ch: oldcomm::Chan<Line>) -> ()
         let x = cmplx {re: xincr*(j as f64) - 1.5f64, im: y};
         crv.push(fillbyte(x, incr));
     };
-    oldcomm::send(ch, Line {i:i, b: move crv});
+    Line {i:i, b:crv}
 }
 
-type devnull = {dn: int};
+struct Devnull();
 
-impl devnull: io::Writer {
+impl Devnull: io::Writer {
     fn write(&self, _b: &[const u8]) {}
     fn seek(&self, _i: int, _s: io::SeekStyle) {}
     fn tell(&self) -> uint {0_u}
@@ -106,14 +106,11 @@ fn flush(&self) -> int {0}
     fn get_type(&self) -> io::WriterType { io::File }
 }
 
-fn writer(path: ~str, writech: oldcomm::Chan<oldcomm::Chan<Line>>, size: uint)
+fn writer(path: ~str, pport: pipes::Port<Line>, size: uint)
 {
-    let p: oldcomm::Port<Line> = oldcomm::Port();
-    let ch = oldcomm::Chan(&p);
-    oldcomm::send(writech, ch);
     let cout: io::Writer = match path {
         ~"" => {
-            {dn: 0} as io::Writer
+            Devnull as io::Writer
         }
         ~"-" => {
             io::stdout()
@@ -130,7 +127,7 @@ fn writer(path: ~str, writech: oldcomm::Chan<oldcomm::Chan<Line>>, size: uint)
     let mut done = 0_u;
     let mut i = 0_u;
     while i < size {
-        let aline = oldcomm::recv(p);
+        let aline = pport.recv();
         if aline.i == done {
             debug!("W %u", aline.i);
             cout.write(aline.b);
@@ -171,13 +168,11 @@ fn main() {
     let size = if vec::len(args) < 2_u { 80_u }
     else { uint::from_str(args[1]).get() };
 
-    let writep = oldcomm::Port();
-    let writech = oldcomm::Chan(&writep);
-    do task::spawn |move path| {
-        writer(copy path, writech, size);
-    };
-    let ch = oldcomm::recv(writep);
+    let (pport, pchan) = pipes::stream();
+    let pchan = pipes::SharedChan(pchan);
     for uint::range(0_u, size) |j| {
-        do task::spawn { chanmb(j, size, ch) };
+        let cchan = pchan.clone();
+        do task::spawn |move cchan| { cchan.send(chanmb(j, size)) };
     };
+    writer(path, pport, size);
 }
index a2660255910312c29a05c5b9c634c9436a898060..1c0a70c32a2de0339916e46374224dfb5f4e0fee 100644 (file)
@@ -13,6 +13,8 @@
 
 extern mod std;
 
+use core::os;
+
 // Using sqrt from the standard library is way slower than using libc
 // directly even though std just calls libc, I guess it must be
 // because the the indirection through another dynamic linker
@@ -45,9 +47,9 @@ fn main() {
 }
 
 mod NBodySystem {
-    #[legacy_exports];
+    use Body;
 
-    fn make() -> ~[Body::props] {
+    pub fn make() -> ~[Body::props] {
         let mut bodies: ~[Body::props] =
             ~[Body::sun(),
               Body::jupiter(),
@@ -74,8 +76,7 @@ fn make() -> ~[Body::props] {
         return bodies;
     }
 
-    fn advance(bodies: &mut [Body::props], dt: float) {
-
+    pub fn advance(bodies: &mut [Body::props], dt: float) {
         let mut i = 0;
         while i < 5 {
             let mut j = i + 1;
@@ -95,16 +96,16 @@ fn advance(bodies: &mut [Body::props], dt: float) {
         }
     }
 
-    fn advance_one(bi: &mut Body::props,
-                   bj: &mut Body::props,
-                   dt: float) unsafe {
+    pub fn advance_one(bi: &mut Body::props,
+                       bj: &mut Body::props,
+                       dt: float) unsafe {
         let dx = bi.x - bj.x;
         let dy = bi.y - bj.y;
         let dz = bi.z - bj.z;
 
         let dSquared = dx * dx + dy * dy + dz * dz;
 
-        let distance = libc::sqrt(dSquared);
+        let distance = ::libc::sqrt(dSquared);
         let mag = dt / (dSquared * distance);
 
         bi.vx -= dx * bj.mass * mag;
@@ -116,13 +117,13 @@ fn advance_one(bi: &mut Body::props,
         bj.vz += dz * bi.mass * mag;
     }
 
-    fn move_(b: &mut Body::props, dt: float) {
+    pub fn move_(b: &mut Body::props, dt: float) {
         b.x += dt * b.vx;
         b.y += dt * b.vy;
         b.z += dt * b.vz;
     }
 
-    fn energy(bodies: &[Body::props]) -> float unsafe {
+    pub fn energy(bodies: &[Body::props]) -> float unsafe {
         let mut dx;
         let mut dy;
         let mut dz;
@@ -142,7 +143,7 @@ fn energy(bodies: &[Body::props]) -> float unsafe {
                 dy = bodies[i].y - bodies[j].y;
                 dz = bodies[i].z - bodies[j].z;
 
-                distance = libc::sqrt(dx * dx + dy * dy + dz * dz);
+                distance = ::libc::sqrt(dx * dx + dy * dy + dz * dz);
                 e -= bodies[i].mass * bodies[j].mass / distance;
 
                 j += 1;
@@ -156,14 +157,14 @@ fn energy(bodies: &[Body::props]) -> float unsafe {
 }
 
 mod Body {
-    #[legacy_exports];
+    use Body;
 
-    const PI: float = 3.141592653589793;
-    const SOLAR_MASS: float = 39.478417604357432;
+    pub const PI: float = 3.141592653589793;
+    pub const SOLAR_MASS: float = 39.478417604357432;
     // was 4 * PI * PI originally
-    const DAYS_PER_YEAR: float = 365.24;
+    pub const DAYS_PER_YEAR: float = 365.24;
 
-    type props =
+    pub type props =
         {mut x: float,
          mut y: float,
          mut z: float,
@@ -172,7 +173,7 @@ mod Body {
          mut vz: float,
          mass: float};
 
-    fn jupiter() -> Body::props {
+    pub fn jupiter() -> Body::props {
         return {mut x: 4.84143144246472090e+00,
              mut y: -1.16032004402742839e+00,
              mut z: -1.03622044471123109e-01,
@@ -182,7 +183,7 @@ fn jupiter() -> Body::props {
              mass: 9.54791938424326609e-04 * SOLAR_MASS};
     }
 
-    fn saturn() -> Body::props {
+    pub fn saturn() -> Body::props {
         return {mut x: 8.34336671824457987e+00,
              mut y: 4.12479856412430479e+00,
              mut z: -4.03523417114321381e-01,
@@ -192,7 +193,7 @@ fn saturn() -> Body::props {
              mass: 2.85885980666130812e-04 * SOLAR_MASS};
     }
 
-    fn uranus() -> Body::props {
+    pub fn uranus() -> Body::props {
         return {mut x: 1.28943695621391310e+01,
              mut y: -1.51111514016986312e+01,
              mut z: -2.23307578892655734e-01,
@@ -202,7 +203,7 @@ fn uranus() -> Body::props {
              mass: 4.36624404335156298e-05 * SOLAR_MASS};
     }
 
-    fn neptune() -> Body::props {
+    pub fn neptune() -> Body::props {
         return {mut x: 1.53796971148509165e+01,
              mut y: -2.59193146099879641e+01,
              mut z: 1.79258772950371181e-01,
@@ -212,7 +213,7 @@ fn neptune() -> Body::props {
              mass: 5.15138902046611451e-05 * SOLAR_MASS};
     }
 
-    fn sun() -> Body::props {
+    pub fn sun() -> Body::props {
         return {mut x: 0.0,
              mut y: 0.0,
              mut z: 0.0,
@@ -222,7 +223,7 @@ fn sun() -> Body::props {
              mass: SOLAR_MASS};
     }
 
-    fn offset_momentum(props: &mut Body::props,
+    pub fn offset_momentum(props: &mut Body::props,
                        px: float, py: float, pz: float) {
         props.vx = -px / SOLAR_MASS;
         props.vy = -py / SOLAR_MASS;
index 56257aa305e47a40ea9e412ca428970499a58d8c..a817414314600f9687a248ed9cd01fee4255764a 100644 (file)
 
 extern mod std;
 
-use option = option;
-use option::Some;
-use option::None;
+use core::option;
 use std::map;
 use std::map::HashMap;
-use hash::Hash;
-use io::{ReaderUtil, WriterUtil};
+use core::hash::Hash;
+use core::io::{ReaderUtil, WriterUtil};
 
 use std::time;
 
-use oldcomm::Chan;
-use oldcomm::Port;
-use oldcomm::recv;
-use oldcomm::send;
-use cmp::Eq;
-use to_bytes::IterBytes;
+use core::oldcomm::Chan;
+use core::oldcomm::Port;
+use core::oldcomm::recv;
+use core::oldcomm::send;
+use core::cmp::Eq;
+use core::to_bytes::IterBytes;
 
 macro_rules! move_out (
     { $x:expr } => { unsafe { let y = move *ptr::addr_of(&($x)); move y } }
@@ -47,9 +45,9 @@ trait word_reader {
     fn read_word() -> Option<~str>;
 }
 
-// These used to be in task, but they disappeard.
-type joinable_task = Port<()>;
-fn spawn_joinable(+f: fn~()) -> joinable_task {
+// These used to be in task, but they disappeared.
+pub type joinable_task = Port<()>;
+pub fn spawn_joinable(+f: fn~()) -> joinable_task {
     let p = Port();
     let c = Chan(&p);
     do task::spawn() |move f| {
@@ -59,7 +57,7 @@ fn spawn_joinable(+f: fn~()) -> joinable_task {
     p
 }
 
-fn join(t: joinable_task) {
+pub fn join(t: joinable_task) {
     t.recv()
 }
 
@@ -92,11 +90,11 @@ fn reduce(word: &~str, get: map_reduce::getter<int>) {
     io::println(fmt!("%s\t%?", *word, count));
 }
 
-struct box<T> {
+pub struct box<T> {
     mut contents: Option<T>,
 }
 
-impl<T> box<T> {
+pub impl<T> box<T> {
     fn swap(f: fn(+v: T) -> T) {
         let mut tmp = None;
         self.contents <-> tmp;
@@ -110,30 +108,28 @@ fn unwrap() -> T {
     }
 }
 
-fn box<T>(+x: T) -> box<T> {
+pub fn box<T>(+x: T) -> box<T> {
     box {
         contents: Some(move x)
     }
 }
 
 mod map_reduce {
-    #[legacy_exports];
-    export putter;
-    export getter;
-    export mapper;
-    export reducer;
-    export map_reduce;
+    use core::oldcomm::*;
 
-    type putter<K: Owned, V: Owned> = fn(&K, V);
+    use std::map::HashMap;
+    use std::map;
 
-    type mapper<K1: Owned, K2: Owned, V: Owned> = fn~(K1, putter<K2, V>);
+    pub type putter<K: Owned, V: Owned> = fn(&K, V);
 
-    type getter<V: Owned> = fn() -> Option<V>;
+    pub type mapper<K1: Owned, K2: Owned, V: Owned> = fn~(K1, putter<K2, V>);
 
-    type reducer<K: Copy Owned, V: Copy Owned> = fn~(&K, getter<V>);
+    pub type getter<V: Owned> = fn() -> Option<V>;
+
+    pub type reducer<K: Copy Owned, V: Copy Owned> = fn~(&K, getter<V>);
 
     enum ctrl_proto<K: Copy Owned, V: Copy Owned> {
-        find_reducer(K, Chan<Chan<reduce_proto<V>>>),
+        find_reducer(K, Chan<Chan<::map_reduce::reduce_proto<V>>>),
         mapper_done
     }
 
@@ -145,26 +141,32 @@ enum ctrl_proto<K: Copy Owned, V: Copy Owned> {
         }
 
         reducer_response: recv<K: Copy Owned, V: Copy Owned> {
-            reducer(Chan<reduce_proto<V>>) -> open<K, V>
+            reducer(::core::oldcomm::Chan<::map_reduce::reduce_proto<V>>)
+                -> open<K, V>
         }
     )
 
-    enum reduce_proto<V: Copy Owned> { emit_val(V), done, addref, release }
+    pub enum reduce_proto<V: Copy Owned> {
+        emit_val(V),
+        done,
+        addref,
+        release
+    }
 
     fn start_mappers<K1: Copy Owned, K2: Hash IterBytes Eq Const Copy Owned,
                      V: Copy Owned>(
         map: &mapper<K1, K2, V>,
         ctrls: &mut ~[ctrl_proto::server::open<K2, V>],
         inputs: &~[K1])
-        -> ~[joinable_task]
+        -> ~[::joinable_task]
     {
         let mut tasks = ~[];
         for inputs.each |i| {
             let (ctrl, ctrl_server) = ctrl_proto::init();
-            let ctrl = box(move ctrl);
+            let ctrl = ::box(move ctrl);
             let i = copy *i;
             let m = copy *map;
-            tasks.push(spawn_joinable(|move ctrl, move i| map_task(copy m, &ctrl, i)));
+            tasks.push(::spawn_joinable(|move ctrl, move i| map_task(copy m, &ctrl, i)));
             ctrls.push(move ctrl_server);
         }
         move tasks
@@ -172,16 +174,16 @@ fn start_mappers<K1: Copy Owned, K2: Hash IterBytes Eq Const Copy Owned,
 
     fn map_task<K1: Copy Owned, K2: Hash IterBytes Eq Const Copy Owned, V: Copy Owned>(
         map: mapper<K1, K2, V>,
-        ctrl: &box<ctrl_proto::client::open<K2, V>>,
+        ctrl: &::box<ctrl_proto::client::open<K2, V>>,
         input: K1)
     {
         // log(error, "map_task " + input);
-        let intermediates: HashMap<K2, Chan<reduce_proto<V>>>
+        let intermediates: HashMap<K2, Chan<::map_reduce::reduce_proto<V>>>
             = map::HashMap();
 
         do map(input) |key: &K2, val| {
             let mut c = None;
-            let found: Option<Chan<reduce_proto<V>>>
+            let found: Option<Chan<::map_reduce::reduce_proto<V>>>
                 = intermediates.find(*key);
             match found {
               Some(_c) => { c = Some(_c); }
@@ -202,7 +204,8 @@ fn map_task<K1: Copy Owned, K2: Hash IterBytes Eq Const Copy Owned, V: Copy Owne
             send(c.get(), emit_val(val));
         }
 
-        fn finish<K: Copy Owned, V: Copy Owned>(_k: K, v: Chan<reduce_proto<V>>)
+        fn finish<K: Copy Owned, V: Copy Owned>(
+            _k: K, v: Chan<::map_reduce::reduce_proto<V>>)
         {
             send(v, release);
         }
@@ -213,7 +216,7 @@ fn finish<K: Copy Owned, V: Copy Owned>(_k: K, v: Chan<reduce_proto<V>>)
     fn reduce_task<K: Copy Owned, V: Copy Owned>(
         reduce: ~reducer<K, V>, 
         key: K,
-        out: Chan<Chan<reduce_proto<V>>>)
+        out: Chan<Chan<::map_reduce::reduce_proto<V>>>)
     {
         let p = Port();
 
@@ -222,7 +225,7 @@ fn reduce_task<K: Copy Owned, V: Copy Owned>(
         let mut ref_count = 0;
         let mut is_done = false;
 
-        fn get<V: Copy Owned>(p: Port<reduce_proto<V>>,
+        fn get<V: Copy Owned>(p: Port<::map_reduce::reduce_proto<V>>,
                              ref_count: &mut int, is_done: &mut bool)
            -> Option<V> {
             while !*is_done || *ref_count > 0 {
@@ -245,7 +248,7 @@ fn get<V: Copy Owned>(p: Port<reduce_proto<V>>,
         (*reduce)(&key, || get(p, &mut ref_count, &mut is_done) );
     }
 
-    fn map_reduce<K1: Copy Owned, K2: Hash IterBytes Eq Const Copy Owned, V: Copy Owned>(
+    pub fn map_reduce<K1: Copy Owned, K2: Hash IterBytes Eq Const Copy Owned, V: Copy Owned>(
         map: mapper<K1, K2, V>,
         reduce: reducer<K2, V>,
         inputs: ~[K1])
@@ -281,7 +284,7 @@ fn map_reduce<K1: Copy Owned, K2: Hash IterBytes Eq Const Copy Owned, V: Copy Ow
                     let p = Port();
                     let ch = Chan(&p);
                     let r = copy reduce, kk = k;
-                    tasks.push(spawn_joinable(|move r|
+                    tasks.push(::spawn_joinable(|move r|
                         reduce_task(~copy r, kk, ch)
                     ));
                     c = recv(p);
@@ -297,7 +300,7 @@ fn map_reduce<K1: Copy Owned, K2: Hash IterBytes Eq Const Copy Owned, V: Copy Ow
 
         for reducers.each_value |v| { send(v, done) }
 
-        for tasks.each |t| { join(*t); }
+        for tasks.each |t| { ::join(*t); }
     }
 }
 
@@ -313,8 +316,8 @@ fn main() {
 
     let readers: ~[fn~() -> word_reader]  = if argv.len() >= 2 {
         vec::view(argv, 1u, argv.len()).map(|f| {
-            let f = *f;
-            fn~() -> word_reader { file_word_reader(f) }
+            let f = copy *f;
+            fn~() -> word_reader { file_word_reader(copy f) }
         })
     }
     else {
diff --git a/src/test/compile-fail/access-mode-in-closures.rs b/src/test/compile-fail/access-mode-in-closures.rs
new file mode 100644 (file)
index 0000000..6b785fb
--- /dev/null
@@ -0,0 +1,10 @@
+enum sty = ~[int];
+
+fn unpack(_unpack: &fn(v: &sty) -> ~[int]) {}
+
+fn main() {
+    let _foo = unpack(|s| {
+        // Test that `s` is moved here.
+        match *s { sty(v) => v } //~ ERROR moving out of dereference of immutable & pointer
+    });
+}
index 3f4d60a5ec97da6e8724cd8686e3771f67ab6680..9e73bbe1406bdc79b4e5258bbd9de21beab1aca8 100644 (file)
@@ -13,7 +13,7 @@
 
 fn bad_bang(i: uint) -> ! {
     return 7u;
-    //~^ ERROR expected `_|_` but found `uint`
+    //~^ ERROR expected `!` but found `uint`
 }
 
 fn main() { bad_bang(5u); }
index da08692797f83ec880c96f5d7630a8301e02820a..4dbe5876a978e850c57d07741c16efaaf6a006fe 100644 (file)
@@ -13,7 +13,7 @@
 
 fn bad_bang(i: uint) -> ! {
     if i < 0u { } else { fail; }
-    //~^ ERROR expected `_|_` but found `()`
+    //~^ ERROR expected `!` but found `()`
 }
 
 fn main() { bad_bang(5u); }
index fa33e1f832b00393c04b86fca9fa9583a302b9d8..af78e19e8c2e21ebcaa3f3bd11590f63c0fc00b3 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 fn f() -> ! {
-    3i //~ ERROR expected `_|_` but found `int`
+    3i //~ ERROR expected `!` but found `int`
 }
 fn main() { }
index 1e539dc4f36f61c90b27899d783fe7a282f3c2cf..b2265f5e959a0b7af49b3d8a4cf25091211b0589 100644 (file)
@@ -19,5 +19,5 @@ fn g(f: extern fn(fn())) {
     }
 
     f(g);
-    //~^ ERROR mismatched types: expected `fn(fn(fn()))`
+    //~^ ERROR mismatched types: expected `extern fn(extern fn(extern fn()))`
 }
index 6c6f59d00ea9843554bac2eda95a1f5981244f1b..457cdd2344737a3ec142f1cbca976baceb910e1e 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use either::*;
-enum X = Either<(uint,uint),fn()>;
+use core::either::*;
+enum X = Either<(uint,uint),extern fn()>;
 impl &X {
-    fn with(blk: fn(x: &Either<(uint,uint),fn()>)) {
+    fn with(blk: fn(x: &Either<(uint,uint),extern fn()>)) {
         blk(&**self)
     }
 }
@@ -26,4 +26,4 @@ fn main() {
             _ => fail
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/closure-that-fails.rs b/src/test/compile-fail/closure-that-fails.rs
new file mode 100644 (file)
index 0000000..00bfa7a
--- /dev/null
@@ -0,0 +1,7 @@
+fn foo(f: fn() -> !) {}
+
+fn main() {
+    // Type inference didn't use to be able to handle this:
+    foo(|| fail);
+    foo(|| 22); //~ ERROR mismatched types
+}
index bb96db8c41cc44c8994f157f5469040114bcf207..21d4fa8eab8808a29c592413992512ce3839d3f3 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn closure2(+x: util::NonCopyable) -> (util::NonCopyable,
-                                       fn@() -> util::NonCopyable) {
-    let f = fn@(copy x) -> util::NonCopyable {
+fn closure2(+x: core::util::NonCopyable)
+        -> (core::util::NonCopyable, fn@() -> core::util::NonCopyable) {
+    let f = fn@(copy x) -> core::util::NonCopyable {
         //~^ ERROR copying a noncopyable value
         //~^^ NOTE non-copyable value cannot be copied into a @fn closure
         copy x
@@ -18,7 +18,7 @@ fn closure2(+x: util::NonCopyable) -> (util::NonCopyable,
     };
     (move x,f)
 }
-fn closure3(+x: util::NonCopyable) {
+fn closure3(+x: core::util::NonCopyable) {
     do task::spawn |copy x| {
         //~^ ERROR copying a noncopyable value
         //~^^ NOTE non-copyable value cannot be copied into a ~fn closure
index b7d70c60c223f3a9a300307d3c046ab5476b1c9a..464f292b75899c4b9848ce599c4beeb16f94b07f 100644 (file)
@@ -10,6 +10,7 @@
 
 // Test that we use fully-qualified type names in error messages.
 
+// xfail-test
 type T1 = uint;
 type T2 = int;
 
index a0d2536d85f0e7d2b22e04fa75ae7a855cd0e138..2a64666d94ca671a0b4bcb796353a462744f9d54 100644 (file)
@@ -10,8 +10,7 @@
 
 // Testing that we don't fail abnormally after hitting the errors
 
-use unresolved::*; //~ ERROR unresolved name
-//~^ ERROR failed to resolve import
+use unresolved::*; //~ ERROR unresolved import
 
 fn main() {
 }
index 16b6360b55987a03281036694d58e71157547453..2684289d70f73e69f64fea76429c3e2e5af41f16 100644 (file)
@@ -32,9 +32,9 @@ fn main() {
 
     {
         let mut res = foo(x);
-        
+
         let mut v = ~[mut];
-        v = move ~[mut (move res)] + v; //~ ERROR instantiating a type parameter with an incompatible type (needs `copy`, got `durable`, missing `copy`)
+        v = move ~[mut (move res)] + v; //~ ERROR instantiating a type parameter with an incompatible type (needs `copy`, got `&static`, missing `copy`)
         assert (v.len() == 2);
     }
 
index 8acabc6bdc17fd86e9e0b5406c9f1d824119c5dd..2332d54037fbd567bdaf183bc90072af0fabd634 100644 (file)
@@ -8,15 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct send_packet<T: Copy> {
+pub struct send_packet<T: Copy> {
   p: T
 }
 
 
 mod pingpong {
-    #[legacy_exports];
-    type ping = send_packet<pong>;
-    enum pong = send_packet<ping>; //~ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
+    use send_packet;
+    pub type ping = send_packet<pong>;
+    pub enum pong = send_packet<ping>; //~ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
 }
 
 fn main() {}
index c0b27789977efdd62d655be30e9ac802a1cc572e..0b63ae5b1bad3947eedcde2f77b0ee7cc7ef304f 100644 (file)
@@ -8,16 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-mod stream {
-    #[legacy_exports];
-    enum Stream<T: Owned> { send(T, server::Stream<T>), }
-    mod server {
-        #[legacy_exports];
+pub mod stream {
+    pub enum Stream<T: Owned> { send(T, ::stream::server::Stream<T>), }
+    pub mod server {
+        use core::option;
+        use core::pipes;
+
         impl<T: Owned> Stream<T> {
-            fn recv() -> extern fn(+v: Stream<T>) -> stream::Stream<T> {
+            pub fn recv() -> extern fn(+v: Stream<T>) -> ::stream::Stream<T> {
               // resolve really should report just one error here.
               // Change the test case when it changes.
-              fn recv(+pipe: Stream<T>) -> stream::Stream<T> { //~ ERROR attempt to use a type argument out of scope
+              pub fn recv(+pipe: Stream<T>) -> ::stream::Stream<T> { //~ ERROR attempt to use a type argument out of scope
                 //~^ ERROR use of undeclared type name
                 //~^^ ERROR attempt to use a type argument out of scope
                 //~^^^ ERROR use of undeclared type name
@@ -26,7 +27,8 @@ fn recv(+pipe: Stream<T>) -> stream::Stream<T> { //~ ERROR attempt to use a type
                 recv
             }
         }
-        type Stream<T: Owned> = pipes::RecvPacket<stream::Stream<T>>;
+
+        pub type Stream<T: Owned> = pipes::RecvPacket<::stream::Stream<T>>;
     }
 }
 
diff --git a/src/test/compile-fail/issue-3477.rs b/src/test/compile-fail/issue-3477.rs
new file mode 100644 (file)
index 0000000..7e18934
--- /dev/null
@@ -0,0 +1,3 @@
+fn main() {
+    let _p: char = 100; //~ ERROR mismatched types: expected `char` but found
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/issue-3563.rs b/src/test/compile-fail/issue-3563.rs
new file mode 100644 (file)
index 0000000..9f7a074
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+trait A {
+  fn a(&self) {
+      || self.b() //~ ERROR type `&self/self` does not implement any method in scope named `b`
+  }
+}
+fn main() {}
diff --git a/src/test/compile-fail/issue-3601.rs b/src/test/compile-fail/issue-3601.rs
new file mode 100644 (file)
index 0000000..3e54aaa
--- /dev/null
@@ -0,0 +1,42 @@
+// 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.
+
+// xfail-test
+struct HTMLImageData {
+    mut image: Option<~str>
+}
+
+struct ElementData {
+    kind: ~ElementKind
+}
+
+enum ElementKind {
+    HTMLImageElement(HTMLImageData)
+}
+
+enum NodeKind {
+    Element(ElementData)
+}
+
+enum NodeData = {
+    kind: ~NodeKind
+};
+
+fn main() {
+    let id = HTMLImageData { image: None };
+    let ed = ElementData { kind: ~HTMLImageElement(id) };
+    let n = NodeData({kind : ~Element(ed)});
+    match n.kind {
+        ~Element(ed) => match ed.kind {
+            ~HTMLImageElement(d) if d.image.is_some() => { true }
+        },
+        _ => fail ~"WAT" //~ ERROR wat
+    };
+}
diff --git a/src/test/compile-fail/issue-3707.rs b/src/test/compile-fail/issue-3707.rs
new file mode 100644 (file)
index 0000000..c166c40
--- /dev/null
@@ -0,0 +1,29 @@
+// 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.
+
+// xfail-test
+struct Obj {
+    member: uint
+}
+
+impl Obj {
+    static pure fn boom() -> bool {
+        return 1+1 == 2
+    }
+    pure fn chirp() {
+        self.boom(); //~ ERROR wat
+    }
+}
+
+fn main() {
+    let o = Obj { member: 0 };
+    o.chirp();
+    1 + 1;
+}
diff --git a/src/test/compile-fail/issue-3820.rs b/src/test/compile-fail/issue-3820.rs
new file mode 100644 (file)
index 0000000..719036d
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.
+
+// xfail-test
+struct Thing {
+    x: int
+}
+
+impl Thing/*: Mul<int, Thing>*/ { //~ ERROR Look ma, no Mul!
+    pure fn mul(c: &int) -> Thing {
+        Thing {x: self.x * *c}
+    }
+}
+
+fn main() {
+    let u = Thing {x: 2};
+    let _v = u.mul(&3); // Works
+    let w = u * 3; // Works!!
+    io::println(fmt!("%i", w.x));
+
+    /*
+    // This doesn't work though.
+    let u2 = u as @Mul<int, Thing>;
+    let w2 = u2.mul(&4);
+    io::println(fmt!("%i", w2.x));
+    */
+}
diff --git a/src/test/compile-fail/issue-3973.rs b/src/test/compile-fail/issue-3973.rs
new file mode 100644 (file)
index 0000000..6c97784
--- /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.
+
+// xfail-test
+
+struct Point {
+    mut x: float,
+    mut y: float,
+}
+
+impl Point : ToStr { //~ ERROR implements a method not defined in the trait
+    static fn new(x: float, y: float) -> Point {
+        Point { x: x, y: y }
+    }
+
+    pure fn to_str() -> ~str {
+        fmt!("(%f, %f)", self.x, self.y)
+    }
+}
+
+fn main() {
+    let p = Point::new(0.0f, 0.0f);
+    io::println(p.to_str());
+}
index 77de0b115cbb6dd737ae4cacaf534e9dd6e4eb13..61afdab405dc47dfab2000b873115d51d52d765f 100644 (file)
@@ -10,7 +10,7 @@
 
 fn g() -> ! { fail; }
 fn f() -> ! {
-    return 42i; //~ ERROR expected `_|_` but found `int`
+    return 42i; //~ ERROR expected `!` but found `int`
     g(); //~ WARNING unreachable statement
 }
 fn main() { }
index 3086bcc9b3f3b4b611e878a560a1be053e4595be..1ed7034be77cd63e9d3997a6cf17c6482ebca5b9 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn f() -> ! {
-    return 42i; //~ ERROR expected `_|_` but found `int`
+    return 42i; //~ ERROR expected `!` but found `int`
     fail; //~ WARNING unreachable statement
 }
 fn main() { }
index d1eae60ac9d2da5b499a8cc3591e26c93a341e8c..6c6cdbbb2c7730a9045a1828c08470d8dcd06609 100644 (file)
@@ -32,10 +32,10 @@ fn to_foo<T:Copy>(t: T) {
 fn to_foo_2<T:Copy>(t: T) -> foo {
     // Not OK---T may contain borrowed ptrs and it is going to escape
     // as part of the returned foo value
-    {f:t} as foo //~ ERROR value may contain borrowed pointers; use `durable` bound
+    {f:t} as foo //~ ERROR value may contain borrowed pointers; use `&static` bound
 }
 
-fn to_foo_3<T:Copy Durable>(t: T) -> foo {
+fn to_foo_3<T:Copy &static>(t: T) -> foo {
     // OK---T may escape as part of the returned foo value, but it is
     // owned and hence does not contain borrowed ptrs
     {f:t} as foo
index 35dc066e32089cb6d77fb9d99dc41ab542ab5490..683d66d0d72e90729f3f8a2bf23d46c173c5b3b1 100644 (file)
 trait foo { fn foo(); }
 
 fn to_foo<T: Copy foo>(t: T) -> foo {
-    t as foo //~ ERROR value may contain borrowed pointers; use `durable` bound
+    t as foo //~ ERROR value may contain borrowed pointers; use `&static` bound
 }
 
-fn to_foo2<T: Copy foo Durable>(t: T) -> foo {
+fn to_foo2<T: Copy foo &static>(t: T) -> foo {
     t as foo
 }
 
index 111b621c5a08f17182e2bf03d72c513a31626b14..52031c900a28979ff723511726b3248ac5398675 100644 (file)
@@ -12,18 +12,18 @@ fn copy1<T: Copy>(t: T) -> fn@() -> T {
     fn@() -> T { t } //~ ERROR value may contain borrowed pointers
 }
 
-fn copy2<T: Copy Durable>(t: T) -> fn@() -> T {
+fn copy2<T: Copy &static>(t: T) -> fn@() -> T {
     fn@() -> T { t }
 }
 
 fn main() {
     let x = &3;
-    copy2(&x); //~ ERROR missing `durable`
+    copy2(&x); //~ ERROR missing `&static`
 
     copy2(@3);
-    copy2(@&x); //~ ERROR missing `durable`
+    copy2(@&x); //~ ERROR missing `&static`
 
     copy2(fn@() {});
     copy2(fn~() {}); //~ WARNING instantiating copy type parameter with a not implicitly copyable type
-    copy2(fn&() {}); //~ ERROR missing `copy durable`
+    copy2(fn&() {}); //~ ERROR missing `copy &static`
 }
index 77b906ca9a2cdbfca7db4c7985ce9cebd2f33e5e..0265bd6d24b675c0bde3801d7f714507f33bbee8 100644 (file)
@@ -14,7 +14,7 @@ fn forever() -> ! {
   loop {
     break;
   }
-  return 42i; //~ ERROR expected `_|_` but found `int`
+  return 42i; //~ ERROR expected `!` but found `int`
 }
 
 fn main() {
index 4e1989eb25c5ef2d2f6ff82285891a610126de26..bb6633ecdc1fd47fc2fa87b3acb84a54363041b3 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() -> char {
-//~^ ERROR Wrong type in main function: found `fn() -> char`
+//~^ ERROR Wrong type in main function: found `extern fn() -> char`
 }
index 7f8a4053c43ee52172162bfea217e14158f4375b..33d7b913dafb5f6c4bdb99e8c4f9b4058310814a 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main(foo: {x: int, y: int}) {
-//~^ ERROR Wrong type in main function: found `fn({x: int,y: int})`
+//~^ ERROR Wrong type in main function: found `extern fn({x: int,y: int})`
 }
index 3a0e8ffb9c48d9a3824344cb8d845db09a8444bc..916008373c875d65f2e9308d52a0761ab7960b58 100644 (file)
@@ -14,6 +14,6 @@ fn foo(f: fn()) { f() }
 
 fn main() {
     ~"" || 42; //~ ERROR binary operation || cannot be applied to type `~str`
-    foo || {}; //~ ERROR binary operation || cannot be applied to type `fn(&fn())`
+    foo || {}; //~ ERROR binary operation || cannot be applied to type `extern fn(&fn())`
     //~^ NOTE did you forget the 'do' keyword for the call?
 }
index 9947c882a5854feb81313ea5b6d5ebcf1768a415..e64d651dab2b460f45542a397af03110e753fc20 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // error-pattern:declaration of `None` shadows
-use option::*;
+use core::option::*;
 
 fn main() {
   let None: int = 42;
index 98220195e613d90f784fed3cece9ca70e90e79e9..7dc3c247ea48e5db9de04b2670b2e6d01d7c8687 100644 (file)
@@ -12,7 +12,7 @@
 
 extern mod std;
 use std::arc;
-use oldcomm::*;
+use core::oldcomm::*;
 
 fn main() {
     let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
index 8cb8f31c4897682fd5e9de0b3758c9806441b30d..8a7c37649d2edf6c126195a0174e09216721e282 100644 (file)
@@ -10,7 +10,7 @@
 
 extern mod std;
 use std::arc;
-use oldcomm::*;
+use core::oldcomm::*;
 
 fn main() {
     let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
index 9ed520a6c9958114466013b3ecdbfe17f9213e44..223d7effa4ce610f474e77ca26a245d2469d7897 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// xfail-test
 type foo = Option<int>;
 
 fn bar(_t: foo) {}
diff --git a/src/test/compile-fail/static-region-bound.rs b/src/test/compile-fail/static-region-bound.rs
new file mode 100644 (file)
index 0000000..b70b0cd
--- /dev/null
@@ -0,0 +1,9 @@
+fn f<T:&static>(_: T) {}
+
+fn main() {
+    let x = @3;
+    f(x);
+    let x = &3;
+    f(x);   //~ ERROR instantiating a type parameter with an incompatible type
+}
+
index 4932e5265747385609e3dcc753b32f17f4567d38..b602d1717be709671512b1f11454ce916c9fd797 100644 (file)
@@ -9,7 +9,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+// xfail-test
 type rec = {f: int};
 fn f(p: *rec) -> int {
 
index 08457f071431ca1e50781f391b523593f139009e..aee6f4e480ca18dc6577afdf6830b91c3ac13e20 100644 (file)
@@ -15,7 +15,7 @@ fn main() {
     let carrots = @~"crunchy";
 
     fn@(tasties: @~str, macerate: fn(~str)) {
-        macerate(*tasties);
+        macerate(copy *tasties);
     } (carrots, |food| {
         let mush = food + cheese;
         let f = fn@() {
index 3345dcaaad02a611d618b751b604e333495c802e..4e4df552a2ecd71bf404a8d04f032e11e9aca690 100644 (file)
@@ -15,7 +15,7 @@
 extern mod std;
 extern mod syntax;
 
-use io::*;
+use core::io::*;
 
 use syntax::diagnostic;
 use syntax::ast;
index 8acbee4400ce3c214351345cb30208d761d5a676..a880b50d628985463f1be2ac5a11d9806c34607d 100644 (file)
@@ -12,7 +12,7 @@
     a: A, b: B
 };
 
-fn f<A:Copy Durable>(a: A, b: u16) -> fn@() -> (A, u16) {
+fn f<A:Copy &static>(a: A, b: u16) -> fn@() -> (A, u16) {
     fn@() -> (A, u16) { (a, b) }
 }
 
index c90bec114ed26e3dc1cf179dba0681b32ea14865..ccc65cdab7515a2706779ca0f73c9a79f95b131d 100644 (file)
@@ -14,7 +14,7 @@
 enum t { make_t(@int), clam, }
 
 fn foo(s: @int) {
-    let count = core::sys::refcount(s);
+    let count = ::core::sys::refcount(s);
     let x: t = make_t(s); // ref up
 
     match x {
@@ -24,20 +24,20 @@ fn foo(s: @int) {
       }
       _ => { debug!("?"); fail; }
     }
-    log(debug, core::sys::refcount(s));
-    assert (core::sys::refcount(s) == count + 1u);
-    let _ = core::sys::refcount(s); // don't get bitten by last-use.
+    log(debug, ::core::sys::refcount(s));
+    assert (::core::sys::refcount(s) == count + 1u);
+    let _ = ::core::sys::refcount(s); // don't get bitten by last-use.
 }
 
 fn main() {
     let s: @int = @0; // ref up
 
-    let count = core::sys::refcount(s);
+    let count = ::core::sys::refcount(s);
 
     foo(s); // ref up then down
 
-    log(debug, core::sys::refcount(s));
-    let count2 = core::sys::refcount(s);
-    let _ = core::sys::refcount(s); // don't get bitten by last-use.
+    log(debug, ::core::sys::refcount(s));
+    let count2 = ::core::sys::refcount(s);
+    let _ = ::core::sys::refcount(s); // don't get bitten by last-use.
     assert count == count2;
 }
index 555171f9d5f30423167b78be0dff9ff25461e3a9..2bd00ddc4ef14e8ce167a51de56892e34125e036 100644 (file)
 use std::prettyprint;
 use std::time;
 
-fn test_prettyprint<A: Encodable<prettyprint::Encoder>>(
+fn test_prettyprint<A: Encodable<prettyprint::Serializer>>(
     a: &A,
     expected: &~str
 ) {
     let s = do io::with_str_writer |w| {
-        a.encode(&prettyprint::Encoder(w))
+        a.encode(&prettyprint::Serializer(w))
     };
     debug!("s == %?", s);
     assert s == *expected;
index 7f7da086df30ce042e169db9bd9131c142f21daa..87fd1443db9e3c1de236132f49105268ec2100fb 100644 (file)
 // except according to those terms.
 
 
-fn a(c: core::oldcomm::Chan<int>) { core::oldcomm::send(c, 10); }
+fn a(c: ::core::oldcomm::Chan<int>) { ::core::oldcomm::send(c, 10); }
 
 fn main() {
-    let p = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&p);
+    let p = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&p);
     task::spawn(|| a(ch) );
     task::spawn(|| a(ch) );
     let mut n: int = 0;
-    n = core::oldcomm::recv(p);
-    n = core::oldcomm::recv(p);
+    n = ::core::oldcomm::recv(p);
+    n = ::core::oldcomm::recv(p);
     //    debug!("Finished.");
 }
 
-fn b(c: core::oldcomm::Chan<int>) {
+fn b(c: ::core::oldcomm::Chan<int>) {
     //    debug!("task b0");
     //    debug!("task b1");
     //    debug!("task b2");
     //    debug!("task b3");
     //    debug!("task b4");
     //    debug!("task b5");
-    core::oldcomm::send(c, 10);
+    ::core::oldcomm::send(c, 10);
 }
index 36ed4c5162b67f611313333a8ceb83420c863cc1..0e542e157cf934ecdd1905a6799e368ecbf2a06c 100644 (file)
 // except according to those terms.
 
 
-fn a(c: core::oldcomm::Chan<int>) {
+fn a(c: ::core::oldcomm::Chan<int>) {
     debug!("task a0");
     debug!("task a1");
-    core::oldcomm::send(c, 10);
+    ::core::oldcomm::send(c, 10);
 }
 
 fn main() {
-    let p = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&p);
+    let p = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&p);
     task::spawn(|| a(ch) );
     task::spawn(|| b(ch) );
     let mut n: int = 0;
-    n = core::oldcomm::recv(p);
-    n = core::oldcomm::recv(p);
+    n = ::core::oldcomm::recv(p);
+    n = ::core::oldcomm::recv(p);
     debug!("Finished.");
 }
 
-fn b(c: core::oldcomm::Chan<int>) {
+fn b(c: ::core::oldcomm::Chan<int>) {
     debug!("task b0");
     debug!("task b1");
     debug!("task b2");
     debug!("task b2");
     debug!("task b3");
-    core::oldcomm::send(c, 10);
+    ::core::oldcomm::send(c, 10);
 }
index a84bfdcdbb7ee4c8acd585357f6753534ccc9fec..ac029b63eef4075d344c886dc796aafa7ccd54f9 100644 (file)
@@ -10,7 +10,7 @@
 // except according to those terms.
 
 
-fn a(c: core::oldcomm::Chan<int>) {
+fn a(c: ::core::oldcomm::Chan<int>) {
     if true {
         debug!("task a");
         debug!("task a");
@@ -18,7 +18,7 @@ fn a(c: core::oldcomm::Chan<int>) {
         debug!("task a");
         debug!("task a");
     }
-    core::oldcomm::send(c, 10);
+    ::core::oldcomm::send(c, 10);
 }
 
 fn k(x: int) -> int { return 15; }
@@ -34,18 +34,18 @@ fn main() {
     let mut n: int = 2 + 3 * 7;
     let s: ~str = ~"hello there";
     let p = oldcomm::Port();
-    let ch = core::oldcomm::Chan(&p);
+    let ch = ::core::oldcomm::Chan(&p);
     task::spawn(|| a(ch) );
     task::spawn(|| b(ch) );
     let mut x: int = 10;
     x = g(n, s);
     log(debug, x);
-    n = core::oldcomm::recv(p);
-    n = core::oldcomm::recv(p);
+    n = ::core::oldcomm::recv(p);
+    n = ::core::oldcomm::recv(p);
     debug!("children finished, root finishing");
 }
 
-fn b(c: core::oldcomm::Chan<int>) {
+fn b(c: ::core::oldcomm::Chan<int>) {
     if true {
         debug!("task b");
         debug!("task b");
@@ -54,5 +54,5 @@ fn b(c: core::oldcomm::Chan<int>) {
         debug!("task b");
         debug!("task b");
     }
-    core::oldcomm::send(c, 10);
+    ::core::oldcomm::send(c, 10);
 }
index 72299e2b329c1e52878f8f40c6cb6a012a8b4176..04cc55b22640c865ee76dfd82b8dbc1508df2671 100644 (file)
@@ -63,9 +63,9 @@ fn test_box() {
 }
 
 fn test_ptr() unsafe {
-    let p1: *u8 = core::cast::reinterpret_cast(&0);
-    let p2: *u8 = core::cast::reinterpret_cast(&0);
-    let p3: *u8 = core::cast::reinterpret_cast(&1);
+    let p1: *u8 = ::core::cast::reinterpret_cast(&0);
+    let p2: *u8 = ::core::cast::reinterpret_cast(&0);
+    let p3: *u8 = ::core::cast::reinterpret_cast(&1);
 
     assert p1 == p2;
     assert p1 != p3;
@@ -110,8 +110,8 @@ fn test_class() {
   
   unsafe {
   error!("q = %x, r = %x",
-         (core::cast::reinterpret_cast::<*p, uint>(&ptr::addr_of(&q))),
-         (core::cast::reinterpret_cast::<*p, uint>(&ptr::addr_of(&r))));
+         (::core::cast::reinterpret_cast::<*p, uint>(&ptr::addr_of(&q))),
+         (::core::cast::reinterpret_cast::<*p, uint>(&ptr::addr_of(&r))));
   }
   assert(q == r);
   r.y = 17;
index 8f9049ac27b2baa7c8f6186ab83c891b75d68d3a..893912d5c05897a159619cbb2865644dca1f8740 100644 (file)
@@ -24,9 +24,9 @@
 // course preferable, as the value itself is
 // irrelevant).
 
-fn foo(&&x: ()) -> core::oldcomm::Port<()> {
-    let p = core::oldcomm::Port();
-    let c = core::oldcomm::Chan(&p);
+fn foo(&&x: ()) -> ::core::oldcomm::Port<()> {
+    let p = ::core::oldcomm::Port();
+    let c = ::core::oldcomm::Chan(&p);
     do task::spawn() |copy c, copy x| {
         c.send(x);
     }
index be64fcd8992fade591095fa24403042d740af9ca..a439d2af8fc020a715e7179d97f458d5c20db355 100644 (file)
@@ -18,7 +18,7 @@
 
 extern mod cci_capture_clause;
 
-use oldcomm::recv;
+use core::oldcomm::recv;
 
 fn main() {
     cci_capture_clause::foo(()).recv()
index bb429a07f39dbc5ea0b9bdf777b8402cf735aac7..43825b03c296d8c9e139597a6a09f62a091d9557 100644 (file)
 
 // Issue #763
 
-enum request { quit, close(core::oldcomm::Chan<bool>), }
+enum request { quit, close(::core::oldcomm::Chan<bool>), }
 
-type ctx = core::oldcomm::Chan<request>;
+type ctx = ::core::oldcomm::Chan<request>;
 
-fn request_task(c: core::oldcomm::Chan<ctx>) {
-    let p = core::oldcomm::Port();
-    core::oldcomm::send(c, core::oldcomm::Chan(&p));
+fn request_task(c: ::core::oldcomm::Chan<ctx>) {
+    let p = ::core::oldcomm::Port();
+    ::core::oldcomm::send(c, ::core::oldcomm::Chan(&p));
     let mut req: request;
-    req = core::oldcomm::recv(p);
+    req = ::core::oldcomm::recv(p);
     // Need to drop req before receiving it again
-    req = core::oldcomm::recv(p);
+    req = ::core::oldcomm::recv(p);
 }
 
 fn new_cx() -> ctx {
-    let p = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&p);
+    let p = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&p);
     let t = task::spawn(|| request_task(ch) );
     let mut cx: ctx;
-    cx = core::oldcomm::recv(p);
+    cx = ::core::oldcomm::recv(p);
     return cx;
 }
 
 fn main() {
     let cx = new_cx();
 
-    let p = core::oldcomm::Port::<bool>();
-    core::oldcomm::send(cx, close(core::oldcomm::Chan(&p)));
-    core::oldcomm::send(cx, quit);
+    let p = ::core::oldcomm::Port::<bool>();
+    ::core::oldcomm::send(cx, close(::core::oldcomm::Chan(&p)));
+    ::core::oldcomm::send(cx, quit);
 }
index f84332a6382b59e930b71e249619466b6c5575f7..5d53453ffc00564c11bd740c41879c09a62b2737 100644 (file)
@@ -11,7 +11,7 @@
 // xfail-fast
 // aux-build:cci_class_cast.rs
 extern mod cci_class_cast;
-use to_str::ToStr;
+use core::to_str::ToStr;
 use cci_class_cast::kitty::*;
 
 fn print_out<T: ToStr>(thing: T, expected: ~str) {
index 23c1e6792a4150c992cca43e4057f57c7ec3dde2..eb3728f2c6fc3cdbf1d17079883567c459896f32 100644 (file)
@@ -9,8 +9,7 @@
 // except according to those terms.
 
 // xfail-fast
-use to_str::*;
-use to_str::ToStr;
+use core::to_str::*;
 
 struct cat {
   priv mut meows : uint,
index a0b55a1ea8d458e8247e17f1e6be182b18398820..a2a97f531deb64fa2117c6ddecc0622b833d9bb0 100644 (file)
@@ -16,7 +16,7 @@
     a: A, b: B
 };
 
-fn f<A:Copy Durable>(a: A, b: u16) -> fn@() -> (A, u16) {
+fn f<A:Copy &static>(a: A, b: u16) -> fn@() -> (A, u16) {
     fn@() -> (A, u16) { (a, b) }
 }
 
index 90cd3397c80e54a8171b62c06f93f1c4a0b4d9e8..e014ffe4bef4786e0650ce28faa8175b77a94d6f 100644 (file)
@@ -10,7 +10,7 @@
 
 fn main() {
     enum x { foo }
-    impl x : core::cmp::Eq {
+    impl x : ::core::cmp::Eq {
         pure fn eq(&self, other: &x) -> bool {
             (*self) as int == (*other) as int
         }
index 453ae679523191f378ef8d9e296179bd65f786d7..7a79d2360684d02f29be5d060458b252db5ac483 100644 (file)
 
 fn main() {
     let p = oldcomm::Port();
-    let ch = core::oldcomm::Chan(&p);
+    let ch = ::core::oldcomm::Chan(&p);
     let t = task::spawn(|| child(ch) );
-    let y = core::oldcomm::recv(p);
+    let y = ::core::oldcomm::recv(p);
     error!("received");
     log(error, y);
     assert (y == 10);
 }
 
-fn child(c: core::oldcomm::Chan<int>) {
+fn child(c: ::core::oldcomm::Chan<int>) {
     error!("sending");
-    core::oldcomm::send(c, 10);
+    ::core::oldcomm::send(c, 10);
     error!("value sent");
 }
diff --git a/src/test/run-pass/const-big-enum.rs b/src/test/run-pass/const-big-enum.rs
new file mode 100644 (file)
index 0000000..aa977f1
--- /dev/null
@@ -0,0 +1,38 @@
+// 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.
+
+enum Foo {
+    Bar(u32),
+    Baz,
+    Quux(u64, u16)
+}
+
+const X: Foo = Baz;
+
+fn main() {
+    match X {
+        Baz => {}
+        _ => fail
+    }
+    match Y {
+        Bar(s) => assert(s == 2654435769),
+        _ => fail
+    }
+    match Z {
+        Quux(d,h) => {
+            assert(d == 0x123456789abcdef0);
+            assert(h == 0x1234);
+        }
+        _ => fail
+    }
+}
+
+const Y: Foo = Bar(2654435769);
+const Z: Foo = Quux(0x123456789abcdef0, 0x1234);
diff --git a/src/test/run-pass/const-enum-byref-self.rs b/src/test/run-pass/const-enum-byref-self.rs
new file mode 100644 (file)
index 0000000..cd939bc
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum E { V, VV(int) }
+const C: E = V;
+
+impl E {
+    fn method(&self) {
+        match *self {
+            V => {}
+            VV(*) => fail
+        }
+    }
+}
+
+fn main() {
+    C.method()
+}
diff --git a/src/test/run-pass/const-enum-byref.rs b/src/test/run-pass/const-enum-byref.rs
new file mode 100644 (file)
index 0000000..8ee9e79
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum E { V, VV(int) }
+const C: E = V;
+
+fn f(a: &E) {
+    match *a {
+        V => {}
+        VV(*) => fail
+    }
+}
+
+fn main() {
+    f(&C)
+}
diff --git a/src/test/run-pass/const-newtype-enum.rs b/src/test/run-pass/const-newtype-enum.rs
new file mode 100644 (file)
index 0000000..069565a
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+enum Foo = u32;
+
+const X: Foo = Foo(17);
+
+fn main() {
+    assert(*X == 17);
+    assert(*Y == 23);
+}
+
+const Y: Foo = Foo(23);
index abdddfe1c62c2eea6773ff7647db1bbefc055891..098305bbe35e0a15f2a7aed74e2221592c296856 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// 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.
 //
@@ -21,5 +21,10 @@ fn main() {
         Bar => {}
         Baz | Boo => fail
     }
+    match Y {
+        Baz => {}
+        Bar | Boo => fail
+    }
 }
 
+const Y: Foo = Baz;
diff --git a/src/test/run-pass/const-nullary-univariant-enum.rs b/src/test/run-pass/const-nullary-univariant-enum.rs
new file mode 100644 (file)
index 0000000..2fa5a77
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum Foo {
+    Bar = 0xDEADBEE
+}
+
+const X: Foo = Bar;
+
+fn main() {
+    assert((X as uint) == 0xDEADBEE);
+    assert((Y as uint) == 0xDEADBEE);
+}
+
+const Y: Foo = Bar;
index a78ca37172b28d94220033adf2787f614536786d..9b080206fcdea58ea12380e3e450c52e26413825 100644 (file)
@@ -14,5 +14,5 @@ fn main() {
 
     let digits: uint = 10 as uint;
 
-    core::io::println(float::to_str(f64::sqrt(42.0f64) as float, digits));
+    ::core::io::println(float::to_str(f64::sqrt(42.0f64) as float, digits));
 }
index 4b4d6a86806d1bc7e812efa75bce5a0f4dda175c..a3679f71a6b1bb7a3096daa1b234e7336bc48a28 100644 (file)
 
 
 fn main() {
-    let po = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&po);
-    core::oldcomm::send(ch, 10);
-    let i = core::oldcomm::recv(po);
+    let po = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&po);
+    ::core::oldcomm::send(ch, 10);
+    let i = ::core::oldcomm::recv(po);
     assert (i == 10);
-    core::oldcomm::send(ch, 11);
-    let j = core::oldcomm::recv(po);
+    ::core::oldcomm::send(ch, 11);
+    let j = ::core::oldcomm::recv(po);
     assert (j == 11);
 }
index 1f29a08a804682a4788fc2f954daf965b21cbf06..849ad64270de9b80b40c2b0590bb8d8d27570c7a 100644 (file)
@@ -1,3 +1,5 @@
+// xfail-fast
+
 // 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.
index a71d51cf21c0da9271a406e265bded7d45316fb4..5855b1a530ba3ef362abe3545dd08fd8f4927cde 100644 (file)
@@ -1,3 +1,5 @@
+// xfail-fast
+
 // 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.
index c0501a09207408d72b0e80089b51748bd077beb9..b1b196e6986a43d77a880e0d44996e0c3a97a9a1 100644 (file)
@@ -1,3 +1,5 @@
+// xfail-fast
+
 // 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.
index 4906f0e70b96eb0d62f68095ed11db9dec359bc6..238f3b8b587a3e5f890aafe70cbfb72dcaa8267a 100644 (file)
@@ -12,7 +12,7 @@ struct S<T> {
     x: T
 }
 
-impl<T> S<T> : core::ops::Drop {
+impl<T> S<T> : ::core::ops::Drop {
     fn finalize(&self) {
         io::println("bye");
     }
diff --git a/src/test/run-pass/enum-variants.rs b/src/test/run-pass/enum-variants.rs
new file mode 100644 (file)
index 0000000..26fae68
--- /dev/null
@@ -0,0 +1,11 @@
+enum Animal {
+    Dog (~str, float),
+    Cat { name: ~str, weight: float }
+}
+
+fn main() {
+    let mut a: Animal = Dog(~"Cocoa", 37.2);
+    a = Cat{ name: ~"Spotty", weight: 2.7 };
+    // permuting the fields should work too
+    let c = Cat { weight: 3.1, name: ~"Spreckles" };
+}
index 464acfba9344dd473d540869b426b5ceaeb178ca..dae4e15fee0fdf4aa12372bfcfb1e69ca080105b 100644 (file)
@@ -9,16 +9,11 @@
 // except according to those terms.
 
 mod foo {
-    #[legacy_exports];
-
-    export bar;
-
     mod bar {
-        #[legacy_exports];
-        fn y() { x(); }
+        pub fn y() { super::super::foo::x(); }
     }
 
-    fn x() { debug!("x"); }
+    pub fn x() { debug!("x"); }
 }
 
-fn main() { foo::bar::y(); }
+fn main() { self::foo::bar::y(); }
index 85d1a33826c5b03bebe6fe06ce7f0720b643b1ec..5f8a74203e4e8aba2cf11f224a79077257bdf020 100644 (file)
@@ -1,3 +1,5 @@
+// xfail-fast
+
 // 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.
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-mod foo {
-    #[legacy_exports];
-    export x;
-
-    fn x() { bar::x(); }
+pub mod foo {
+    pub fn x() { ::bar::x(); }
 }
 
-mod bar {
-    #[legacy_exports];
-    export x;
-
-    fn x() { debug!("x"); }
+pub mod bar {
+    pub fn x() { debug!("x"); }
 }
 
 fn main() { foo::x(); }
index a00afd8c6d969f2330aed7fd68aa58bcb86c5aeb..f01b2b082d00d24ec0ddcf98491ec1ecfc3ad191 100644 (file)
 // xfail-fast
 #[legacy_modes];
 
-fn fix_help<A: Durable, B: Owned>(f: extern fn(fn@(A) -> B, A) -> B, x: A) -> B {
+fn fix_help<A: &static, B: Owned>(f: extern fn(fn@(A) -> B, A) -> B, x: A) -> B {
     return f({|a|fix_help(f, a)}, x);
 }
 
-fn fix<A: Durable, B: Owned>(f: extern fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
+fn fix<A: &static, B: Owned>(f: extern fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
     return {|a|fix_help(f, a)};
 }
 
index 47f4f122f93f6bb821307b7f827116b92b4fd6ea..0e7d90e2fd81f4b684d07724dcdb12461e18a667 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type r = {
+struct r {
     field: fn@()
-};
+}
 
 fn main() {
     fn f() {}
-    let i: r = {field: f};
+    let i: r = {field: f};
 }
\ No newline at end of file
index 4b7b762f4d17c45e6efa5f047bbd2cd3d6d15cb5..0018a1d62f68644fdbae688051509efdab47dcac 100644 (file)
@@ -23,7 +23,7 @@
 extern mod libc {
     #[legacy_exports];
     fn write(fd: int, buf: *u8,
-             count: core::libc::size_t) -> core::libc::ssize_t;
+             count: ::core::libc::size_t) -> ::core::libc::ssize_t;
 }
 
 #[abi = "cdecl"]
index c8fbb0dd7418ba0a36ef61c4bc814ce7bd392c53..6232f0c6e06d8d1fe958a8c002f6e7edd6e72c84 100644 (file)
 
 use std::map;
 use std::map::HashMap;
-use oldcomm::Chan;
-use oldcomm::Port;
-use oldcomm::send;
-use oldcomm::recv;
+use core::oldcomm::Chan;
+use core::oldcomm::Port;
+use core::oldcomm::send;
+use core::oldcomm::recv;
 
-fn map(filename: ~str, emit: map_reduce::putter) { emit(filename, ~"1"); }
+pub fn map(filename: ~str, emit: map_reduce::putter) { emit(filename, ~"1"); }
 
 mod map_reduce {
-    #[legacy_exports];
-    export putter;
-    export mapper;
-    export map_reduce;
+    use std::map;
+    use std::map::HashMap;
+    use core::oldcomm::Chan;
+    use core::oldcomm::Port;
+    use core::oldcomm::send;
+    use core::oldcomm::recv;
 
-    type putter = fn@(~str, ~str);
+    pub type putter = fn@(~str, ~str);
 
-    type mapper = extern fn(~str, putter);
+    pub type mapper = extern fn(~str, putter);
 
     enum ctrl_proto { find_reducer(~[u8], Chan<int>), mapper_done, }
 
@@ -66,11 +68,11 @@ fn emit(im: map::HashMap<~str, int>, ctrl: Chan<ctrl_proto>, key: ~str,
             }
         }
 
-        map(input, |a,b| emit(intermediates, ctrl, a, b) );
+        ::map(input, |a,b| emit(intermediates, ctrl, a, b) );
         send(ctrl, mapper_done);
     }
 
-    fn map_reduce(inputs: ~[~str]) {
+    pub fn map_reduce(inputs: ~[~str]) {
         let ctrl = Port();
 
         // This task becomes the master control task. It spawns others
index 0d3d08b3a39ac466a760cdd4b0674e79bf2c7de9..eba69134c4f0a280dce9e84d0d5c0ec114a7fd60 100644 (file)
@@ -12,7 +12,7 @@
 
 
 extern mod std;
-use vec::*;
+use core::vec::*;
 
 fn main() {
     let mut v = from_elem(0u, 0);
index 6239df9827845a433015b3649666c9b67e43442a..01da68ec3426fd97a10bf1c7fea4ed0e3b78376c 100644 (file)
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
 mod m {
-    #[legacy_exports];
     #[cfg(target_arch = "x86")]
-    fn main() {
-        assert rusti::pref_align_of::<u64>() == 8u;
-        assert rusti::min_align_of::<u64>() == 4u;
+    pub fn main() {
+        assert ::rusti::pref_align_of::<u64>() == 8u;
+        assert ::rusti::min_align_of::<u64>() == 4u;
     }
 
     #[cfg(target_arch = "x86_64")]
-    fn main() {
-        assert rusti::pref_align_of::<u64>() == 8u;
-        assert rusti::min_align_of::<u64>() == 8u;
+    pub fn main() {
+        assert ::rusti::pref_align_of::<u64>() == 8u;
+        assert ::rusti::min_align_of::<u64>() == 8u;
     }
 }
 
 #[cfg(target_os = "win32")]
 mod m {
-    #[legacy_exports];
     #[cfg(target_arch = "x86")]
-    fn main() {
-        assert rusti::pref_align_of::<u64>() == 8u;
-        assert rusti::min_align_of::<u64>() == 8u;
+    pub fn main() {
+        assert ::rusti::pref_align_of::<u64>() == 8u;
+        assert ::rusti::min_align_of::<u64>() == 8u;
     }
 }
index 653e84ea347cf03ac762f15a6bea7187707c50ac..4b48e9a49c2ac6858890d02ed2e54b6d0a200650 100644 (file)
@@ -13,7 +13,7 @@
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     #[legacy_exports];
-    fn frame_address(f: fn(*u8));
+    fn frame_address(f: &once fn(*u8));
 }
 
 fn main() {
index 588cc496b28215fe6880bfed1eb342ac36138997..feddd0ab9cbc81f8a6c74df1e343e0d9fffe7ab1 100644 (file)
     fn cttz16(x: i16) -> i16;
     fn cttz32(x: i32) -> i32;
     fn cttz64(x: i64) -> i64;
+
+    fn bswap16(x: i16) -> i16;
+    fn bswap32(x: i32) -> i32;
+    fn bswap64(x: i64) -> i64;
 }
 
 fn main() {
@@ -109,4 +113,8 @@ fn main() {
     assert(cttz32(-1i32) == 0i32);
     assert(cttz64(-1i64) == 0i64);
 
+    assert(bswap16(0x0A0Bi16) == 0x0B0Ai16);
+    assert(bswap32(0x0ABBCC0Di32) == 0x0DCCBB0Ai32);
+    assert(bswap64(0x0122334455667708i64) == 0x0877665544332201i64);
+
 }
index b87b3d3aa0d0f984cf4aab49cb0dea4b07442a0c..15d809e8208b35339dd9416642753efae2e582df 100644 (file)
@@ -12,7 +12,7 @@ fn plus_one(f: fn() -> int) -> int {
   return f() + 1;
 }
 
-fn ret_plus_one() -> fn(fn() -> int) -> int {
+fn ret_plus_one() -> extern fn(fn() -> int) -> int {
   return plus_one;
 }
 
index 05c2595931eb1d2ce08b263fc3327a89f6e0a53d..efa6d05f9da767f460fdde69801685d6eef9055b 100644 (file)
@@ -10,8 +10,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use libc::{c_double, c_int};
-use f64::*;
+use core::cast;
+use core::libc::{c_double, c_int};
+use core::f64::*;
 
 fn to_c_int(v: &mut int) -> &mut c_int unsafe {
     cast::reinterpret_cast(&v)
@@ -24,13 +25,12 @@ fn lgamma(n: c_double, value: &mut int) -> c_double {
 #[link_name = "m"]
 #[abi = "cdecl"]
 extern mod m {
-    #[legacy_exports];
     #[cfg(unix)]
-    #[link_name="lgamma_r"] fn lgamma(n: c_double, sign: &mut c_int)
+    #[link_name="lgamma_r"] pub fn lgamma(n: c_double, sign: &mut c_int)
       -> c_double;
     #[cfg(windows)]
-    #[link_name="__lgamma_r"] fn lgamma(n: c_double,
-                                        sign: &mut c_int) -> c_double;
+    #[link_name="__lgamma_r"] pub fn lgamma(n: c_double,
+                                            sign: &mut c_int) -> c_double;
 
 }
 
index 632fe348d8d943472a5b3db66e1919e001ed1a69..7c35c9e8cf1ac2364a0eb4b091d625682d72f7d4 100644 (file)
 // except according to those terms.
 
 // tjc: I don't know why
-mod pipes {
-    #[legacy_exports];
-    use cast::{forget, transmute};
+pub mod pipes {
+    use core::cast::{forget, transmute};
 
-    enum state {
+    pub enum state {
         empty,
         full,
         blocked,
         terminated
     }
 
-    impl state : cmp::Eq {
+    pub impl state : cmp::Eq {
         pure fn eq(&self, other: &state) -> bool {
             ((*self) as uint) == ((*other) as uint)
         }
         pure fn ne(&self, other: &state) -> bool { !(*self).eq(other) }
     }
 
-    type packet<T: Owned> = {
+    pub type packet<T: Owned> = {
         mut state: state,
         mut blocked_task: Option<task::Task>,
         mut payload: Option<T>
     };
 
-    fn packet<T: Owned>() -> *packet<T> unsafe {
+    pub fn packet<T: Owned>() -> *packet<T> unsafe {
         let p: *packet<T> = cast::transmute(~{
             mut state: empty,
             mut blocked_task: None::<task::Task>,
@@ -46,31 +45,30 @@ fn packet<T: Owned>() -> *packet<T> unsafe {
 
     #[abi = "rust-intrinsic"]
     mod rusti {
-        #[legacy_exports];
-      fn atomic_xchg(_dst: &mut int, _src: int) -> int { fail; }
-      fn atomic_xchg_acq(_dst: &mut int, _src: int) -> int { fail; }
-      fn atomic_xchg_rel(_dst: &mut int, _src: int) -> int { fail; }
+      pub fn atomic_xchg(_dst: &mut int, _src: int) -> int { fail; }
+      pub fn atomic_xchg_acq(_dst: &mut int, _src: int) -> int { fail; }
+      pub fn atomic_xchg_rel(_dst: &mut int, _src: int) -> int { fail; }
     }
 
-    // We should consider moving this to core::unsafe, although I
+    // We should consider moving this to ::core::unsafe, although I
     // suspect graydon would want us to use void pointers instead.
-    unsafe fn uniquify<T>(+x: *T) -> ~T {
+    pub unsafe fn uniquify<T>(+x: *T) -> ~T {
         unsafe { cast::transmute(move x) }
     }
 
-    fn swap_state_acq(+dst: &mut state, src: state) -> state {
+    pub fn swap_state_acq(+dst: &mut state, src: state) -> state {
         unsafe {
             transmute(rusti::atomic_xchg_acq(transmute(move dst), src as int))
         }
     }
 
-    fn swap_state_rel(+dst: &mut state, src: state) -> state {
+    pub fn swap_state_rel(+dst: &mut state, src: state) -> state {
         unsafe {
             transmute(rusti::atomic_xchg_rel(transmute(move dst), src as int))
         }
     }
 
-    fn send<T: Owned>(-p: send_packet<T>, -payload: T) {
+    pub fn send<T: Owned>(-p: send_packet<T>, -payload: T) {
         let p = p.unwrap();
         let p = unsafe { uniquify(p) };
         assert (*p).payload.is_none();
@@ -96,7 +94,7 @@ fn send<T: Owned>(-p: send_packet<T>, -payload: T) {
         }
     }
 
-    fn recv<T: Owned>(-p: recv_packet<T>) -> Option<T> {
+    pub fn recv<T: Owned>(-p: recv_packet<T>) -> Option<T> {
         let p = p.unwrap();
         let p = unsafe { uniquify(p) };
         loop {
@@ -117,7 +115,7 @@ fn recv<T: Owned>(-p: recv_packet<T>) -> Option<T> {
         }
     }
 
-    fn sender_terminate<T: Owned>(p: *packet<T>) {
+    pub fn sender_terminate<T: Owned>(p: *packet<T>) {
         let p = unsafe { uniquify(p) };
         match swap_state_rel(&mut (*p).state, terminated) {
           empty | blocked => {
@@ -134,7 +132,7 @@ fn sender_terminate<T: Owned>(p: *packet<T>) {
         }
     }
 
-    fn receiver_terminate<T: Owned>(p: *packet<T>) {
+    pub fn receiver_terminate<T: Owned>(p: *packet<T>) {
         let p = unsafe { uniquify(p) };
         match swap_state_rel(&mut (*p).state, terminated) {
           empty => {
@@ -151,11 +149,11 @@ fn receiver_terminate<T: Owned>(p: *packet<T>) {
         }
     }
 
-    struct send_packet<T: Owned> {
+    pub struct send_packet<T: Owned> {
         mut p: Option<*packet<T>>,
     }
 
-    impl<T: Owned> send_packet<T> : Drop {
+    pub impl<T: Owned> send_packet<T> : Drop {
         fn finalize(&self) {
             if self.p != None {
                 let mut p = None;
@@ -165,7 +163,7 @@ fn finalize(&self) {
         }
     }
 
-    impl<T: Owned> send_packet<T> {
+    pub impl<T: Owned> send_packet<T> {
         fn unwrap() -> *packet<T> {
             let mut p = None;
             p <-> self.p;
@@ -173,17 +171,17 @@ fn unwrap() -> *packet<T> {
         }
     }
 
-    fn send_packet<T: Owned>(p: *packet<T>) -> send_packet<T> {
+    pub fn send_packet<T: Owned>(p: *packet<T>) -> send_packet<T> {
         send_packet {
             p: Some(p)
         }
     }
 
-    struct recv_packet<T: Owned> {
+    pub struct recv_packet<T: Owned> {
         mut p: Option<*packet<T>>,
     }
 
-    impl<T: Owned> recv_packet<T> : Drop {
+    pub impl<T: Owned> recv_packet<T> : Drop {
         fn finalize(&self) {
             if self.p != None {
                 let mut p = None;
@@ -193,7 +191,7 @@ fn finalize(&self) {
         }
     }
 
-    impl<T: Owned> recv_packet<T> {
+    pub impl<T: Owned> recv_packet<T> {
         fn unwrap() -> *packet<T> {
             let mut p = None;
             p <-> self.p;
@@ -201,25 +199,27 @@ fn unwrap() -> *packet<T> {
         }
     }
 
-    fn recv_packet<T: Owned>(p: *packet<T>) -> recv_packet<T> {
+    pub fn recv_packet<T: Owned>(p: *packet<T>) -> recv_packet<T> {
         recv_packet {
             p: Some(p)
         }
     }
 
-    fn entangle<T: Owned>() -> (send_packet<T>, recv_packet<T>) {
+    pub fn entangle<T: Owned>() -> (send_packet<T>, recv_packet<T>) {
         let p = packet();
         (send_packet(p), recv_packet(p))
     }
 }
 
-mod pingpong {
-    #[legacy_exports];
-    enum ping = pipes::send_packet<pong>;
-    enum pong = pipes::send_packet<ping>;
+pub mod pingpong {
+    use core::cast;
+    use core::ptr;
 
-    fn liberate_ping(-p: ping) -> pipes::send_packet<pong> unsafe {
-        let addr : *pipes::send_packet<pong> = match &p {
+    pub enum ping = ::pipes::send_packet<pong>;
+    pub enum pong = ::pipes::send_packet<ping>;
+
+    pub fn liberate_ping(-p: ping) -> ::pipes::send_packet<pong> unsafe {
+        let addr : *::pipes::send_packet<pong> = match &p {
           &ping(ref x) => { cast::transmute(ptr::addr_of(x)) }
         };
         let liberated_value = move *addr;
@@ -227,8 +227,8 @@ fn liberate_ping(-p: ping) -> pipes::send_packet<pong> unsafe {
         move liberated_value
     }
 
-    fn liberate_pong(-p: pong) -> pipes::send_packet<ping> unsafe {
-        let addr : *pipes::send_packet<ping> = match &p {
+    pub fn liberate_pong(-p: pong) -> ::pipes::send_packet<ping> unsafe {
+        let addr : *::pipes::send_packet<ping> = match &p {
           &pong(ref x) => { cast::transmute(ptr::addr_of(x)) }
         };
         let liberated_value = move *addr;
@@ -236,47 +236,50 @@ fn liberate_pong(-p: pong) -> pipes::send_packet<ping> unsafe {
         move liberated_value
     }
 
-    fn init() -> (client::ping, server::ping) {
-        pipes::entangle()
+    pub fn init() -> (client::ping, server::ping) {
+        ::pipes::entangle()
     }
 
-    mod client {
-        #[legacy_exports];
-        type ping = pipes::send_packet<pingpong::ping>;
-        type pong = pipes::recv_packet<pingpong::pong>;
+    pub mod client {
+        use core::option;
+        use pingpong;
+
+        pub type ping = ::pipes::send_packet<pingpong::ping>;
+        pub type pong = ::pipes::recv_packet<pingpong::pong>;
 
-        fn do_ping(-c: ping) -> pong {
-            let (sp, rp) = pipes::entangle();
+        pub fn do_ping(-c: ping) -> pong {
+            let (sp, rp) = ::pipes::entangle();
 
-            pipes::send(move c, ping(move sp));
+            ::pipes::send(move c, pingpong::ping(move sp));
             move rp
         }
 
-        fn do_pong(-c: pong) -> (ping, ()) {
-            let packet = pipes::recv(move c);
+        pub fn do_pong(-c: pong) -> (ping, ()) {
+            let packet = ::pipes::recv(move c);
             if packet.is_none() {
                 fail ~"sender closed the connection"
             }
-            (liberate_pong(option::unwrap(move packet)), ())
+            (pingpong::liberate_pong(option::unwrap(move packet)), ())
         }
     }
 
-    mod server {
-        #[legacy_exports];
-        type ping = pipes::recv_packet<pingpong::ping>;
-        type pong = pipes::send_packet<pingpong::pong>;
+    pub mod server {
+        use pingpong;
+
+        pub type ping = ::pipes::recv_packet<pingpong::ping>;
+        pub type pong = ::pipes::send_packet<pingpong::pong>;
 
-        fn do_ping(-c: ping) -> (pong, ()) {
-            let packet = pipes::recv(move c);
+        pub fn do_ping(-c: ping) -> (pong, ()) {
+            let packet = ::pipes::recv(move c);
             if packet.is_none() {
                 fail ~"sender closed the connection"
             }
-            (liberate_ping(option::unwrap(move packet)), ())
+            (pingpong::liberate_ping(option::unwrap(move packet)), ())
         }
 
-        fn do_pong(-c: pong) -> ping {
-            let (sp, rp) = pipes::entangle();
-            pipes::send(move c, pong(move sp));
+        pub fn do_pong(-c: pong) -> ping {
+            let (sp, rp) = ::pipes::entangle();
+            ::pipes::send(move c, pingpong::pong(move sp));
             move rp
         }
     }
index 7156e015473619e0043cc7fb14ea11f84adac032..0ab6c630ac8e11d2bc29bcea4fb5068c89a1d2e5 100644 (file)
@@ -11,7 +11,7 @@
 trait hax { } 
 impl <A> A: hax { } 
 
-fn perform_hax<T: Durable>(x: @T) -> hax {
+fn perform_hax<T: &static>(x: @T) -> hax {
     x as hax 
 }
 
index 360e7b3c241b458436910defdf3f73d2604578f3..675397a0881907de9ca8c8bc91cf23c081faacfd 100644 (file)
@@ -11,7 +11,7 @@
 trait hax { } 
 impl <A> A: hax { } 
 
-fn perform_hax<T: Durable>(x: @T) -> hax {
+fn perform_hax<T: &static>(x: @T) -> hax {
     x as hax 
 }
 
index 33e5e386e390dcd08464542530e992cbeb375bd4..5e66d2c7c1909c6de1e5be0c892f08953d8c7274 100644 (file)
@@ -59,7 +59,7 @@ fn square_from_char(c: char) -> square {
     }
 }
 
-fn read_board_grid<rdr: Durable io::Reader>(+in: rdr) -> ~[~[square]] {
+fn read_board_grid<rdr: &static io::Reader>(+in: rdr) -> ~[~[square]] {
     let in = (move in) as io::Reader;
     let mut grid = ~[];
     for in.each_line |line| {
index 406e055884a5de9565c97a4c3d5ce17877b009b6..505b9b65512f2b19991af162d8b930b0598403f6 100755 (executable)
Binary files a/src/test/run-pass/issue-3559 and b/src/test/run-pass/issue-3559 differ
index ee68a546cafedd3353135002b5a4b3746e10c673..da7746681f281d449c9f6b8cfd574e7165c78979 100644 (file)
@@ -12,7 +12,8 @@
 
 // rustc --test map_to_str.rs && ./map_to_str
 extern mod std;
-use io::{WriterUtil};
+
+use core::io::{WriterUtil};
 use std::map::*;
 
 #[cfg(test)]
diff --git a/src/test/run-pass/issue-3563-2.rs b/src/test/run-pass/issue-3563-2.rs
new file mode 100644 (file)
index 0000000..aa4598f
--- /dev/null
@@ -0,0 +1,22 @@
+// 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(default_methods)]
+trait Canvas {
+    fn add_point(point: &int);
+    fn add_points(shapes: &[int]) {
+        for shapes.each |pt| {
+            self.add_point(pt)
+        }
+    }
+
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs
new file mode 100644 (file)
index 0000000..4517ce7
--- /dev/null
@@ -0,0 +1,212 @@
+// 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.
+
+// ASCII art shape renderer.
+// Demonstrates traits, impls, operator overloading, non-copyable struct, unit testing.
+// To run execute: rustc --test shapes.rs && ./shapes
+
+// Rust's core library is tightly bound to the language itself so it is automatically linked in.
+// However the std library is designed to be optional (for code that must run on constrained
+//  environments like embedded devices or special environments like kernel code) so it must
+// be explicitly linked in.
+extern mod std;
+
+// Extern mod controls linkage. Use controls the visibility of names to modules that are
+// already linked in. Using WriterUtil allows us to use the write_line method.
+use io::WriterUtil;
+
+// Represents a position on a canvas.
+struct Point
+{
+    x: int,
+    y: int,
+}
+
+// Represents an offset on a canvas. (This has the same structure as a Point.
+// but different semantics).
+struct Size
+{
+    width: int,
+    height: int,
+}
+
+struct Rect
+{
+    top_left: Point,
+    size: Size,
+}
+
+// TODO: operators
+
+// Contains the information needed to do shape rendering via ASCII art.
+struct AsciiArt
+{
+    width: uint,
+    height: uint,
+    priv fill: char,
+    priv lines: ~[~[mut char]],
+
+    // This struct can be quite large so we'll disable copying: developers need
+    // to either pass these structs around via borrowed pointers or move them.
+    drop {}
+}
+
+// It's common to define a constructor sort of function to create struct instances.
+// If there is a canonical constructor it is typically named the same as the type.
+// Other constructor sort of functions are typically named from_foo, from_bar, etc. 
+fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt
+{
+    // Use an anonymous function to build a vector of vectors containing
+    // blank characters for each position in our canvas.
+    let lines = do vec::build_sized(height)
+        |push|
+        {
+            for height.times
+            {
+                let mut line = ~[];   
+                vec::grow_set(&mut line, width-1, &'.', '.');
+                push(vec::to_mut(line));
+            }
+        };
+
+    // Rust code often returns values by omitting the trailing semi-colon
+    // instead of using an explicit return statement.
+    AsciiArt {width: width, height: height, fill: fill, lines: lines}
+}
+
+// Methods particular to the AsciiArt struct.
+impl AsciiArt
+{
+    fn add_pt(x: int, y: int)
+    {
+        if x >= 0 && x < self.width as int
+        {
+            if y >= 0 && y < self.height as int
+            {
+                // Note that numeric types don't implicitly convert to each other.
+                let v = y as uint;
+                let h = x as uint;
+
+                // Vector subscripting will normally copy the element, but &v[i]
+                // will return a reference which is what we need because the
+                // element is:
+                // 1) potentially large
+                // 2) needs to be modified
+                let row = &self.lines[v];
+                row[h] = self.fill;
+            }
+        }
+    }
+}
+
+// Allows AsciiArt to be converted to a string using the libcore ToStr trait.
+// Note that the %s fmt! specifier will not call this automatically.
+impl AsciiArt : ToStr
+{
+    pure fn to_str() -> ~str
+    {
+        // Convert each line into a string.
+        let lines = do self.lines.map |line| {str::from_chars(*line)};
+
+        // Concatenate the lines together using a new-line.
+        str::connect(lines, "\n")
+    }
+}
+
+// This is similar to an interface in other languages: it defines a protocol which
+// developers can implement for arbitrary concrete types.
+#[allow(default_methods)]
+trait Canvas
+{
+    fn add_point(shape: Point);
+    fn add_rect(shape: Rect);
+
+    // Unlike interfaces traits support default implementations.
+    // Got an ICE as soon as I added this method.
+    fn add_points(shapes: &[Point])
+    {
+        for shapes.each |pt| {self.add_point(*pt)};
+    }
+}
+
+// Here we provide an implementation of the Canvas methods for AsciiArt.
+// Other implementations could also be provided (e.g. for PDF or Apple's Quartz)
+// and code can use them polymorphically via the Canvas trait.
+impl AsciiArt : Canvas
+{
+    fn add_point(shape: Point)
+    {
+        self.add_pt(shape.x, shape.y);
+    }
+
+    fn add_rect(shape: Rect)
+    {
+        // Add the top and bottom lines.
+        for int::range(shape.top_left.x, shape.top_left.x + shape.size.width)
+        |x|
+        {
+            self.add_pt(x, shape.top_left.y);
+            self.add_pt(x, shape.top_left.y + shape.size.height - 1);
+        }
+
+        // Add the left and right lines.
+        for int::range(shape.top_left.y, shape.top_left.y + shape.size.height)
+        |y|
+        {
+            self.add_pt(shape.top_left.x, y);
+            self.add_pt(shape.top_left.x + shape.size.width - 1, y);
+        }
+    }
+}
+
+// Rust's unit testing framework is currently a bit under-developed so we'll use
+// this little helper.
+pub fn check_strs(actual: &str, expected: &str) -> bool
+{
+    if actual != expected
+    {
+        io::stderr().write_line(fmt!("Found:\n%s\nbut expected\n%s", actual, expected));
+        return false;
+    }
+    return true;
+}
+
+
+fn test_ascii_art_ctor()
+{
+    let art = AsciiArt(3, 3, '*');
+    assert check_strs(art.to_str(), "...\n...\n...");
+}
+
+
+fn test_add_pt()
+{
+    let art = AsciiArt(3, 3, '*');
+    art.add_pt(0, 0);
+    art.add_pt(0, -10);
+    art.add_pt(1, 2);
+    assert check_strs(art.to_str(), "*..\n...\n.*.");
+}
+
+
+fn test_shapes()
+{
+    let 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(), "****\n*..*\n*.**\n****");
+}
+
+fn main() {
+    test_ascii_art_ctor();
+    test_add_pt();
+    test_shapes();
+}
+
diff --git a/src/test/run-pass/issue-3563.rs b/src/test/run-pass/issue-3563.rs
deleted file mode 100644 (file)
index 2c390bf..0000000
+++ /dev/null
@@ -1,16 +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.
-
-// xfail-test
-trait A {
-  fn a(&self) {
-    || self.b()
-  }
-}
diff --git a/src/test/run-pass/issue-3609.rs b/src/test/run-pass/issue-3609.rs
new file mode 100644 (file)
index 0000000..9eff98f
--- /dev/null
@@ -0,0 +1,28 @@
+extern mod std;
+
+use pipes::Chan;
+
+type RingBuffer = ~[float];
+type SamplesFn = fn~ (samples: &RingBuffer);
+
+enum Msg
+{
+    GetSamples(~str, SamplesFn), // sample set name, callback which receives samples
+}
+
+fn foo(name: ~str, samples_chan: Chan<Msg>) {
+    do task::spawn
+    |copy name|
+    {
+        let callback: SamplesFn =
+            |buffer|
+            {
+                for uint::range(0, buffer.len())
+                    |i| {error!("%?: %f", i, buffer[i])}
+            };
+        samples_chan.send(GetSamples(copy name, callback));
+    };
+}
+
+fn main() {}
+
index bd79e287098c242daf70bbdb5873f35d08234153..66c2a4672b4b0c8a90a43acbb3cd1da147660217 100644 (file)
@@ -13,7 +13,7 @@
 // Incorrect struct size computation in the FFI, because of not taking
 // the alignment of elements into account.
 
-use libc::*;
+use core::libc::*;
 
 struct KEYGEN {
     hash_algorithm: [c_uint * 2],
diff --git a/src/test/run-pass/issue-3847.rs b/src/test/run-pass/issue-3847.rs
new file mode 100644 (file)
index 0000000..878f6c6
--- /dev/null
@@ -0,0 +1,22 @@
+// 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.
+
+mod buildings {
+    pub struct Tower { height: uint }
+}
+
+fn main() {
+    let sears = buildings::Tower { height: 1451 };
+    let h: uint = match sears {
+        buildings::Tower { height: h } => { h }
+    };
+
+    io::println(h.to_str());
+}
diff --git a/src/test/run-pass/issue-3888.rs b/src/test/run-pass/issue-3888.rs
new file mode 100644 (file)
index 0000000..393659f
--- /dev/null
@@ -0,0 +1,40 @@
+// 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.
+
+// xfail-test
+
+fn vec_peek<T>(v: &r/[T]) -> Option< (&r/T, &r/[T]) > {
+    if v.len() == 0 {
+        None
+    } else {
+        let head = &v[0];
+        let tail = v.view(1, v.len());
+        Some( (head, tail) )
+    }
+}
+
+
+fn test_peek_empty_stack() {
+    let v : &[int] = &[];
+    assert (None == vec_peek(v));
+}
+
+fn test_peek_empty_unique() {
+    let v : ~[int] = ~[];
+    assert (None == vec_peek(v));
+}
+
+fn test_peek_empty_managed() {
+    let v : @[int] = @[];
+    assert (None == vec_peek(v));
+}
+
+
+fn main() {}
diff --git a/src/test/run-pass/issue-3904.rs b/src/test/run-pass/issue-3904.rs
new file mode 100644 (file)
index 0000000..047791a
--- /dev/null
@@ -0,0 +1,37 @@
+// 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.
+
+// xfail-test
+type ErrPrinter = &fn(&str, &str);
+
+fn example_err(prog: &str, arg: &str) {
+    io::println(fmt!("%s: %s", prog, arg))
+}
+
+fn exit(+print: ErrPrinter, prog: &str, arg: &str) {
+    print(prog, arg);
+}
+
+struct X {
+    mut err: ErrPrinter
+}
+
+impl X {
+    fn boom() {
+        exit(self.err, "prog", "arg");
+    }
+}
+
+fn main(){
+    let val = &X{
+        err: example_err,
+    };
+    val.boom();
+}
diff --git a/src/test/run-pass/issue-3935.rs b/src/test/run-pass/issue-3935.rs
new file mode 100644 (file)
index 0000000..2f24018
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+#[deriving_eq]
+struct Bike {
+    name: ~str,
+}
+
+pub fn main() {
+    let town_bike = Bike { name: ~"schwinn" };
+    let my_bike = Bike { name: ~"surly" };
+
+    assert town_bike != my_bike;
+}
index 556e597a86da7c6637433e9c1affc9a306aa0c85..52f202a2deb48497125a9c6c5aebde401f16678b 100644 (file)
    https://github.com/graydon/rust/issues/507
 */
 
-fn grandchild(c: core::oldcomm::Chan<int>) { core::oldcomm::send(c, 42); }
+fn grandchild(c: ::core::oldcomm::Chan<int>) { ::core::oldcomm::send(c, 42); }
 
-fn child(c: core::oldcomm::Chan<int>) {
+fn child(c: ::core::oldcomm::Chan<int>) {
     task::spawn(|| grandchild(c) )
 }
 
 fn main() {
-    let p = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&p);
+    let p = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&p);
 
     task::spawn(|| child(ch) );
 
-    let x: int = core::oldcomm::recv(p);
+    let x: int = ::core::oldcomm::recv(p);
 
     log(debug, x);
 
index 9cfec06007c95fd9715109d054bdab9ff2136b6e..53827bb63fa3cfaeac61d354109cfb658fa77e48 100644 (file)
 
 enum msg { closed, received(~[u8]), }
 
-fn producer(c: core::oldcomm::Chan<~[u8]>) {
-    core::oldcomm::send(c, ~[1u8, 2u8, 3u8, 4u8]);
+fn producer(c: ::core::oldcomm::Chan<~[u8]>) {
+    ::core::oldcomm::send(c, ~[1u8, 2u8, 3u8, 4u8]);
     let empty: ~[u8] = ~[];
-    core::oldcomm::send(c, empty);
+    ::core::oldcomm::send(c, empty);
 }
 
-fn packager(cb: core::oldcomm::Chan<core::oldcomm::Chan<~[u8]>>, msg: core::oldcomm::Chan<msg>) {
-    let p: core::oldcomm::Port<~[u8]> = core::oldcomm::Port();
-    core::oldcomm::send(cb, core::oldcomm::Chan(&p));
+fn packager(cb: ::core::oldcomm::Chan<::core::oldcomm::Chan<~[u8]>>, msg: ::core::oldcomm::Chan<msg>) {
+    let p: ::core::oldcomm::Port<~[u8]> = ::core::oldcomm::Port();
+    ::core::oldcomm::send(cb, ::core::oldcomm::Chan(&p));
     loop {
         debug!("waiting for bytes");
-        let data = core::oldcomm::recv(p);
+        let data = ::core::oldcomm::recv(p);
         debug!("got bytes");
         if vec::len(data) == 0u {
             debug!("got empty bytes, quitting");
@@ -29,26 +29,26 @@ fn packager(cb: core::oldcomm::Chan<core::oldcomm::Chan<~[u8]>>, msg: core::oldc
         }
         debug!("sending non-empty buffer of length");
         log(debug, vec::len(data));
-        core::oldcomm::send(msg, received(data));
+        ::core::oldcomm::send(msg, received(data));
         debug!("sent non-empty buffer");
     }
     debug!("sending closed message");
-    core::oldcomm::send(msg, closed);
+    ::core::oldcomm::send(msg, closed);
     debug!("sent closed message");
 }
 
 fn main() {
-    let p: core::oldcomm::Port<msg> = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&p);
-    let recv_reader: core::oldcomm::Port<core::oldcomm::Chan<~[u8]>> = core::oldcomm::Port();
-    let recv_reader_chan = core::oldcomm::Chan(&recv_reader);
+    let p: ::core::oldcomm::Port<msg> = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&p);
+    let recv_reader: ::core::oldcomm::Port<::core::oldcomm::Chan<~[u8]>> = ::core::oldcomm::Port();
+    let recv_reader_chan = ::core::oldcomm::Chan(&recv_reader);
     let pack = task::spawn(|| packager(recv_reader_chan, ch) );
 
-    let source_chan: core::oldcomm::Chan<~[u8]> = core::oldcomm::recv(recv_reader);
+    let source_chan: ::core::oldcomm::Chan<~[u8]> = ::core::oldcomm::recv(recv_reader);
     let prod = task::spawn(|| producer(source_chan) );
 
     loop {
-        let msg = core::oldcomm::recv(p);
+        let msg = ::core::oldcomm::recv(p);
         match msg {
           closed => { debug!("Got close message"); break; }
           received(data) => {
index 3820ff770227cedbab120a3cc1e9aadee95c48b9..75404c01fc53aa2a605c88f810524c95f0e6cfc1 100644 (file)
 
 fn a() {
     fn doit() {
-        fn b(c: core::oldcomm::Chan<core::oldcomm::Chan<int>>) {
-            let p = core::oldcomm::Port();
-            core::oldcomm::send(c, core::oldcomm::Chan(&p));
+        fn b(c: ::core::oldcomm::Chan<::core::oldcomm::Chan<int>>) {
+            let p = ::core::oldcomm::Port();
+            ::core::oldcomm::send(c, ::core::oldcomm::Chan(&p));
         }
-        let p = core::oldcomm::Port();
-        let ch = core::oldcomm::Chan(&p);
+        let p = ::core::oldcomm::Port();
+        let ch = ::core::oldcomm::Chan(&p);
         task::spawn(|| b(ch) );
-        core::oldcomm::recv(p);
+        ::core::oldcomm::recv(p);
     }
     let mut i = 0;
     while i < 100 {
diff --git a/src/test/run-pass/issue_3882.rs b/src/test/run-pass/issue_3882.rs
new file mode 100644 (file)
index 0000000..b568846
--- /dev/null
@@ -0,0 +1,17 @@
+// xfail-test
+
+// 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:issue_3882.rc
+extern mod linenoise;
+use linenoise::issue_3882::*;
+
+fn main() {}
index 7066b5f63cd60d774fb5caf627b4062ec99e8736..31651ab7c20a63a50b333eee00565a47c9e10ee0 100644 (file)
@@ -1,13 +1,13 @@
-fn producer(c: core::oldcomm::Chan<~[u8]>) {
-    core::oldcomm::send(c,
+fn producer(c: ::core::oldcomm::Chan<~[u8]>) {
+    ::core::oldcomm::send(c,
          ~[1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8,
           13u8]);
 }
 
 fn main() {
-    let p: core::oldcomm::Port<~[u8]> = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&p);
+    let p: ::core::oldcomm::Port<~[u8]> = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&p);
     let prod = task::spawn(|| producer(ch) );
 
-    let data: ~[u8] = core::oldcomm::recv(p);
+    let data: ~[u8] = ::core::oldcomm::recv(p);
 }
index b40778638529b6bdb283c6651ec6bc1627d96187..1dfccac8bce674788cdd4f2d9e5af3da0b01ff72 100644 (file)
@@ -39,6 +39,6 @@ fn main() {
     // Verify that blocks can't interfere with each other.
     fn two_blocks(a: fn(), b: fn()) { a(); b(); a(); b(); }
     let q = ~50;
-    two_blocks(|| { let a = q; assert *a == 50;},
-               || { let a = q; assert *a == 50;});
+    two_blocks(|| { let a = copy q; assert *a == 50;},
+               || { let a = copy q; assert *a == 50;});
 }
index 34244c2ef01cbb7501887764346f6acb91f59dba..4e5ce6cd0915fa7ef6b2939bd91630fc648f03f1 100644 (file)
 // except according to those terms.
 
 fn main() {
-    let p = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&p);
+    let p = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&p);
     let mut y: int;
 
     task::spawn(|| child(ch) );
-    y = core::oldcomm::recv(p);
+    y = ::core::oldcomm::recv(p);
     debug!("received 1");
     log(debug, y);
     assert (y == 10);
 
     task::spawn(|| child(ch) );
-    y = core::oldcomm::recv(p);
+    y = ::core::oldcomm::recv(p);
     debug!("received 2");
     log(debug, y);
     assert (y == 10);
 }
 
-fn child(c: core::oldcomm::Chan<int>) { core::oldcomm::send(c, 10); }
+fn child(c: ::core::oldcomm::Chan<int>) { ::core::oldcomm::send(c, 10); }
index 8abc8236b65610f7f5a13963592a54787de7d05c..210defa578934101bd82fe3912b743dda6e6e9dd 100644 (file)
@@ -43,6 +43,8 @@ fn transform(x: Option<int>) -> Option<~str> {
 fn main() {
     assert transform(Some(10)) == Some(~"11");
     assert transform(None) == None;
-    assert (~[~"hi"]).bind(|x| ~[x, x + ~"!"] ).bind(|x| ~[x, x + ~"?"] ) ==
+    assert (~[~"hi"])
+        .bind(|x| ~[copy x, x + ~"!"] )
+        .bind(|x| ~[copy x, x + ~"?"] ) ==
         ~[~"hi", ~"hi?", ~"hi!", ~"hi!?"];
 }
index 6d0473a7d2c0acaaf66c9b659544034572611e25..13439c6e7e67a7e4a6fce9e60f94483d18939cd3 100644 (file)
@@ -34,6 +34,12 @@ impl Point : ops::Neg<Point> {
     }
 }
 
+impl Point : ops::Not<Point> {
+    pure fn not(&self) -> Point {
+        Point {x: !self.x, y: !self.y }
+    }
+}
+
 impl Point : ops::Index<bool,int> {
     pure fn index(&self, +x: bool) -> int {
         if x { self.x } else { self.y }
@@ -55,6 +61,11 @@ fn main() {
     assert -p == Point {x: -11, y: -22};
     assert p[true] == 11;
     assert p[false] == 22;
+
+    let q = !p;
+    assert q.x == !(p.x);
+    assert q.y == !(p.y);
+
     // Issue #1733
     fn~(_x: int){}(p[true]);
 }
index 487db85ad66bd6331bceaf8fe99bcf6caaf6937d..856057e10ae8327b942111c4601e0b1c7f9cf9f4 100644 (file)
 
 use pipes::try_recv;
 
-type username = ~str;
-type password = ~str;
-type money = float;
-type amount = float;
+pub type username = ~str;
+pub type password = ~str;
+pub type money = float;
+pub type amount = float;
 
 proto! bank (
     login:send {
-        login(username, password) -> login_response
+        login(::username, ::password) -> login_response
     }
 
     login_response:recv {
     }
 
     connected:send {
-        deposit(money) -> connected,
-        withdrawal(amount) -> withdrawal_response
+        deposit(::money) -> connected,
+        withdrawal(::amount) -> withdrawal_response
     }
 
     withdrawal_response:recv {
-        money(money) -> connected,
+        money(::money) -> connected,
         insufficient_funds -> connected
     }
 )
index 8589bbb8e257f06c5a2b9388f0dd34f0072c3e9a..774e3544d891db2a11af4899c3e4eb47d83d36f1 100644 (file)
 // This was generated initially by the pipe compiler, but it's been
 // modified in hopefully straightforward ways.
 mod pingpong {
-    #[legacy_exports];
-    use pipes::*;
+    use core::pipes::*;
+    use core::ptr;
 
-    type packets = {
-        // This is probably a resolve bug, I forgot to export packet,
-        // but since I didn't import pipes::*, it worked anyway.
+    pub type packets = {
         ping: Packet<ping>,
         pong: Packet<pong>,
     };
 
-    fn init() -> (client::ping, server::ping) {
+    pub fn init() -> (client::ping, server::ping) {
         let buffer = ~{
             header: BufferHeader(),
             data: {
@@ -42,50 +40,53 @@ fn init() -> (client::ping, server::ping) {
             ptr::addr_of(&(data.ping))
         }
     }
-    enum ping = server::pong;
-    enum pong = client::ping;
-    mod client {
-        #[legacy_exports];
-        fn ping(+pipe: ping) -> pong {
+    pub enum ping = server::pong;
+    pub enum pong = client::ping;
+    pub mod client {
+        use core::pipes::*;
+        use core::ptr;
+
+        pub fn ping(+pipe: ping) -> pong {
             {
                 let b = pipe.reuse_buffer();
                 let s = SendPacketBuffered(ptr::addr_of(&(b.buffer.data.pong)));
                 let c = RecvPacketBuffered(ptr::addr_of(&(b.buffer.data.pong)));
-                let message = pingpong::ping(move s);
-                pipes::send(move pipe, move message);
+                let message = ::pingpong::ping(move s);
+                ::pipes::send(move pipe, move message);
                 move c
             }
         }
-        type ping = pipes::SendPacketBuffered<pingpong::ping,
-        pingpong::packets>;
-        type pong = pipes::RecvPacketBuffered<pingpong::pong,
-        pingpong::packets>;
+        pub type ping = pipes::SendPacketBuffered<::pingpong::ping,
+                                                  ::pingpong::packets>;
+        pub type pong = pipes::RecvPacketBuffered<::pingpong::pong,
+                                                  ::pingpong::packets>;
     }
-    mod server {
-        #[legacy_exports];
-        type ping = pipes::RecvPacketBuffered<pingpong::ping,
-        pingpong::packets>;
-        fn pong(+pipe: pong) -> ping {
+    pub mod server {
+        use core::pipes::*;
+        use core::ptr;
+
+        pub type ping = pipes::RecvPacketBuffered<::pingpong::ping,
+        ::pingpong::packets>;
+        pub fn pong(+pipe: pong) -> ping {
             {
                 let b = pipe.reuse_buffer();
                 let s = SendPacketBuffered(ptr::addr_of(&(b.buffer.data.ping)));
                 let c = RecvPacketBuffered(ptr::addr_of(&(b.buffer.data.ping)));
-                let message = pingpong::pong(move s);
-                pipes::send(move pipe, move message);
+                let message = ::pingpong::pong(move s);
+                ::pipes::send(move pipe, move message);
                 move c
             }
         }
-        type pong = pipes::SendPacketBuffered<pingpong::pong,
-        pingpong::packets>;
+        pub type pong = pipes::SendPacketBuffered<::pingpong::pong,
+                                                  ::pingpong::packets>;
     }
 }
 
 mod test {
-    #[legacy_exports];
     use pipes::recv;
     use pingpong::{ping, pong};
 
-    fn client(-chan: pingpong::client::ping) {
+    pub fn client(-chan: ::pingpong::client::ping) {
         use pingpong::client;
 
         let chan = client::ping(move chan); return;
@@ -94,7 +95,7 @@ fn client(-chan: pingpong::client::ping) {
         log(error, "Received pong");
     }
     
-    fn server(-chan: pingpong::server::ping) {
+    pub fn server(-chan: ::pingpong::server::ping) {
         use pingpong::server;
 
         let ping(chan) = recv(move chan); return;
@@ -105,7 +106,7 @@ fn server(-chan: pingpong::server::ping) {
 }
 
 fn main() {
-    let (client_, server_) = pingpong::init();
+    let (client_, server_) = ::pingpong::init();
     let client_ = ~mut Some(move client_);
     let server_ = ~mut Some(move server_);
     do task::spawn |move client_| {
index 88db8953b8c333f3ec9567f47bb378eacca7965e..7fb77cba3bde99fea7fb89a46e138d83f81a1bfa 100644 (file)
@@ -12,6 +12,7 @@
 
 // An example to make sure the protocol parsing syntax extension works.
 
+use core::option;
 
 proto! pingpong (
     ping:send {
 )
 
 mod test {
-    #[legacy_exports];
-    use pipes::recv;
+    use core::pipes::recv;
     use pingpong::{ping, pong};
 
-    fn client(-chan: pingpong::client::ping) {
+    pub fn client(-chan: ::pingpong::client::ping) {
         use pingpong::client;
 
         let chan = client::ping(move chan);
@@ -37,7 +37,7 @@ fn client(-chan: pingpong::client::ping) {
         log(error, ~"Received pong");
     }
     
-    fn server(-chan: pingpong::server::ping) {
+    pub fn server(-chan: ::pingpong::server::ping) {
         use pingpong::server;
 
         let ping(chan) = recv(move chan);
index 173325834c068d1f5ff72e228f156eda9f29ea1e..0fe845dd1f934196ed369ba21657f8f32412ab67 100644 (file)
@@ -75,12 +75,12 @@ macro_rules! select (
 )
 
 // Types and protocols
-struct Buffer {
+pub struct Buffer {
     foo: (),
 
 }
 
-impl Buffer : Drop {
+pub impl Buffer : Drop {
     fn finalize(&self) {}
 }
 
@@ -90,11 +90,11 @@ fn finalize(&self) {}
     }
 
     wait_buffer:recv {
-        give_buffer(Buffer) -> release
+        give_buffer(::Buffer) -> release
     }
 
     release:send {
-        release(Buffer) -> acquire
+        release(::Buffer) -> acquire
     }
 )
 
diff --git a/src/test/run-pass/recursion.rs b/src/test/run-pass/recursion.rs
new file mode 100644 (file)
index 0000000..8cc2c8c
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.
+
+// xfail-test
+enum Nil {Nil}
+struct Cons<T> {head:int, tail:T}
+trait Dot {fn dot(other:self) -> int;}
+impl Nil:Dot {
+  fn dot(_:Nil) -> int {0}
+}
+impl<T:Dot> Cons<T>:Dot {
+  fn dot(other:Cons<T>) -> int {
+    self.head * other.head + self.tail.dot(other.tail)
+  }
+}
+fn test<T:Dot> (n:int, i:int, first:T, second:T) ->int {
+  match n {
+    0 => {first.dot(second)}
+      // Error message should be here. It should be a type error
+      // to instantiate `test` at a type other than T. (See #4287)
+    _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
+  }
+}
+fn main() {
+  let n = test(1, 0, Nil, Nil);
+  io::println(fmt!("%d", n));
+}
index cdc23aef9448290e155aee8d24b9e79fc92bd4a7..3e66c18d58b8f77dccf793bdfb8fec7f70b21c88 100644 (file)
@@ -11,6 +11,7 @@
 // xfail-fast
 #[legacy_modes];
 
+use core::bool;
 use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor};
 use libc::c_void;
 use vec::UnboxedVecRepr;
index dca62e0f9dffa6e6a9c72a15308f2a80a25e4920..1ddeee336e3c0d4f65d1e261ba3596f5e9191809 100644 (file)
@@ -13,7 +13,7 @@
 // Regression tests for circular_buffer when using a unit
 // that has a size that is not a power of two
 
-// A 12-byte unit to core::oldcomm::send over the channel
+// A 12-byte unit to ::core::oldcomm::send over the channel
 type record = {val1: u32, val2: u32, val3: u32};
 
 
 // power of two so needs to be rounded up. Don't trigger any
 // assertions.
 fn test_init() {
-    let myport = core::oldcomm::Port();
-    let mychan = core::oldcomm::Chan(&myport);
+    let myport = ::core::oldcomm::Port();
+    let mychan = ::core::oldcomm::Chan(&myport);
     let val: record = {val1: 0u32, val2: 0u32, val3: 0u32};
-    core::oldcomm::send(mychan, val);
+    ::core::oldcomm::send(mychan, val);
 }
 
 
 // Dump lots of items into the channel so it has to grow.
 // Don't trigger any assertions.
 fn test_grow() {
-    let myport = core::oldcomm::Port();
-    let mychan = core::oldcomm::Chan(&myport);
+    let myport = ::core::oldcomm::Port();
+    let mychan = ::core::oldcomm::Chan(&myport);
     for uint::range(0u, 100u) |i| {
         let val: record = {val1: 0u32, val2: 0u32, val3: 0u32};
-        core::oldcomm::send(mychan, val);
+        ::core::oldcomm::send(mychan, val);
     }
 }
 
 
 // Don't allow the buffer to shrink below it's original size
 fn test_shrink1() {
-    let myport = core::oldcomm::Port();
-    let mychan = core::oldcomm::Chan(&myport);
-    core::oldcomm::send(mychan, 0i8);
-    let x = core::oldcomm::recv(myport);
+    let myport = ::core::oldcomm::Port();
+    let mychan = ::core::oldcomm::Chan(&myport);
+    ::core::oldcomm::send(mychan, 0i8);
+    let x = ::core::oldcomm::recv(myport);
 }
 
 fn test_shrink2() {
-    let myport = core::oldcomm::Port();
-    let mychan = core::oldcomm::Chan(&myport);
+    let myport = ::core::oldcomm::Port();
+    let mychan = ::core::oldcomm::Chan(&myport);
     for uint::range(0u, 100u) |_i| {
         let val: record = {val1: 0u32, val2: 0u32, val3: 0u32};
-        core::oldcomm::send(mychan, val);
+        ::core::oldcomm::send(mychan, val);
     }
-    for uint::range(0u, 100u) |_i| { let x = core::oldcomm::recv(myport); }
+    for uint::range(0u, 100u) |_i| { let x = ::core::oldcomm::recv(myport); }
 }
 
 
 // Test rotating the buffer when the unit size is not a power of two
 fn test_rotate() {
-    let myport = core::oldcomm::Port();
-    let mychan = core::oldcomm::Chan(&myport);
+    let myport = ::core::oldcomm::Port();
+    let mychan = ::core::oldcomm::Chan(&myport);
     for uint::range(0u, 100u) |i| {
         let val = {val1: i as u32, val2: i as u32, val3: i as u32};
-        core::oldcomm::send(mychan, val);
-        let x = core::oldcomm::recv(myport);
+        ::core::oldcomm::send(mychan, val);
+        let x = ::core::oldcomm::recv(myport);
         assert (x.val1 == i as u32);
         assert (x.val2 == i as u32);
         assert (x.val3 == i as u32);
@@ -78,16 +78,16 @@ fn test_rotate() {
 // Test rotating and growing the buffer when
 // the unit size is not a power of two
 fn test_rotate_grow() {
-    let myport = core::oldcomm::Port::<record>();
-    let mychan = core::oldcomm::Chan(&myport);
+    let myport = ::core::oldcomm::Port::<record>();
+    let mychan = ::core::oldcomm::Chan(&myport);
     for uint::range(0u, 10u) |j| {
         for uint::range(0u, 10u) |i| {
             let val: record =
                 {val1: i as u32, val2: i as u32, val3: i as u32};
-            core::oldcomm::send(mychan, val);
+            ::core::oldcomm::send(mychan, val);
         }
         for uint::range(0u, 10u) |i| {
-            let x = core::oldcomm::recv(myport);
+            let x = ::core::oldcomm::recv(myport);
             assert (x.val1 == i as u32);
             assert (x.val2 == i as u32);
             assert (x.val3 == i as u32);
diff --git a/src/test/run-pass/self-type-param.rs b/src/test/run-pass/self-type-param.rs
new file mode 100644 (file)
index 0000000..ea42045
--- /dev/null
@@ -0,0 +1,16 @@
+trait MyTrait {
+    fn f(&self) -> Self;
+}
+
+struct S {
+    x: int
+}
+
+impl S : MyTrait {
+    fn f(&self) -> S {
+        S { x: 3 }
+    }
+}
+
+fn main() {}
+
index a85b01acc8eddb6016893f7b242b19d1428bbc7e..39ef99a72b6114a129410f810e79eac2d9a0c472 100644 (file)
@@ -23,12 +23,12 @@ fn test(f: int) -> test {
 }
 
 fn main() {
-    let p = core::oldcomm::Port();
-    let c = core::oldcomm::Chan(&p);
+    let p = ::core::oldcomm::Port();
+    let c = ::core::oldcomm::Chan(&p);
 
     do task::spawn() {
-        let p = core::oldcomm::Port();
-        c.send(core::oldcomm::Chan(&p));
+        let p = ::core::oldcomm::Port();
+        c.send(::core::oldcomm::Chan(&p));
 
         let _r = p.recv();
     }
index 2003a12ea0caff7620365c041f104619c92a6f88..6987dfab1b5a3d159fca9955ea266011f6f31d72 100644 (file)
 // xfail-fast
 #[legacy_modes];
 
-use a::*;
-
-trait plus {
+pub trait plus {
     fn plus() -> int;
 }
 
 mod a {
-    #[legacy_exports];
-    impl uint: plus { fn plus() -> int { self as int + 20 } }
+    use plus;
+    pub impl uint: plus { fn plus() -> int { self as int + 20 } }
 }
 
 mod b {
-    #[legacy_exports];
-    impl ~str: plus { fn plus() -> int { 200 } }
+    use plus;
+    pub impl ~str: plus { fn plus() -> int { 200 } }
 }
 
 trait uint_utils {
diff --git a/src/test/run-pass/struct-field-assignability.rs b/src/test/run-pass/struct-field-assignability.rs
new file mode 100644 (file)
index 0000000..93c490b
--- /dev/null
@@ -0,0 +1,9 @@
+struct Foo {
+    x: &int
+}
+
+fn main() {
+    let f = Foo { x: @3 };
+    assert *f.x == 3;
+}
+
diff --git a/src/test/run-pass/super.rs b/src/test/run-pass/super.rs
new file mode 100644 (file)
index 0000000..0eb9226
--- /dev/null
@@ -0,0 +1,12 @@
+pub mod a {
+    pub fn f() {}
+    pub mod b {
+        fn g() {
+            super::f();
+        }
+    }
+}
+
+fn main() {
+}
+
index d95f4af791c654d8fda8f67936b573330cdc6f76..311da9762b3c796947506cf3dc06def0b0ee2d21 100644 (file)
@@ -17,12 +17,12 @@ fn main() {
     test06();
 }
 
-fn test00_start(ch: core::oldcomm::Chan<int>, message: int, count: int) {
+fn test00_start(ch: ::core::oldcomm::Chan<int>, message: int, count: int) {
     debug!("Starting test00_start");
     let mut i: int = 0;
     while i < count {
         debug!("Sending Message");
-        core::oldcomm::send(ch, message + 0);
+        ::core::oldcomm::send(ch, message + 0);
         i = i + 1;
     }
     debug!("Ending test00_start");
@@ -33,8 +33,8 @@ fn test00() {
     let number_of_messages: int = 4;
     debug!("Creating tasks");
 
-    let po = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&po);
+    let po = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&po);
 
     let mut i: int = 0;
 
@@ -50,7 +50,7 @@ fn test00() {
     let mut sum: int = 0;
     for results.each |r| {
         i = 0;
-        while i < number_of_messages { sum += core::oldcomm::recv(po); i = i + 1; }
+        while i < number_of_messages { sum += ::core::oldcomm::recv(po); i = i + 1; }
     }
 
     for results.each |r| { r.recv(); }
@@ -63,19 +63,19 @@ fn test00() {
 }
 
 fn test01() {
-    let p = core::oldcomm::Port();
+    let p = ::core::oldcomm::Port();
     debug!("Reading from a port that is never written to.");
-    let value: int = core::oldcomm::recv(p);
+    let value: int = ::core::oldcomm::recv(p);
     log(debug, value);
 }
 
 fn test02() {
-    let p = core::oldcomm::Port();
-    let c = core::oldcomm::Chan(&p);
+    let p = ::core::oldcomm::Port();
+    let c = ::core::oldcomm::Chan(&p);
     debug!("Writing to a local task channel.");
-    core::oldcomm::send(c, 42);
+    ::core::oldcomm::send(c, 42);
     debug!("Reading from a local task port.");
-    let value: int = core::oldcomm::recv(p);
+    let value: int = ::core::oldcomm::recv(p);
     log(debug, value);
 }
 
@@ -93,22 +93,22 @@ fn test04() {
     debug!("Finishing up.");
 }
 
-fn test05_start(ch: core::oldcomm::Chan<int>) {
-    core::oldcomm::send(ch, 10);
-    core::oldcomm::send(ch, 20);
-    core::oldcomm::send(ch, 30);
-    core::oldcomm::send(ch, 30);
-    core::oldcomm::send(ch, 30);
+fn test05_start(ch: ::core::oldcomm::Chan<int>) {
+    ::core::oldcomm::send(ch, 10);
+    ::core::oldcomm::send(ch, 20);
+    ::core::oldcomm::send(ch, 30);
+    ::core::oldcomm::send(ch, 30);
+    ::core::oldcomm::send(ch, 30);
 }
 
 fn test05() {
-    let po = core::oldcomm::Port();
-    let ch = core::oldcomm::Chan(&po);
+    let po = ::core::oldcomm::Port();
+    let ch = ::core::oldcomm::Chan(&po);
     task::spawn(|| test05_start(ch) );
     let mut value: int;
-    value = core::oldcomm::recv(po);
-    value = core::oldcomm::recv(po);
-    value = core::oldcomm::recv(po);
+    value = ::core::oldcomm::recv(po);
+    value = ::core::oldcomm::recv(po);
+    value = ::core::oldcomm::recv(po);
     log(debug, value);
 }
 
index 17309d27900f83cac220b12d25501b3ae4253220..d8a8fc26d7fdfb456955b28988b9f70f2e224cdd 100644 (file)
@@ -1,3 +1,5 @@
+// xfail-fast
+
 // 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.
@@ -17,7 +19,7 @@ pub struct Foo {
         dummy: (),
     }
 
-    pub impl Foo : base::HasNew<Foo> {
+    pub impl Foo : ::base::HasNew<Foo> {
         static pure fn new() -> Foo {
                        unsafe { io::println("Foo"); }
             Foo { dummy: () }
@@ -28,7 +30,7 @@ pub struct Bar {
         dummy: (),
     }
 
-    pub impl Bar : base::HasNew<Bar> {
+    pub impl Bar : ::base::HasNew<Bar> {
         static pure fn new() -> Bar {
                        unsafe { io::println("Bar"); }
             Bar { dummy: () }
index badb0245b8174f5e9ed3b5858064348f011f54d7..298253b8825d37abcd93a0ac03071611b5bc6104 100644 (file)
@@ -1,22 +1,22 @@
 fn main() {
     let x = @[1, 2, 3];
     match x {
-        [2, .._] => core::util::unreachable(),
+        [2, .._] => ::core::util::unreachable(),
         [1, ..tail] => {
             assert tail == [2, 3];
         }
-        [_] => core::util::unreachable(),
-        [] => core::util::unreachable()
+        [_] => ::core::util::unreachable(),
+        [] => ::core::util::unreachable()
     }
 
     let y = (~[(1, true), (2, false)], 0.5);
     match y {
-        ([_, _, _], 0.5) => core::util::unreachable(),
+        ([_, _, _], 0.5) => ::core::util::unreachable(),
         ([(1, a), (b, false), ..tail], _) => {
             assert a == true;
             assert b == 2;
             assert tail.is_empty();
         }
-        ([..tail], _) => core::util::unreachable()
+        ([..tail], _) => ::core::util::unreachable()
     }
 }
index ea21408788e880d5bf1b25b941a32c0c3710f3e7..6b005bf0e1218fe7781833f80e83490f40b3a5b7 100644 (file)
@@ -3,7 +3,7 @@ fn main() {
     if !x.is_empty() {
         let el = match x {
             [1, ..ref tail] => &tail[0], 
-            _ => core::util::unreachable()
+            _ => ::core::util::unreachable()
         };
         io::println(fmt!("%d", *el));
     }
index a3840c9f561f82aab77648a81b68a1777390f74d..687788d8ce83d1d944c4646e875b649d54e243b8 100644 (file)
@@ -14,7 +14,7 @@ fn main() {
     let x = [1, 2, 3, 4, 5];
     match x {
         [a, b, c, d, e, f] => {
-            core::util::unreachable();
+            ::core::util::unreachable();
         }
         [a, b, c, d, e] => {
             assert a == 1;
@@ -24,7 +24,7 @@ fn main() {
             assert e == 5;
         }
         _ => {
-            core::util::unreachable();
+            ::core::util::unreachable();
         }
     }
 
index e2b68a11776e1044cfcc929dfa2f39b308c12193..8a50d7b1643ac21bfbcb1e420b94c94d37fa9c93 100644 (file)
@@ -17,19 +17,19 @@ fn main() {
 
             match tail {
                 [Foo { _ }, _, Foo { _ }, ..tail] => {
-                    core::util::unreachable();
+                    ::core::util::unreachable();
                 }
                 [Foo { string: a }, Foo { string: b }] => {
                     assert a == ~"bar";
                     assert b == ~"baz";
                 }
                 _ => {
-                    core::util::unreachable();
+                    ::core::util::unreachable();
                 }
             }
         }
         _ => {
-            core::util::unreachable();
+            ::core::util::unreachable();
         }
     }
 }